Decompiled source of LoyalSpears v1.0.0

BepInEx/plugins/LoyalSpears.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Extensions;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("LoyalSpears")]
[assembly: AssemblyDescription("Spears that are loyal, Return on throw and do not get picked up by others.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LoyalSpears")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("C00EDC1A-636F-4221-834A-B22A0174B582")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LoyalSpears
{
	[BepInPlugin("com.loyalspears.mod", "Loyal Spears", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class LoyalSpearsPlugin : BaseUnityPlugin
	{
		private const string Guid = "com.loyalspears.mod";

		private const string Name = "Loyal Spears";

		private const string Version = "1.0.0";

		private void Awake()
		{
			PluginConfig.Init((BaseUnityPlugin)(object)this);
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loyal Spears v1.0.0 loaded");
		}
	}
	internal class LoyaltyComponent : WeightReserverComponent
	{
		private float _ownerDeathCountOnThrow;

		private ItemDrop _attachedItemDrop;

		public void Setup(ItemDrop attachedItemDrop, Player originalOwner, float ownerDeathCountOnThrow)
		{
			_attachedItemDrop = attachedItemDrop;
			_ownerDeathCountOnThrow = ownerDeathCountOnThrow;
			Setup(attachedItemDrop.m_itemData, originalOwner);
		}

		protected override void StartTimer()
		{
			((MonoBehaviour)this).StartCoroutine("ReturnInABit");
		}

		public override void StopTimer()
		{
			((MonoBehaviour)this).StopCoroutine("ReturnInABit");
		}

		private IEnumerator ReturnInABit()
		{
			float value = PluginConfig.ReturnAfterSeconds.Value;
			if (value > 0f)
			{
				yield return (object)new WaitForSeconds(value);
			}
			if ((Object)(object)base.OriginalOwner != (Object)null && (Object)(object)_attachedItemDrop != (Object)null && _attachedItemDrop.CanPickup(true))
			{
				ZNetView nview = SpearPatches.GetNview((Character)(object)base.OriginalOwner);
				ZNetView nview2 = SpearPatches.GetNview(_attachedItemDrop);
				nview.InvokeRPC("RPC_PickupLoyaltySpear", new object[2]
				{
					nview2.GetZDO().m_uid,
					_ownerDeathCountOnThrow
				});
			}
			Object.Destroy((Object)(object)this);
		}
	}
	internal class PlayerWeightReserverTrackerComponent : MonoBehaviour
	{
		public readonly List<WeightReserverComponent> WeightReservers = new List<WeightReserverComponent>();
	}
	public static class PluginConfig
	{
		public static ConfigEntry<bool> EnableBlockAutoPickup { get; private set; }

		public static ConfigEntry<float> ReturnAfterSeconds { get; private set; }

		public static ConfigEntry<bool> BlockReturnIfOverburdened { get; private set; }

		public static ConfigEntry<bool> ReserveThrowWeight { get; private set; }

		public static ConfigEntry<float> MaxReservationSeconds { get; private set; }

		public static ConfigEntry<float> FlightDistanceUntilAutoReturn { get; private set; }

		public static void Init(BaseUnityPlugin plugin)
		{
			EnableBlockAutoPickup = ConfigFileExtensions.BindConfig<bool>(plugin.Config, "General", "EnableBlockAutoPickup", true, "Prevent other players from auto-picking up your thrown spears.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ReturnAfterSeconds = ConfigFileExtensions.BindConfig<float>(plugin.Config, "General", "ReturnAfterSeconds", 5f, "Seconds until a thrown spear returns to its owner after hitting the ground. 0 or negative disables.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			BlockReturnIfOverburdened = ConfigFileExtensions.BindConfig<bool>(plugin.Config, "General", "BlockReturnIfOverburdened", false, "Skip auto-return if picking it back up would overburden the owner.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ReserveThrowWeight = ConfigFileExtensions.BindConfig<bool>(plugin.Config, "General", "ReserveThrowWeight", true, "Count thrown spear weight as reserved during auto-pickup checks.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			MaxReservationSeconds = ConfigFileExtensions.BindConfig<float>(plugin.Config, "General", "MaxReservationSeconds", 60f, "Safety cap so a lost spear doesn't reserve weight forever.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			FlightDistanceUntilAutoReturn = ConfigFileExtensions.BindConfig<float>(plugin.Config, "General", "FlightDistanceUntilAutoReturn", -1f, "If a thrown spear travels further than this distance from the owner without hitting the ground, it auto-returns. Negative disables.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		}
	}
	[HarmonyPatch]
	internal class SpearPatches
	{
		private static readonly FieldInfo FieldOwner = AccessTools.Field(typeof(Projectile), "m_owner");

		private static readonly FieldInfo FieldNview = AccessTools.Field(typeof(Character), "m_nview");

		private static readonly FieldInfo FieldInventory = AccessTools.Field(typeof(Humanoid), "m_inventory");

		private static readonly FieldInfo FieldPlayerProfile = AccessTools.Field(typeof(Game), "m_playerProfile");

		private static readonly FieldInfo FieldItemNview = AccessTools.Field(typeof(ItemDrop), "m_nview");

		private static readonly FieldInfo FieldSpawnItem = AccessTools.Field(typeof(Projectile), "m_spawnItem");

		public static bool IsSpear(ItemData itemData)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			if (itemData != null && itemData.m_shared != null)
			{
				return (int)itemData.m_shared.m_skillType == 5;
			}
			return false;
		}

		public static bool IsWeapon(ItemData itemData)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			if (itemData == null || itemData.m_shared == null)
			{
				return false;
			}
			ItemType itemType = itemData.m_shared.m_itemType;
			if ((int)itemType == 3 || (int)itemType == 14 || (int)itemType == 22)
			{
				return true;
			}
			return false;
		}

		public static bool IsCompatibleThrowableWeaponModInstalled()
		{
			return Chainloader.PluginInfos.ContainsKey("randyknapp.mods.epicloot");
		}

		private static bool IsIncompatibleThrowableWeaponModInstalled()
		{
			return Chainloader.PluginInfos.ContainsKey("neobotics.valheim_mod.maxaxe");
		}

		public static bool IsPotentiallyThrowable(ItemData itemData)
		{
			if (IsSpear(itemData))
			{
				return true;
			}
			if (!IsIncompatibleThrowableWeaponModInstalled() && IsCompatibleThrowableWeaponModInstalled())
			{
				return IsWeapon(itemData);
			}
			return false;
		}

		public static ZNetView GetNview(Character character)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			return (ZNetView)FieldNview.GetValue(character);
		}

		public static ZNetView GetNview(ItemDrop itemDrop)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			return (ZNetView)FieldItemNview.GetValue(itemDrop);
		}

		public static Inventory GetInventory(Humanoid humanoid)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			return (Inventory)FieldInventory.GetValue(humanoid);
		}

		public static PlayerProfile GetPlayerProfile(Game game)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			return (PlayerProfile)FieldPlayerProfile.GetValue(game);
		}

		public static Character GetProjectileOwner(Projectile projectile)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			return (Character)FieldOwner.GetValue(projectile);
		}

		public static ItemData GetSpawnItem(Projectile projectile)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			return (ItemData)FieldSpawnItem.GetValue(projectile);
		}

		public static float GetPlayerDeathCount()
		{
			return GetPlayerProfile(Game.instance).m_playerStats[0].m_stats[(PlayerStatType)0];
		}

		[HarmonyPatch(typeof(Player), "Awake")]
		[HarmonyPostfix]
		private static void AddLoyaltySpearRPC(Player __instance)
		{
			GetNview((Character)(object)__instance).Register<ZDOID, float>("RPC_PickupLoyaltySpear", (Action<long, ZDOID, float>)delegate(long player, ZDOID item, float deaths)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				RPC_PickupLoyaltySpear(__instance, item, deaths);
			});
		}

		private static void RPC_PickupLoyaltySpear(Player player, ZDOID item, float deathCountOnThrow)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = ZNetScene.instance.FindInstance(item);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			ItemDrop component = val.GetComponent<ItemDrop>();
			if (!((Object)(object)component == (Object)null))
			{
				Inventory inventory = GetInventory((Humanoid)(object)player);
				if (inventory.CanAddItem(component.m_itemData, -1) && (!PluginConfig.BlockReturnIfOverburdened.Value || !(component.m_itemData.GetWeight(-1) + inventory.GetTotalWeight() > player.GetMaxCarryWeight())) && (!(deathCountOnThrow >= 0f) || !(GetPlayerDeathCount() > deathCountOnThrow)))
				{
					component.Pickup((Humanoid)(object)player);
				}
			}
		}

		private static ItemDrop AddLoyaltySpearPickupComponent(ItemDrop item, Projectile projectile)
		{
			Character projectileOwner = GetProjectileOwner(projectile);
			Player val = (Player)(object)((projectileOwner is Player) ? projectileOwner : null);
			if (val != null && (Object)(object)val == (Object)(object)Player.m_localPlayer && (Object)(object)item != (Object)null && IsPotentiallyThrowable(item.m_itemData))
			{
				if (IsSpear(item.m_itemData) && PluginConfig.ReturnAfterSeconds.Value >= 0f)
				{
					LoyaltyComponent loyaltyComponent = default(LoyaltyComponent);
					if (((Component)item).gameObject.TryGetComponent<LoyaltyComponent>(ref loyaltyComponent))
					{
						loyaltyComponent.StopTimer();
					}
					else
					{
						loyaltyComponent = ((Component)item).gameObject.AddComponent<LoyaltyComponent>();
					}
					float playerDeathCount = GetPlayerDeathCount();
					loyaltyComponent.Setup(item, val, playerDeathCount);
				}
				else if (PluginConfig.ReserveThrowWeight.Value && PluginConfig.MaxReservationSeconds.Value >= 0f)
				{
					WeightReserverComponent weightReserverComponent = default(WeightReserverComponent);
					if (((Component)item).gameObject.TryGetComponent<WeightReserverComponent>(ref weightReserverComponent))
					{
						weightReserverComponent.StopTimer();
					}
					else
					{
						weightReserverComponent = ((Component)item).gameObject.AddComponent<WeightReserverComponent>();
					}
					weightReserverComponent.Setup(item.m_itemData, val);
				}
			}
			return item;
		}

		[HarmonyPatch(typeof(Projectile), "Setup")]
		[HarmonyPostfix]
		public static void Projectile_Setup_Postfix(Projectile __instance)
		{
			ItemData spawnItem = GetSpawnItem(__instance);
			if (!PluginConfig.ReserveThrowWeight.Value || PluginConfig.MaxReservationSeconds.Value < 0f)
			{
				return;
			}
			Character projectileOwner = GetProjectileOwner(__instance);
			Player val = (Player)(object)((projectileOwner is Player) ? projectileOwner : null);
			if (val != null && (Object)(object)val == (Object)(object)Player.m_localPlayer && spawnItem != null && IsPotentiallyThrowable(spawnItem))
			{
				WeightReserverComponent weightReserverComponent = default(WeightReserverComponent);
				if (((Component)__instance).gameObject.TryGetComponent<WeightReserverComponent>(ref weightReserverComponent))
				{
					weightReserverComponent.StopTimer();
				}
				else
				{
					weightReserverComponent = ((Component)__instance).gameObject.AddComponent<WeightReserverComponent>();
				}
				weightReserverComponent.Setup(spawnItem, val);
			}
		}

		[HarmonyPatch(typeof(Projectile), "SpawnOnHit")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Projectile_SpawnOnHit_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			MethodInfo DropItemMethod = AccessTools.DeclaredMethod(typeof(ItemDrop), "DropItem", (Type[])null, (Type[])null);
			MethodInfo AddLoyaltyToSpearMethod = AccessTools.DeclaredMethod(typeof(SpearPatches), "AddLoyaltySpearPickupComponent", (Type[])null, (Type[])null);
			foreach (CodeInstruction instruction in instructions)
			{
				yield return instruction;
				if (instruction.opcode == OpCodes.Call && CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)DropItemMethod))
				{
					yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null);
					yield return new CodeInstruction(OpCodes.Call, (object)AddLoyaltyToSpearMethod);
				}
			}
		}

		[HarmonyPatch(typeof(Projectile), "LateUpdate")]
		[HarmonyPostfix]
		public static void Projectile_LateUpdate_Postfix(Projectile __instance)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			ItemData spawnItem = GetSpawnItem(__instance);
			Character projectileOwner = GetProjectileOwner(__instance);
			if (!(projectileOwner is Player) || spawnItem == null || !IsSpear(spawnItem))
			{
				return;
			}
			float value = PluginConfig.FlightDistanceUntilAutoReturn.Value;
			if (!(value < 0f))
			{
				Vector3 val = ((Component)projectileOwner).transform.position - ((Component)__instance).transform.position;
				if (((Vector3)(ref val)).sqrMagnitude > value * value)
				{
					ZNetView nview = GetNview(ItemDrop.DropItem(spawnItem, 0, ((Component)__instance).transform.position, ((Component)__instance).transform.rotation));
					GetNview(projectileOwner).InvokeRPC("RPC_PickupLoyaltySpear", new object[2]
					{
						nview.GetZDO().m_uid,
						-1f
					});
					FieldSpawnItem.SetValue(__instance, null);
					ZNetScene.instance.Destroy(((Component)__instance).gameObject);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "AutoPickup")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> AutoPickupTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0039: 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_005a: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			FieldInfo autoPickupField = AccessTools.DeclaredField(typeof(ItemDrop), "m_autoPickup");
			MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(SpearPatches), "ShouldAutoPickup", (Type[])null, (Type[])null);
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instruction) => CodeInstructionExtensions.LoadsField(instruction, autoPickupField, false)), (string)null)
			}).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Dup, (object)null)
			}).Advance(1)
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, (object)methodInfo)
				})
				.Instructions();
		}

		public static bool ShouldAutoPickup(ItemDrop itemDrop, bool isAutoPickupable, Player player)
		{
			if (!Object.op_Implicit((Object)(object)itemDrop) || itemDrop.m_itemData == null)
			{
				return isAutoPickupable;
			}
			if (!isAutoPickupable)
			{
				return isAutoPickupable;
			}
			if (IsPotentiallyThrowable(itemDrop.m_itemData))
			{
				ZNetView nview = GetNview(itemDrop);
				if ((Object)(object)nview != (Object)null)
				{
					return nview.IsOwner();
				}
				return true;
			}
			return !BlockAutoPickupDueToReservedWeight(itemDrop, player);
		}

		private static bool BlockAutoPickupDueToReservedWeight(ItemDrop itemDrop, Player player)
		{
			if (!PluginConfig.ReserveThrowWeight.Value || PluginConfig.MaxReservationSeconds.Value < 0f)
			{
				return false;
			}
			float num = 0f;
			PlayerWeightReserverTrackerComponent playerWeightReserverTrackerComponent = default(PlayerWeightReserverTrackerComponent);
			if (((Component)player).TryGetComponent<PlayerWeightReserverTrackerComponent>(ref playerWeightReserverTrackerComponent))
			{
				for (int num2 = playerWeightReserverTrackerComponent.WeightReservers.Count - 1; num2 >= 0; num2--)
				{
					WeightReserverComponent weightReserverComponent = playerWeightReserverTrackerComponent.WeightReservers[num2];
					if ((Object)(object)weightReserverComponent != (Object)null && weightReserverComponent.AttachedItemData != null)
					{
						num += weightReserverComponent.AttachedItemData.GetWeight(-1);
					}
					else
					{
						playerWeightReserverTrackerComponent.WeightReservers.RemoveAt(num2);
					}
				}
			}
			if (num <= 0f)
			{
				return false;
			}
			Inventory inventory = GetInventory((Humanoid)(object)player);
			return itemDrop.m_itemData.GetWeight(-1) + inventory.GetTotalWeight() > player.GetMaxCarryWeight() - num;
		}

		[HarmonyPatch(typeof(Player), "TeleportTo")]
		[HarmonyPostfix]
		private static void TeleportTo_Postfix(Player __instance)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			Projectile[] array = Object.FindObjectsByType<Projectile>((FindObjectsSortMode)0);
			foreach (Projectile val in array)
			{
				Character projectileOwner = GetProjectileOwner(val);
				Player val2 = (Player)(object)((projectileOwner is Player) ? projectileOwner : null);
				if (val2 != null && (Object)(object)val2 == (Object)(object)__instance)
				{
					LoyaltyComponent component = ((Component)val).GetComponent<LoyaltyComponent>();
					if ((Object)(object)component != (Object)null)
					{
						Object.Destroy((Object)(object)component);
					}
					WeightReserverComponent component2 = ((Component)val).GetComponent<WeightReserverComponent>();
					if ((Object)(object)component2 != (Object)null)
					{
						Object.Destroy((Object)(object)component2);
					}
				}
			}
			LoyaltyComponent[] array2 = Object.FindObjectsByType<LoyaltyComponent>((FindObjectsSortMode)0);
			foreach (LoyaltyComponent loyaltyComponent in array2)
			{
				if ((Object)(object)loyaltyComponent.OriginalOwner == (Object)(object)__instance)
				{
					Object.Destroy((Object)(object)loyaltyComponent);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "OnDestroy")]
		[HarmonyPostfix]
		private static void OnDestroy_Postfix(Player __instance)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			LoyaltyComponent[] array = Object.FindObjectsByType<LoyaltyComponent>((FindObjectsSortMode)0);
			foreach (LoyaltyComponent loyaltyComponent in array)
			{
				if ((Object)(object)loyaltyComponent.OriginalOwner == (Object)(object)__instance)
				{
					Object.Destroy((Object)(object)loyaltyComponent);
				}
			}
			WeightReserverComponent[] array2 = Object.FindObjectsByType<WeightReserverComponent>((FindObjectsSortMode)0);
			foreach (WeightReserverComponent weightReserverComponent in array2)
			{
				if ((Object)(object)weightReserverComponent.OriginalOwner == (Object)(object)__instance)
				{
					Object.Destroy((Object)(object)weightReserverComponent);
				}
			}
		}
	}
	internal class WeightReserverComponent : MonoBehaviour
	{
		protected ItemData _attachedItemData;

		protected Player _originalOwner;

		public ItemData AttachedItemData => _attachedItemData;

		public Player OriginalOwner => _originalOwner;

		public void Setup(ItemData attachedItemData, Player originalOwner)
		{
			if ((Object)(object)originalOwner == (Object)null)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			_attachedItemData = attachedItemData;
			_originalOwner = originalOwner;
			PlayerWeightReserverTrackerComponent playerWeightReserverTrackerComponent = default(PlayerWeightReserverTrackerComponent);
			if (!((Component)originalOwner).TryGetComponent<PlayerWeightReserverTrackerComponent>(ref playerWeightReserverTrackerComponent))
			{
				playerWeightReserverTrackerComponent = ((Component)originalOwner).gameObject.AddComponent<PlayerWeightReserverTrackerComponent>();
			}
			playerWeightReserverTrackerComponent.WeightReservers.Add(this);
			StartTimer();
		}

		protected virtual void StartTimer()
		{
			((MonoBehaviour)this).StartCoroutine("UnreserveInABit");
		}

		public virtual void StopTimer()
		{
			((MonoBehaviour)this).StopCoroutine("UnreserveInABit");
		}

		private IEnumerator UnreserveInABit()
		{
			float value = PluginConfig.MaxReservationSeconds.Value;
			if (value > 0f)
			{
				yield return (object)new WaitForSeconds(value);
			}
			Object.Destroy((Object)(object)this);
		}

		public void OnDestroy()
		{
			PlayerWeightReserverTrackerComponent playerWeightReserverTrackerComponent = default(PlayerWeightReserverTrackerComponent);
			if (((Component)_originalOwner).TryGetComponent<PlayerWeightReserverTrackerComponent>(ref playerWeightReserverTrackerComponent))
			{
				playerWeightReserverTrackerComponent.WeightReservers.Remove(this);
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LoyalSpears";

		public const string PLUGIN_NAME = "LoyalSpears";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}