Decompiled source of Safe Beehive Looting v3.0.0

tony4twentys-Safe Beehive Looting.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PEAKLib.Core;
using Photon.Pun;
using Photon.Realtime;
using PhotonCustomPropsUtils;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
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("Safe Beehive Looting")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Safe Beehive Looting")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("825daf2a-23c0-489c-b237-ebbe84d04038")]
[assembly: AssemblyFileVersion("3.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("3.0.0.0")]
[module: UnverifiableCode]
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;
		}
	}
}
namespace SafeBeehiveLooting
{
	internal static class BeeSwarmAccess
	{
		private static readonly FieldRef<BeeSwarm, bool> Dispersing = AccessTools.FieldRefAccess<BeeSwarm, bool>("dispersing");

		private static readonly FieldRef<BeeSwarm, bool> HiveDestroyed = AccessTools.FieldRefAccess<BeeSwarm, bool>("hiveDestroyed");

		private static readonly FieldRef<BeeSwarm, float> BeehiveDangerTick = AccessTools.FieldRefAccess<BeeSwarm, float>("beehiveDangerTick");

		private static readonly MethodInfo DisperseMethod = AccessTools.Method(typeof(BeeSwarm), "Disperse", (Type[])null, (Type[])null);

		internal static bool GetDispersing(BeeSwarm swarm)
		{
			return Dispersing.Invoke(swarm);
		}

		internal static void SetDispersing(BeeSwarm swarm, bool value)
		{
			Dispersing.Invoke(swarm) = value;
		}

		internal static void SetHiveDestroyed(BeeSwarm swarm, bool value)
		{
			HiveDestroyed.Invoke(swarm) = value;
		}

		internal static void SetDangerTick(BeeSwarm swarm, float value)
		{
			BeehiveDangerTick.Invoke(swarm) = value;
		}

		internal static void CallDisperse(BeeSwarm swarm)
		{
			if (DisperseMethod != null)
			{
				DisperseMethod.Invoke(swarm, null);
			}
			else if (Object.op_Implicit((Object)(object)swarm) && Object.op_Implicit((Object)(object)((MonoBehaviourPun)swarm).photonView))
			{
				((MonoBehaviourPun)swarm).photonView.RPC("DisperseRPC", (RpcTarget)0, Array.Empty<object>());
			}
		}
	}
	[BepInPlugin("tony4twentys.Safe_Beehive_looting", "Safe Beehive Looting", "3.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class SafeBeehiveLootingPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "tony4twentys.Safe_Beehive_looting";

		public const string PluginName = "Safe Beehive Looting";

		public const string PluginVersion = "3.0.0";

		internal const float BeeStingResistanceCap = 0.06f;

		internal const string HarvestPromptLabel = "harvest";

		private Harmony _harmony;

		private ConfigEntry<float> _beeCheckRadius;

		private ConfigEntry<float> _smokeProximityTime;

		private ConfigEntry<float> _checkInterval;

		private ConfigEntry<bool> _enableLogging;

		private ConfigEntry<bool> _blowgunKnocksDownHives;

		private ConfigEntry<bool> _allowBeehiveInInventory;

		private ConfigEntry<bool> _enableHoneyHarvest;

		private ConfigEntry<KeyCode> _harvestKey;

		private ConfigEntry<int> _customHoneycombCount;

		private ConfigEntry<bool> _enableBeeCalm;

		private ConfigEntry<float> _flareSmokeCalmSeconds;

		private ConfigEntry<float> _blowgunCalmSeconds;

		private ConfigEntry<float> _harvestRegenIntervalSeconds;

		private ConfigEntry<bool> _enableFallBreakBeehives;

		private ConfigEntry<float> _minFallInjuryToBreakHive;

		private ConfigEntry<float> _campfireCalmSeconds;

		private ConfigEntry<bool> _trustedBeekeeper;

		private ConfigEntry<bool> _enableBeeStingResistance;

		private ConfigEntry<float> _beeStingResistanceGainScale;

		private readonly Dictionary<int, FlareSmokeSession> _sessions = new Dictionary<int, FlareSmokeSession>();

		internal static SafeBeehiveLootingPlugin Instance { get; private set; }

		private BeehiveSyncedSettings Effective => GetEffectiveSettings();

		internal bool IsClientOnlyFallback => BeehiveModAuthorizationService.IsClientOnlyFallback();

		internal bool IsWaitingForHostConfig => BeehiveModAuthorizationService.IsWaitingForHostConfig();

		internal float BeeCheckRadius => Mathf.Max(0.5f, Effective.BeeCheckRadius);

		internal float SmokeProximityTime => Mathf.Max(0.1f, Effective.SmokeProximityTime);

		internal float CheckInterval => Mathf.Max(0.1f, Effective.CheckInterval);

		internal bool EnableLogging => _enableLogging.Value;

		internal bool BlowgunKnocksDownHives => IsClientOnlyFallback || Effective.BlowgunKnocksDownHives;

		internal bool AllowBeehiveInInventory => IsClientOnlyFallback ? _allowBeehiveInInventory.Value : Effective.AllowBeehiveInInventory;

		internal bool EnableHoneyHarvest => BeehiveModAuthorizationService.CanUseFullGameplay() && Effective.EnableHoneyHarvest;

		internal KeyCode HarvestKey => _harvestKey.Value;

		internal int CustomHoneycombCount => Mathf.Max(1, Effective.CustomHoneycombCount);

		internal int EffectiveHoneycombCount => EnableHoneyHarvest ? CustomHoneycombCount : 4;

		internal bool EnableBeeCalm => BeehiveModAuthorizationService.CanUseFullGameplay() && Effective.EnableBeeCalm;

		internal float FlareSmokeCalmSeconds => Mathf.Max(0f, Effective.FlareSmokeCalmSeconds);

		internal float BlowgunCalmSeconds => Mathf.Max(0f, Effective.BlowgunCalmSeconds);

		internal float HarvestRegenIntervalSeconds => Mathf.Max(0f, Effective.HarvestRegenIntervalSeconds);

		internal bool EnableFallBreakBeehives => BeehiveModAuthorizationService.CanUseFullGameplay() && Effective.EnableFallBreakBeehives;

		internal float MinFallInjuryToBreakHive => Mathf.Max(0f, Effective.MinFallInjuryToBreakHive);

		internal float CampfireCalmSeconds => Mathf.Max(0f, Effective.CampfireCalmSeconds);

		internal bool TrustedBeekeeper => BeehiveModAuthorizationService.CanUseFullGameplay() && Effective.TrustedBeekeeper;

		internal bool EnableBeeStingResistance => BeehiveModAuthorizationService.CanUseFullGameplay() && Effective.EnableBeeStingResistance;

		internal float BeeStingResistanceGainScale => Mathf.Max(0f, Effective.BeeStingResistanceGainScale);

		internal BeehiveSyncedSettings BuildLocalSnapshot()
		{
			return new BeehiveSyncedSettings
			{
				BeeCheckRadius = _beeCheckRadius.Value,
				SmokeProximityTime = _smokeProximityTime.Value,
				CheckInterval = _checkInterval.Value,
				BlowgunKnocksDownHives = _blowgunKnocksDownHives.Value,
				AllowBeehiveInInventory = _allowBeehiveInInventory.Value,
				EnableHoneyHarvest = _enableHoneyHarvest.Value,
				CustomHoneycombCount = Mathf.Max(1, _customHoneycombCount.Value),
				EnableBeeCalm = _enableBeeCalm.Value,
				FlareSmokeCalmSeconds = _flareSmokeCalmSeconds.Value,
				BlowgunCalmSeconds = _blowgunCalmSeconds.Value,
				CampfireCalmSeconds = _campfireCalmSeconds.Value,
				TrustedBeekeeper = _trustedBeekeeper.Value,
				HarvestRegenIntervalSeconds = _harvestRegenIntervalSeconds.Value,
				EnableFallBreakBeehives = _enableFallBreakBeehives.Value,
				MinFallInjuryToBreakHive = _minFallInjuryToBreakHive.Value,
				EnableBeeStingResistance = _enableBeeStingResistance.Value,
				BeeStingResistanceGainScale = _beeStingResistanceGainScale.Value
			};
		}

		internal BeehiveSyncedSettings GetEffectiveSettings()
		{
			if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient && BeehiveModAuthorizationService.IsHostAuthorized && BeehiveHostConfigSyncService.HasRemoteHostSettings)
			{
				return BeehiveHostConfigSyncService.RemoteHostSettings;
			}
			return BuildLocalSnapshot();
		}

		internal void LogInfo(string message)
		{
			if (_enableLogging.Value)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)message);
			}
		}

		internal void LogAlways(string message)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)message);
		}

		internal void LogWarning(string message)
		{
			if (_enableLogging.Value)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)message);
			}
		}

		internal void LogError(string message)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)message);
		}

		private void Awake()
		{
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Expected O, but got Unknown
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Expected O, but got Unknown
			Instance = this;
			_beeCheckRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "BeeCheckRadius", 6f, "Max distance from flare smoke or a lit campfire to a swarm (or its beehive) to count as in range.");
			_smokeProximityTime = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SmokeProximityTime", 3f, "Seconds flare smoke or a lit campfire must stay near bees before calm/dispersal triggers.");
			_checkInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CheckInterval", 0.5f, "How often (seconds) to test smoke/campfire-to-swarm distance.");
			_enableLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableLogging", false, "If true, writes flare/campfire/calm/resistance info (including smoke distances) to the BepInEx log.");
			_blowgunKnocksDownHives = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "KnockDownBeehives", true, "If true, blowgun darts can knock tree beehives loose so they fall.");
			_allowBeehiveInInventory = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AllowBeehiveInInventory", true, "If true, beehives can be pocketed and put in a backpack (vanilla blocks this). Also available in client-only fallback when the host lacks this mod.");
			_enableHoneyHarvest = ((BaseUnityPlugin)this).Config.Bind<bool>("Harvest", "EnableHoneyHarvest", true, "If true, enables harvest prompts, honey regen, and CustomHoneycombCount for break/fall loot. If false, break/fall use vanilla 4 honeycomb.");
			_harvestKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Harvest", "HarvestKey", (KeyCode)103, "Key that harvests honeycomb from a hovered beehive (Pickup still uses Interact). Shown in ModConfig Controls.");
			_harvestKey.SettingChanged += delegate
			{
				BeehiveHarvestSupport.RefreshPrompts();
			};
			_customHoneycombCount = ((BaseUnityPlugin)this).Config.Bind<int>("Harvest", "CustomHoneycombCount", 4, "Honeycomb budget per beehive when EnableHoneyHarvest is on (harvest uses + break/fall loot). Ignored when harvest is off (vanilla 4).");
			try
			{
				((BaseUnityPlugin)this).Config.Remove(new ConfigDefinition("Harvest", "MaxHoneyHarvests"));
			}
			catch
			{
			}
			_enableBeeCalm = ((BaseUnityPlugin)this).Config.Bind<bool>("Calm", "EnableBeeCalm", true, "If true, flare smoke, blowgun, and lit campfires calm bees. If false, those same sources disperse bees instead (flare / campfire / blowgun).");
			_flareSmokeCalmSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Calm", "FlareSmokeCalmSeconds", 300f, "How long (seconds) bees stay calm after flare smoke reaches them.");
			_blowgunCalmSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Calm", "BlowgunCalmSeconds", 300f, "How long (seconds) bees stay calm after a blowgun dart hits their hive.");
			_campfireCalmSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Calm", "CampfireCalmSeconds", 300f, "How long (seconds) bees stay calm after a lit campfire reaches them.");
			_trustedBeekeeper = ((BaseUnityPlugin)this).Config.Bind<bool>("Calm", "TrustedBeekeeper", true, "If true, calming a hive 4 times (any source) OR at 2 distinct lit campfires permanently calms it for the bonded owner: swarm despawns, honey keeps regenerating. Giving the hive to someone else brings the swarm back.");
			_harvestRegenIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Calm", "HarvestRegenIntervalSeconds", 60f, "While calm, seconds between each restored harvest use (e.g. 60 with CustomHoneycombCount 4 = 4 minutes to refill).");
			_enableBeeStingResistance = ((BaseUnityPlugin)this).Config.Bind<bool>("Resistance", "EnableBeeStingResistance", true, "If true, taking bee poison builds resistance that reduces future bee StatusField poison (other poison sources unchanged). Cap is fixed at angry bee rate (0.06) for full immunity.");
			_beeStingResistanceGainScale = ((BaseUnityPlugin)this).Config.Bind<float>("Resistance", "BeeStingResistanceGainScale", 0.02f, "How fast resistance grows vs poison taken. resist += poisonApplied * scale. At 0.02, ~50s of angry stinging reaches full immunity (0.06).");
			_enableFallBreakBeehives = ((BaseUnityPlugin)this).Config.Bind<bool>("FallBreak", "EnableFallBreakBeehives", true, "If true, hard falls smash beehives in your hands, pockets, or equipped backpack.");
			_minFallInjuryToBreakHive = ((BaseUnityPlugin)this).Config.Bind<float>("FallBreak", "MinFallInjuryToBreakHive", 0.25f, "Minimum fall-injury amount (same scale as vanilla Injury from CheckFallDamage) required to break carried beehives.");
			_harmony = new Harmony("tony4twentys.Safe_Beehive_looting");
			_harmony.PatchAll();
			SceneRegistries.SeedFromScene();
			BeeCalmSupport.Initialize();
			BeehiveModAuthorizationService.Initialize();
			BeeStingResistanceSupport.Initialize();
			BeehiveInventorySupport.ApplyInventoryPermission();
			BeeCalmSupport.StartRegenLoop(this);
			CampfireCalmSupport.StartLoop(this);
			TrustedBeekeeperSupport.StartLoop(this);
			((BaseUnityPlugin)this).Config.SettingChanged += OnConfigSettingChanged;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[Safe Beehive Looting] v3.0.0 loaded (host handshake + config sync)");
		}

		private void OnConfigSettingChanged(object sender, SettingChangedEventArgs e)
		{
			if (((e != null) ? e.ChangedSetting : null) != null && (object)e.ChangedSetting != _enableLogging && (object)e.ChangedSetting != _harvestKey)
			{
				if ((object)e.ChangedSetting == _allowBeehiveInInventory)
				{
					BeehiveInventorySupport.ApplyInventoryPermission();
				}
				BeehiveModAuthorizationService.OnHostConfigChangedLocally();
			}
		}

		private void Update()
		{
			BeehiveHarvestSupport.TickInput();
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.SettingChanged -= OnConfigSettingChanged;
			BeeCalmSupport.Shutdown();
			BeeStingResistanceSupport.Shutdown();
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		internal void RegisterLitFlare(Flare flare)
		{
			if (!Object.op_Implicit((Object)(object)flare))
			{
				return;
			}
			TrackableNetworkObject component = ((Component)flare).GetComponent<TrackableNetworkObject>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				LogWarning("[SafeBeehiveLooting] Lit flare has no TrackableNetworkObject.");
				return;
			}
			int num = component.instanceID;
			if (num == 0)
			{
				PhotonView component2 = ((Component)flare).GetComponent<PhotonView>();
				if (Object.op_Implicit((Object)(object)component2))
				{
					num = component2.ViewID;
				}
			}
			if (num == 0)
			{
				LogWarning("[SafeBeehiveLooting] Could not resolve a stable ID for lit flare.");
			}
			else if (!_sessions.ContainsKey(num))
			{
				FlareSmokeSession flareSmokeSession = new FlareSmokeSession(this, flare, component, num);
				_sessions[num] = flareSmokeSession;
				flareSmokeSession.Start();
				LogInfo($"[SafeBeehiveLooting] Tracking lit flare id={num} (active sessions: {_sessions.Count})");
			}
		}

		internal void UnregisterSession(int key)
		{
			_sessions.Remove(key);
		}

		internal SmokeCheckResult CheckSwarms(Vector3 smokePosition, bool actIfInRange)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			SmokeCheckResult result = default(SmokeCheckResult);
			bool enableBeeCalm = EnableBeeCalm;
			if (IsWaitingForHostConfig)
			{
				actIfInRange = false;
			}
			float beeCheckRadius = BeeCheckRadius;
			float num = beeCheckRadius * beeCheckRadius;
			float num2 = float.MaxValue;
			float flareSmokeCalmSeconds = FlareSmokeCalmSeconds;
			SceneRegistries.PruneDestroyed();
			foreach (BeeSwarm swarm in SceneRegistries.Swarms)
			{
				if (!Object.op_Implicit((Object)(object)swarm) || BeeSwarmAccess.GetDispersing(swarm))
				{
					continue;
				}
				float num3 = SqrDistanceToSwarm(smokePosition, swarm);
				float num4 = Mathf.Sqrt(num3);
				if (num4 < num2)
				{
					num2 = num4;
				}
				if (num3 > num)
				{
					continue;
				}
				result.AnyInRange = true;
				if (!actIfInRange)
				{
					continue;
				}
				if (enableBeeCalm)
				{
					if (!(flareSmokeCalmSeconds <= 0f))
					{
						PhotonView photonView = ((MonoBehaviourPun)swarm).photonView;
						LogInfo($"[SafeBeehiveLooting] Calming BeeSwarm viewId={((photonView != null) ? new int?(photonView.ViewID) : ((int?)null))} via flare smoke");
						BeeCalmSupport.ApplyCalmLocal(swarm, flareSmokeCalmSeconds, "flare-smoke");
						result.CalmedAny = true;
					}
				}
				else
				{
					PhotonView photonView2 = ((MonoBehaviourPun)swarm).photonView;
					LogInfo($"[SafeBeehiveLooting] Releasing BeeSwarm viewId={((photonView2 != null) ? new int?(photonView2.ViewID) : ((int?)null))}");
					ReleaseSwarm(swarm);
					result.DispersedAny = true;
				}
			}
			if (_enableLogging.Value)
			{
				string arg = ((num2 < float.MaxValue) ? $"dist={num2:F1} (radius={beeCheckRadius})" : "none");
				LogInfo($"[SafeBeehiveLooting] Smoke@ {smokePosition} nearest: {arg}");
			}
			return result;
		}

		internal static void ReleaseSwarm(BeeSwarm swarm)
		{
			if (!Object.op_Implicit((Object)(object)swarm) || BeeSwarmAccess.GetDispersing(swarm))
			{
				return;
			}
			swarm.currentAggroCharacter = null;
			Beehive beehive = swarm.beehive;
			if (Object.op_Implicit((Object)(object)beehive))
			{
				if ((Object)(object)beehive.currentBees == (Object)(object)swarm)
				{
					beehive.currentBees = null;
				}
				swarm.beehive = null;
			}
			swarm.beehiveID = -1;
			BeeSwarmAccess.SetHiveDestroyed(swarm, value: true);
			if (Object.op_Implicit((Object)(object)((MonoBehaviourPun)swarm).photonView))
			{
				((MonoBehaviourPun)swarm).photonView.RPC("DisperseRPC", (RpcTarget)0, Array.Empty<object>());
			}
		}

		internal static float SqrDistanceToSwarm(Vector3 smokePosition, BeeSwarm swarm)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_0033: 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_0039: 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)
			Vector3 val = ((Component)swarm).transform.position - smokePosition;
			float num = ((Vector3)(ref val)).sqrMagnitude;
			Beehive beehive = swarm.beehive;
			if (Object.op_Implicit((Object)(object)beehive))
			{
				val = ((Component)beehive).transform.position - smokePosition;
				float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
				if (sqrMagnitude < num)
				{
					num = sqrMagnitude;
				}
			}
			return num;
		}
	}
	internal struct SmokeCheckResult
	{
		public bool AnyInRange;

		public bool DispersedAny;

		public bool CalmedAny;
	}
	internal sealed class FlareSmokeSession
	{
		private readonly SafeBeehiveLootingPlugin _plugin;

		private readonly Flare _flare;

		private readonly TrackableNetworkObject _trackable;

		private readonly int _key;

		private TrackNetworkedObject _smokeVfx;

		private ParticleSystem[] _smokeParticles;

		private float _sessionAge;

		public FlareSmokeSession(SafeBeehiveLootingPlugin plugin, Flare flare, TrackableNetworkObject trackable, int key)
		{
			_plugin = plugin;
			_flare = flare;
			_trackable = trackable;
			_key = key;
		}

		public void Start()
		{
			((MonoBehaviour)_plugin).StartCoroutine(Run());
		}

		private IEnumerator Run()
		{
			float timeInRange = 0f;
			float interval = _plugin.CheckInterval;
			float needInRange = _plugin.SmokeProximityTime;
			_sessionAge = 0f;
			while (IsStillSmoking())
			{
				try
				{
					RefreshSmokeVfx();
					Vector3 smokePosition = GetSmokePosition();
					bool readyToAct = timeInRange + interval >= needInRange;
					SmokeCheckResult check = _plugin.CheckSwarms(smokePosition, readyToAct);
					if (check.AnyInRange)
					{
						timeInRange += interval;
						if (readyToAct)
						{
							if (check.CalmedAny)
							{
								_plugin.LogInfo($"[SafeBeehiveLooting] Flare id={_key} calmed swarm(s); still smoking for more.");
							}
							else if (check.DispersedAny)
							{
								_plugin.LogInfo($"[SafeBeehiveLooting] Flare id={_key} dispersed swarm(s); still smoking for more.");
							}
							timeInRange = 0f;
						}
					}
					else
					{
						timeInRange = 0f;
					}
				}
				catch (Exception arg)
				{
					_plugin.LogError($"[SafeBeehiveLooting] Flare session id={_key} tick failed: {arg}");
					timeInRange = 0f;
				}
				_sessionAge += interval;
				yield return (object)new WaitForSeconds(interval);
			}
			_plugin.UnregisterSession(_key);
			_plugin.LogInfo($"[SafeBeehiveLooting] Flare session id={_key} ended (smoke particles finished)");
		}

		private bool IsStillSmoking()
		{
			RefreshSmokeVfx();
			if (HasLivingSmokeParticles())
			{
				return true;
			}
			return _sessionAge < 2f && IsFlareActiveFlag();
		}

		private bool HasLivingSmokeParticles()
		{
			if (_smokeParticles == null || _smokeParticles.Length == 0)
			{
				return false;
			}
			ParticleSystem[] smokeParticles = _smokeParticles;
			foreach (ParticleSystem val in smokeParticles)
			{
				if (Object.op_Implicit((Object)(object)val) && val.particleCount > 0)
				{
					return true;
				}
			}
			return false;
		}

		private bool IsFlareActiveFlag()
		{
			if (!Object.op_Implicit((Object)(object)_flare))
			{
				return false;
			}
			try
			{
				if (!((ItemComponent)_flare).HasData((DataEntryKey)3))
				{
					return false;
				}
				return ((ItemComponent)_flare).GetData<BoolItemData>((DataEntryKey)3)?.Value ?? false;
			}
			catch
			{
				return false;
			}
		}

		private void RefreshSmokeVfx()
		{
			if (Object.op_Implicit((Object)(object)_smokeVfx) && _smokeParticles != null)
			{
				return;
			}
			if (Object.op_Implicit((Object)(object)_trackable) && Object.op_Implicit((Object)(object)_trackable.currentTracker))
			{
				_smokeVfx = _trackable.currentTracker;
			}
			if (!Object.op_Implicit((Object)(object)_smokeVfx))
			{
				TrackNetworkedObject[] array = Object.FindObjectsByType<TrackNetworkedObject>((FindObjectsSortMode)0);
				foreach (TrackNetworkedObject val in array)
				{
					if (Object.op_Implicit((Object)(object)val) && (val.trackedObjectID == _key || !((Object)(object)val.trackedObject != (Object)(object)_trackable)))
					{
						_smokeVfx = val;
						if (Object.op_Implicit((Object)(object)_trackable) && !Object.op_Implicit((Object)(object)_trackable.currentTracker))
						{
							_trackable.currentTracker = val;
						}
						break;
					}
				}
			}
			if (Object.op_Implicit((Object)(object)_smokeVfx) && _smokeParticles == null)
			{
				_smokeParticles = ((Component)_smokeVfx).GetComponentsInChildren<ParticleSystem>(true);
			}
		}

		private Vector3 GetSmokePosition()
		{
			//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_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_006f: 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_005f: 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)
			if (Object.op_Implicit((Object)(object)_smokeVfx))
			{
				return ((Component)_smokeVfx).transform.position;
			}
			if (Object.op_Implicit((Object)(object)_trackable))
			{
				return ((Component)_trackable).transform.position;
			}
			if (Object.op_Implicit((Object)(object)_flare))
			{
				return ((Component)_flare).transform.position;
			}
			return Vector3.zero;
		}
	}
	[HarmonyPatch(typeof(Flare), "EnableFlareVisuals")]
	internal static class FlareEnableVisualsPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Flare __instance)
		{
			if (!((Object)(object)SafeBeehiveLootingPlugin.Instance == (Object)null) && Object.op_Implicit((Object)(object)__instance))
			{
				SafeBeehiveLootingPlugin.Instance.RegisterLitFlare(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(BeeSwarm), "DisperseRPC")]
	internal static class BeeSwarmDispersePatch
	{
		[HarmonyPrefix]
		private static bool Prefix(BeeSwarm __instance)
		{
			if (!Object.op_Implicit((Object)(object)__instance) || BeeSwarmAccess.GetDispersing(__instance))
			{
				return false;
			}
			BeeSwarmAccess.SetDispersing(__instance, value: true);
			((MonoBehaviour)__instance).StartCoroutine(DisperseFadeRoutine(__instance));
			return false;
		}

		private static IEnumerator DisperseFadeRoutine(BeeSwarm swarm)
		{
			if (Object.op_Implicit((Object)(object)swarm.stingerField))
			{
				Object.Destroy((Object)(object)((Component)swarm.stingerField).gameObject);
			}
			ParticleSystem ps = swarm.beeParticles;
			EmissionModule emission = default(EmissionModule);
			ShapeModule shape = default(ShapeModule);
			bool hasPs = Object.op_Implicit((Object)(object)ps);
			float initialEmission = 0f;
			float initialRadius = 0f;
			if (hasPs)
			{
				emission = ps.emission;
				shape = ps.shape;
				initialEmission = ((EmissionModule)(ref emission)).rateOverTimeMultiplier;
				initialRadius = ((ShapeModule)(ref shape)).radius;
			}
			ParticleSystemForceField forceField = swarm.beeForceField;
			bool hasFf = Object.op_Implicit((Object)(object)forceField);
			float gravityMin = 0f;
			float gravityMax = 0f;
			MinMaxCurve gravity;
			if (hasFf)
			{
				gravity = forceField.gravity;
				gravityMin = ((MinMaxCurve)(ref gravity)).constantMin;
				gravity = forceField.gravity;
				gravityMax = ((MinMaxCurve)(ref gravity)).constantMax;
			}
			AudioSource angry = swarm.beeAngryLoop;
			AudioSource idle = swarm.beeIdleLoop;
			float elapsed = 0f;
			while (elapsed < 0.85f)
			{
				if (!Object.op_Implicit((Object)(object)swarm))
				{
					yield break;
				}
				float t = Mathf.Clamp01(elapsed / 0.85f);
				float ease = 1f - Mathf.Pow(1f - t, 3f);
				if (hasPs)
				{
					((ShapeModule)(ref shape)).radius = Mathf.Lerp(initialRadius, initialRadius + 2f, ease);
					((EmissionModule)(ref emission)).rateOverTimeMultiplier = Mathf.Lerp(initialEmission, initialEmission * 0.8f, t);
				}
				if (hasFf)
				{
					float min = Mathf.Lerp(gravityMin, Mathf.Max(gravityMin - 0.2f, 0f), t);
					float max = Mathf.Lerp(gravityMax, Mathf.Max(gravityMax - 0.2f, 0f), t);
					forceField.gravity = new MinMaxCurve(min, max);
				}
				if (Object.op_Implicit((Object)(object)angry))
				{
					angry.volume = Mathf.Lerp(angry.volume, 0.3f, Time.deltaTime * 3f);
				}
				if (Object.op_Implicit((Object)(object)idle))
				{
					idle.volume = Mathf.Lerp(idle.volume, 0.6f, Time.deltaTime * 2f);
				}
				elapsed += Time.deltaTime;
				yield return null;
			}
			float phase2 = 0f;
			while (phase2 < 2.5f)
			{
				if (!Object.op_Implicit((Object)(object)swarm))
				{
					yield break;
				}
				float t2 = Mathf.Clamp01(phase2 / 2.5f);
				float ease2 = 1f - Mathf.Pow(1f - t2, 3f);
				if (hasPs)
				{
					((ShapeModule)(ref shape)).radius = Mathf.Lerp(((ShapeModule)(ref shape)).radius, initialRadius + 3.5f, ease2);
					((EmissionModule)(ref emission)).rateOverTimeMultiplier = Mathf.Lerp(((EmissionModule)(ref emission)).rateOverTimeMultiplier, 0f, t2);
				}
				if (hasFf)
				{
					gravity = forceField.gravity;
					float min2 = Mathf.Lerp(((MinMaxCurve)(ref gravity)).constantMin, 0f, t2);
					gravity = forceField.gravity;
					float max2 = Mathf.Lerp(((MinMaxCurve)(ref gravity)).constantMax, 0f, t2);
					forceField.gravity = new MinMaxCurve(min2, max2);
				}
				if (Object.op_Implicit((Object)(object)angry))
				{
					angry.volume = Mathf.Lerp(angry.volume, 0f, Time.deltaTime * 2f);
				}
				if (Object.op_Implicit((Object)(object)idle))
				{
					idle.volume = Mathf.Lerp(idle.volume, 0.4f, Time.deltaTime * 2f);
				}
				phase2 += Time.deltaTime;
				yield return null;
			}
			while (elapsed + phase2 < 4f)
			{
				if (!Object.op_Implicit((Object)(object)swarm))
				{
					yield break;
				}
				elapsed += Time.deltaTime;
				yield return null;
			}
			if (Object.op_Implicit((Object)(object)swarm) && Object.op_Implicit((Object)(object)((MonoBehaviourPun)swarm).photonView) && ((MonoBehaviourPun)swarm).photonView.IsMine)
			{
				PhotonNetwork.Destroy(((Component)swarm).gameObject);
			}
		}
	}
	internal static class BeehiveInventorySupport
	{
		internal const ushort BeehiveItemId = 8;

		internal static void ApplyInventoryPermission()
		{
			SafeBeehiveLootingPlugin instance = SafeBeehiveLootingPlugin.Instance;
			bool flag = (Object)(object)instance != (Object)null && instance.AllowBeehiveInInventory;
			Item val = default(Item);
			if (ItemDatabase.TryGetItem((ushort)8, ref val) && Object.op_Implicit((Object)(object)val))
			{
				SetStorable(val, flag);
			}
			for (int i = 0; i < Beehive.ALL_BEEHIVES.Count; i++)
			{
				Beehive val2 = Beehive.ALL_BEEHIVES[i];
				if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)((ItemComponent)val2).item))
				{
					SetStorable(((ItemComponent)val2).item, flag);
				}
			}
			instance?.LogInfo(flag ? $"[SafeBeehiveLooting] Beehive itemID={(ushort)8} unlocked for inventory/backpack." : $"[SafeBeehiveLooting] Beehive itemID={(ushort)8} locked out of inventory/backpack.");
		}

		internal static bool SetStorable(Item item, bool allow)
		{
			if (!Object.op_Implicit((Object)(object)item) || item.UIData == null)
			{
				return false;
			}
			if (item.itemID != 8 && !Object.op_Implicit((Object)(object)((Component)item).GetComponent<Beehive>()))
			{
				return false;
			}
			ItemUIData uIData = item.UIData;
			bool result = uIData.canPocket != allow || uIData.canBackpack != allow;
			uIData.canPocket = allow;
			uIData.canBackpack = allow;
			return result;
		}

		internal static void UnlockPrefab()
		{
			ApplyInventoryPermission();
		}

		internal static bool MakeStorable(Item item)
		{
			SafeBeehiveLootingPlugin instance = SafeBeehiveLootingPlugin.Instance;
			bool allow = (Object)(object)instance == (Object)null || instance.AllowBeehiveInInventory;
			return SetStorable(item, allow);
		}
	}
	[HarmonyPatch(typeof(Beehive), "OnEnable")]
	internal static class BeehiveInventoryOnEnablePatch
	{
		[HarmonyPostfix]
		private static void Postfix(Beehive __instance)
		{
			if (Object.op_Implicit((Object)(object)__instance) && Object.op_Implicit((Object)(object)((ItemComponent)__instance).item))
			{
				BeehiveHarvestSupport.GetOrCreateState(__instance);
				BeehiveInventorySupport.MakeStorable(((ItemComponent)__instance).item);
			}
		}
	}
	[HarmonyPatch(typeof(CharacterItems), "EquipSlot")]
	internal static class BeehiveInventoryEquipSlotPatch
	{
		[HarmonyPrefix]
		private static void Prefix(CharacterItems __instance)
		{
			try
			{
				if ((Object)(object)__instance == (Object)null)
				{
					return;
				}
				Character component = ((Component)__instance).GetComponent<Character>();
				if (Object.op_Implicit((Object)(object)component) && !((Object)(object)component.data == (Object)null))
				{
					Item currentItem = component.data.currentItem;
					if (Object.op_Implicit((Object)(object)currentItem))
					{
						BeehiveInventorySupport.MakeStorable(currentItem);
					}
				}
			}
			catch (Exception ex)
			{
				SafeBeehiveLootingPlugin.Instance?.LogError("[SafeBeehiveLooting] Inventory equip refresh failed: " + ex.GetType().Name + ": " + ex.Message);
			}
		}
	}
	[HarmonyPatch(typeof(Action_RaycastDart), "FireDart")]
	internal static class BlowgunBeehiveFireDartPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Action_RaycastDart __instance)
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: 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_0109: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				SafeBeehiveLootingPlugin instance = SafeBeehiveLootingPlugin.Instance;
				if ((Object)(object)instance == (Object)null || !Object.op_Implicit((Object)(object)__instance))
				{
					return;
				}
				bool isWaitingForHostConfig = instance.IsWaitingForHostConfig;
				bool blowgunKnocksDownHives = instance.BlowgunKnocksDownHives;
				bool flag = !isWaitingForHostConfig && instance.EnableBeeCalm && instance.BlowgunCalmSeconds > 0f;
				bool flag2 = !isWaitingForHostConfig && !instance.EnableBeeCalm;
				if ((blowgunKnocksDownHives || flag || flag2) && Object.op_Implicit((Object)(object)__instance.spawnTransform) && !((Object)(object)MainCamera.instance == (Object)null))
				{
					Vector3 position = __instance.spawnTransform.position;
					Vector3 forward = ((Component)MainCamera.instance).transform.forward;
					float maxDistance = __instance.maxDistance;
					float radius = Mathf.Max(0.05f, __instance.dartCollisionSize);
					if (TryFindBeehiveHit(position, forward, maxDistance, radius, out var bestHive, out var hitPoint))
					{
						GameObject dartVFX = __instance.dartVFX;
						float blowgunCalmSeconds = instance.BlowgunCalmSeconds;
						((MonoBehaviour)instance).StartCoroutine(ProcessHiveHitDeferred(bestHive, hitPoint, dartVFX, blowgunKnocksDownHives, flag, flag2, blowgunCalmSeconds));
					}
				}
			}
			catch (Exception arg)
			{
				SafeBeehiveLootingPlugin.Instance?.LogError($"[SafeBeehiveLooting] Blowgun beehive schedule failed: {arg}");
			}
		}

		private static bool TryFindBeehiveHit(Vector3 origin, Vector3 direction, float maxDistance, float radius, out Beehive bestHive, out Vector3 hitPoint)
		{
			//IL_0007: 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_000a: 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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: 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_01b2: 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_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			bestHive = null;
			hitPoint = origin + direction * maxDistance;
			float num = float.MaxValue;
			int num2 = -5;
			RaycastHit[] array = Physics.SphereCastAll(origin, radius, direction, maxDistance, num2, (QueryTriggerInteraction)2);
			for (int i = 0; i < array.Length; i++)
			{
				RaycastHit val = array[i];
				if (Object.op_Implicit((Object)(object)((RaycastHit)(ref val)).collider))
				{
					Beehive componentInParent = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Beehive>();
					if (Object.op_Implicit((Object)(object)componentInParent) && !(((RaycastHit)(ref val)).distance >= num))
					{
						num = ((RaycastHit)(ref val)).distance;
						bestHive = componentInParent;
						hitPoint = ((RaycastHit)(ref val)).point;
					}
				}
			}
			Collider[] array2 = Physics.OverlapSphere(origin, radius, num2, (QueryTriggerInteraction)2);
			foreach (Collider val2 in array2)
			{
				if (Object.op_Implicit((Object)(object)val2))
				{
					Beehive componentInParent2 = ((Component)val2).GetComponentInParent<Beehive>();
					if (Object.op_Implicit((Object)(object)componentInParent2) && !(0f >= num))
					{
						num = 0f;
						bestHive = componentInParent2;
						hitPoint = val2.ClosestPoint(origin);
					}
				}
			}
			Vector3 val3 = ((((Vector3)(ref direction)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref direction)).normalized : Vector3.forward);
			for (int k = 0; k < Beehive.ALL_BEEHIVES.Count; k++)
			{
				Beehive val4 = Beehive.ALL_BEEHIVES[k];
				if (!Object.op_Implicit((Object)(object)val4))
				{
					continue;
				}
				Vector3 val5 = ((Component)val4).transform.position - origin;
				float num3 = Vector3.Dot(val5, val3);
				if (num3 < 0f - radius || num3 > maxDistance + radius)
				{
					continue;
				}
				Vector3 val6 = Vector3.Cross(val3, val5);
				float magnitude = ((Vector3)(ref val6)).magnitude;
				if (!(magnitude > radius + 1.25f))
				{
					float num4 = Mathf.Max(0f, num3);
					if (!(num4 >= num))
					{
						num = num4;
						bestHive = val4;
						hitPoint = ((Component)val4).transform.position;
					}
				}
			}
			return Object.op_Implicit((Object)(object)bestHive);
		}

		private static IEnumerator ProcessHiveHitDeferred(Beehive bestHive, Vector3 hitPoint, GameObject dartVfx, bool wantKnock, bool wantCalm, bool wantDisperse, float calmSeconds)
		{
			//IL_000e: 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)
			yield return null;
			try
			{
				SafeBeehiveLootingPlugin plugin = SafeBeehiveLootingPlugin.Instance;
				if ((Object)(object)plugin == (Object)null || !Object.op_Implicit((Object)(object)bestHive))
				{
					yield break;
				}
				if (wantCalm)
				{
					BeeCalmSupport.ApplyCalm(bestHive, calmSeconds, "blowgun");
				}
				else if (wantDisperse)
				{
					BeeSwarm swarm = BeeCalmSupport.FindSwarmForHive(bestHive);
					if (Object.op_Implicit((Object)(object)swarm) && !BeeSwarmAccess.GetDispersing(swarm))
					{
						PhotonView photonView = ((MonoBehaviourPun)swarm).photonView;
						plugin.LogInfo($"[SafeBeehiveLooting] Blowgun dispersing BeeSwarm viewId={((photonView != null) ? new int?(photonView.ViewID) : ((int?)null))}");
						SafeBeehiveLootingPlugin.ReleaseSwarm(swarm);
					}
				}
				if (wantKnock && BlowgunBeehiveKnockdown.TryKnockDown(bestHive))
				{
					plugin.LogInfo($"[SafeBeehiveLooting] Blowgun knocked down beehive id={bestHive.instanceID}");
					if (Object.op_Implicit((Object)(object)dartVfx))
					{
						Object.Instantiate<GameObject>(dartVfx, hitPoint, Quaternion.identity);
					}
				}
			}
			catch (Exception ex)
			{
				Exception ex2 = ex;
				SafeBeehiveLootingPlugin.Instance?.LogError($"[SafeBeehiveLooting] Blowgun beehive check failed: {ex2}");
			}
		}
	}
	[HarmonyPatch(typeof(Item), "SetKinematicRPC")]
	internal static class BeehiveUnparentOnLoosePatch
	{
		[HarmonyPostfix]
		private static void Postfix(Item __instance, bool value)
		{
			if (!value && Object.op_Implicit((Object)(object)__instance) && Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<Beehive>()))
			{
				SafeBeehiveLootingPlugin instance = SafeBeehiveLootingPlugin.Instance;
				if (!((Object)(object)instance == (Object)null) && instance.BlowgunKnocksDownHives)
				{
					BlowgunBeehiveKnockdown.UnparentIfNeeded(__instance);
				}
			}
		}
	}
	internal static class BlowgunBeehiveKnockdown
	{
		private const float CollisionIgnoreSeconds = 1.5f;

		private const float SettledMaxDepenetration = 0.5f;

		internal static bool TryKnockDown(Beehive hive)
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Invalid comparison between Unknown and I4
			if (!Object.op_Implicit((Object)(object)hive))
			{
				return false;
			}
			Item item = ((ItemComponent)hive).item;
			if (!Object.op_Implicit((Object)(object)item) || !Object.op_Implicit((Object)(object)item.rig))
			{
				return false;
			}
			if ((Object)(object)((Component)item).transform.parent == (Object)null && !item.rig.isKinematic)
			{
				return false;
			}
			DetachSafely(item);
			if ((int)item.itemState > 0)
			{
				item.SetState((ItemState)0, (Character)null);
			}
			else
			{
				item.rig.useGravity = true;
			}
			item.SetKinematicNetworked(false);
			return true;
		}

		internal static void UnparentIfNeeded(Item item)
		{
			if (Object.op_Implicit((Object)(object)item) && Object.op_Implicit((Object)(object)((Component)item).transform.parent) && !Object.op_Implicit((Object)(object)((Component)((Component)item).transform.parent).GetComponentInParent<Character>()))
			{
				DetachSafely(item);
			}
		}

		private static void DetachSafely(Item item)
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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)
			if (Object.op_Implicit((Object)(object)item) && Object.op_Implicit((Object)(object)item.rig) && Object.op_Implicit((Object)(object)((Component)item).transform.parent))
			{
				Transform transform = ((Component)item).transform;
				Transform parent = transform.parent;
				Collider[] hiveColliders = GetHiveColliders(item);
				List<Collider> ignored = new List<Collider>();
				IgnoreCurrentOverlaps(item, hiveColliders, ignored);
				IgnoreTransformColliders(item, hiveColliders, parent, ignored);
				transform.SetParent((Transform)null, true);
				float maxDepenetrationVelocity = item.rig.maxDepenetrationVelocity;
				item.rig.maxDepenetrationVelocity = 0.5f;
				item.rig.linearVelocity = Vector3.zero;
				item.rig.angularVelocity = Vector3.zero;
				transform.position += Vector3.down * 0.05f;
				SafeBeehiveLootingPlugin instance = SafeBeehiveLootingPlugin.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					((MonoBehaviour)instance).StartCoroutine(RestoreAfterDelay(item, ignored, maxDepenetrationVelocity, 1.5f));
				}
			}
		}

		private static Collider[] GetHiveColliders(Item item)
		{
			if (item.colliders != null && item.colliders.Length != 0)
			{
				return item.colliders;
			}
			return ((Component)item).GetComponentsInChildren<Collider>(true);
		}

		private static void IgnoreCurrentOverlaps(Item item, Collider[] hiveCols, List<Collider> ignored)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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)
			//IL_004b: 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_005a: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			if (hiveCols == null)
			{
				return;
			}
			int terrainBits = TerrainLayerBits();
			foreach (Collider val in hiveCols)
			{
				if (!Object.op_Implicit((Object)(object)val))
				{
					continue;
				}
				Bounds bounds = val.bounds;
				Collider[] array = Physics.OverlapBox(((Bounds)(ref bounds)).center, ((Bounds)(ref bounds)).extents + Vector3.one * 0.05f, ((Component)val).transform.rotation, -5, (QueryTriggerInteraction)1);
				Collider[] array2 = array;
				foreach (Collider val2 in array2)
				{
					if (ShouldIgnoreOverlap(item, val, val2, terrainBits))
					{
						Physics.IgnoreCollision(val, val2, true);
						if (!ignored.Contains(val2))
						{
							ignored.Add(val2);
						}
					}
				}
			}
		}

		private static void IgnoreTransformColliders(Item item, Collider[] hiveCols, Transform root, List<Collider> ignored)
		{
			if (hiveCols == null || !Object.op_Implicit((Object)(object)root))
			{
				return;
			}
			Collider[] componentsInChildren = ((Component)root).GetComponentsInChildren<Collider>(true);
			int terrainBits = TerrainLayerBits();
			foreach (Collider val in hiveCols)
			{
				if (!Object.op_Implicit((Object)(object)val))
				{
					continue;
				}
				Collider[] array = componentsInChildren;
				foreach (Collider val2 in array)
				{
					if (ShouldIgnoreOverlap(item, val, val2, terrainBits))
					{
						Physics.IgnoreCollision(val, val2, true);
						if (!ignored.Contains(val2))
						{
							ignored.Add(val2);
						}
					}
				}
			}
		}

		private static bool ShouldIgnoreOverlap(Item item, Collider hiveCol, Collider other, int terrainBits)
		{
			if (!Object.op_Implicit((Object)(object)other) || (Object)(object)other == (Object)(object)hiveCol)
			{
				return false;
			}
			if (Object.op_Implicit((Object)(object)item) && ((Component)other).transform.IsChildOf(((Component)item).transform))
			{
				return false;
			}
			int num = 1 << ((Component)other).gameObject.layer;
			if ((terrainBits & num) != 0)
			{
				return false;
			}
			return true;
		}

		private static int TerrainLayerBits()
		{
			//IL_0005: 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)
			int num = 0;
			try
			{
				num |= LayerMask.op_Implicit(HelperFunctions.terrainMask);
				num |= LayerMask.op_Implicit(HelperFunctions.terrainMapMask);
			}
			catch
			{
				num |= LayerMask.GetMask(new string[2] { "Terrain", "Ground" });
			}
			return num;
		}

		private static IEnumerator RestoreAfterDelay(Item item, List<Collider> ignored, float previousMaxDepenetration, float delay)
		{
			yield return (object)new WaitForSeconds(delay);
			if (Object.op_Implicit((Object)(object)item) && Object.op_Implicit((Object)(object)item.rig))
			{
				item.rig.maxDepenetrationVelocity = previousMaxDepenetration;
			}
			if (!Object.op_Implicit((Object)(object)item) || ignored == null)
			{
				yield break;
			}
			Collider[] hiveCols = GetHiveColliders(item);
			if (hiveCols == null)
			{
				yield break;
			}
			Collider[] array = hiveCols;
			foreach (Collider hiveCol in array)
			{
				if (!Object.op_Implicit((Object)(object)hiveCol))
				{
					continue;
				}
				foreach (Collider other in ignored)
				{
					if (Object.op_Implicit((Object)(object)other))
					{
						Physics.IgnoreCollision(hiveCol, other, false);
					}
				}
			}
		}
	}
	internal sealed class BeehiveEcoState : MonoBehaviour
	{
		public bool Initialized;

		public float CalmUntil;

		public float RegenAccumulator;

		public bool IsCalm => Time.time < CalmUntil;

		[PunRPC]
		public void SafeBeehiveCalmRPC(float durationSeconds)
		{
			if (!(durationSeconds <= 0f))
			{
				Beehive component = ((Component)this).GetComponent<Beehive>();
				if (Object.op_Implicit((Object)(object)component))
				{
					BeeCalmSupport.ApplyCalmLocal(component, durationSeconds, "rpc");
				}
			}
		}
	}
	internal static class BeehiveHarvestSupport
	{
		internal const ushort HoneycombItemId = 38;

		internal const string HoneycombPrefabName = "Item_Honeycomb";

		internal const int DefaultMaxHarvests = 4;

		private static readonly Dictionary<int, bool> _disabledPromptObjects = new Dictionary<int, bool>();

		private static TextMeshProUGUI _heldHarvestPrompt;

		private static GameObject _heldHarvestPromptGo;

		private static TextMeshProUGUI _heldHarvestKeycap;

		private const float HeldHarvestKeycapTopMargin = 1f;

		internal static BeehiveEcoState GetOrCreateState(Beehive hive)
		{
			if (!Object.op_Implicit((Object)(object)hive))
			{
				return null;
			}
			BeehiveEcoState beehiveEcoState = ((Component)hive).GetComponent<BeehiveEcoState>();
			if (!Object.op_Implicit((Object)(object)beehiveEcoState))
			{
				beehiveEcoState = ((Component)hive).gameObject.AddComponent<BeehiveEcoState>();
			}
			if ((Object)(object)SafeBeehiveLootingPlugin.Instance == (Object)null || SafeBeehiveLootingPlugin.Instance.EnableHoneyHarvest)
			{
				EnsureHarvestUses(hive);
			}
			if (hive.instanceID > 0 && BeeCalmSupport.IsHiveIdCalm(hive.instanceID))
			{
				BeeCalmSupport.IsHiveCalm(hive);
			}
			return beehiveEcoState;
		}

		internal static int GetBreakHoneycombCount(Beehive hive)
		{
			SafeBeehiveLootingPlugin instance = SafeBeehiveLootingPlugin.Instance;
			if ((Object)(object)instance == (Object)null || !instance.EnableHoneyHarvest)
			{
				return 4;
			}
			return GetRemainingHarvests(hive);
		}

		internal static int GetBreakHoneycombCountFromData(ItemInstanceData data)
		{
			SafeBeehiveLootingPlugin instance = SafeBeehiveLootingPlugin.Instance;
			if ((Object)(object)instance == (Object)null || !instance.EnableHoneyHarvest)
			{
				return 4;
			}
			return GetRemainingHarvestsFromData(data);
		}

		internal static void EnsureHarvestUses(Beehive hive)
		{
			if (!Object.op_Implicit((Object)(object)hive) || !Object.op_Implicit((Object)(object)((ItemComponent)hive).item))
			{
				return;
			}
			SafeBeehiveLootingPlugin instance = SafeBeehiveLootingPlugin.Instance;
			if ((Object)(object)instance != (Object)null && !instance.EnableHoneyHarvest)
			{
				return;
			}
			int num = (((Object)(object)instance != (Object)null) ? instance.EffectiveHoneycombCount : 4);
			if (num < 1)
			{
				num = 4;
			}
			BeehiveEcoState beehiveEcoState = ((Component)hive).GetComponent<BeehiveEcoState>();
			if (!Object.op_Implicit((Object)(object)beehiveEcoState))
			{
				beehiveEcoState = ((Component)hive).gameObject.AddComponent<BeehiveEcoState>();
			}
			OptionableIntItemData data = ((ItemComponent)hive).item.GetData<OptionableIntItemData>((DataEntryKey)2);
			if (data == null)
			{
				return;
			}
			if (!beehiveEcoState.Initialized)
			{
				if (!data.HasData || data.Value < 0 || data.Value > num)
				{
					data.HasData = true;
					data.Value = num;
					((ItemComponent)hive).item.SetUseRemainingPercentage(1f);
				}
				beehiveEcoState.Initialized = true;
			}
			else if (data.HasData && data.Value > num)
			{
				data.Value = num;
			}
		}

		internal static int GetRemainingHarvests(Beehive hive)
		{
			if (!Object.op_Implicit((Object)(object)hive) || !Object.op_Implicit((Object)(object)((ItemComponent)hive).item))
			{
				return 0;
			}
			EnsureHarvestUses(hive);
			OptionableIntItemData data = ((ItemComponent)hive).item.GetData<OptionableIntItemData>((DataEntryKey)2);
			if (data == null)
			{
				return 0;
			}
			if (!data.HasData)
			{
				SafeBeehiveLootingPlugin instance = SafeBeehiveLootingPlugin.Instance;
				return ((Object)(object)instance != (Object)null) ? instance.EffectiveHoneycombCount : 4;
			}
			return Mathf.Max(0, data.Value);
		}

		internal static int GetRemainingHarvestsFromData(ItemInstanceData data)
		{
			SafeBeehiveLootingPlugin instance = SafeBeehiveLootingPlugin.Instance;
			int num = (((Object)(object)instance != (Object)null) ? instance.EffectiveHoneycombCount : 4);
			if (data == null)
			{
				return num;
			}
			OptionableIntItemData val = default(OptionableIntItemData);
			if (!data.TryGetDataEntry<OptionableIntItemData>((DataEntryKey)2, ref val) || val == null || !val.HasData)
			{
				return num;
			}
			return Mathf.Clamp(val.Value, 0, num);
		}

		internal static void SpillHoneycombs(Character character, int count, Vector3 around)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_00f1: 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_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: 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_011e: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)character) || count <= 0)
			{
				return;
			}
			if (!TryResolveHoneycomb(out var prefab, out var spawnName))
			{
				SafeBeehiveLootingPlugin.Instance?.LogError("[SafeBeehiveLooting] Cannot spill honeycomb — prefab missing.");
				return;
			}
			Player player = character.player;
			Vector3 val = around + Vector3.up * 0.35f;
			if ((Object)(object)character.data != (Object)null)
			{
				val += character.data.lookDirection * 0.2f;
			}
			for (int i = 0; i < count; i++)
			{
				bool flag = false;
				if ((Object)(object)player != (Object)null && TryFindEmptyHotbarSlot(player, out var slot) && (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient))
				{
					flag = player.AddItem(prefab.itemID, (ItemInstanceData)null, ref slot);
				}
				if (!flag)
				{
					Vector3 val2 = Random.insideUnitSphere * 0.35f;
					val2.y = Mathf.Abs(val2.y) * 0.25f;
					SpawnHoneycombOnGround(val + val2, spawnName);
				}
			}
		}

		internal static bool IsHarvestable(Beehive hive)
		{
			return GetRemainingHarvests(hive) > 0;
		}

		internal static void ConsumeHarvestUse(Beehive hive)
		{
			if (Object.op_Implicit((Object)(object)hive) && Object.op_Implicit((Object)(object)((ItemComponent)hive).item))
			{
				EnsureHarvestUses(hive);
				OptionableIntItemData data = ((ItemComponent)hive).item.GetData<OptionableIntItemData>((DataEntryKey)2);
				if (data != null && data.HasData && data.Value > 0)
				{
					data.Value--;
					int num = (((Object)(object)SafeBeehiveLootingPlugin.Instance != (Object)null) ? Mathf.Max(1, SafeBeehiveLootingPlugin.Instance.EffectiveHoneycombCount) : 4);
					((ItemComponent)hive).item.SetUseRemainingPercentage((num > 0) ? ((float)data.Value / (float)num) : 0f);
				}
			}
		}

		internal static bool TryAddHarvestUse(Beehive hive)
		{
			if (!Object.op_Implicit((Object)(object)hive) || !Object.op_Implicit((Object)(object)((ItemComponent)hive).item))
			{
				return false;
			}
			EnsureHarvestUses(hive);
			OptionableIntItemData data = ((ItemComponent)hive).item.GetData<OptionableIntItemData>((DataEntryKey)2);
			if (data == null)
			{
				return false;
			}
			int num = (((Object)(object)SafeBeehiveLootingPlugin.Instance != (Object)null) ? Mathf.Max(1, SafeBeehiveLootingPlugin.Instance.EffectiveHoneycombCount) : 4);
			if (!data.HasData)
			{
				data.HasData = true;
				data.Value = 0;
			}
			if (data.Value >= num)
			{
				return false;
			}
			data.Value++;
			((ItemComponent)hive).item.SetUseRemainingPercentage((num > 0) ? ((float)data.Value / (float)num) : 0f);
			return true;
		}

		internal static bool TryAddHarvestUseFromData(ItemInstanceData data)
		{
			if (data == null)
			{
				return false;
			}
			SafeBeehiveLootingPlugin instance = SafeBeehiveLootingPlugin.Instance;
			int num = (((Object)(object)instance != (Object)null) ? Mathf.Max(1, instance.EffectiveHoneycombCount) : 4);
			OptionableIntItemData val = default(OptionableIntItemData);
			if (!data.TryGetDataEntry<OptionableIntItemData>((DataEntryKey)2, ref val) || val == null)
			{
				val = data.RegisterNewEntry<OptionableIntItemData>((DataEntryKey)2);
				if (val == null)
				{
					return false;
				}
				val.HasData = true;
				val.Value = 0;
			}
			if (!val.HasData)
			{
				val.HasData = true;
				val.Value = 0;
			}
			if (val.Value >= num)
			{
				return false;
			}
			OptionableIntItemData obj = val;
			obj.Value++;
			return true;
		}

		internal static Beehive GetTargetBeehive()
		{
			Beehive hoveredBeehive = GetHoveredBeehive();
			if (Object.op_Implicit((Object)(object)hoveredBeehive))
			{
				return hoveredBeehive;
			}
			Character localCharacter = Character.localCharacter;
			if (Object.op_Implicit((Object)(object)localCharacter) && (Object)(object)localCharacter.data != (Object)null && Object.op_Implicit((Object)(object)localCharacter.data.currentItem))
			{
				return ((Component)localCharacter.data.currentItem).GetComponent<Beehive>();
			}
			return null;
		}

		internal static Beehive GetHoveredBeehive()
		{
			if ((Object)(object)Interaction.instance == (Object)null)
			{
				return null;
			}
			IInteractible currentHovered = Interaction.instance.currentHovered;
			if (currentHovered == null)
			{
				return null;
			}
			Item val = (Item)(object)((currentHovered is Item) ? currentHovered : null);
			if (val != null)
			{
				return ((Component)val).GetComponent<Beehive>();
			}
			Component val2 = (Component)(object)((currentHovered is Component) ? currentHovered : null);
			if (Object.op_Implicit((Object)(object)val2))
			{
				return val2.GetComponentInParent<Beehive>();
			}
			return null;
		}

		internal static bool IsHolding(Beehive hive)
		{
			Character localCharacter = Character.localCharacter;
			return Object.op_Implicit((Object)(object)localCharacter) && (Object)(object)localCharacter.data != (Object)null && Object.op_Implicit((Object)(object)localCharacter.data.currentItem) && (Object)(object)((Component)localCharacter.data.currentItem).GetComponent<Beehive>() == (Object)(object)hive;
		}

		internal static string FormatPrompt(KeyCode keyCode, string label, bool keyOnRight = false)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			string keycapSpriteTag = GetKeycapSpriteTag(keyCode);
			string text = (string.IsNullOrWhiteSpace(label) ? "harvest" : label.Trim().ToLowerInvariant());
			if (string.IsNullOrEmpty(keycapSpriteTag))
			{
				return text;
			}
			return keyOnRight ? (text + " " + keycapSpriteTag) : (keycapSpriteTag + " " + text);
		}

		internal static void ApplyPromptStyle(TextMeshProUGUI tmp)
		{
			if ((Object)(object)tmp == (Object)null)
			{
				return;
			}
			InputSpriteData instance = SingletonAsset<InputSpriteData>.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				TMP_SpriteAsset val = AccessTools.FieldRefAccess<InputSpriteData, TMP_SpriteAsset>("keyboardSprites").Invoke(instance);
				if ((Object)(object)val != (Object)null)
				{
					((TMP_Text)tmp).spriteAsset = val;
				}
			}
		}

		internal static string GetKeycapSpriteTag(KeyCode keyCode)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			InputSpriteData instance = SingletonAsset<InputSpriteData>.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return string.Empty;
			}
			string text = KeyCodeToSpritePathKey(keyCode);
			if (string.IsNullOrEmpty(text))
			{
				return string.Empty;
			}
			string spriteTagFromInputPathKeyboard = instance.GetSpriteTagFromInputPathKeyboard("<Keyboard>/" + text);
			return string.IsNullOrEmpty(spriteTagFromInputPathKeyboard) ? string.Empty : spriteTagFromInputPathKeyboard;
		}

		internal static void TickInput()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			SafeBeehiveLootingPlugin instance = SafeBeehiveLootingPlugin.Instance;
			if ((Object)(object)instance == (Object)null || !instance.EnableHoneyHarvest || !WasKeyPressed(instance.HarvestKey))
			{
				return;
			}
			Character localCharacter = Character.localCharacter;
			if (Object.op_Implicit((Object)(object)localCharacter) && localCharacter.refs != null && Object.op_Implicit((Object)(object)localCharacter.refs.items))
			{
				Beehive targetBeehive = GetTargetBeehive();
				if (Object.op_Implicit((Object)(object)targetBeehive) && IsHarvestable(targetBeehive))
				{
					TryHarvest(localCharacter, targetBeehive);
				}
			}
		}

		internal static bool TryHarvest(Character character, Beehive hive)
		{
			SafeBeehiveLootingPlugin instance = SafeBeehiveLootingPlugin.Instance;
			if ((Object)(object)instance == (Object)null || !instance.EnableHoneyHarvest || !Object.op_Implicit((Object)(object)character) || !Object.op_Implicit((Object)(object)hive))
			{
				return false;
			}
			if (!IsHarvestable(hive))
			{
				return false;
			}
			if (!TryResolveHoneycomb(out var prefab, out var spawnName))
			{
				instance.LogError(string.Format("[SafeBeehiveLooting] Honeycomb not found (tried itemID={0} / '{1}').", (ushort)38, "Item_Honeycomb"));
				return false;
			}
			if (!(IsHolding(hive) ? GiveHoneycombWhileHolding(character, prefab, spawnName) : GiveHoneycombFromWorld(character, hive, spawnName)))
			{
				return false;
			}
			ConsumeHarvestUse(hive);
			instance.LogInfo($"[SafeBeehiveLooting] Harvested '{spawnName}' from beehive id={hive.instanceID} " + $"(remaining={GetRemainingHarvests(hive)})");
			RefreshPrompts();
			return true;
		}

		private static bool GiveHoneycombFromWorld(Character character, Beehive hive, string spawnName)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			Player player = character.player;
			if ((Object)(object)player != (Object)null && player.HasEmptySlot((ushort)38))
			{
				character.refs.items.SpawnItemInHand(spawnName);
				return true;
			}
			Vector3 position = ((Object.op_Implicit((Object)(object)hive) && Object.op_Implicit((Object)(object)((Component)hive).transform)) ? (((Component)hive).transform.position + Vector3.up * 0.35f + character.data.lookDirection * 0.25f) : (character.Center + character.data.lookDirection * 0.6f + Vector3.up * 0.25f));
			return SpawnHoneycombOnGround(position, spawnName);
		}

		private static bool GiveHoneycombWhileHolding(Character character, Item honeycombPrefab, string spawnName)
		{
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: 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_013b: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			Player player = character.player;
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			if (TryFindEmptyHotbarSlot(player, out var slot))
			{
				if (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient)
				{
					if (!player.AddItem(honeycombPrefab.itemID, (ItemInstanceData)null, ref slot))
					{
						SpawnHoneycombOnGround(character.Center + character.data.lookDirection * 0.6f + Vector3.up * 0.25f, spawnName);
					}
				}
				else
				{
					byte slotId = 0;
					bool isSome = character.refs.items.currentSelectedSlot.IsSome;
					if (isSome)
					{
						slotId = character.refs.items.currentSelectedSlot.Value;
					}
					character.refs.items.SpawnItemInHand(spawnName);
					SafeBeehiveLootingPlugin instance = SafeBeehiveLootingPlugin.Instance;
					if ((Object)(object)instance != (Object)null && isSome)
					{
						((MonoBehaviour)instance).StartCoroutine(ReequipSlotNextFrame(character, slotId));
					}
				}
				return true;
			}
			SpawnHoneycombOnGround(character.Center + character.data.lookDirection * 0.6f + Vector3.up * 0.25f, spawnName);
			return true;
		}

		private static IEnumerator ReequipSlotNextFrame(Character character, byte slotId)
		{
			yield return null;
			if (Object.op_Implicit((Object)(object)character) && character.refs != null && Object.op_Implicit((Object)(object)character.refs.items))
			{
				character.refs.items.EquipSlot(Optionable<byte>.Some(slotId));
			}
		}

		private static bool TryFindEmptyHotbarSlot(Player player, out ItemSlot slot)
		{
			slot = null;
			if ((Object)(object)player == (Object)null || player.itemSlots == null)
			{
				return false;
			}
			for (int i = 0; i < player.itemSlots.Length; i++)
			{
				ItemSlot val = player.itemSlots[i];
				if (val != null && val.IsEmpty())
				{
					slot = val;
					return true;
				}
			}
			return false;
		}

		private static bool SpawnHoneycombOnGround(Vector3 position, string spawnName)
		{
			//IL_0033: 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)
			if (!PhotonNetwork.InRoom)
			{
				SafeBeehiveLootingPlugin.Instance?.LogWarning("[SafeBeehiveLooting] Not in a Photon room; cannot spawn honeycomb on ground.");
				return false;
			}
			PhotonNetwork.Instantiate("0_Items/" + spawnName, position, Quaternion.identity, (byte)0, (object[])null);
			return true;
		}

		internal static void RefreshPrompts()
		{
			GUIManager instance = GUIManager.instance;
			if (!((Object)(object)instance == (Object)null))
			{
				instance.RefreshInteractablePrompt();
				instance.UpdateItemPrompts();
			}
		}

		internal static bool TryResolveHoneycomb(out Item prefab, out string spawnName)
		{
			prefab = null;
			spawnName = "Item_Honeycomb";
			if (ItemDatabase.TryGetItem((ushort)38, ref prefab) && Object.op_Implicit((Object)(object)prefab))
			{
				spawnName = ((Object)((Component)prefab).gameObject).name;
				return true;
			}
			if (ItemDatabase.TryGetItem("Item_Honeycomb", ref prefab) && Object.op_Implicit((Object)(object)prefab))
			{
				spawnName = ((Object)((Component)prefab).gameObject).name;
				return true;
			}
			return false;
		}

		internal static void ShowWorldHarvestPrompt(GUIManager gui, string promptText)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			if ((Object)(object)gui == (Object)null || (Object)(object)gui.interactPromptSecondary == (Object)null || (Object)(object)gui.secondaryInteractPromptText == (Object)null)
			{
				return;
			}
			GameObject interactPromptSecondary = gui.interactPromptSecondary;
			TextMeshProUGUI secondaryInteractPromptText = gui.secondaryInteractPromptText;
			StripSecondaryChrome(interactPromptSecondary, secondaryInteractPromptText);
			if ((Object)(object)interactPromptSecondary.transform.parent != (Object)null)
			{
				foreach (Transform item in interactPromptSecondary.transform.parent)
				{
					Transform val = item;
					if (Object.op_Implicit((Object)(object)val) && !((Object)(object)val == (Object)(object)interactPromptSecondary.transform) && IsPromptChrome(val))
					{
						RememberAndDisable(((Component)val).gameObject);
					}
				}
			}
			interactPromptSecondary.SetActive(true);
			ApplyPromptStyle(secondaryInteractPromptText);
			((TMP_Text)secondaryInteractPromptText).text = promptText;
		}

		internal static void ShowHeldHarvestPrompt(GUIManager gui, KeyCode harvestKey)
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)gui == (Object)null)
			{
				return;
			}
			if ((Object)(object)gui.itemPromptSecondary != (Object)null)
			{
				((Component)gui.itemPromptSecondary).gameObject.SetActive(false);
			}
			if ((Object)(object)gui.itemPromptScroll != (Object)null)
			{
				((Component)gui.itemPromptScroll).gameObject.SetActive(false);
			}
			TextMeshProUGUI val = EnsureHeldHarvestPromptRow(gui);
			if (!((Object)(object)val == (Object)null) && Object.op_Implicit((Object)(object)_heldHarvestPromptGo))
			{
				((TMP_Text)val).text = "harvest";
				ApplyPromptStyle(val);
				if (Object.op_Implicit((Object)(object)_heldHarvestKeycap))
				{
					ApplyPromptStyle(_heldHarvestKeycap);
					string keycapSpriteTag = GetKeycapSpriteTag(harvestKey);
					((TMP_Text)_heldHarvestKeycap).text = (string.IsNullOrEmpty(keycapSpriteTag) ? string.Empty : keycapSpriteTag);
				}
				_heldHarvestPromptGo.SetActive(true);
				Transform parent = _heldHarvestPromptGo.transform.parent;
				RectTransform val2 = (RectTransform)(object)((parent is RectTransform) ? parent : null);
				if (val2 != null)
				{
					LayoutRebuilder.ForceRebuildLayoutImmediate(val2);
				}
			}
		}

		internal static void HideHeldHarvestPrompt()
		{
			if (Object.op_Implicit((Object)(object)_heldHarvestPromptGo))
			{
				_heldHarvestPromptGo.SetActive(false);
			}
		}

		private static void ApplyHeldHarvestKeycapTopMargin(TextMeshProUGUI keycap)
		{
			//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_0024: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)keycap))
			{
				Vector4 margin = ((TMP_Text)keycap).margin;
				margin.y = 1f;
				((TMP_Text)keycap).margin = margin;
			}
		}

		private static TextMeshProUGUI EnsureHeldHarvestPromptRow(GUIManager gui)
		{
			bool flag = Object.op_Implicit((Object)(object)_heldHarvestPromptGo) && (Object)(object)_heldHarvestPromptGo.transform.Find("UI_InputIcon") == (Object)null;
			Transform val = (((Object)(object)gui != (Object)null && (Object)(object)gui.itemPromptDrop != (Object)null && (Object)(object)((TMP_Text)gui.itemPromptDrop).transform.parent != (Object)null) ? ((TMP_Text)gui.itemPromptDrop).transform.parent.Find("SafeBeehive_HarvestSpacer") : null);
			if (flag || (Object)(object)val != (Object)null)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					Object.Destroy((Object)(object)((Component)val).gameObject);
				}
				if (Object.op_Implicit((Object)(object)_heldHarvestPromptGo))
				{
					Object.Destroy((Object)(object)_heldHarvestPromptGo);
				}
				_heldHarvestPromptGo = null;
				_heldHarvestPrompt = null;
				_heldHarvestKeycap = null;
			}
			if (Object.op_Implicit((Object)(object)_heldHarvestPrompt) && Object.op_Implicit((Object)(object)_heldHarvestPromptGo))
			{
				return _heldHarvestPrompt;
			}
			if ((Object)(object)gui.itemPromptDrop == (Object)null)
			{
				return null;
			}
			TextMeshProUGUI itemPromptDrop = gui.itemPromptDrop;
			Transform parent = ((TMP_Text)itemPromptDrop).transform.parent;
			if ((Object)(object)parent == (Object)null)
			{
				return null;
			}
			GameObject val2 = Object.Instantiate<GameObject>(((Component)itemPromptDrop).gameObject, parent, false);
			((Object)val2).name = "SafeBeehive_HarvestPrompt";
			if ((Object)(object)gui.itemPromptThrow != (Object)null)
			{
				val2.transform.SetSiblingIndex(((TMP_Text)gui.itemPromptThrow).transform.GetSiblingIndex() + 1);
			}
			else
			{
				val2.transform.SetAsLastSibling();
			}
			TextMeshProUGUI component = val2.GetComponent<TextMeshProUGUI>();
			if ((Object)(object)component == (Object)null)
			{
				Object.Destroy((Object)(object)val2);
				return null;
			}
			LocalizedText component2 = val2.GetComponent<LocalizedText>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.autoSet = false;
				((Behaviour)component2).enabled = false;
			}
			((TMP_Text)component).text = "harvest";
			Transform val3 = val2.transform.Find("UI_InputIcon");
			TextMeshProUGUI val4 = null;
			if ((Object)(object)val3 != (Object)null)
			{
				Transform val5 = val3.Find("PromptHold");
				if (Object.op_Implicit((Object)(object)val5))
				{
					((Component)val5).gameObject.SetActive(false);
				}
				TextMeshProUGUI[] componentsInChildren = ((Component)val3).GetComponentsInChildren<TextMeshProUGUI>(true);
				foreach (TextMeshProUGUI val6 in componentsInChildren)
				{
					if (Object.op_Implicit((Object)(object)val6) && !((Object)(object)val6 == (Object)(object)component) && (!Object.op_Implicit((Object)(object)val5) || !((TMP_Text)val6).transform.IsChildOf(val5)))
					{
						val4 = val6;
						break;
					}
				}
			}
			ApplyHeldHarvestKeycapTopMargin(val4);
			_heldHarvestPromptGo = val2;
			_heldHarvestPrompt = component;
			_heldHarvestKeycap = val4;
			val2.SetActive(false);
			return component;
		}

		internal static void StripSecondaryChrome(GameObject root, TextMeshProUGUI keepText)
		{
			if (!Object.op_Implicit((Object)(object)root))
			{
				return;
			}
			Transform val = (((Object)(object)keepText != (Object)null) ? ((TMP_Text)keepText).transform : null);
			Transform[] componentsInChildren = root.GetComponentsInChildren<Transform>(true);
			foreach (Transform val2 in componentsInChildren)
			{
				if (Object.op_Implicit((Object)(object)val2) && !((Object)(object)val2 == (Object)(object)root.transform) && (!((Object)(object)val != (Object)null) || (!((Object)(object)val2 == (Object)(object)val) && !val2.IsChildOf(val))) && IsPromptChrome(val2))
				{
					RememberAndDisable(((Component)val2).gameObject);
				}
			}
			Image[] componentsInChildren2 = root.GetComponentsInChildren<Image>(true);
			foreach (Image val3 in componentsInChildren2)
			{
				if (!((Object)(object)val3 == (Object)null) && (!((Object)(object)val != (Object)null) || !((Object)(object)((Component)val3).transform == (Object)(object)val)) && !((Object)(object)((Component)val3).GetComponent<TextMeshProUGUI>() != (Object)null))
				{
					RememberAndDisable(((Component)val3).gameObject);
				}
			}
		}

		private static bool IsPromptChrome(Transform t)
		{
			if (!Object.op_Implicit((Object)(object)t))
			{
				return false;
			}
			string text = ((Object)t).name ?? string.Empty;
			if (text.IndexOf("icon", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
			if (text.IndexOf("mouse", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
			if ((Object)(object)((Component)t).GetComponent<Image>() != (Object)null && (Object)(object)((Component)t).GetComponent<TextMeshProUGUI>() == (Object)null)
			{
				return true;
			}
			TextMeshProUGUI component = ((Component)t).GetComponent<TextMeshProUGUI>();
			if ((Object)(object)component != (Object)null)
			{
				string text2 = ((TMP_Text)component).text ?? string.Empty;
				if (text2.IndexOf("sprite", StringComparison.OrdinalIgnoreCase) < 0)
				{
					return false;
				}
				string text3 = text2;
				while (true)
				{
					int num = text3.IndexOf('<');
					if (num < 0)
					{
						break;
					}
					int num2 = text3.IndexOf('>', num);
					if (num2 < 0)
					{
						break;
					}
					text3 = text3.Remove(num, num2 - num + 1);
				}
				return string.IsNullOrWhiteSpace(text3);
			}
			return false;
		}

		private static void RememberAndDisable(GameObject go)
		{
			if (Object.op_Implicit((Object)(object)go))
			{
				int instanceID = ((Object)go).GetInstanceID();
				if (!_disabledPromptObjects.ContainsKey(instanceID))
				{
					_disabledPromptObjects[instanceID] = go.activeSelf;
				}
				if (go.activeSelf)
				{
					go.SetActive(false);
				}
			}
		}

		internal static void RestorePromptIcons(GameObject root)
		{
			if (!Object.op_Implicit((Object)(object)root))
			{
				return;
			}
			List<int> list = null;
			foreach (KeyValuePair<int, bool> disabledPromptObject in _disabledPromptObjects)
			{
			}
			Transform[] componentsInChildren = root.GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (!Object.op_Implicit((Object)(object)val))
				{
					continue;
				}
				int instanceID = ((Object)((Component)val).gameObject).GetInstanceID();
				if (_disabledPromptObjects.TryGetValue(instanceID, out var value))
				{
					((Component)val).gameObject.SetActive(value);
					if (list == null)
					{
						list = new List<int>();
					}
					list.Add(instanceID);
				}
			}
			int instanceID2 = ((Object)root).GetInstanceID();
			if (_disabledPromptObjects.TryGetValue(instanceID2, out var value2))
			{
				root.SetActive(value2);
				_disabledPromptObjects.Remove(instanceID2);
			}
			if (list != null)
			{
				for (int j = 0; j < list.Count; j++)
				{
					_disabledPromptObjects.Remove(list[j]);
				}
			}
		}

		private static bool WasKeyPressed(KeyCode keyCode)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_000d: 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)
			if ((int)keyCode == 0)
			{
				return false;
			}
			if (TryGetInputKey(keyCode, out var key) && Keyboard.current != null)
			{
				return ((ButtonControl)Keyboard.current[key]).wasPressedThisFrame;
			}
			return false;
		}

		private unsafe static bool TryGetInputKey(KeyCode keyCode, out Key key)
		{
			if (Enum.TryParse<Key>(((object)(*(KeyCode*)(&keyCode))/*cast due to .constrained prefix*/).ToString(), ignoreCase: true, out key))
			{
				return true;
			}
			string text = ((object)(*(KeyCode*)(&keyCode))/*cast due to .constrained prefix*/).ToString();
			if (text.StartsWith("Alpha", StringComparison.Ordinal) && text.Length == 6)
			{
				return Enum.TryParse<Key>("Digit" + text[5], out key);
			}
			key = (Key)0;
			return false;
		}

		private unsafe static string KeyCodeToSpritePathKey(KeyCode keyCode)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: 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_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			//IL_0091: 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_00b2: Expected I4, but got Unknown
			//IL_004b: 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_0078: Expected I4, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Invalid comparison between Unknown and I4
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected I4, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Invalid comparison between Unknown and I4
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_00e6: 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_0112: Expected I4, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Invalid comparison between Unknown and I4
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Invalid comparison between Unknown and I4
			KeyCode val = keyCode;
			KeyCode val2 = val;
			if ((int)val2 <= 32)
			{
				if ((int)val2 <= 9)
				{
					if ((int)val2 == 8)
					{
						return "backspace";
					}
					if ((int)val2 == 9)
					{
						return "tab";
					}
				}
				else
				{
					if ((int)val2 == 13)
					{
						return "enter";
					}
					if ((int)val2 == 27)
					{
						return "esc";
					}
					if ((int)val2 == 32)
					{
						return "space";
					}
				}
			}
			else if ((int)val2 <= 61)
			{
				switch (val2 - 39)
				{
				default:
					if ((int)val2 != 59)
					{
						if ((int)val2 != 61)
						{
							break;
						}
						return "equals";
					}
					return "semicolon";
				case 6:
					return "minus";
				case 0:
					return "quote";
				case 5:
					return "comma";
				case 7:
					return "period";
				case 8:
					return "slash";
				case 1:
				case 2:
				case 3:
				case 4:
					break;
				}
			}
			else
			{
				switch (val2 - 91)
				{
				default:
					switch (val2 - 273)
					{
					default:
						switch (val2 - 301)
						{
						case 2:
						case 3:
							return "shift";
						case 4:
						case 5:
							return "ctrl";
						case 6:
						case 7:
							return "alt";
						case 0:
							return "capsLock";
						}
						break;
					case 0:
						return "upArrow";
					case 1:
						return "downArrow";
					case 3:
						return "leftArrow";
					case 2:
						return "rightArrow";
					case 7:
						return "pageUp";
					case 8:
						return "pageDown";
					case 4:
					case 5:
					case 6:
						break;
					}
					break;
				case 5:
					return "backquote";
				case 0:
					return "leftBracket";
				case 2:
					return "rightBracket";
				case 1:
					return "backslash";
				case 3:
				case 4:
					break;
				}
			}
			string text = ((object)(*(KeyCode*)(&keyCode))/*cast due to .constrained prefix*/).ToString();
			if (text.StartsWith("Alpha", StringComparison.Ordinal) && text.Length == 6)
			{
				return char.ToLowerInvariant(text[5]).ToString();
			}
			if (text.StartsWith("Keypad", StringComparison.Ordinal))
			{
				string text2 = text.Substring("Keypad".Length);
				if (text2.Length == 1 && char.IsDigit(text2[0]))
				{
					return "numpad" + text2;
				}
				switch (text2)
				{
				case "Period":
					return "numpadPeriod";
				case "Plus":
					return "numpadPlus";
				case "Minus":
					return "numpadMinus";
				case "Divide":
					return "numpadDivide";
				case "Multiply":
					return "numpadMultiply";
				case "Enter":
					return "numpadEnter";
				}
			}
			if (text.Length == 1)
			{
				return text.ToLowerInvariant();
			}
			return text.ToLowerInvariant();
		}
	}
	[HarmonyPatch(typeof(GUIManager), "RefreshInteractablePrompt")]
	internal static class BeehiveHarvestWorldPromptPatch
	{
		[HarmonyPostfix]
		private static void Postfix(GUIManager __instance)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				SafeBeehiveLootingPlugin instance = SafeBeehiveLootingPlugin.Instance;
				if ((Object)(object)__instance == (Object)null)
				{
					return;
				}
				if ((Object)(object)__instance.interactPromptSecondary != (Object)null)
				{
					BeehiveHarvestSupport.RestorePromptIcons(__instance.interactPromptSecondary);
				}
				if (!((Object)(object)instance == (Object)null) && instance.EnableHoneyHarvest)
				{
					Beehive hoveredBeehive = BeehiveHarvestSupport.GetHoveredBeehive();
					if (Object.op_Implicit((Object)(object)hoveredBeehive) && BeehiveHarvestSupport.IsHarvestable(hoveredBeehive))
					{
						string promptText = BeehiveHarvestSupport.FormatPrompt(instance.HarvestKey, "harvest");
						BeehiveHarvestSupport.ShowWorldHarvestPrompt(__instance, promptText);
					}
				}
			}
			catch (Exception ex)
			{
				SafeBeehiveLootingPlugin.Instance?.LogError("[SafeBeehiveLooting] World harvest prompt failed: " + ex.GetType().Name + ": " + ex.Message);
			}
		}
	}
	[HarmonyPatch(typeof(GUIManager), "UpdateItemPrompts")]
	internal static class BeehiveHarvestHeldPromptPatch
	{
		[HarmonyPostfix]
		private static void Postfix(GUIManager __instance)
		{
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				SafeBeehiveLootingPlugin instance = SafeBeehiveLootingPlugin.Instance;
				if ((Object)(object)__instance == (Object)null)
				{
					return;
				}
				if ((Object)(object)__instance.itemPromptSecondary != (Object)null)
				{
					BeehiveHarvestSupport.RestorePromptIcons(((Component)__instance.itemPromptSecondary).gameObject);
				}
				if ((Object)(object)instance == (Object)null || !instance.EnableHoneyHarvest)
				{
					BeehiveHarvestSupport.HideHeldHarvestPrompt();
					return;
				}
				Character localCharacter = Character.localCharacter;
				if (!Object.op_Implicit((Object)(object)localCharacter) || (Object)(object)localCharacter.data == (Object)null || !Object.op_Implicit((Object)(object)localCharacter.data.currentItem))
				{
					BeehiveHarvestSupport.HideHeldHarvestPrompt();
					return;
				}
				Beehive component = ((Component)localCharacter.data.currentItem).GetComponent<Beehive>();
				if (!Object.op_Implicit((Object)(object)component) || !BeehiveHarvestSupport.IsHarvestable(component))
				{
					BeehiveHarvestSupport.HideHeldHarvestPrompt();
				}
				else
				{
					BeehiveHarvestSupport.ShowHeldHarvestPrompt(__instance, instance.HarvestKey);
				}
			}
			catch (Exception ex)
			{
				SafeBeehiveLootingPlugin.Instance?.LogError("[SafeBeehiveLooting] Held harvest prompt failed: " + ex.GetType().Name + ": " + ex.Message);
			}
		}
	}
	[HarmonyPatch(typeof(Breakable), "Break")]
	internal static class BeehiveBreakHarvestSyncPatch
	{
		private static bool _pendingRevenge;

		private static Vector3 _revengePos;

		private static Character _revengeTarget;

		private static BeeSwarm _revengePrefab;

		[HarmonyPrefix]
		private static void Prefix(Breakable __instance)
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			_pendingRevenge = false;
			_revengePrefab = null;
			_revengeTarget = null;
			try
			{
				if ((Object)(object)__instance == (Object)null)
				{
					return;
				}
				Beehive component = ((Component)__instance).GetComponent<Beehive>();
				if (Object.op_Implicit((Object)(object)component))
				{
					SafeBeehiveLootingPlugin instance = SafeBeehiveLootingPlugin.Instance;
					if ((Object)(object)instance != (Object)null && instance.EnableHoneyHarvest)
					{
						int remainingHarvests = BeehiveHarvestSupport.GetRemainingHarvests(component);
						TrimBreakLootToRemaining(__instance.instantiateOnBreak, __instance.instantiatePoints, remainingHarvests);
						TrimBreakLootToRemaining(__instance.alternateInstantiateOnBreak, null, remainingHarvests);
						instance.LogInfo($"[SafeBeehiveLooting] Beehive break loot trimmed to {remainingHarvests} honeycomb.");
					}
					if (TrustedBeekeeperSupport.IsPermanent(component))
					{
						_pendingRevenge = true;
						_revengePos = ((Component)component).transform.position;
						_revengeTarget = TrustedBeekeeperSupport.ResolveCurrentOwner(component) ?? Character.localCharacter;
						_revengePrefab = component.beeSwarmPrefab;
					}
				}
			}
			catch (Exception ex)
			{
				SafeBeehiveLootingPlugin.Instance?.LogError("[SafeBeehiveLooting] Break loot sync failed: " + ex.GetType().Name + ": " + ex.Message);
			}
		}

		[HarmonyPostfix]
		private static void Postfix(Breakable __instance)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (_pendingRevenge)
			{
				_pendingRevenge = false;
				TrustedBeekeeperSupport.OnPermanentHiveBroken(_revengePos, _revengeTarget, _revengePrefab);
				_revengePrefab = null;
				_revengeTarget = null;
			}
		}

		private static void TrimBreakLootToRemaining(List<GameObject> loot, List<Transform> points, int remaining)
		{
			if (loot == null)
			{
				return;
			}
			if (remaining < 0)
			{
				remaining = 0;
			}
			while (loot.Count > remaining)
			{
				int num = loot.Count - 1;
				loot.RemoveAt(num);
				if (points != null && points.Count > num)
				{
					points.RemoveAt(num);
				}
			}
		}
	}
	internal static class BeeCalmSupport
	{
		private const float RegenTickSeconds = 1f;

		private static readonly Dictionary<int, float> _calmUntilByHiveId = new Dictionary<int, float>();

		private static readonly Dictionary<Guid, float> _calmUntilByItemGuid = new Dictionary<Guid, float>();

		private static bool _hooksReady;

		private static readonly Dictionary<int, float> _stingerEntryAmountBySwarm = new Dictionary<int, float>();

		private static readonly Dictionary<Guid, float> _regenAccumulatorByGuid = new Dictionary<Guid, float>();

		internal static void Initialize()
		{
			if (!_hooksReady)
			{
				_hooksReady = true;
				SceneManager.sceneLoaded += OnSceneLoaded;
			}
		}

		internal static void Shutdown()
		{
			if (_hooksReady)
			{
				SceneManager.sceneLoaded -= OnSceneLoaded;
				_hooksReady = false;
				ClearAllCalmState("shutdown");
			}
		}

		private static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			ClearAllCalmState(((Scene)(ref scene)).name);
			SceneRegistries.SeedFromScene();
			TrustedBeekeeperSupport.ClearSessionState();
			CampfireCalmSupport.ClearSessionState();
		}

		internal static void ClearAllCalmState(string reason = null)
		{
			_calmUntilByHiveId.Clear();
			_calmUntilByItemGuid.Clear();
			_regenAccumulatorByGuid.Clear();
			SceneRegistries.PruneDestroyed();
			IReadOnlyList<BeeSwarm> swarms = SceneRegistries.Swarms;
			for (int i = 0; i < swarms.Count; i++)
			{
				RestoreStingerEntry(swarms[i]);
			}
			_stingerEntryAmountBySwarm.Clear();
			SafeBeehiveLootingPlugin.Instance?.LogInfo("[SafeBeehiveLooting] Calm state cleared" + (string.IsNullOrEmpty(reason) ? "." : (" (" + reason + ").")));
		}

		internal static void StartRegenLoop(SafeBeehiveLootingPlugin plugin)
		{
			if (!((Object)(object)plugin == (Object)null))
			{
				((MonoBehaviour)plugin).StartCoroutine(RegenLoop());
			}
		}

		internal static void RegisterCalm(int hiveInstanceId, float calmUntil)
		{
			if (hiveInstanceId > 0 && !(calmUntil <= Time.time) && (!_calmUntilByHiveId.TryGetValue(hiveInstanceId, out var value) || calmUntil > value))
			{
				_calmUntilByHiveId[hiveInstanceId] = calmUntil;
			}
		}

		internal static void RegisterCalm(Beehive hive, float calmUntil)
		{
			if (Object.op_Implicit((Object)(object)hive) && !(calmUntil <= Time.time))
			{
				if (hive.instanceID > 0)
				{
					RegisterCalm(hive.instanceID, calmUntil);
				}
				Guid itemGuid = GetItemGuid(hive);
				if (!(itemGuid == Guid.Empty) && (!_calmUntilByItemGuid.TryGetValue(itemGuid, out var value) || calmUntil > value))
				{
					_calmUntilByItemGuid[itemGuid] = calmUntil;
				}
			}
		}

		internal static bool IsHiveIdCalm(int hiveInstanceId)
		{
			if (hiveInstanceId <= 0)
			{
				return false;
			}
			if (!_calmUntilByHiveId.TryGetValue(hiveInstanceId, out var value))
			{
				return false;
			}
			if (Time.time < value)
			{
				return true;
			}
			_calmUntilByHiveId.Remove(hiveInstanceId);
			return false;
		}

		internal static bool IsItemGuidCalm(Guid guid)
		{
			if (guid == Guid.Empty)
			{
				return false;
			}
			if (!_calmUntilByItemGuid.TryGetValue(guid, out var value))
			{
				return false;
			}
			if (Time.time < value)
			{
				return true;
			}
			_calmUntilByItemGuid.Remove(guid);
			return false;
		}

		internal static void ClearCalm(Beehive hive)
		{
			if (Object.op_Implicit((Object)(object)hive))
			{
				if (hive.instanceID > 0)
				{
					_calmUntilByHiveId.Remove(hive.instanceID);
				}
				Guid itemGuid = GetItemGuid(hive);
				if (itemGuid != Guid.Empty)
				{
					_calmUntilByItemGuid.Remove(itemGuid);
					_regenAccumulatorByGuid.Remove(itemGuid);
				}
				BeehiveEcoState component = ((Component)hive).GetComponent<BeehiveEcoState>();
				if ((Object)(object)component != (Object)null)
				{
					component.CalmUntil = 0f;
				}
				BeeSwarm val = FindSwarmForHive(hive);
				if (Object.op_Implicit((Object)(object)val))
				{
					RestoreStingerEntry(val);
				}
			}
		}

		internal static bool IsHiveCalm(Beehive hive)
		{
			if (!Object.op_Implicit((Object)(object)hive))
			{
				return false;
			}
			if (TrustedBeekeeperSupport.IsHivePermanentlyCalm(hive))
			{
				return true;
			}
			Guid itemGuid = GetItemGuid(hive);
			if (IsHiveIdCalm(hive.instanceID) && _calmUntilByHiveId.TryGetValue(hive.instanceID, out var value))
			{
				BeehiveEcoState component = ((Component)hive).GetComponent<BeehiveEcoState>();
				if (Object.op_Implicit((Object)(object)component) && value > component.CalmUntil)
				{
					component.CalmUntil = value;
				}
				return true;
			}
			if (IsItemGuidCalm(itemGuid) && _calmUntilByItemGuid.TryGetValue(itemGuid, out var value2))
			{
				BeehiveEcoState component2 = ((Component)hive).GetComponent<BeehiveEcoState>();
				if (Object.op_Implicit((Object)(object)component2) && value2 > component2.CalmUntil)
				{
					component2.CalmUntil = value2;
				}
				return true;
			}
			BeehiveEcoState component3 = ((Component)hive).GetComponent<BeehiveEcoState>();
			if ((Object)(object)component3 != (Object)null && component3.IsCalm)
			{
				RegisterCalm(hive, component3.CalmUntil);
				return true;
			}
			return false;
		}

		internal static bool IsSwarmCalm(BeeSwarm swarm)
		{
			if (!Object.op_Implicit((Object)(object)swarm))
			{
				return false;
			}
			if (TrustedBeekeeperSupport.IsSwarmPermanentlyCalm(swarm))
			{
				return true;
			}
			Beehive beehive = swarm.beehive;
			if (!Object.op_Implicit((Object)(object)beehive) && swarm.beehiveID > 0)
			{
				beehive = Beehive.GetBeehive(swarm.beehiveID);
			}
			if (!Object.op_Implicit((Object)(object)beehive) && Object.op_Implicit((Object)(object)swarm.beehive))
			{
				beehive = swarm.beehive;
			}
			if (Object.op_Implicit((Object)(object)beehive) && IsHiveCalm(beehive))
			{
				return true;
			}
			return swarm.beehiveID > 0 && IsHiveIdCalm(swarm.beehiveID);
		}

		private static Guid GetItemGuid(Beehive hive)
		{
			if (!Object.op_Implicit((Object)(object)hive) || !Object.op_Implicit((Object)(object)((ItemComponent)hive).item) || ((ItemComponent)hive).item.data == null)
			{
				return Guid.Empty;
			}
			return ((ItemComponent)hive).item.data.guid;
		}

		internal static BeeSwarm FindSwarmForHive(Beehive hive)
		{
			if (!Object.op_Implicit((Object)(object)hive))
			{
				return null;
			}
			if (Object.op_Implicit((Object)(object)hive.currentBees))
			{
				return hive.currentBees;
			}
			IReadOnlyList<BeeSwarm> swarms = SceneRegistries.Swarms;
			for (int i = 0; i < swarms.Count; i++)
			{
				BeeSwarm val = swarms[i];
				if (Object.op_Implicit((Object)(object)val) && (Object)(object)val.beehive == (Object)(object)hive)
				{
					return val;
				}
			}
			if (hive.instanceID == 0)
			{
				return null;
			}
			for (int j = 0; j < swarms.Count; j++)
			{
				BeeSwarm val2 = swarms[j];
				if (Object.op_Implicit((Object)(object)val2) && val2.beehiveID == hive.instanceID)
				{
					return val2;
				}
			}
			return null;
		}

		internal static void ApplyCalm(Beehive hive, float durationSeconds, string source)
		{
			if (!Object.op_Implicit((Object)(object)hive) || durationSeconds <= 0f)
			{
				return;
			}
			SafeBeehiveLootingPlugin instance = SafeBeehiveLootingPlugin.Instance;
			if ((Object)(object)instance == (Object)null || !instance.EnableBeeCalm)
			{
				return;
			}
			ApplyCalmLocal(hive, d