Decompiled source of Safe Beehive Looting v3.0.0
tony4twentys-Safe Beehive Looting.dll
Decompiled 2 months ago
The result has been truncated due to the large size, download it to view full contents!
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