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 Pinned = new HashSet(); 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(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 _holding = new List(); private readonly List _pinned = new List(); 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().sharedMesh = RackMesh.Build(layout, val2, val3); ((Renderer)val.AddComponent()).sharedMaterial = RackMesh.CreateMaterial(val2, val3); RackMesh.AddColliders(val, layout); ItemRack itemRack = val.AddComponent(); 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 items) { if (items == null || items.Count == 0) { return; } Dictionary flat = new Dictionary(); List list = new List(); List list2 = new List(); List list3 = new List(); 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 PlaceStanding(List 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 list = new List(); 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 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> PackIntoRows(List plans) { plans.Sort((Footprint a, Footprint b) => b.Width.CompareTo(a.Width)); float usableShelfWidth = _layout.UsableShelfWidth; List> list = new List>(); List list2 = new List(); 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()); 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> 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 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 list = new List(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 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 list = new List(32); Transform transform = ((Component)item).transform; Rigidbody rig = item.Rig; Collider[] componentsInChildren = ((Component)item).GetComponentsInChildren(); 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(); 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 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 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 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 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 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 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 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(); 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(); 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 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 Enabled; internal static ConfigEntry SweepLooseItems; internal static ConfigEntry SweepRadius; internal static ConfigEntry OffsetForward; internal static ConfigEntry OffsetRight; internal static ConfigEntry PinItems; internal static ConfigEntry PinSettleSeconds; internal static ConfigEntry LingerSeconds; internal static ConfigEntry PoofWhenEmptied; internal static ConfigEntry ShelfCount; internal static ConfigEntry CabinetWidth; internal static ConfigEntry StandingLength; internal static ConfigEntry RackSpacing; internal static ConfigEntry WoodPrimaryColor; internal static ConfigEntry WoodSecondColor; internal static ConfigEntry NameplateHeight; internal static ConfigEntry 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("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("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("General", "SweepRadius", 25f, "How far from the wipe site to look for those dropped items, in metres."); OffsetForward = ((BaseUnityPlugin)this).Config.Bind("Placement", "OffsetForward", 3f, "Metres in front of the island's spawn point to stand the racks."); OffsetRight = ((BaseUnityPlugin)this).Config.Bind("Placement", "OffsetRight", 0f, "Metres to the right of the spawn point. Use this if the racks land on something."); PinItems = ((BaseUnityPlugin)this).Config.Bind("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("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("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("Lifetime", "PoofWhenEmptied", true, "Make a rack disappear as soon as the last item has been taken off it."); ShelfCount = ((BaseUnityPlugin)this).Config.Bind("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("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("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("Appearance", "RackSpacing", 0.5f, "Gap between neighbouring players' racks, in metres."); WoodPrimaryColor = ((BaseUnityPlugin)this).Config.Bind("Appearance", "WoodPrimaryColor", "8A5A2B", "Plank colour, hex RRGGBB. Takes effect on the next rack."); WoodSecondColor = ((BaseUnityPlugin)this).Config.Bind("Appearance", "WoodSecondColor", "C89B54", "Highlight colour, hex RRGGBB. Takes effect on the next rack."); NameplateHeight = ((BaseUnityPlugin)this).Config.Bind("Appearance", "NameplateHeight", 0.35f, "How far above each rack its owner's name floats, in metres."); NameplateScale = ((BaseUnityPlugin)this).Config.Bind("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> Pending = new Dictionary>(); private static readonly Dictionary Racks = new Dictionary(); 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(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 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 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> 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 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 OrderedPlayers() { List list = new List(); 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 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 UnitCubes = new Dictionary(); 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 parts = new List(); 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 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(); 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(); 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 list = new List(24); List list2 = new List(24); List list3 = new List(24); List list4 = new List(24); List list5 = new List(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().renderMode = (RenderMode)2; val.AddComponent(); 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(); 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(); } 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()) ?? 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(); 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 DroppedOnDeath = new Dictionary(); [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 list = null; foreach (KeyValuePair item in DroppedOnDeath) { if ((Object)(object)item.Key == (Object)null || ((NetworkBehaviour)item.Key).IsDeinitializing || (Object)(object)item.Value == (Object)null) { (list ?? (list = new List())).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 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 list = new List(); HashSet seen = new HashSet(); foreach (KeyValuePair 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 items, HashSet 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); } } }