Decompiled source of DeathItemRack v1.1.0

HowToFish.DeathItemRack.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FishNet.Object;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("HowToFish.DeathItemRack")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+486118753589c7ccf2c8f6410896a489260c7684")]
[assembly: AssemblyProduct("Death Item Rack")]
[assembly: AssemblyTitle("HowToFish.DeathItemRack")]
[assembly: AssemblyVersion("1.1.0.0")]
namespace HowToFish.DeathItemRack;

internal enum PinMode
{
	None,
	LongGearOnly,
	Everything
}
internal static class ItemPinning
{
	private static readonly HashSet<Item> Pinned = new HashSet<Item>();

	internal static bool IsPinned(Item item)
	{
		if ((Object)(object)item != (Object)null)
		{
			return Pinned.Contains(item);
		}
		return false;
	}

	internal static void Hold(Item item)
	{
		if (!((Object)(object)item == (Object)null) && !((Object)(object)item.RigidbodySync == (Object)null))
		{
			Pinned.Add(item);
			item.RigidbodySync.SetKinematic(true);
		}
	}

	internal static void Reassert(Item item, Vector3 position, Quaternion rotation)
	{
		//IL_006a: 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)
		//IL_0085: 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)
		if ((Object)(object)item == (Object)null || item.IsDestroying || ((NetworkBehaviour)item).IsDeinitializing || !Pinned.Contains(item) || (Object)(object)item.Holder != (Object)null || (Object)(object)item.SyncedHolder != (Object)null || item.IsInInventory)
		{
			return;
		}
		RigidbodySync rigidbodySync = item.RigidbodySync;
		if (!((Object)(object)rigidbodySync == (Object)null))
		{
			rigidbodySync.SetKinematic(true);
			((Component)item).transform.SetPositionAndRotation(position, rotation);
			if ((Object)(object)item.Rig != (Object)null)
			{
				item.Rig.position = position;
				item.Rig.rotation = rotation;
			}
		}
	}

	internal static void Latch(Item item)
	{
		if ((Object)(object)item == (Object)null || item.IsDestroying || ((NetworkBehaviour)item).IsDeinitializing || !Pinned.Contains(item))
		{
			return;
		}
		RigidbodySync rigidbodySync = item.RigidbodySync;
		if (!((Object)(object)rigidbodySync == (Object)null))
		{
			rigidbodySync.ServerSetIsFloating(true);
			if (!rigidbodySync.IsFloating)
			{
				Plugin.Log.LogWarning((object)(item.GetName() + " would not latch; it is held on this machine only, and will come loose if anything disturbs it."));
			}
		}
	}

	internal static void Relatch(Item item)
	{
		if (!((Object)(object)item == (Object)null) && !item.IsDestroying && !((NetworkBehaviour)item).IsDeinitializing && Pinned.Contains(item))
		{
			RigidbodySync rigidbodySync = item.RigidbodySync;
			if ((Object)(object)rigidbodySync != (Object)null && !rigidbodySync.IsFloating)
			{
				rigidbodySync.ServerSetIsFloating(true);
			}
		}
	}

	internal static void Release(Item item)
	{
		if (!((Object)(object)item == (Object)null) && Pinned.Remove(item))
		{
			RigidbodySync rigidbodySync = item.RigidbodySync;
			if (!((Object)(object)rigidbodySync == (Object)null) && !((NetworkBehaviour)item).IsDeinitializing)
			{
				rigidbodySync.ServerSetIsFloating(false);
				rigidbodySync.SetKinematic(false);
			}
		}
	}

	internal static void ReleaseAll()
	{
		foreach (Item item in new List<Item>(Pinned))
		{
			Release(item);
		}
		Pinned.Clear();
	}
}
internal sealed class ItemRack : MonoBehaviour
{
	private struct Footprint
	{
		public Item Item;

		public Quaternion LocalRotation;

		public float Width;

		public float Depth;

		public float Height;

		public Vector3 BottomOffset;

		public float LowReachRight;

		public float LowReachLeft;

		internal float LowReach(bool right)
		{
			if (!right)
			{
				return LowReachLeft;
			}
			return LowReachRight;
		}
	}

	private struct Held
	{
		public Item Item;

		public Vector3 Position;

		public Quaternion Rotation;
	}

	private const float GraceSeconds = 3f;

	private const float PoofSeconds = 0.25f;

	private const float DropClearance = 0.05f;

	private const float Gap = 0.04f;

	private const float FitMargin = 0.05f;

	private const float ChannelMargin = 0.02f;

	private const float StackHeight = 0.24f;

	private RackLayout _layout;

	private float _createdAt;

	private float _nextEmptyCheck;

	private bool _sawAnyItem;

	private bool _poofing;

	private readonly List<Held> _holding = new List<Held>();

	private readonly List<Item> _pinned = new List<Item>();

	private float _latchAt = -1f;

	private bool _latched;

	private static readonly Quaternion[] Orientations = BuildOrientations();

	private const int Spins = 12;

	private static bool PinsLongGear => Plugin.PinItems.Value != PinMode.None;

	private static bool PinsShelfGear => Plugin.PinItems.Value == PinMode.Everything;

	internal static ItemRack Build(RackLayout layout, string ownerName)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		//IL_0012: 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_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: 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_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("DeathItemRack");
		val.transform.SetPositionAndRotation(layout.Origin, layout.Rotation);
		int num = LayerMask.NameToLayer("Level");
		if (num >= 0)
		{
			val.layer = num;
		}
		Color val2 = ParseColor(Plugin.WoodPrimaryColor.Value, Color32.op_Implicit(new Color32((byte)138, (byte)90, (byte)43, byte.MaxValue)));
		Color val3 = ParseColor(Plugin.WoodSecondColor.Value, Color32.op_Implicit(new Color32((byte)200, (byte)155, (byte)84, byte.MaxValue)));
		val.AddComponent<MeshFilter>().sharedMesh = RackMesh.Build(layout, val2, val3);
		((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterial = RackMesh.CreateMaterial(val2, val3);
		RackMesh.AddColliders(val, layout);
		ItemRack itemRack = val.AddComponent<ItemRack>();
		itemRack._layout = layout;
		itemRack._createdAt = Time.time;
		RackNameplate.Create(val.transform, new Vector3(0f, layout.Height + Plugin.NameplateHeight.Value, 0.225f), string.IsNullOrEmpty(ownerName) ? "?" : ownerName, Plugin.NameplateScale.Value);
		return itemRack;
	}

	internal void PlaceItems(Player player, IList<Item> items)
	{
		if (items == null || items.Count == 0)
		{
			return;
		}
		Dictionary<Item, Footprint> flat = new Dictionary<Item, Footprint>();
		List<Item> list = new List<Item>();
		List<Footprint> list2 = new List<Footprint>();
		List<Footprint> list3 = new List<Footprint>();
		foreach (Item item in items)
		{
			if (IsPlaceable(item))
			{
				Footprint footprint = ChooseFlatFootprint(item);
				flat[item] = footprint;
				bool flag = FitsAShelf(footprint);
				bool flag2 = footprint.Width >= Mathf.Max(0.05f, Plugin.StandingLength.Value) && (Object)(object)item.Creature == (Object)null;
				if (flag2)
				{
					list.Add(item);
				}
				else if (flag)
				{
					list2.Add(footprint);
				}
				else
				{
					list3.Add(footprint);
				}
				Plugin.Log.LogInfo((object)("  " + item.GetName() + ": " + footprint.Width.ToString("0.00") + "m long x " + footprint.Depth.ToString("0.00") + "m deep x " + footprint.Height.ToString("0.00") + "m tall -> " + (flag2 ? "standing (long)" : (flag ? "shelf" : (((Object)(object)item.Creature != (Object)null) ? "on top (too big to lie on a shelf)" : "on top (will not lie on a shelf)")))));
			}
		}
		list.Sort((Item a, Item b) => flat[b].Width.CompareTo(flat[a].Width));
		int stood;
		foreach (Item item2 in PlaceStanding(list, out stood))
		{
			Footprint footprint2 = flat[item2];
			(FitsAShelf(footprint2) ? list2 : list3).Add(footprint2);
		}
		int num = stood + PlaceRows(PackIntoRows(list2)) + PlaceOnTop(list3);
		if (num > 0)
		{
			_sawAnyItem = true;
		}
		string text = (((Object)(object)player != (Object)null) ? player.SteamName : "someone");
		Plugin.Log.LogInfo((object)("Racked " + num + " item(s) for " + text + "."));
	}

	private bool FitsAShelf(Footprint lying)
	{
		if (lying.Width <= _layout.UsableShelfWidth - 0.05f)
		{
			return lying.Depth <= _layout.UsableShelfDepth - 0.05f;
		}
		return false;
	}

	private List<Item> PlaceStanding(List<Item> items, out int stood)
	{
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		List<Item> list = new List<Item>();
		int num = 0;
		foreach (Item item in items)
		{
			if (num >= 4)
			{
				list.Add(item);
				continue;
			}
			bool flag = _layout.FlankIsRight(num);
			Footprint footprint = ChooseUprightFootprint(item, flag);
			if (!ThreadsTheProngs(footprint, flag))
			{
				Plugin.Log.LogInfo((object)("  " + item.GetName() + " on end is " + footprint.Depth.ToString("0.00") + "m through the fork and " + footprint.LowReach(flag).ToString("0.00") + "m across the flank at the wall (fork " + 0.14f.ToString("0.00") + "m, flank " + _layout.FlankClearance.ToString("0.00") + "m); it cannot stand here."));
				list.Add(item);
			}
			else
			{
				Vector3 target = _layout.ToWorld(_layout.FlankFootLocal(num, _layout.FootOffsetFor(footprint.Width)));
				PlaceAt(footprint, target, PinsLongGear);
				num++;
			}
		}
		stood = num;
		if (num > 0)
		{
			Plugin.Log.LogInfo((object)("Stood " + num + " long item(s) in the flanks."));
		}
		return list;
	}

	private int PlaceOnTop(List<Footprint> plans)
	{
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: 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)
		for (int i = 0; i < plans.Count; i++)
		{
			float num = 0.45f * (0.3f + 0.4f * (float)(i % 2));
			float num2 = _layout.CabinetWidth * 0.25f * ((i % 4 < 2) ? (-1f) : 1f);
			Vector3 target = _layout.ToWorld(new Vector3(num2, _layout.Height, num));
			PlaceAt(plans[i], target, PinsLongGear);
		}
		if (plans.Count > 0)
		{
			Plugin.Log.LogInfo((object)("Laid " + plans.Count + " item(s) on top of the cabinet."));
		}
		return plans.Count;
	}

	private bool ThreadsTheProngs(Footprint upright, bool right)
	{
		if (upright.Depth > 0.120000005f)
		{
			return false;
		}
		if (0.03f + upright.LowReach(right) > _layout.FlankClearance)
		{
			return false;
		}
		return upright.Width + 0.03f - 0.38f <= Mathf.Max(0f, Plugin.RackSpacing.Value);
	}

	private List<List<Footprint>> PackIntoRows(List<Footprint> plans)
	{
		plans.Sort((Footprint a, Footprint b) => b.Width.CompareTo(a.Width));
		float usableShelfWidth = _layout.UsableShelfWidth;
		List<List<Footprint>> list = new List<List<Footprint>>();
		List<float> list2 = new List<float>();
		foreach (Footprint plan in plans)
		{
			int num = -1;
			for (int num2 = 0; num2 < list.Count; num2++)
			{
				if (list2[num2] + 0.04f + plan.Width <= usableShelfWidth)
				{
					num = num2;
					break;
				}
			}
			if (num < 0)
			{
				list.Add(new List<Footprint>());
				list2.Add(0f);
				num = list.Count - 1;
			}
			list2[num] += ((list[num].Count > 0) ? 0.04f : 0f) + plan.Width;
			list[num].Add(plan);
		}
		return list;
	}

	private int PlaceRows(List<List<Footprint>> rows)
	{
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		int num = 0;
		for (int i = 0; i < rows.Count; i++)
		{
			List<Footprint> list = rows[i];
			float num2 = 0.04f * (float)Mathf.Max(0, list.Count - 1);
			foreach (Footprint item in list)
			{
				num2 += item.Width;
			}
			int shelf = i % _layout.Shelves;
			int num3 = i / _layout.Shelves;
			float num4 = _layout.ShelfSurfaceY(shelf) + (float)num3 * 0.24f;
			float num5 = (0f - num2) * 0.5f;
			foreach (Footprint item2 in list)
			{
				num5 += item2.Width * 0.5f;
				Vector3 target = _layout.ToWorld(new Vector3(num5, num4, _layout.UsableShelfDepth * 0.5f));
				PlaceAt(item2, target, PinsShelfGear);
				num++;
				num5 += item2.Width * 0.5f + 0.04f;
			}
		}
		return num;
	}

	private static Quaternion[] BuildOrientations()
	{
		//IL_0008: 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_0014: 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_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: 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_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		Vector3[] obj = new Vector3[6]
		{
			Vector3.up,
			Vector3.down,
			Vector3.forward,
			Vector3.back,
			Vector3.right,
			Vector3.left
		};
		List<Quaternion> list = new List<Quaternion>(24);
		Vector3[] array = (Vector3[])(object)obj;
		foreach (Vector3 val in array)
		{
			Vector3 val2 = ((Mathf.Abs(Vector3.Dot(val, Vector3.up)) > 0.9f) ? Vector3.forward : Vector3.up);
			Quaternion val3 = Quaternion.LookRotation(val, val2);
			for (int j = 0; j < 4; j++)
			{
				list.Add(Quaternion.AngleAxis(90f * (float)j, val) * val3);
			}
		}
		return list.ToArray();
	}

	private static List<Vector3> ShapePoints(Item item)
	{
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		List<Vector3> list = new List<Vector3>(32);
		Transform transform = ((Component)item).transform;
		Rigidbody rig = item.Rig;
		Collider[] componentsInChildren = ((Component)item).GetComponentsInChildren<Collider>();
		foreach (Collider val in componentsInChildren)
		{
			if (!((Object)(object)val == (Object)null) && val.enabled && !val.isTrigger && TryShapeBounds(val, out var shape))
			{
				Rigidbody attachedRigidbody = val.attachedRigidbody;
				if (!((Object)(object)rig != (Object)null) || !((Object)(object)attachedRigidbody != (Object)null) || !((Object)(object)attachedRigidbody != (Object)(object)rig))
				{
					AddCorners(transform, ((Component)val).transform, shape, list);
				}
			}
		}
		if (list.Count > 0)
		{
			return list;
		}
		Renderer[] componentsInChildren2 = ((Component)item).GetComponentsInChildren<Renderer>();
		foreach (Renderer val2 in componentsInChildren2)
		{
			if (!((Object)(object)val2 == (Object)null) && val2.enabled && !(val2 is ParticleSystemRenderer) && !(val2 is TrailRenderer) && !(val2 is LineRenderer) && TryMeshBounds(val2, out var shape2))
			{
				AddCorners(transform, ((Component)val2).transform, shape2, list);
			}
		}
		return list;
	}

	private static void AddCorners(Transform root, Transform child, Bounds shape, List<Vector3> points)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//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_0011: 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_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: 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_006d: 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)
		Matrix4x4 val = root.worldToLocalMatrix * child.localToWorldMatrix;
		Vector3 center = ((Bounds)(ref shape)).center;
		Vector3 extents = ((Bounds)(ref shape)).extents;
		Vector3 val2 = default(Vector3);
		for (int i = 0; i < 8; i++)
		{
			((Vector3)(ref val2))..ctor(((i & 1) == 0) ? (0f - extents.x) : extents.x, ((i & 2) == 0) ? (0f - extents.y) : extents.y, ((i & 4) == 0) ? (0f - extents.z) : extents.z);
			points.Add(((Matrix4x4)(ref val)).MultiplyPoint3x4(center + val2));
		}
	}

	private static Vector3 LongestAxis(List<Vector3> points)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: 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_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: 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_003e: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = Vector3.right;
		float num = 0f;
		for (int i = 0; i < points.Count; i++)
		{
			for (int j = i + 1; j < points.Count; j++)
			{
				Vector3 val2 = points[j] - points[i];
				float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
				if (sqrMagnitude > num)
				{
					num = sqrMagnitude;
					val = val2;
				}
			}
		}
		if (!(num > 1E-06f))
		{
			return Vector3.right;
		}
		return ((Vector3)(ref val)).normalized;
	}

	private static Footprint Measure(Item item, Quaternion localRotation, List<Vector3> points)
	{
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: 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_0042: 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_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: 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_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: 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_0074: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: 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_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0190: Unknown result type (might be due to invalid IL or missing references)
		//IL_019e: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = default(Vector3);
		((Vector3)(ref val))..ctor(float.MaxValue, float.MaxValue, float.MaxValue);
		Vector3 val2 = default(Vector3);
		((Vector3)(ref val2))..ctor(float.MinValue, float.MinValue, float.MinValue);
		foreach (Vector3 point in points)
		{
			Vector3 val3 = localRotation * point;
			val = Vector3.Min(val, val3);
			val2 = Vector3.Max(val2, val3);
		}
		float num = val.y + 0.2f;
		float num2 = float.MaxValue;
		float num3 = float.MinValue;
		foreach (Vector3 point2 in points)
		{
			Vector3 val4 = localRotation * point2;
			if (!(val4.y > num))
			{
				num2 = Mathf.Min(num2, val4.x);
				num3 = Mathf.Max(num3, val4.x);
			}
		}
		if (num2 > num3)
		{
			num2 = val.x;
			num3 = val2.x;
		}
		return new Footprint
		{
			Item = item,
			LocalRotation = localRotation,
			Width = val2.x - val.x,
			Depth = val2.z - val.z,
			Height = val2.y - val.y,
			BottomOffset = new Vector3((val.x + val2.x) * 0.5f, val.y, (val.z + val2.z) * 0.5f),
			LowReachRight = num3 - val.x,
			LowReachLeft = val2.x - num2
		};
	}

	private Footprint ChooseFlatFootprint(Item item)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: 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_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		List<Vector3> list = ShapePoints(item);
		if (list.Count == 0)
		{
			return Guess(item);
		}
		Quaternion val = Quaternion.FromToRotation(LongestAxis(list), Vector3.right);
		Footprint result = default(Footprint);
		float num = float.MaxValue;
		for (int i = 0; i < 12; i++)
		{
			Quaternion val2 = Quaternion.AngleAxis((float)i * 15f, Vector3.right);
			Footprint footprint = Measure(item, val2 * val, list);
			if (footprint.Height < num)
			{
				num = footprint.Height;
				result = footprint;
			}
		}
		return result;
	}

	private Footprint ChooseUprightFootprint(Item item, bool leanRight)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0050: 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_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: 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_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		List<Vector3> list = ShapePoints(item);
		if (list.Count == 0)
		{
			return Guess(item);
		}
		Quaternion val = Quaternion.FromToRotation(LongestAxis(list), Vector3.up);
		Quaternion val2 = Quaternion.identity;
		float num = float.MaxValue;
		for (int i = 0; i < 12; i++)
		{
			Quaternion val3 = Quaternion.AngleAxis((float)i * 15f, Vector3.up);
			Footprint footprint = Measure(item, val3 * val, list);
			if (footprint.Depth < num)
			{
				num = footprint.Depth;
				val2 = val3;
			}
		}
		Quaternion val4 = val2 * val;
		if (CentreOfBulk(val4, list) > MidHeight(item, val4, list))
		{
			val4 = Quaternion.AngleAxis(180f, Vector3.right) * val4;
		}
		Quaternion val5 = Quaternion.AngleAxis(1f * (leanRight ? 1f : (-1f)), Vector3.forward);
		return Measure(item, val5 * val4, list);
	}

	private static float CentreOfBulk(Quaternion rotation, List<Vector3> points)
	{
		//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_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_001a: Unknown result type (might be due to invalid IL or missing references)
		float num = 0f;
		foreach (Vector3 point in points)
		{
			num += (rotation * point).y;
		}
		return num / (float)points.Count;
	}

	private static float MidHeight(Item item, Quaternion rotation, List<Vector3> points)
	{
		//IL_0001: 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)
		Footprint footprint = Measure(item, rotation, points);
		return footprint.BottomOffset.y + footprint.Height * 0.5f;
	}

	private static Footprint Guess(Item item)
	{
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		float num = Mathf.Max(item.ModelHeight * 2f, 0.25f);
		Plugin.Log.LogWarning((object)(item.GetName() + " has no shape to measure; treating it as " + num.ToString("0.00") + "m cubed."));
		return new Footprint
		{
			Item = item,
			LocalRotation = Quaternion.identity,
			Width = num,
			Depth = num,
			Height = num,
			BottomOffset = new Vector3(0f, (0f - num) * 0.5f, 0f)
		};
	}

	private static bool TryShapeBounds(Collider collider, out Bounds shape)
	{
		//IL_000c: 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_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: 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)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: 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_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		BoxCollider val = (BoxCollider)(object)((collider is BoxCollider) ? collider : null);
		if (val != null)
		{
			shape = new Bounds(val.center, val.size);
			return true;
		}
		SphereCollider val2 = (SphereCollider)(object)((collider is SphereCollider) ? collider : null);
		if (val2 != null)
		{
			shape = new Bounds(val2.center, Vector3.one * (val2.radius * 2f));
			return true;
		}
		CapsuleCollider val3 = (CapsuleCollider)(object)((collider is CapsuleCollider) ? collider : null);
		if (val3 != null)
		{
			float num = val3.radius * 2f;
			Vector3 val4 = default(Vector3);
			((Vector3)(ref val4))..ctor(num, num, num);
			float num2 = Mathf.Max(val3.height, num);
			if (val3.direction == 0)
			{
				val4.x = num2;
			}
			else if (val3.direction == 1)
			{
				val4.y = num2;
			}
			else
			{
				val4.z = num2;
			}
			shape = new Bounds(val3.center, val4);
			return true;
		}
		MeshCollider val5 = (MeshCollider)(object)((collider is MeshCollider) ? collider : null);
		if (val5 != null && (Object)(object)val5.sharedMesh != (Object)null)
		{
			shape = val5.sharedMesh.bounds;
			return true;
		}
		shape = default(Bounds);
		return false;
	}

	private static bool TryMeshBounds(Renderer renderer, out Bounds shape)
	{
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null);
		if (val != null && (Object)(object)val.sharedMesh != (Object)null)
		{
			shape = val.sharedMesh.bounds;
			return true;
		}
		MeshFilter component = ((Component)renderer).GetComponent<MeshFilter>();
		if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null)
		{
			shape = component.sharedMesh.bounds;
			return true;
		}
		shape = default(Bounds);
		return false;
	}

	private void PlaceAt(Footprint plan, Vector3 target, bool pin)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: 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_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: 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_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: 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_005e: 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)
		if (!pin)
		{
			target.y += 0.05f;
		}
		Vector3 position = target - _layout.Rotation * plan.BottomOffset;
		Quaternion rotation = _layout.Rotation * plan.LocalRotation;
		Settle(plan.Item, position, rotation);
		if (pin)
		{
			Hold(plan.Item, position, rotation);
		}
	}

	private void Hold(Item item, Vector3 position, Quaternion rotation)
	{
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: 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)
		ItemPinning.Hold(item);
		_pinned.Add(item);
		_holding.Add(new Held
		{
			Item = item,
			Position = position,
			Rotation = rotation
		});
		_latchAt = Time.time + Mathf.Max(0f, Plugin.PinSettleSeconds.Value);
	}

	private void FixedUpdate()
	{
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		if (_holding.Count == 0 || _poofing)
		{
			return;
		}
		try
		{
			bool flag = !_latched && Time.time >= _latchAt;
			foreach (Held item in _holding)
			{
				ItemPinning.Reassert(item.Item, item.Position, item.Rotation);
				if (flag)
				{
					ItemPinning.Latch(item.Item);
				}
				else if (_latched)
				{
					ItemPinning.Relatch(item.Item);
				}
			}
			if (flag)
			{
				_latched = true;
				Plugin.Log.LogInfo((object)("Pinned " + _holding.Count + " item(s) in place."));
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("Could not hold racked gear; letting it go: " + ex));
			ReleaseGear();
		}
	}

	private void ReleaseGear()
	{
		_holding.Clear();
		_latchAt = -1f;
		_latched = false;
		foreach (Item item in _pinned)
		{
			ItemPinning.Release(item);
		}
		_pinned.Clear();
	}

	private static bool IsPlaceable(Item item)
	{
		if ((Object)(object)item != (Object)null && !item.IsDestroying && !((NetworkBehaviour)item).IsDeinitializing && (Object)(object)item.DeadPlayer == (Object)null)
		{
			return (Object)(object)item.Rig != (Object)null;
		}
		return false;
	}

	private static void Settle(Item item, Vector3 position, Quaternion rotation)
	{
		//IL_003f: 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_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: 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_001c: 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_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			RigidbodySync rigidbodySync = item.RigidbodySync;
			if ((Object)(object)rigidbodySync != (Object)null)
			{
				rigidbodySync.StartSimulateLocal(default(Vector3), default(Quaternion));
				rigidbodySync.SetKinematic(false);
				rigidbodySync.TeleportToPosRot(position, rotation, (float[])null, (Quaternion[])null);
			}
			((Component)item).transform.SetPositionAndRotation(position, rotation);
			Zero(item.Rig, position, rotation);
			if (item.ExtraRigs == null)
			{
				return;
			}
			ItemExtraRigidbody[] extraRigs = item.ExtraRigs;
			foreach (ItemExtraRigidbody val in extraRigs)
			{
				if ((Object)(object)val != (Object)null)
				{
					Zero(val.Rig, null, null);
				}
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("Could not rack an item: " + ex));
		}
	}

	private static void Zero(Rigidbody rig, Vector3? position, Quaternion? rotation)
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)rig == (Object)null))
		{
			if (position.HasValue && rotation.HasValue)
			{
				rig.position = position.Value;
				rig.rotation = rotation.Value;
			}
			if (!rig.isKinematic)
			{
				rig.linearVelocity = Vector3.zero;
				rig.angularVelocity = Vector3.zero;
			}
		}
	}

	private void Update()
	{
		try
		{
			if (IslandManager.IsLoading)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
			else
			{
				if (_poofing)
				{
					return;
				}
				float num = Time.time - _createdAt;
				if (num >= Mathf.Max(5f, Plugin.LingerSeconds.Value))
				{
					Poof();
				}
				else if (Plugin.PoofWhenEmptied.Value && !(num < 3f) && !(Time.time < _nextEmptyCheck))
				{
					_nextEmptyCheck = Time.time + 1f;
					if (HasItems())
					{
						_sawAnyItem = true;
					}
					else if (_sawAnyItem)
					{
						Poof();
					}
				}
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("Rack update failed: " + ex));
			((Behaviour)this).enabled = false;
		}
	}

	internal void Poof()
	{
		//IL_0055: 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_0065: 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_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		if (!_poofing)
		{
			_poofing = true;
			BoxCollider[] components = ((Component)this).GetComponents<BoxCollider>();
			for (int i = 0; i < components.Length; i++)
			{
				((Collider)components[i]).enabled = false;
			}
			ReleaseGear();
			Vector3 val = _layout.ToWorld(new Vector3(0f, _layout.Height * 0.5f, 0.225f));
			ParticleManager.Play("Smoke", val, Vector3.up);
			AudioManager.PlayClipAt("Poof", val, true, (AudioDistance)0, 0.25f, 0.1f);
			LeanTween.cancel(((Component)this).gameObject);
			LeanTween.scale(((Component)this).gameObject, Vector3.zero, 0.25f).setEase((LeanTweenType)2).setDestroyOnComplete(true);
		}
	}

	private bool HasItems()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: 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_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		Quaternion val = Quaternion.Inverse(_layout.Rotation);
		float num = _layout.PlinthWidth * 0.5f;
		foreach (KeyValuePair<Transform, Item> item in ItemManager.Items)
		{
			Item value = item.Value;
			if (!((Object)(object)value == (Object)null) && !value.IsDestroying && !((NetworkBehaviour)value).IsDeinitializing && !value.IsInInventory && !((Object)(object)value.Holder != (Object)null) && !((Object)(object)value.SyncedHolder != (Object)null) && !((Object)(object)value.DeadPlayer != (Object)null))
			{
				Vector3 val2 = val * (((Component)value).transform.position - _layout.Origin);
				if (!(val2.x < 0f - num - 0.15f) && !(val2.x > num + 0.15f) && !(val2.y < -0.15f) && !(val2.y > _layout.Height + 1.5f) && !(val2.z < -0.2f) && !(val2.z > _layout.PlinthDepth + 0.25f))
				{
					return true;
				}
			}
		}
		return false;
	}

	private void OnDestroy()
	{
		ReleaseGear();
		RackController.OnRackDestroyed(this);
	}

	private static Color ParseColor(string hex, Color fallback)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		if (string.IsNullOrEmpty(hex))
		{
			return fallback;
		}
		Color result = default(Color);
		if (!ColorUtility.TryParseHtmlString(hex.StartsWith("#") ? hex : ("#" + hex), ref result))
		{
			return fallback;
		}
		return result;
	}
}
[BepInPlugin("alexandre.howtofish.deathitemrack", "Death Item Rack", "1.1.0")]
public class Plugin : BaseUnityPlugin
{
	public const string Guid = "alexandre.howtofish.deathitemrack";

	internal static ManualLogSource Log;

	internal static Plugin Instance;

	internal static ConfigEntry<bool> Enabled;

	internal static ConfigEntry<bool> SweepLooseItems;

	internal static ConfigEntry<float> SweepRadius;

	internal static ConfigEntry<float> OffsetForward;

	internal static ConfigEntry<float> OffsetRight;

	internal static ConfigEntry<PinMode> PinItems;

	internal static ConfigEntry<float> PinSettleSeconds;

	internal static ConfigEntry<float> LingerSeconds;

	internal static ConfigEntry<bool> PoofWhenEmptied;

	internal static ConfigEntry<int> ShelfCount;

	internal static ConfigEntry<float> CabinetWidth;

	internal static ConfigEntry<float> StandingLength;

	internal static ConfigEntry<float> RackSpacing;

	internal static ConfigEntry<string> WoodPrimaryColor;

	internal static ConfigEntry<string> WoodSecondColor;

	internal static ConfigEntry<float> NameplateHeight;

	internal static ConfigEntry<float> NameplateScale;

	private void Awake()
	{
		//IL_0266: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		Log = ((BaseUnityPlugin)this).Logger;
		Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Build an item rack per player at the spawn point when the whole squad is wiped. Solo, your own death is the wipe.");
		SweepLooseItems = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "SweepLooseItems", true, "Also rack the item a player was carrying in their hand when they died. The game drops that one where the player fell, so without this it stays there.");
		SweepRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SweepRadius", 25f, "How far from the wipe site to look for those dropped items, in metres.");
		OffsetForward = ((BaseUnityPlugin)this).Config.Bind<float>("Placement", "OffsetForward", 3f, "Metres in front of the island's spawn point to stand the racks.");
		OffsetRight = ((BaseUnityPlugin)this).Config.Bind<float>("Placement", "OffsetRight", 0f, "Metres to the right of the spawn point. Use this if the racks land on something.");
		PinItems = ((BaseUnityPlugin)this).Config.Bind<PinMode>("Physics", "PinItems", PinMode.LongGearOnly, "How much of a rack is held still instead of balanced by physics. Long gear stood in the flanks is what falls over, so it is held by default; the shelves hold their own. Pinned gear is released the moment it is picked up, and when the rack goes. None restores the 1.0.0 behaviour.");
		PinSettleSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "PinSettleSeconds", 1.5f, "Seconds the host holds gear in place before pinning it for everyone. This is the window the racked positions have to reach the other players in; raise it if clients see gear frozen somewhere it is not. No effect in single player.");
		LingerSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Lifetime", "LingerSeconds", 180f, "Seconds before the racks disappear. Items left on them are never destroyed - they simply drop to the ground where the rack stood.");
		PoofWhenEmptied = ((BaseUnityPlugin)this).Config.Bind<bool>("Lifetime", "PoofWhenEmptied", true, "Make a rack disappear as soon as the last item has been taken off it.");
		ShelfCount = ((BaseUnityPlugin)this).Config.Bind<int>("Appearance", "ShelfCount", 3, "Shelves in the cabinet. Small gear - handguns, melee, shotguns, uzis - goes here; anything longer stands upright in the flanks either side.");
		CabinetWidth = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "CabinetWidth", 1.2f, "Width of the shelved cabinet, in metres. The rack is wider than this by the two flanks the long gear stands in.");
		StandingLength = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "StandingLength", 0.7f, "Gear at least this long, in metres, stands upright in a flank rather than lying on a shelf, even where a shelf would take it. Rifles look like rifles stood on end; raise it to lay more of them down, lower it to stand more up.");
		RackSpacing = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "RackSpacing", 0.5f, "Gap between neighbouring players' racks, in metres.");
		WoodPrimaryColor = ((BaseUnityPlugin)this).Config.Bind<string>("Appearance", "WoodPrimaryColor", "8A5A2B", "Plank colour, hex RRGGBB. Takes effect on the next rack.");
		WoodSecondColor = ((BaseUnityPlugin)this).Config.Bind<string>("Appearance", "WoodSecondColor", "C89B54", "Highlight colour, hex RRGGBB. Takes effect on the next rack.");
		NameplateHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "NameplateHeight", 0.35f, "How far above each rack its owner's name floats, in metres.");
		NameplateScale = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "NameplateScale", 1f, "Size multiplier for the floating name labels. The typeface always comes from the game's own player nametags; this only changes how big it is drawn.");
		new Harmony("alexandre.howtofish.deathitemrack").PatchAll();
		RackController.Initialize();
		Log.LogInfo((object)"Death Item Rack loaded.");
	}

	private void OnDestroy()
	{
		RackController.Shutdown();
	}
}
internal static class RackController
{
	private static readonly Dictionary<Player, List<Item>> Pending = new Dictionary<Player, List<Item>>();

	private static readonly Dictionary<ulong, ItemRack> Racks = new Dictionary<ulong, ItemRack>();

	private static int _prevAliveCount;

	private static bool _sawWipe;

	private static bool _flushQueued;

	private static bool _wipeLatched;

	internal static bool IsSquadWipe
	{
		get
		{
			if (_wipeLatched)
			{
				return true;
			}
			if (PlayerManager.Players.Count > 0 && PlayerManager.AlivePlayers.Count == 0)
			{
				_wipeLatched = true;
				return true;
			}
			return false;
		}
	}

	internal static void Initialize()
	{
		_prevAliveCount = PlayerManager.AlivePlayers.Count;
		PlayerManager.OnPlayerAmountChange += OnPlayerAmountChange;
	}

	internal static void Shutdown()
	{
		PlayerManager.OnPlayerAmountChange -= OnPlayerAmountChange;
		Pending.Clear();
		_flushQueued = false;
		_wipeLatched = false;
		foreach (ItemRack item in new List<ItemRack>(Racks.Values))
		{
			if ((Object)(object)item != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
		}
		Racks.Clear();
		ItemPinning.ReleaseAll();
	}

	internal static void Capture(Player player, List<Item> items)
	{
		if ((Object)(object)player != (Object)null && items != null && items.Count > 0)
		{
			if (Pending.TryGetValue(player, out var value))
			{
				value.AddRange(items);
			}
			else
			{
				Pending[player] = items;
			}
		}
		QueueFlush();
	}

	private static void QueueFlush()
	{
		if (!_flushQueued)
		{
			if ((Object)(object)Plugin.Instance == (Object)null)
			{
				_wipeLatched = false;
				return;
			}
			_flushQueued = true;
			((MonoBehaviour)Plugin.Instance).StartCoroutine(FlushRoutine());
		}
	}

	internal static void OnRackDestroyed(ItemRack rack)
	{
		foreach (KeyValuePair<ulong, ItemRack> rack2 in Racks)
		{
			if ((Object)(object)rack2.Value == (Object)(object)rack)
			{
				Racks.Remove(rack2.Key);
				break;
			}
		}
	}

	private static IEnumerator FlushRoutine()
	{
		yield return (object)new WaitForEndOfFrame();
		_flushQueued = false;
		try
		{
			EnsureRacks();
			foreach (KeyValuePair<Player, List<Item>> item in Pending)
			{
				Player key = item.Key;
				if (!((Object)(object)key == (Object)null) && Racks.TryGetValue(key.SteamID, out var value) && (Object)(object)value != (Object)null)
				{
					value.PlaceItems(key, item.Value);
				}
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("Failed to fill the racks: " + ex));
		}
		finally
		{
			Pending.Clear();
			_wipeLatched = false;
		}
	}

	private static void OnPlayerAmountChange()
	{
		try
		{
			int count = PlayerManager.AlivePlayers.Count;
			int prevAliveCount = _prevAliveCount;
			_prevAliveCount = count;
			if (Plugin.Enabled.Value)
			{
				if (prevAliveCount > 0 && count == 0)
				{
					_sawWipe = true;
				}
				else if (_sawWipe && count > 0)
				{
					_sawWipe = false;
					EnsureRacks();
				}
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("Wipe watch failed: " + ex));
		}
	}

	private static void EnsureRacks()
	{
		if (Racks.Count > 0)
		{
			return;
		}
		IList<Player> list = OrderedPlayers();
		if (list.Count == 0)
		{
			Plugin.Log.LogWarning((object)"Squad wipe with no players on record; skipping the racks.");
			return;
		}
		for (int i = 0; i < list.Count; i++)
		{
			Player val = list[i];
			RackLayout layout = BuildLayout(i, list.Count);
			Racks[val.SteamID] = ItemRack.Build(layout, val.SteamName);
		}
		Plugin.Log.LogInfo((object)("Built " + list.Count + " rack(s) at the spawn point."));
	}

	private static RackLayout BuildLayout(int index, int count)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//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_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_00a6: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: 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_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		Vector3 playerSpawnPos = SpawnManager.PlayerSpawnPos;
		Quaternion val = Quaternion.Euler(0f, SpawnManager.PlayerSpawnRot, 0f);
		Vector3 val2 = playerSpawnPos + val * new Vector3(Plugin.OffsetRight.Value, 0f, Plugin.OffsetForward.Value);
		Quaternion val3 = Quaternion.Euler(0f, SpawnManager.PlayerSpawnRot + 180f, 0f);
		float num = Mathf.Clamp(Plugin.CabinetWidth.Value, 0.5f, 3f) + 0.76f + Mathf.Max(0f, Plugin.RackSpacing.Value);
		float num2 = ((float)index - (float)(count - 1) * 0.5f) * num;
		Vector3 val4 = val2 + val3 * new Vector3(num2, 0f, 0f);
		RaycastHit val5 = default(RaycastHit);
		if (Physics.Raycast(val4 + Vector3.up * 20f, Vector3.down, ref val5, 60f, LayerMask.op_Implicit(GameInfo.LevelLayer)))
		{
			val4.y = ((RaycastHit)(ref val5)).point.y - 0.05f;
		}
		else
		{
			val4.y = playerSpawnPos.y - 0.05f;
			Plugin.Log.LogWarning((object)"No ground under a rack position; using the spawn height.");
		}
		return new RackLayout(val4, val3, Plugin.ShelfCount.Value, Plugin.CabinetWidth.Value);
	}

	private static IList<Player> OrderedPlayers()
	{
		List<Player> list = new List<Player>();
		foreach (Player player in PlayerManager.Players)
		{
			if ((Object)(object)player != (Object)null && !((NetworkBehaviour)player).IsDeinitializing)
			{
				list.Add(player);
			}
		}
		list.Sort(delegate(Player a, Player b)
		{
			int num = a.SteamID.CompareTo(b.SteamID);
			return (num == 0) ? ((NetworkBehaviour)a).ObjectId.CompareTo(((NetworkBehaviour)b).ObjectId) : num;
		});
		return list;
	}
}
internal sealed class RackLayout
{
	internal const float Depth = 0.45f;

	internal const float ShelfThickness = 0.05f;

	internal const float BackThickness = 0.05f;

	internal const float PostWidth = 0.07f;

	internal const float LipHeight = 0.08f;

	internal const float LipThickness = 0.04f;

	internal const float PlinthHeight = 0.22f;

	internal const float PlinthFrontOverhang = 0.1f;

	internal const float FlankWidth = 0.38f;

	internal const float FlankWallThickness = 0.06f;

	internal const float FlankWallHeight = 0.2f;

	internal const float ProngLength = 0.26f;

	internal const float ProngThickness = 0.03f;

	internal const float ProngHeight = 0.05f;

	internal const float ProngChannel = 0.14f;

	internal const int ProngLevels = 2;

	internal const float FirstShelfAbovePlinth = 0.06f;

	internal const float ShelfSpacing = 0.42f;

	internal const float HeadRoom = 0.34f;

	internal const float Overlap = 0.012f;

	internal const float Overhang = 0.04f;

	internal const float StandingLeanDegrees = 1f;

	internal const int FlankSlots = 4;

	internal readonly Vector3 Origin;

	internal readonly Quaternion Rotation;

	internal readonly int Shelves;

	internal readonly float CabinetWidth;

	internal const float StandingInset = 0.03f;

	internal float PlinthWidth => CabinetWidth + 0.76f;

	internal float PlinthDepth => 0.55f;

	internal float CabinetHeight => 0.06f + (float)(Shelves - 1) * 0.42f + 0.34f;

	internal float Height => 0.22f + CabinetHeight;

	internal float UsableShelfWidth => Mathf.Max(0.1f, CabinetWidth - 0.14f);

	internal float UsableShelfDepth => 0.41f;

	internal float FlankFootOffset => 0.19f;

	internal float FlankClearance => 0.32f;

	internal RackLayout(Vector3 origin, Quaternion rotation, int shelves, float cabinetWidth)
	{
		//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_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)
		Origin = origin;
		Rotation = rotation;
		Shelves = Mathf.Clamp(shelves, 1, 5);
		CabinetWidth = Mathf.Clamp(cabinetWidth, 0.5f, 3f);
	}

	internal float ShelfSurfaceY(int shelf)
	{
		return 0.28f + (float)shelf * 0.42f;
	}

	internal Vector3 ToWorld(Vector3 local)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//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)
		return Origin + Rotation * local;
	}

	internal bool FlankIsRight(int slot)
	{
		return slot % 2 == 0;
	}

	internal float FlankSlotZ(int slot)
	{
		float num = -0.038000003f;
		float num2 = 0.46199998f;
		bool flag = slot >= 2;
		return num + (num2 - num) * (flag ? 0.73f : 0.27f);
	}

	internal float FootOffsetFor(float width)
	{
		return width * 0.5f + 0.03f;
	}

	internal float ProngLevelY(int level)
	{
		if (level != 0)
		{
			return Height - 0.2f;
		}
		return 0.22f + (Height - 0.22f) * 0.28f;
	}

	internal Vector3 FlankFootLocal(int slot, float footOffset)
	{
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		slot = Mathf.Clamp(slot, 0, 3);
		return new Vector3((CabinetWidth * 0.5f + footOffset) * (FlankIsRight(slot) ? 1f : (-1f)), 0.22f, FlankSlotZ(slot));
	}

	internal Vector3 FlankFootLocal(int slot)
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		slot = Mathf.Clamp(slot, 0, 3);
		return FlankFootLocal(slot, FlankFootOffset);
	}

	internal void ForEachBox(Action<Vector3, Vector3, bool> box)
	{
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_015d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0219: Unknown result type (might be due to invalid IL or missing references)
		//IL_0222: Unknown result type (might be due to invalid IL or missing references)
		//IL_0250: Unknown result type (might be due to invalid IL or missing references)
		//IL_025b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0283: Unknown result type (might be due to invalid IL or missing references)
		//IL_029a: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_033c: Unknown result type (might be due to invalid IL or missing references)
		//IL_034a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0360: Unknown result type (might be due to invalid IL or missing references)
		//IL_0374: Unknown result type (might be due to invalid IL or missing references)
		float num = CabinetWidth * 0.5f;
		float num2 = PlinthWidth * 0.5f;
		float height = Height;
		float num3 = 0.46199998f;
		float num4 = 0.426f;
		float num5 = 0.438f;
		float num6 = -0.038000003f;
		float num7 = 0f - num + 0.07f - 0.012f;
		float num8 = num - 0.07f + 0.012f;
		Corners(new Vector3(0f - num2, 0f, -0.05f), new Vector3(num2, 0.22f, PlinthDepth), isShelf: false);
		float num9 = Mathf.Clamp(0.42000002f, 0.37f, height - 0.15f);
		for (int i = -1; i <= 1; i += 2)
		{
			float num10 = (num2 + 0.012f) * (float)i;
			float num11 = (num2 - 0.06f) * (float)i;
			Corners(new Vector3(Mathf.Min(num10, num11), 0.208f, -0.062f), new Vector3(Mathf.Max(num10, num11), num9, PlinthDepth + 0.012f), isShelf: false);
			float num12 = (num - 0.035f) * (float)i;
			float num13 = (num2 - 0.012f) * (float)i;
			float num14 = Mathf.Min(num12, num13);
			float num15 = Mathf.Max(num12, num13);
			Corners(new Vector3(num14, 0.196f, PlinthDepth - 0.06f), new Vector3(num15, num9 - 0.012f, PlinthDepth + 0.024f), isShelf: false);
			Corners(new Vector3(num14, 0.196f, -0.074f), new Vector3(num15, num9 - 0.012f, num6 + 0.012f + 0.06f), isShelf: false);
		}
		Corners(new Vector3(0f - num + 0.012f, 0.232f, -0.05f), new Vector3(num - 0.012f, height - 0.012f, 0f), isShelf: false);
		Corners(new Vector3(0f - num, 0.208f, num6), new Vector3(0f - num + 0.07f, height, num3), isShelf: false);
		Corners(new Vector3(num - 0.07f, 0.208f, num6), new Vector3(num, height, num3), isShelf: false);
		for (int j = 0; j < Shelves; j++)
		{
			float num16 = ShelfSurfaceY(j);
			Corners(new Vector3(num7, num16 - 0.05f, num6 + 0.012f), new Vector3(num8, num16, num4), isShelf: true);
			Corners(new Vector3(num7 - 0.012f, num16 - 0.05f + 0.012f, 0.41f), new Vector3(num8 + 0.012f, num16 + 0.08f, num5), isShelf: true);
		}
		for (int k = 0; k < 4; k++)
		{
			float num17 = (FlankIsRight(k) ? 1f : (-1f));
			float num18 = FlankSlotZ(k);
			float num19 = 0.07f;
			float num20 = (num - 0.0245f) * num17;
			float num21 = (num + 0.26f) * num17;
			float num22 = Mathf.Min(num20, num21);
			float num23 = Mathf.Max(num20, num21);
			for (int l = 0; l < 2; l++)
			{
				float num24 = ProngLevelY(l);
				float num25 = num24 + 0.05f;
				Corners(new Vector3(num22, num24, num18 - num19 - 0.03f), new Vector3(num23, num25, num18 - num19), isShelf: false);
				Corners(new Vector3(num22, num24, num18 + num19), new Vector3(num23, num25, num18 + num19 + 0.03f), isShelf: false);
			}
		}
		Corners(new Vector3(0f - num - 0.04f, height - 0.05f, -0.09f), new Vector3(num + 0.04f, height + 0.012f, 0.48999998f), isShelf: false);
		void Corners(Vector3 min, Vector3 max, bool isShelf)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			box((min + max) * 0.5f, max - min, isShelf);
		}
	}
}
internal static class RackMesh
{
	private static readonly int ColorsId = Shader.PropertyToID("_Colors");

	internal static readonly Vector2 FrameUv = new Vector2(0.25f, 0.5f);

	internal static readonly Vector2 ShelfUv = new Vector2(0.75f, 0.5f);

	private static readonly Dictionary<Vector2, Mesh> UnitCubes = new Dictionary<Vector2, Mesh>();

	private static Texture _palette;

	private static Color[] _palettePixels;

	private static int _paletteWidth;

	private static int _paletteHeight;

	private static bool _paletteSearched;

	internal static Mesh Build(RackLayout layout, Color frame, Color shelf)
	{
		//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_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: 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_006f: Expected O, but got Unknown
		Mesh frameCube = UnitCube(FrameUv, frame);
		Mesh shelfCube = UnitCube(ShelfUv, shelf);
		List<CombineInstance> parts = new List<CombineInstance>();
		layout.ForEachBox(delegate(Vector3 centre, Vector3 size, bool isShelf)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			List<CombineInstance> list = parts;
			CombineInstance item = default(CombineInstance);
			((CombineInstance)(ref item)).mesh = (isShelf ? shelfCube : frameCube);
			((CombineInstance)(ref item)).subMeshIndex = 0;
			((CombineInstance)(ref item)).transform = Matrix4x4.TRS(centre, Quaternion.identity, size);
			list.Add(item);
		});
		Mesh val = new Mesh
		{
			name = "DeathItemRack"
		};
		val.CombineMeshes(parts.ToArray(), true, true);
		val.RecalculateBounds();
		return val;
	}

	internal static void AddColliders(GameObject go, RackLayout layout)
	{
		layout.ForEachBox(delegate(Vector3 centre, Vector3 size, bool _)
		{
			//IL_000c: 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)
			BoxCollider obj = go.AddComponent<BoxCollider>();
			obj.center = centre;
			obj.size = size;
		});
	}

	internal static Material CreateMaterial(Color primary, Color secondary)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Expected O, but got Unknown
		//IL_0063: 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_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: 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_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		Material val = new Material(PropShader())
		{
			name = "DeathItemRack_Wood"
		};
		if (val.HasProperty(ColorsId))
		{
			val.SetTexture(ColorsId, (Texture)(object)SwatchTexture(primary, secondary));
		}
		TrySetInt(val, ShaderManager.UseSkinID, 0);
		TrySetInt(val, ShaderManager.RainbowSkinID, 0);
		TrySetFloat(val, ShaderManager.CooknessID, 0f);
		TrySetVector(val, ShaderManager.PlayerPrimaryColorID, primary);
		TrySetVector(val, ShaderManager.PlayerSecondColorID, secondary);
		TrySetVector(val, ShaderManager.PlayerThirdColorID, secondary);
		TrySetVector(val, ShaderManager.PlayerSkinID, primary);
		TrySetColor(val, "_BaseColor", primary);
		TrySetColor(val, "_Color", primary);
		TrySetFloatByName(val, "_Smoothness", 0.05f);
		TrySetFloatByName(val, "_Glossiness", 0.05f);
		TrySetFloatByName(val, "_Metallic", 0f);
		LogShaderProperties(val.shader);
		return val;
	}

	private static Texture Palette()
	{
		if (_paletteSearched)
		{
			return _palette;
		}
		_paletteSearched = true;
		try
		{
			Shader val = PropShader();
			Material[] array = Resources.FindObjectsOfTypeAll<Material>();
			foreach (Material val2 in array)
			{
				if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.shader != (Object)(object)val) && val2.HasProperty(ColorsId))
				{
					Texture texture = val2.GetTexture(ColorsId);
					if ((Object)(object)texture != (Object)null)
					{
						_palette = texture;
						Plugin.Log.LogInfo((object)("Rack palette: " + ((Object)texture).name + " (" + texture.width + "x" + texture.height + ") from material " + ((Object)val2).name + "."));
						return _palette;
					}
				}
			}
			Plugin.Log.LogWarning((object)"No _Colors palette found; the rack will render white.");
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("Palette lookup failed: " + ex));
		}
		return _palette;
	}

	private static Texture2D SwatchTexture(Color frame, Color shelf)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//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_000d: Unknown result type (might be due to invalid IL or missing references)
		//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_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Expected O, but got Unknown
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: 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)
		Color val = NearestSwatch(frame);
		Color val2 = NearestSwatch(shelf);
		Texture2D val3 = new Texture2D(2, 1, (TextureFormat)4, false, false)
		{
			name = "DeathItemRack_Swatches",
			filterMode = (FilterMode)0,
			wrapMode = (TextureWrapMode)1,
			anisoLevel = 0
		};
		val3.SetPixels((Color[])(object)new Color[2] { val, val2 });
		val3.Apply(false, false);
		return val3;
	}

	private static Color NearestSwatch(Color wanted)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//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_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: 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_0040: 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_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: 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)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		if (!LoadPalettePixels())
		{
			return wanted;
		}
		int num = -1;
		float num2 = float.MaxValue;
		for (int i = 0; i < _palettePixels.Length; i++)
		{
			Color val = _palettePixels[i];
			if (!(val.a < 0.5f))
			{
				float num3 = val.r - wanted.r;
				float num4 = val.g - wanted.g;
				float num5 = val.b - wanted.b;
				float num6 = num3 * num3 + num4 * num4 + num5 * num5;
				if (num6 < num2)
				{
					num2 = num6;
					num = i;
				}
			}
		}
		if (num < 0)
		{
			return wanted;
		}
		Color val2 = _palettePixels[num];
		val2.a = 1f;
		Plugin.Log.LogInfo((object)("Wanted #" + ColorUtility.ToHtmlStringRGB(wanted) + ", using palette #" + ColorUtility.ToHtmlStringRGB(val2) + "."));
		return val2;
	}

	private static bool LoadPalettePixels()
	{
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: 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_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Expected O, but got Unknown
		if (_palettePixels != null)
		{
			return true;
		}
		Texture val = Palette();
		if ((Object)(object)val == (Object)null)
		{
			return false;
		}
		RenderTexture val2 = null;
		RenderTexture active = RenderTexture.active;
		try
		{
			val2 = RenderTexture.GetTemporary(val.width, val.height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
			Graphics.Blit(val, val2);
			RenderTexture.active = val2;
			Texture2D val3 = new Texture2D(val.width, val.height, (TextureFormat)4, false);
			val3.ReadPixels(new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), 0, 0);
			val3.Apply();
			_palettePixels = val3.GetPixels();
			_paletteWidth = ((Texture)val3).width;
			_paletteHeight = ((Texture)val3).height;
			Object.Destroy((Object)val3);
			return true;
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("Could not read the palette: " + ex));
			return false;
		}
		finally
		{
			RenderTexture.active = active;
			if ((Object)(object)val2 != (Object)null)
			{
				RenderTexture.ReleaseTemporary(val2);
			}
		}
	}

	private static void LogShaderProperties(Shader shader)
	{
		try
		{
			StringBuilder stringBuilder = new StringBuilder();
			int propertyCount = shader.GetPropertyCount();
			for (int i = 0; i < propertyCount; i++)
			{
				if (i > 0)
				{
					stringBuilder.Append(", ");
				}
				stringBuilder.Append(shader.GetPropertyName(i));
			}
			Plugin.Log.LogInfo((object)("Rack shader: " + ((Object)shader).name + " [" + stringBuilder?.ToString() + "]"));
		}
		catch (Exception ex)
		{
			Plugin.Log.LogInfo((object)("Rack shader: " + ((Object)shader).name + " (properties unreadable: " + ex.Message + ")"));
		}
	}

	private static Shader PropShader()
	{
		Shader val = DefaultGameShader();
		if ((Object)(object)val != (Object)null)
		{
			return val;
		}
		Plugin.Log.LogWarning((object)"Game prop shader not found; falling back to stock URP.");
		return Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Universal Render Pipeline/Simple Lit") ?? Shader.Find("Standard");
	}

	private static Shader DefaultGameShader()
	{
		try
		{
			object? obj = AccessTools.Field(typeof(ShaderManager), "_instance")?.GetValue(null);
			ShaderManager val = (ShaderManager)((obj is ShaderManager) ? obj : null);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			object? obj2 = AccessTools.Field(typeof(ShaderManager), "_defaultShader")?.GetValue(val);
			return (Shader)((obj2 is Shader) ? obj2 : null);
		}
		catch (Exception ex)
		{
			Plugin.Log.LogDebug((object)("Could not reach the default shader: " + ex.Message));
			return null;
		}
	}

	private static Mesh UnitCube(Vector2 uv, Color vertexColor)
	{
		//IL_0005: 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_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: 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_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: 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_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: 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_013d: 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_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_0172: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: 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_0209: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: Unknown result type (might be due to invalid IL or missing references)
		//IL_021b: Expected O, but got Unknown
		//IL_0255: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		if (UnitCubes.TryGetValue(uv, out var value) && (Object)(object)value != (Object)null)
		{
			return value;
		}
		Vector3[] array = (Vector3[])(object)new Vector3[6]
		{
			Vector3.up,
			Vector3.down,
			Vector3.forward,
			Vector3.back,
			Vector3.right,
			Vector3.left
		};
		Vector3[] array2 = (Vector3[])(object)new Vector3[6]
		{
			Vector3.right,
			Vector3.right,
			Vector3.right,
			Vector3.left,
			Vector3.back,
			Vector3.forward
		};
		List<Vector3> list = new List<Vector3>(24);
		List<Vector3> list2 = new List<Vector3>(24);
		List<Vector2> list3 = new List<Vector2>(24);
		List<Color> list4 = new List<Color>(24);
		List<int> list5 = new List<int>(36);
		for (int i = 0; i < array.Length; i++)
		{
			Vector3 val = array[i];
			Vector3 val2 = val * 0.5f;
			Vector3 val3 = array2[i] * 0.5f;
			Vector3 val4 = Vector3.Cross(((Vector3)(ref val3)).normalized, val) * 0.5f;
			int count = list.Count;
			list.Add(val2 - val3 - val4);
			list.Add(val2 + val3 - val4);
			list.Add(val2 + val3 + val4);
			list.Add(val2 - val3 + val4);
			for (int j = 0; j < 4; j++)
			{
				list2.Add(val);
				list3.Add(uv);
				list4.Add(vertexColor);
			}
			list5.Add(count);
			list5.Add(count + 2);
			list5.Add(count + 1);
			list5.Add(count);
			list5.Add(count + 3);
			list5.Add(count + 2);
		}
		Mesh val5 = new Mesh
		{
			name = "DeathItemRack_UnitCube"
		};
		val5.SetVertices(list);
		val5.SetNormals(list2);
		val5.SetUVs(0, list3);
		val5.SetColors(list4);
		val5.SetTriangles(list5, 0);
		val5.RecalculateBounds();
		UnitCubes[uv] = val5;
		return val5;
	}

	private static void TrySetVector(Material m, int id, Color value)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		if (m.HasProperty(id))
		{
			m.SetVector(id, new Vector4(value.r, value.g, value.b, 1f));
		}
	}

	private static void TrySetColor(Material m, string name, Color value)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		if (m.HasProperty(name))
		{
			m.SetColor(name, value);
		}
	}

	private static void TrySetInt(Material m, int id, int value)
	{
		if (m.HasProperty(id))
		{
			m.SetInt(id, value);
		}
	}

	private static void TrySetFloat(Material m, int id, float value)
	{
		if (m.HasProperty(id))
		{
			m.SetFloat(id, value);
		}
	}

	private static void TrySetFloatByName(Material m, string name, float value)
	{
		if (m.HasProperty(name))
		{
			m.SetFloat(name, value);
		}
	}
}
internal sealed class RackNameplate : MonoBehaviour
{
	private const float CanvasWidth = 420f;

	private const float CanvasHeight = 90f;

	private const float MetresPerPixel = 0.0022f;

	private static TMP_FontAsset _font;

	private static bool _fontSearched;

	private void LateUpdate()
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		Camera curCamera = GameInfo.CurCamera;
		if ((Object)(object)curCamera != (Object)null)
		{
			((Component)this).transform.forward = ((Component)curCamera).transform.forward;
		}
	}

	internal static RackNameplate Create(Transform parent, Vector3 localPosition, string text, float scale)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Expected O, but got Unknown
		//IL_0031: 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_004d: 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_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("DeathItemRackNameplate", new Type[1] { typeof(RectTransform) });
		val.transform.SetParent(parent, false);
		val.transform.localPosition = localPosition;
		val.transform.localRotation = Quaternion.identity;
		val.transform.localScale = Vector3.one * (0.0022f * Mathf.Clamp(scale, 0.2f, 5f));
		((RectTransform)val.transform).sizeDelta = new Vector2(420f, 90f);
		val.AddComponent<Canvas>().renderMode = (RenderMode)2;
		val.AddComponent<CanvasScaler>();
		GameObject val2 = new GameObject("Label", new Type[1] { typeof(RectTransform) });
		val2.transform.SetParent(val.transform, false);
		RectTransform val3 = (RectTransform)val2.transform;
		val3.anchorMin = Vector2.zero;
		val3.anchorMax = Vector2.one;
		val3.offsetMin = Vector2.zero;
		val3.offsetMax = Vector2.zero;
		TextMeshProUGUI val4 = val2.AddComponent<TextMeshProUGUI>();
		TMP_FontAsset val5 = BorrowFont();
		if ((Object)(object)val5 != (Object)null)
		{
			((TMP_Text)val4).font = val5;
		}
		((TMP_Text)val4).text = text;
		((TMP_Text)val4).fontSize = 56f;
		((TMP_Text)val4).enableAutoSizing = true;
		((TMP_Text)val4).fontSizeMin = 16f;
		((TMP_Text)val4).fontSizeMax = 56f;
		((TMP_Text)val4).alignment = (TextAlignmentOptions)514;
		((TMP_Text)val4).overflowMode = (TextOverflowModes)1;
		((Graphic)val4).color = Color.white;
		((Graphic)val4).raycastTarget = false;
		ApplyOutline(val4);
		return val.AddComponent<RackNameplate>();
	}

	private static void ApplyOutline(TextMeshProUGUI label)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			Material fontMaterial = ((TMP_Text)label).fontMaterial;
			if (!((Object)(object)fontMaterial == (Object)null))
			{
				fontMaterial.EnableKeyword(ShaderUtilities.Keyword_Outline);
				((TMP_Text)label).outlineColor = Color32.op_Implicit(Color.black);
				((TMP_Text)label).outlineWidth = 0.2f;
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogDebug((object)("Could not outline the nameplate: " + ex.Message));
		}
	}

	private static TMP_FontAsset BorrowFont()
	{
		if (_fontSearched)
		{
			return _font;
		}
		_fontSearched = true;
		_font = FontFrom(SafePrefabOtherPlayer()) ?? FontFrom(Object.FindAnyObjectByType<OtherPlayer>()) ?? AnyLoadedFont();
		if ((Object)(object)_font == (Object)null)
		{
			Plugin.Log.LogWarning((object)"No TMP font found; name labels will use the TMP default.");
		}
		return _font;
	}

	private static OtherPlayer SafePrefabOtherPlayer()
	{
		try
		{
			Player playerPrefab = GameInfo.PlayerPrefab;
			return ((Object)(object)playerPrefab != (Object)null) ? playerPrefab.Other : null;
		}
		catch (Exception)
		{
			return null;
		}
	}

	private static TMP_FontAsset FontFrom(OtherPlayer other)
	{
		if ((Object)(object)other == (Object)null)
		{
			return null;
		}
		try
		{
			object? obj = AccessTools.Field(typeof(OtherPlayer), "_nameText")?.GetValue(other);
			TextMeshProUGUI val = (TextMeshProUGUI)((obj is TextMeshProUGUI) ? obj : null);
			return ((Object)(object)val != (Object)null) ? ((TMP_Text)val).font : null;
		}
		catch (Exception ex)
		{
			Plugin.Log.LogDebug((object)("Could not read the player nametag font: " + ex.Message));
			return null;
		}
	}

	private static TMP_FontAsset AnyLoadedFont()
	{
		try
		{
			TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
			foreach (TMP_FontAsset val in array)
			{
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogDebug((object)("Font sweep failed: " + ex.Message));
		}
		return null;
	}
}
internal static class Reflected
{
	private static FieldInfo _dyingPlayer;

	private static FieldInfo _inventoryPlayer;

	private static bool _looked;

	internal static Player PlayerOf(PlayerDying dying)
	{
		Look();
		object? obj = _dyingPlayer?.GetValue(dying);
		return (Player)((obj is Player) ? obj : null);
	}

	internal static Player PlayerOf(PlayerInventory inventory)
	{
		Look();
		object? obj = _inventoryPlayer?.GetValue(inventory);
		return (Player)((obj is Player) ? obj : null);
	}

	private static void Look()
	{
		if (_looked)
		{
			return;
		}
		_looked = true;
		try
		{
			_dyingPlayer = AccessTools.Field(typeof(PlayerDying), "_player");
			_inventoryPlayer = AccessTools.Field(typeof(PlayerInventory), "_player");
			if (_dyingPlayer == null || _inventoryPlayer == null)
			{
				Plugin.Log.LogWarning((object)"PlayerDying/PlayerInventory no longer expose _player; racking is off.");
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("Could not resolve the player backreferences: " + ex));
		}
	}
}
[HarmonyPatch(typeof(PlayerDying))]
internal static class DeathHandPatch
{
	internal static readonly Dictionary<Player, Item> DroppedOnDeath = new Dictionary<Player, Item>();

	[HarmonyPatch("ServerDie")]
	[HarmonyPrefix]
	private static void RememberHeldItem(PlayerDying __instance)
	{
		try
		{
			Player val = Reflected.PlayerOf(__instance);
			if (!((Object)(object)val == (Object)null))
			{
				Item val2 = (((Object)(object)val.Holding != (Object)null) ? val.Holding.HeldItem : null);
				if ((Object)(object)val2 == (Object)null || (Object)(object)val2.DeadPlayer != (Object)null)
				{
					DroppedOnDeath.Remove(val);
					return;
				}
				Prune();
				DroppedOnDeath[val] = val2;
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("Could not record the item held at death: " + ex));
		}
	}

	private static void Prune()
	{
		List<Player> list = null;
		foreach (KeyValuePair<Player, Item> item in DroppedOnDeath)
		{
			if ((Object)(object)item.Key == (Object)null || ((NetworkBehaviour)item.Key).IsDeinitializing || (Object)(object)item.Value == (Object)null)
			{
				(list ?? (list = new List<Player>())).Add(item.Key);
			}
		}
		if (list == null)
		{
			return;
		}
		foreach (Player item2 in list)
		{
			DroppedOnDeath.Remove(item2);
		}
	}
}
[HarmonyPatch(typeof(Item))]
internal static class PickUpPatch
{
	[HarmonyPatch("PickUp")]
	[HarmonyPostfix]
	private static void ReleasePin(Item __instance)
	{
		try
		{
			ItemPinning.Release(__instance);
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("Could not release a racked item on pickup: " + ex));
		}
	}
}
[HarmonyPatch(typeof(PlayerInventory))]
internal static class SquadWipePatch
{
	[HarmonyPatch("ServerDropAll")]
	[HarmonyPrefix]
	private static void CaptureBeforeDrop(PlayerInventory __instance, Vector3 pos)
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (Plugin.Enabled.Value && ((NetworkBehaviour)__instance).IsServerInitialized && RackController.IsSquadWipe)
			{
				Player val = Reflected.PlayerOf(__instance);
				if (!((Object)(object)val == (Object)null))
				{
					RackController.Capture(val, Collect(__instance, val, pos));
				}
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("Failed to capture a wiped player's items: " + ex));
		}
	}

	private static List<Item> Collect(PlayerInventory inventory, Player player, Vector3 wipePos)
	{
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		List<Item> list = new List<Item>();
		HashSet<Item> seen = new HashSet<Item>();
		foreach (KeyValuePair<byte, Item> item in inventory._items)
		{
			Add(list, seen, item.Value);
		}
		if ((Object)(object)player.Holding != (Object)null)
		{
			Add(list, seen, player.Holding.HeldItem);
		}
		if (Plugin.SweepLooseItems.Value && DeathHandPatch.DroppedOnDeath.TryGetValue(player, out var value))
		{
			DeathHandPatch.DroppedOnDeath.Remove(player);
			float num = Mathf.Max(0f, Plugin.SweepRadius.Value);
			if ((Object)(object)value != (Object)null)
			{
				Vector3 val = ((Component)value).transform.position - wipePos;
				if (((Vector3)(ref val)).sqrMagnitude <= num * num)
				{
					Add(list, seen, value);
				}
			}
		}
		return list;
	}

	private static void Add(List<Item> items, HashSet<Item> seen, Item item)
	{
		if (!((Object)(object)item == (Object)null) && !item.IsDestroying && !((NetworkBehaviour)item).IsDeinitializing && !((Object)(object)item.DeadPlayer != (Object)null) && seen.Add(item))
		{
			items.Add(item);
		}
	}
}