Decompiled source of PocketConch v1.0.6

tony4twentys-Pocket Conch.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Photon.Pun;
using UnityEngine;
using UnityEngine.SceneManagement;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Pocket Conch")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Pocket Conch")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("a4410986-24cc-4512-83f4-313a05cabc62")]
[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 PocketConch;

[BepInPlugin("tony4twentys.Pocket_Conch", "Pocket Conch", "1.0.6")]
public class Plugin : BaseUnityPlugin
{
	[CompilerGenerated]
	private sealed class <NoDropOnClimb_Transpiler>d__34 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private CodeInstruction <>2__current;

		private int <>l__initialThreadId;

		private IEnumerable<CodeInstruction> instructions;

		public IEnumerable<CodeInstruction> <>3__instructions;

		private List<CodeInstruction> <list>5__1;

		private MethodInfo <equip>5__2;

		private FieldInfo <chField>5__3;

		private MethodInfo <helper>5__4;

		private int <i>5__5;

		private CodeInstruction <inst>5__6;

		CodeInstruction IEnumerator<CodeInstruction>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <NoDropOnClimb_Transpiler>d__34(int <>1__state)
		{
			this.<>1__state = <>1__state;
			<>l__initialThreadId = Environment.CurrentManagedThreadId;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<list>5__1 = null;
			<equip>5__2 = null;
			<chField>5__3 = null;
			<helper>5__4 = null;
			<inst>5__6 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Expected O, but got Unknown
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Expected O, but got Unknown
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Expected O, but got Unknown
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Expected O, but got Unknown
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<list>5__1 = new List<CodeInstruction>(instructions);
				<equip>5__2 = AccessTools.Method(typeof(CharacterItems), "EquipSlot", new Type[1] { typeof(Optionable<byte>) }, (Type[])null);
				<chField>5__3 = AccessTools.Field(typeof(CharacterClimbing), "character");
				<helper>5__4 = AccessTools.Method(typeof(Plugin), "ClearHandsForClimb", (Type[])null, (Type[])null);
				<i>5__5 = 0;
				break;
			case 1:
				<>1__state = -1;
				<>2__current = new CodeInstruction(OpCodes.Pop, (object)null);
				<>1__state = 2;
				return true;
			case 2:
				<>1__state = -1;
				<>2__current = new CodeInstruction(OpCodes.Ldarg_0, (object)null);
				<>1__state = 3;
				return true;
			case 3:
				<>1__state = -1;
				<>2__current = new CodeInstruction(OpCodes.Ldfld, (object)<chField>5__3);
				<>1__state = 4;
				return true;
			case 4:
				<>1__state = -1;
				<>2__current = new CodeInstruction(OpCodes.Call, (object)<helper>5__4);
				<>1__state = 5;
				return true;
			case 5:
				<>1__state = -1;
				goto IL_01fb;
			case 6:
				{
					<>1__state = -1;
					<inst>5__6 = null;
					goto IL_01fb;
				}
				IL_01fb:
				<i>5__5++;
				break;
			}
			if (<i>5__5 < <list>5__1.Count)
			{
				<inst>5__6 = <list>5__1[<i>5__5];
				if (<inst>5__6.opcode == OpCodes.Callvirt && object.Equals(<inst>5__6.operand, <equip>5__2))
				{
					<>2__current = new CodeInstruction(OpCodes.Pop, (object)null);
					<>1__state = 1;
					return true;
				}
				<>2__current = <inst>5__6;
				<>1__state = 6;
				return true;
			}
			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();
		}

		[DebuggerHidden]
		IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
		{
			<NoDropOnClimb_Transpiler>d__34 <NoDropOnClimb_Transpiler>d__;
			if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
			{
				<>1__state = 0;
				<NoDropOnClimb_Transpiler>d__ = this;
			}
			else
			{
				<NoDropOnClimb_Transpiler>d__ = new <NoDropOnClimb_Transpiler>d__34(0);
			}
			<NoDropOnClimb_Transpiler>d__.instructions = <>3__instructions;
			return <NoDropOnClimb_Transpiler>d__;
		}

		[DebuggerHidden]
		IEnumerator IEnumerable.GetEnumerator()
		{
			return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
		}
	}

	public const string Id = "tony4twentys.Pocket_Conch";

	public const string Name = "Pocket Conch";

	public const string Version = "1.0.6";

	private static readonly FieldRef<CharacterItems, Character> _characterRef = AccessTools.FieldRefAccess<CharacterItems, Character>("character");

	private static readonly FieldRef<CharacterClimbing, Character> _climbCharacterRef = AccessTools.FieldRefAccess<CharacterClimbing, Character>("character");

	private static readonly FieldRef<CharacterVineClimbing, Character> _vineCharacterRef = AccessTools.FieldRefAccess<CharacterVineClimbing, Character>("character");

	private static readonly FieldRef<CharacterRopeHandling, Character> _ropeCharacterRef = AccessTools.FieldRefAccess<CharacterRopeHandling, Character>("character");

	private const ushort ConchItemID = 69;

	private const string ConchItemName = "Shell Big";

	private const byte TempSlotId = 250;

	private ConfigEntry<KeyCode> _pocketKey;

	private ConfigEntry<KeyCode> _pocketModifier;

	private const float GUARD_WINDOW = 0.3f;

	private const float GUARD_BLOCK = 1.5f;

	private static Plugin _instance;

	private float _lastUnselectSwitchTime;

	private float _suppressSpawnUntil;

	private float _toggleBlockUntil;

	private float _lastToggleTime1;

	private float _lastToggleTime2;

	private int _cooldownTriggers;

	private void Awake()
	{
		_instance = this;
		((BaseUnityPlugin)this).Logger.LogInfo((object)"[Pocket Conch] Awake...");
		_pocketKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Control", "PocketKey", (KeyCode)99, "Key to spawn/equip or destroy the conch when held with the modifier.");
		_pocketModifier = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Control", "PocketModifier", (KeyCode)308, "Modifier key that must be held with PocketKey.");
		SceneManager.activeSceneChanged += OnSceneChanged;
		Harmony.CreateAndPatchAll(typeof(Plugin), (string)null);
		((BaseUnityPlugin)this).Logger.LogInfo((object)"[Pocket Conch] Ready.");
	}

	private static bool IsConch(Item item)
	{
		return (Object)(object)item != (Object)null && item.itemID == 69;
	}

	private static bool IsHoldingConch(Character ch)
	{
		return (Object)(object)ch != (Object)null && IsConch(ch.data.currentItem);
	}

	private static void DestroyHeldItem(Character ch)
	{
		((MonoBehaviourPun)ch.refs.items).photonView.RPC("DestroyHeldItemRpc", PhotonNetwork.LocalPlayer, Array.Empty<object>());
	}

	private static bool TryDestroyHeldConch(Character ch)
	{
		//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_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		if (!IsHoldingConch(ch))
		{
			return false;
		}
		DestroyHeldItem(ch);
		try
		{
			Optionable<byte> currentSelectedSlot = ch.refs.items.currentSelectedSlot;
			if (currentSelectedSlot.IsSome)
			{
				byte value = currentSelectedSlot.Value;
				ItemSlot[] array = ch.player?.itemSlots;
				if (array != null && value < array.Length)
				{
					ItemSlot val = array[value];
					if (val != null && IsConch(val.prefab))
					{
						ch.player.EmptySlot(currentSelectedSlot);
					}
				}
			}
		}
		catch
		{
		}
		try
		{
			Player player = ch.player;
			if (player != null)
			{
				player.EmptySlot(Optionable<byte>.Some((byte)250));
			}
		}
		catch
		{
		}
		try
		{
			ch.refs.items.EquipSlot(Optionable<byte>.None);
		}
		catch
		{
		}
		return true;
	}

	private static int FindConchIndexPrimary(Character ch)
	{
		if ((Object)(object)ch == (Object)null || (Object)(object)ch.player == (Object)null || ch.player.itemSlots == null)
		{
			return -1;
		}
		ItemSlot[] itemSlots = ch.player.itemSlots;
		int num = Mathf.Min(itemSlots.Length, 3);
		for (int i = 0; i < num; i++)
		{
			ItemSlot val = itemSlots[i];
			if (val != null && !val.IsEmpty() && IsConch(val.prefab))
			{
				return i;
			}
		}
		return -1;
	}

	private static bool RemoveConchFromPrimary(Character ch)
	{
		//IL_0079: 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_0059: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ch == (Object)null)
		{
			return false;
		}
		int num = FindConchIndexPrimary(ch);
		if (num < 0)
		{
			return false;
		}
		try
		{
			ch.refs.items.EquipSlot(Optionable<byte>.None);
		}
		catch
		{
		}
		try
		{
			Player player = ch.player;
			if (player != null)
			{
				player.EmptySlot(Optionable<byte>.Some((byte)250));
			}
		}
		catch
		{
		}
		ch.refs.items.EquipSlot(Optionable<byte>.Some((byte)num));
		if (TryDestroyHeldConch(ch))
		{
			return true;
		}
		return false;
	}

	private static bool TryEquipConch(Character ch)
	{
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		if (IsHoldingConch(ch))
		{
			return true;
		}
		if (!ch.player.tempFullSlot.IsEmpty())
		{
			return true;
		}
		ItemSlot[] array = ch.player.itemSlots ?? Array.Empty<ItemSlot>();
		for (byte b = 0; b < array.Length; b++)
		{
			ItemSlot val = array[b];
			if (val != null && IsConch(val.prefab))
			{
				ch.refs.items.EquipSlot(Optionable<byte>.Some(b));
				return true;
			}
		}
		return false;
	}

	private static void SpawnConch(Character ch)
	{
		((MonoBehaviourPun)ch.refs.items).photonView.RPC("RPC_SpawnItemInHandMaster", (RpcTarget)2, new object[1] { "Shell Big" });
	}

	private void Update()
	{
		//IL_0007: 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)
		if (!Input.GetKey(_pocketModifier.Value) || !Input.GetKeyDown(_pocketKey.Value))
		{
			return;
		}
		Character localCharacter = Character.localCharacter;
		if ((Object)(object)localCharacter == (Object)null)
		{
			return;
		}
		float unscaledTime = Time.unscaledTime;
		if (unscaledTime < _toggleBlockUntil)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[Pocket Conch] Toggle is on cooldown.");
		}
		else if (_lastToggleTime2 > 0f && unscaledTime - _lastToggleTime2 <= 1f)
		{
			_cooldownTriggers++;
			float num = 5f * (float)_cooldownTriggers;
			_toggleBlockUntil = unscaledTime + num;
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"[Pocket Conch] Toggle spam detected. Cooldown {num:0.0}s (x{_cooldownTriggers}).");
		}
		else if (TryDestroyHeldConch(localCharacter))
		{
			_lastToggleTime2 = _lastToggleTime1;
			_lastToggleTime1 = unscaledTime;
		}
		else if (RemoveConchFromPrimary(localCharacter))
		{
			_lastToggleTime2 = _lastToggleTime1;
			_lastToggleTime1 = unscaledTime;
		}
		else if ((Object)(object)localCharacter.data != (Object)null && localCharacter.data.isGrounded && !localCharacter.data.isClimbingAnything)
		{
			unscaledTime = Time.unscaledTime;
			if (unscaledTime - _lastUnselectSwitchTime <= 0.3f && unscaledTime >= _suppressSpawnUntil)
			{
				_suppressSpawnUntil = unscaledTime + 1.5f;
			}
			if (!(unscaledTime < _suppressSpawnUntil))
			{
				SpawnConch(localCharacter);
				_lastToggleTime2 = _lastToggleTime1;
				_lastToggleTime1 = unscaledTime;
			}
		}
		else
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[Pocket Conch] Cannot spawn while climbing or when not grounded.");
		}
	}

	private void OnDestroy()
	{
		SceneManager.activeSceneChanged -= OnSceneChanged;
	}

	private void OnSceneChanged(Scene oldScene, Scene newScene)
	{
		_cooldownTriggers = 0;
		_lastToggleTime1 = 0f;
		_lastToggleTime2 = 0f;
		_toggleBlockUntil = 0f;
		((BaseUnityPlugin)this).Logger.LogInfo((object)"[Pocket Conch] Scene changed — toggle cooldown reset.");
	}

	private static void ClearHandsForClimb(Character ch)
	{
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ch == (Object)null || (Object)(object)ch.data == (Object)null)
		{
			return;
		}
		if (IsHoldingConch(ch) && IsInventoryFull(ch))
		{
			((MonoBehaviourPun)ch.refs.items).photonView.RPC("DestroyHeldItemRpc", PhotonNetwork.LocalPlayer, Array.Empty<object>());
			if ((Object)(object)ch.player != (Object)null)
			{
				ch.player.EmptySlot(Optionable<byte>.Some((byte)250));
			}
		}
		ch.refs.items.EquipSlot(Optionable<byte>.None);
	}

	[IteratorStateMachine(typeof(<NoDropOnClimb_Transpiler>d__34))]
	[HarmonyPatch(typeof(CharacterClimbing), "TryToStartWallClimb")]
	[HarmonyTranspiler]
	private static IEnumerable<CodeInstruction> NoDropOnClimb_Transpiler(IEnumerable<CodeInstruction> instructions)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <NoDropOnClimb_Transpiler>d__34(-2)
		{
			<>3__instructions = instructions
		};
	}

	[HarmonyPatch(typeof(CharacterVineClimbing), "GrabVineRpc")]
	[HarmonyPrefix]
	private static void Pre_GrabVine(CharacterVineClimbing __instance)
	{
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		Character val = _vineCharacterRef.Invoke(__instance);
		if ((Object)(object)val == (Object)null || !val.IsLocal || (Object)(object)val.data == (Object)null || !IsHoldingConch(val) || !IsInventoryFull(val))
		{
			return;
		}
		((MonoBehaviourPun)val.refs.items).photonView.RPC("DestroyHeldItemRpc", PhotonNetwork.LocalPlayer, Array.Empty<object>());
		try
		{
			val.refs.items.EquipSlot(Optionable<byte>.None);
		}
		catch
		{
		}
	}

	[HarmonyPatch(typeof(CharacterRopeHandling), "GrabRopeRpc")]
	[HarmonyPrefix]
	private static void Pre_GrabRope(CharacterRopeHandling __instance)
	{
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		Character val = _ropeCharacterRef.Invoke(__instance);
		if ((Object)(object)val == (Object)null || !val.IsLocal || (Object)(object)val.data == (Object)null || !IsHoldingConch(val) || !IsInventoryFull(val))
		{
			return;
		}
		((MonoBehaviourPun)val.refs.items).photonView.RPC("DestroyHeldItemRpc", PhotonNetwork.LocalPlayer, Array.Empty<object>());
		try
		{
			val.refs.items.EquipSlot(Optionable<byte>.None);
		}
		catch
		{
		}
	}

	[HarmonyPatch(typeof(CharacterItems), "EquipSlot")]
	[HarmonyPrefix]
	private static void Pre_EquipSlot(CharacterItems __instance, Optionable<byte> slotID)
	{
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			Character val = _characterRef.Invoke(__instance);
			if (!((Object)(object)val == (Object)null) && val.IsLocal && !((Object)(object)val.data == (Object)null) && !slotID.IsSome && (Object)(object)val.data.currentItem != (Object)null && IsConch(val.data.currentItem) && IsInventoryFull(val))
			{
				__instance.DestroyHeldItemRpc();
				Player player = val.player;
				if ((Object)(object)player != (Object)null)
				{
					player.EmptySlot(Optionable<byte>.Some((byte)250));
				}
			}
		}
		catch
		{
		}
	}

	[HarmonyPatch(typeof(CharacterItems), "DropAllItems")]
	[HarmonyPrefix]
	private static bool DropAllExceptConch(CharacterItems __instance, bool includeBackpack)
	{
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: 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_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_0209: Unknown result type (might be due to invalid IL or missing references)
		//IL_020b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0215: Unknown result type (might be due to invalid IL or missing references)
		//IL_021a: Unknown result type (might be due to invalid IL or missing references)
		//IL_021f: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
		Character val = _characterRef.Invoke(__instance);
		if ((Object)(object)val == (Object)null)
		{
			return true;
		}
		if ((Object)(object)((MonoBehaviourPun)val).photonView == (Object)null || !((MonoBehaviourPun)val).photonView.IsMine)
		{
			return true;
		}
		FieldInfo fieldInfo = AccessTools.Field(typeof(CharacterItems), "currentSelectedSlot");
		FieldInfo fieldInfo2 = AccessTools.Field(typeof(CharacterItems), "throwChargeLevel");
		Optionable<byte> val2 = (Optionable<byte>)fieldInfo.GetValue(__instance);
		float num = (float)fieldInfo2.GetValue(__instance);
		Transform transform = ((Component)val.refs.hip).transform;
		Vector3 val3 = transform.forward;
		if (Vector3.Dot(val3, Vector3.up) < 0f)
		{
			val3 = -val3;
		}
		Vector3 val4 = transform.position + val3 * 0.6f;
		PhotonView component = ((Component)__instance).GetComponent<PhotonView>();
		if (val2.IsSome && Object.op_Implicit((Object)(object)val.data.currentItem))
		{
			byte value = val2.Value;
			ItemSlot itemSlot = val.player.GetItemSlot(value);
			if (!itemSlot.IsEmpty() && (Object)(object)itemSlot.prefab != (Object)null && IsConch(itemSlot.prefab))
			{
				((MonoBehaviourPun)val.player).photonView.RPC("RPCRemoveItemFromSlot", (RpcTarget)2, new object[1] { value });
			}
			else
			{
				component.RPC("DropItemRpc", (RpcTarget)0, new object[6]
				{
					num,
					value,
					((Component)val.data.currentItem).transform.position,
					Vector3.zero,
					((Component)val.data.currentItem).transform.rotation,
					itemSlot.data
				});
			}
			val4 += Vector3.up * 0.5f;
		}
		for (int num2 = (includeBackpack ? 3 : 2); num2 >= 0; num2--)
		{
			byte b = (byte)num2;
			ItemSlot itemSlot2 = val.player.GetItemSlot(b);
			if (!itemSlot2.IsEmpty() && (Object)(object)itemSlot2.prefab != (Object)null && IsConch(itemSlot2.prefab))
			{
				((MonoBehaviourPun)val.player).photonView.RPC("RPCRemoveItemFromSlot", (RpcTarget)2, new object[1] { b });
			}
			else
			{
				component.RPC("DropItemFromSlotRPC", (RpcTarget)0, new object[2] { b, val4 });
			}
			val4 += Vector3.up * 0.5f;
		}
		return false;
	}

	[HarmonyPatch(typeof(CharacterItems), "DoDropping")]
	[HarmonyPrefix]
	private static bool BlockConchDropping(CharacterItems __instance)
	{
		Character val = _characterRef.Invoke(__instance);
		return (Object)(object)val == (Object)null || !IsHoldingConch(val);
	}

	private static bool IsInventoryFull(Character ch)
	{
		if ((Object)(object)ch == (Object)null)
		{
			return false;
		}
		ItemSlot[] array = (((Object)(object)ch.player != (Object)null) ? ch.player.itemSlots : null);
		if (array == null || array.Length == 0)
		{
			return false;
		}
		foreach (ItemSlot val in array)
		{
			if (val == null || val.IsEmpty())
			{
				return false;
			}
		}
		return true;
	}

	private static bool AreMainSlotsFull(Character ch)
	{
		if ((Object)(object)ch == (Object)null || (Object)(object)ch.player == (Object)null || ch.player.itemSlots == null)
		{
			return false;
		}
		ItemSlot[] itemSlots = ch.player.itemSlots;
		int num = Mathf.Min(itemSlots.Length, 3);
		for (int i = 0; i < num; i++)
		{
			ItemSlot val = itemSlots[i];
			if (val == null || val.IsEmpty())
			{
				return false;
			}
		}
		return num == 3;
	}

	private static bool HasConchInMainSlots(Character ch)
	{
		if ((Object)(object)ch == (Object)null || (Object)(object)ch.player == (Object)null || ch.player.itemSlots == null)
		{
			return false;
		}
		ItemSlot[] itemSlots = ch.player.itemSlots;
		int num = Mathf.Min(itemSlots.Length, 3);
		for (int i = 0; i < num; i++)
		{
			ItemSlot val = itemSlots[i];
			if (val != null && !val.IsEmpty() && IsConch(val.prefab))
			{
				return true;
			}
		}
		return false;
	}

	private static bool InventoryFullOfNonConch(Character ch)
	{
		return AreMainSlotsFull(ch) && !HasConchInMainSlots(ch);
	}

	[HarmonyPatch(typeof(CharacterItems), "DoSwitching")]
	[HarmonyPrefix]
	private static bool BlockConchSwitchWhenFull(CharacterItems __instance)
	{
		Character val = _characterRef.Invoke(__instance);
		if ((Object)(object)val != (Object)null && val.IsLocal)
		{
			try
			{
				CharacterInput input = val.input;
				if ((Object)(object)input != (Object)null && input.unselectSlotWasPressed && (Object)(object)_instance != (Object)null)
				{
					_instance._lastUnselectSwitchTime = Time.unscaledTime;
				}
			}
			catch
			{
			}
		}
		if ((Object)(object)val == (Object)null || !val.IsLocal)
		{
			return true;
		}
		if (!IsHoldingConch(val))
		{
			return true;
		}
		if (!InventoryFullOfNonConch(val))
		{
			return true;
		}
		return false;
	}
}