Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RestlessDrawers v0.1.1
RestlessDrawers.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("RestlessDrawers")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.1.0")] [assembly: AssemblyInformationalVersion("0.1.1+b108291e4de755d164c1385424756b2ee56266dd")] [assembly: AssemblyProduct("RestlessDrawers")] [assembly: AssemblyTitle("RestlessDrawers")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace RestlessDrawers { internal sealed class DrawerRow { public string Id = ""; public string Prefab = ""; public string Source = ""; public string Name = ""; public string Description = ""; } internal static class DrawerBook { public static readonly DrawerRow[] Rows = new DrawerRow[4] { new DrawerRow { Id = "wooden", Prefab = "RestlessDrawerWood", Source = "piece_chest_wood", Name = "Wood drawer", Description = "A furniture chest. Same space as a wood chest." }, new DrawerRow { Id = "personal", Prefab = "RestlessDrawerPersonal", Source = "piece_chest_private", Name = "Personal drawer", Description = "A furniture chest only you can open. Same space as a personal chest." }, new DrawerRow { Id = "reinforced", Prefab = "RestlessDrawerReinforced", Source = "piece_chest", Name = "Reinforced drawer", Description = "A furniture chest. Same space as a reinforced chest." }, new DrawerRow { Id = "blackmetal", Prefab = "RestlessDrawerBlackMetal", Source = "piece_chest_blackmetal", Name = "Black metal drawer", Description = "A furniture chest. Same space as a black metal chest." } }; public static bool IsOurs(string? prefab) { string text = prefab ?? ""; if (text.Length > 0) { return text.StartsWith("RestlessDrawer", StringComparison.Ordinal); } return false; } } public sealed class DrawerFace : MonoBehaviour { private const int Slots = 4; private const float IconSize = 0.14f; private readonly SpriteRenderer[] _faces = (SpriteRenderer[])(object)new SpriteRenderer[4]; private string _stamp = ""; private void Awake() { Ensure(); } private void OnEnable() { Refresh(); } public void Refresh() { Ensure(); Container component = ((Component)this).GetComponent<Container>(); List<Sprite> list = Top(((Object)(object)component != (Object)null) ? component.GetInventory() : null); string text = Signature(list); if (text == _stamp) { return; } _stamp = text; for (int i = 0; i < 4; i++) { SpriteRenderer val = _faces[i]; if (!((Object)(object)val == (Object)null)) { if (i >= list.Count) { ((Renderer)val).enabled = false; val.sprite = null; } else { val.sprite = list[i]; ((Renderer)val).enabled = (Object)(object)list[i] != (Object)null; } } } } private void Ensure() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //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_005f: 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_006e: 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_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: 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_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_013a: 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_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0154: 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_0164: 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_01b0: Unknown result type (might be due to invalid IL or missing references) Transform val = ((Component)this).transform.Find("RestlessDrawerMesh"); if ((Object)(object)val == (Object)null) { return; } MeshFilter component = ((Component)val).GetComponent<MeshFilter>(); Bounds val2 = (Bounds)(((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null) ? component.sharedMesh.bounds : new Bounds(Vector3.zero, Vector3.one * 0.5f)); float num = ((Bounds)(ref val2)).center.z + ((Bounds)(ref val2)).extents.z + 0.012f; float y = ((Bounds)(ref val2)).center.y; float num2 = Mathf.Min(((Bounds)(ref val2)).size.x * 0.72f, 0.56f); float num3 = ((Bounds)(ref val2)).center.x - num2 * 0.5f + num2 / 4f * 0.5f; for (int i = 0; i < 4; i++) { if (!((Object)(object)_faces[i] != (Object)null)) { GameObject val3 = new GameObject("RestlessDrawerFace" + i) { layer = ((Component)this).gameObject.layer }; val3.transform.SetParent(val, false); val3.transform.localPosition = new Vector3(num3 + (float)i * (num2 / 4f), y, num); val3.transform.localRotation = Quaternion.identity; val3.transform.localScale = Vector3.one; SpriteRenderer val4 = val3.AddComponent<SpriteRenderer>(); val4.drawMode = (SpriteDrawMode)0; val4.color = Color.white; ((Renderer)val4).enabled = false; float num4 = 0.14f / Mathf.Max(0.01f, val.lossyScale.x); val3.transform.localScale = new Vector3(num4, num4, num4); _faces[i] = val4; } } } private static List<Sprite> Top(Inventory? inv) { List<Sprite> list = new List<Sprite>(); if (inv == null) { return list; } Dictionary<string, (int, Sprite)> dictionary = new Dictionary<string, (int, Sprite)>(); foreach (ItemData allItem in inv.GetAllItems()) { if (allItem?.m_shared != null) { string name = allItem.m_shared.m_name; dictionary.TryGetValue(name, out var value); dictionary[name] = (value.Item1 + Mathf.Max(1, allItem.m_stack), allItem.GetIcon()); } } List<(int, Sprite)> list2 = new List<(int, Sprite)>(dictionary.Values); list2.Sort(((int count, Sprite? icon) a, (int count, Sprite? icon) b) => b.count.CompareTo(a.count)); foreach (var item in list2) { if (!((Object)(object)item.Item2 == (Object)null)) { list.Add(item.Item2); if (list.Count >= 4) { break; } } } return list; } private static string Signature(List<Sprite> icons) { string text = icons.Count.ToString(); foreach (Sprite icon in icons) { text = text + ":" + (((Object)(object)icon != (Object)null) ? ((Object)icon).name : ""); } return text; } } internal static class DrawerGrid { [HarmonyPatch] private static class Patches { [HarmonyPostfix] [HarmonyPatch(typeof(Player), "UpdatePlacementGhost")] private static void AfterGhost(Player __instance) { Align(__instance); } [HarmonyPrefix] [HarmonyPatch(typeof(WearNTear), "UpdateSupport")] private static bool SkipSupport(WearNTear __instance) { if ((Object)(object)((Component)__instance).GetComponent<DrawerFace>() == (Object)null) { return true; } __instance.m_support = 1000f; return false; } [HarmonyPostfix] [HarmonyPatch(typeof(WearNTear), "HaveSupport")] private static void AlwaysSupported(WearNTear __instance, ref bool __result) { if ((Object)(object)((Component)__instance).GetComponent<DrawerFace>() != (Object)null) { __result = true; } } } public const float Cell = 1.1f; public const float Pull = 0.55f; public const float Overlap = 0.04f; public const float YawSlop = 8f; private static readonly Collider[] Near = (Collider[])(object)new Collider[32]; private static readonly Collider[] Occupied = (Collider[])(object)new Collider[16]; public static float Fit(Mesh mesh) { //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_0009: 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) //IL_0015: 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) Bounds bounds = mesh.bounds; Vector3 size = ((Bounds)(ref bounds)).size; float num = Mathf.Max(size.x, Mathf.Max(size.y, size.z)); return 1.1f / Mathf.Max(0.05f, num); } public static void Dress(GameObject prefab) { //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_0020: 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_0043: 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_0054: 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_006b: 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_008b: 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_0097: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_00f8: Unknown result type (might be due to invalid IL or missing references) StripOldSnaps(prefab); Vector3 val = Extent(prefab.transform); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(val.x * 0.5f, val.y * 0.5f, val.z * 0.5f); AddSnap(prefab, "snap_r", new Vector3(val2.x, val2.y, 0f)); AddSnap(prefab, "snap_l", new Vector3(0f - val2.x, val2.y, 0f)); AddSnap(prefab, "snap_f", new Vector3(0f, val2.y, val2.z)); AddSnap(prefab, "snap_b", new Vector3(0f, val2.y, 0f - val2.z)); AddSnap(prefab, "snap_u", new Vector3(0f, val.y, 0f)); AddSnap(prefab, "snap_d", new Vector3(0f, 0f, 0f)); } public static void Align(Player player) { //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_0052: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null) && ((Character)player).InPlaceMode()) { GameObject placementGhost = player.m_placementGhost; if (!((Object)(object)placementGhost == (Object)null) && !((Object)(object)placementGhost.GetComponent<DrawerFace>() == (Object)null) && TrySnap(placementGhost.transform, out var pos, out var rot)) { placementGhost.transform.SetPositionAndRotation(pos, rot); player.m_placementStatus = (PlacementStatus)0; } } } private static bool TrySnap(Transform ghost, out Vector3 pos, out Quaternion rot) { //IL_0002: 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_000e: 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_001f: 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_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0147: 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_015d: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0173: 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_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) pos = ghost.position; rot = ghost.rotation; float num = 1.6500001f; int num2 = Physics.OverlapSphereNonAlloc(ghost.position, num, Near, -1, (QueryTriggerInteraction)1); float num3 = 0.3025f; bool result = false; for (int i = 0; i < num2; i++) { Collider val = Near[i]; if ((Object)(object)val == (Object)null) { continue; } DrawerFace componentInParent = ((Component)val).GetComponentInParent<DrawerFace>(); if ((Object)(object)componentInParent == (Object)null) { continue; } Transform transform = ((Component)componentInParent).transform; if ((Object)(object)transform == (Object)(object)ghost || transform.IsChildOf(ghost) || ghost.IsChildOf(transform) || Mathf.Abs(Mathf.DeltaAngle(ghost.eulerAngles.y, transform.eulerAngles.y)) > 8f) { continue; } Vector3 val2 = Step(transform); Vector3 val3 = transform.InverseTransformPoint(ghost.position); float num4; float num5; float num6; if (Mathf.Abs(val3.x) < 0.55f && Mathf.Abs(val3.z) < 0.55f) { num4 = 0f; num5 = 0f; num6 = ((val3.y < (0f - val2.y) * 0.4f) ? (-1f) : 1f); } else { num4 = Mathf.Round(val3.x / val2.x); num6 = Mathf.Round(val3.y / val2.y); num5 = Mathf.Round(val3.z / val2.z); if (Mathf.Abs(num4) < 0.01f && Mathf.Abs(num6) < 0.01f && Mathf.Abs(num5) < 0.01f) { if (Mathf.Abs(val3.x) >= Mathf.Abs(val3.z)) { num4 = ((val3.x >= 0f) ? 1f : (-1f)); } else { num5 = ((val3.z >= 0f) ? 1f : (-1f)); } } if (Mathf.Abs(num4) + Mathf.Abs(num6) + Mathf.Abs(num5) > 1.01f) { continue; } } Vector3 val4 = transform.TransformPoint(new Vector3(num4 * val2.x, num6 * val2.y, num5 * val2.z)); if (!Taken(val4, ghost)) { Vector3 val5 = ghost.position - val4; float sqrMagnitude = ((Vector3)(ref val5)).sqrMagnitude; if (!(sqrMagnitude > num3)) { num3 = sqrMagnitude; pos = val4; rot = transform.rotation; result = true; } } } return result; } private static bool Taken(Vector3 pos, Transform ghost) { //IL_0006: 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_006e: 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) float num = 0.12f; int num2 = Physics.OverlapSphereNonAlloc(pos, 1.1f, Occupied, -1, (QueryTriggerInteraction)1); for (int i = 0; i < num2; i++) { Collider val = Occupied[i]; if ((Object)(object)val == (Object)null) { continue; } DrawerFace componentInParent = ((Component)val).GetComponentInParent<DrawerFace>(); if ((Object)(object)componentInParent == (Object)null) { continue; } Transform transform = ((Component)componentInParent).transform; if (!((Object)(object)transform == (Object)(object)ghost) && !transform.IsChildOf(ghost) && !ghost.IsChildOf(transform)) { Vector3 val2 = transform.position - pos; if (((Vector3)(ref val2)).sqrMagnitude < num) { return true; } } } return false; } private static Vector3 Extent(Transform drawer) { //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_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_005c: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_008b: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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) Transform val = drawer.Find("RestlessDrawerMesh"); MeshFilter val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<MeshFilter>() : null); Mesh val3 = (((Object)(object)val2 != (Object)null) ? val2.sharedMesh : null); if ((Object)(object)val3 == (Object)null) { return Vector3.one * 1.1f; } Bounds bounds = val3.bounds; Vector3 size = ((Bounds)(ref bounds)).size; Vector3 lossyScale = val.lossyScale; return new Vector3(Mathf.Max(0.2f, size.x * Mathf.Abs(lossyScale.x)), Mathf.Max(0.2f, size.y * Mathf.Abs(lossyScale.y)), Mathf.Max(0.2f, size.z * Mathf.Abs(lossyScale.z))); } private static Vector3 Step(Transform drawer) { //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_000c: 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_0038: 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) Vector3 val = Extent(drawer); return new Vector3(Mathf.Max(0.2f, val.x - 0.04f), Mathf.Max(0.2f, val.y - 0.04f), Mathf.Max(0.2f, val.z - 0.04f)); } private static void StripOldSnaps(GameObject prefab) { for (int num = prefab.transform.childCount - 1; num >= 0; num--) { Transform child = prefab.transform.GetChild(num); if (((Object)child).name.StartsWith("snap", StringComparison.OrdinalIgnoreCase)) { Object.DestroyImmediate((Object)(object)((Component)child).gameObject); } } } private static void AddSnap(GameObject prefab, string name, Vector3 local) { //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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(prefab.transform, false); val.transform.localPosition = local; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; } } internal static class DrawerMesh { private static readonly Dictionary<string, Mesh> Meshes = new Dictionary<string, Mesh>(); private static readonly Dictionary<string, Texture2D> Albedos = new Dictionary<string, Texture2D>(); private static readonly Dictionary<string, Texture2D> Surfaces = new Dictionary<string, Texture2D>(); private static readonly Dictionary<string, Sprite> Icons = new Dictionary<string, Sprite>(); private static string? _folder; private static MethodInfo? _loadImage; private static bool _searched; public static string Folder() { if (_folder != null) { return _folder; } string[] array = PluginRoots(); string[] array2 = array; foreach (string text in array2) { string dir = Path.Combine(text, "mesh"); if (HasRcm(dir)) { return Remember(dir); } if (HasRcm(text)) { return Remember(text); } } _folder = Path.Combine((array.Length != 0) ? array[0] : ".", "mesh"); Plugin.Log.LogWarning((object)("drawer mesh folder missing, looking in " + _folder)); return _folder; } private static string[] PluginRoots() { List<string> list = new List<string>(); Plugin instance = Plugin.Instance; object obj; if (instance == null) { obj = null; } else { PluginInfo info = ((BaseUnityPlugin)instance).Info; obj = ((info != null) ? info.Location : null); } string text = (string)obj; if (!string.IsNullOrEmpty(text)) { AddRoot(list, Path.GetDirectoryName(text)); } string location = typeof(DrawerMesh).Assembly.Location; if (!string.IsNullOrEmpty(location)) { AddRoot(list, Path.GetDirectoryName(location)); } return list.ToArray(); } private static void AddRoot(List<string> roots, string? root) { string text = root ?? ""; if (text.Length == 0) { return; } foreach (string root2 in roots) { if (string.Equals(root2, text, StringComparison.OrdinalIgnoreCase)) { return; } } roots.Add(text); } private static string Remember(string dir) { _folder = dir; Plugin.Log.LogInfo((object)("drawer mesh folder " + dir)); return dir; } private static bool HasRcm(string dir) { if (Directory.Exists(dir)) { return Directory.GetFiles(dir, "*.rcm").Length != 0; } return false; } public static Mesh? Mesh(string id) { if (Meshes.TryGetValue(id, out Mesh value) && (Object)(object)value != (Object)null) { return value; } string path = Path.Combine(Folder(), id + ".rcm"); if (!File.Exists(path)) { Plugin.Log.LogWarning((object)("drawer mesh missing " + id)); return null; } value = ReadRcm(File.ReadAllBytes(path), id); if ((Object)(object)value != (Object)null) { Meshes[id] = value; } return value; } public static Texture2D? Albedo(string id) { if (Albedos.TryGetValue(id, out Texture2D value) && (Object)(object)value != (Object)null) { return value; } string path = Path.Combine(Folder(), id + ".png"); if (!File.Exists(path)) { Plugin.Log.LogWarning((object)("drawer albedo missing " + id)); return null; } value = DecodePng(File.ReadAllBytes(path), id); if ((Object)(object)value != (Object)null) { Albedos[id] = value; } return value; } public static Texture2D? Surface(string id) { if (Surfaces.TryGetValue(id, out Texture2D value) && (Object)(object)value != (Object)null) { return value; } string path = Path.Combine(Folder(), id + ".metal.png"); if (!File.Exists(path)) { Plugin.Log.LogWarning((object)("drawer surface missing " + id)); return null; } value = DecodePng(File.ReadAllBytes(path), id + ".metal", linear: true); if ((Object)(object)value != (Object)null) { Surfaces[id] = value; } return value; } public static Sprite? Icon(string id) { //IL_00c6: 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) if (Icons.TryGetValue(id, out Sprite value) && (Object)(object)value != (Object)null) { return value; } Stream manifestResourceStream = typeof(DrawerMesh).Assembly.GetManifestResourceStream("RestlessDrawers.Assets." + id + ".png"); if (manifestResourceStream == null) { Plugin.Log.LogWarning((object)("drawer icon missing " + id)); return null; } using (manifestResourceStream) { byte[] array = new byte[manifestResourceStream.Length]; int num; for (int i = 0; i < array.Length; i += num) { num = manifestResourceStream.Read(array, i, array.Length - i); if (num <= 0) { break; } } Texture2D val = DecodePng(array, id); if ((Object)(object)val == (Object)null) { return null; } value = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); ((Object)value).name = id; Icons[id] = value; return value; } } private static Mesh? ReadRcm(byte[] data, string name) { //IL_00ce: 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_00fa: 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_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_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017e: 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_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Expected O, but got Unknown if (data.Length < 12 || data[0] != 82 || data[1] != 67 || data[2] != 77 || (data[3] != 49 && data[3] != 50)) { Plugin.Log.LogWarning((object)("drawer mesh bad header " + name)); return null; } bool flag = data[3] == 49; int num = 4; int num2 = BitConverter.ToInt32(data, num); num += 4; int num3 = BitConverter.ToInt32(data, num); num += 4; if (num2 <= 0 || num3 <= 0 || num + num2 * 32 + num3 * 4 > data.Length) { Plugin.Log.LogWarning((object)("drawer mesh truncated " + name)); return null; } Vector3[] array = (Vector3[])(object)new Vector3[num2]; Vector3[] array2 = (Vector3[])(object)new Vector3[num2]; Vector2[] array3 = (Vector2[])(object)new Vector2[num2]; for (int i = 0; i < num2; i++) { array[i] = new Vector3(BitConverter.ToSingle(data, num), BitConverter.ToSingle(data, num + 4), BitConverter.ToSingle(data, num + 8)); array2[i] = new Vector3(BitConverter.ToSingle(data, num + 12), BitConverter.ToSingle(data, num + 16), BitConverter.ToSingle(data, num + 20)); float num4 = BitConverter.ToSingle(data, num + 28); array3[i] = new Vector2(BitConverter.ToSingle(data, num + 24), flag ? (1f - num4) : num4); num += 32; } int[] array4 = new int[num3]; for (int j = 0; j < num3; j++) { array4[j] = BitConverter.ToInt32(data, num); num += 4; } Mesh val = new Mesh { name = name, indexFormat = (IndexFormat)(num2 > 65000) }; val.SetVertices(array); val.SetNormals(array2); val.SetUVs(0, array3); val.SetTriangles(array4, 0); val.RecalculateBounds(); return val; } private static Texture2D? DecodePng(byte[] bytes, string name, bool linear = false) { //IL_0013: 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_0019: Expected O, but got Unknown Texture2D val = (linear ? new Texture2D(2, 2, (TextureFormat)4, true, true) : new Texture2D(2, 2, (TextureFormat)4, true)); MethodInfo methodInfo = LoadImage(); if (methodInfo == null || !(bool)methodInfo.Invoke(null, new object[2] { val, bytes })) { Object.Destroy((Object)(object)val); Plugin.Log.LogWarning((object)("drawer png decode failed " + name)); return null; } ((Object)val).name = name; ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).anisoLevel = 4; val.Apply(true, false); return val; } private static MethodInfo? LoadImage() { if (_searched) { return _loadImage; } _searched = true; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { Type type = assemblies[i].GetType("UnityEngine.ImageConversion"); if (!(type == null)) { _loadImage = type.GetMethod("LoadImage", new Type[2] { typeof(Texture2D), typeof(byte[]) }); if (_loadImage != null) { return _loadImage; } } } return null; } } [HarmonyPatch] internal static class DrawerPatches { [HarmonyPostfix] [HarmonyPatch(typeof(Container), "Load")] private static void AfterLoad(Container __instance) { Face(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(Container), "Save")] private static void AfterSave(Container __instance) { Face(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(Container), "OnContainerChanged")] private static void AfterChanged(Container __instance) { Face(__instance); } private static void Face(Container container) { if (!((Object)(object)container == (Object)null)) { DrawerFace component = ((Component)container).GetComponent<DrawerFace>(); if ((Object)(object)component != (Object)null) { component.Refresh(); } } } } internal static class DrawerPieces { private static bool _added; public static void Load() { PrefabManager.OnVanillaPrefabsAvailable += Add; } private static void Add() { //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Expected O, but got Unknown //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Expected O, but got Unknown PrefabManager.OnVanillaPrefabsAvailable -= Add; if (_added) { return; } _added = true; int num = 0; DrawerRow[] rows = DrawerBook.Rows; foreach (DrawerRow drawerRow in rows) { if ((Object)(object)PrefabManager.Instance.GetPrefab(drawerRow.Source) == (Object)null) { Plugin.Log.LogInfo((object)("RestlessDrawers skipped " + drawerRow.Source + " (no vanilla prefab).")); continue; } GameObject val = PrefabManager.Instance.CreateClonedPrefab(drawerRow.Prefab, drawerRow.Source); if ((Object)(object)val == (Object)null) { continue; } DrawerVisual.Apply(val, drawerRow); Piece val2 = val.GetComponent<Piece>() ?? val.AddComponent<Piece>(); Sprite icon = (val2.m_icon = DrawerMesh.Icon(drawerRow.Id) ?? val2.m_icon); val2.m_name = drawerRow.Name; val2.m_description = drawerRow.Description; val2.m_groundOnly = false; val2.m_groundPiece = false; val2.m_clipGround = false; SitAsFurniture(val); PieceConfig val3 = new PieceConfig { Name = drawerRow.Name, Description = drawerRow.Description, PieceTable = PieceTables.Hammer, Icon = icon }; if ((Object)(object)val2.m_craftingStation != (Object)null) { val3.CraftingStation = ((Object)val2.m_craftingStation).name; } if (val2.m_resources != null) { Requirement[] resources = val2.m_resources; foreach (Requirement val4 in resources) { if (!((Object)(object)val4?.m_resItem == (Object)null) && val4.m_amount > 0) { val3.AddRequirement(((Object)val4.m_resItem).name, val4.m_amount, val4.m_recover); } } } PieceManager.Instance.AddPiece(new CustomPiece(val, true, val3)); num++; } Plugin.Log.LogInfo((object)("RestlessDrawers added " + num + " drawers.")); } private static void SitAsFurniture(GameObject prefab) { WearNTear component = prefab.GetComponent<WearNTear>(); if (!((Object)(object)component == (Object)null)) { component.m_noSupportWear = false; component.m_supports = true; AccessTools.Method(typeof(WearNTear), "SetupColliders", (Type[])null, (Type[])null)?.Invoke(component, null); } } } internal static class DrawerVisual { public const string ChildName = "RestlessDrawerMesh"; public static void Apply(GameObject prefab, DrawerRow row) { //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_019d: 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) Mesh val = DrawerMesh.Mesh(row.Id); Texture2D albedo = DrawerMesh.Albedo(row.Id); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("RestlessDrawers: no custom model for " + row.Id)); return; } Material mat = CopyLit(prefab, row.Source); LODGroup[] componentsInChildren = prefab.GetComponentsInChildren<LODGroup>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } GameObject val2 = FindOrCreate(prefab, val); (val2.GetComponent<MeshFilter>() ?? val2.AddComponent<MeshFilter>()).sharedMesh = val; MeshRenderer val3 = val2.GetComponent<MeshRenderer>() ?? val2.AddComponent<MeshRenderer>(); ((Renderer)val3).enabled = true; Paint((Renderer)(object)val3, albedo, DrawerMesh.Surface(row.Id), mat); Renderer[] componentsInChildren2 = prefab.GetComponentsInChildren<Renderer>(true); foreach (Renderer val4 in componentsInChildren2) { if (!((Object)(object)val4 == (Object)null) && !((Object)(object)val4 == (Object)(object)val3) && ((val4 is MeshRenderer || val4 is SkinnedMeshRenderer) ? true : false)) { val4.enabled = false; } } Collider[] componentsInChildren3 = prefab.GetComponentsInChildren<Collider>(true); foreach (Collider val5 in componentsInChildren3) { if (!((Object)(object)val5 == (Object)null) && !((Object)(object)((Component)val5).transform == (Object)(object)val2.transform)) { Object.DestroyImmediate((Object)(object)val5); } } BoxCollider obj = val2.GetComponent<BoxCollider>() ?? val2.AddComponent<BoxCollider>(); Bounds bounds = val.bounds; obj.center = ((Bounds)(ref bounds)).center; obj.size = Vector3.Max(((Bounds)(ref bounds)).size, new Vector3(0.2f, 0.2f, 0.2f)); ((Collider)obj).enabled = true; if ((Object)(object)prefab.GetComponent<DrawerFace>() == (Object)null) { prefab.AddComponent<DrawerFace>(); } DrawerGrid.Dress(prefab); } private static GameObject FindOrCreate(GameObject prefab, Mesh mesh) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_00a7: 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_00b7: 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_00c7: 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_00d8: Expected O, but got Unknown //IL_002f: 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_0045: 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) Transform val = prefab.transform.Find("RestlessDrawerMesh"); float num = DrawerGrid.Fit(mesh); if ((Object)(object)val != (Object)null) { val.SetParent(prefab.transform, false); val.localPosition = Vector3.zero; val.localRotation = Quaternion.identity; val.localScale = Vector3.one * num; ((Component)val).gameObject.layer = prefab.layer; ((Component)val).gameObject.SetActive(true); return ((Component)val).gameObject; } GameObject val2 = new GameObject("RestlessDrawerMesh") { layer = prefab.layer }; val2.transform.SetParent(prefab.transform, false); val2.transform.localPosition = Vector3.zero; val2.transform.localRotation = Quaternion.identity; val2.transform.localScale = Vector3.one * num; return val2; } private static void Paint(Renderer renderer, Texture2D? albedo, Texture2D? surface, Material? mat) { //IL_000b: 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_002b: 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) if ((Object)(object)mat == (Object)null) { return; } mat.color = Color.white; SetColor(mat, "_Color", Color.white); SetColor(mat, "_BaseColor", Color.white); SetColor(mat, "_Tint", Color.white); MuteGlow(mat); if ((Object)(object)albedo != (Object)null) { if (mat.HasProperty("_MainTex")) { mat.SetTexture("_MainTex", (Texture)(object)albedo); } if (mat.HasProperty("_BaseMap")) { mat.SetTexture("_BaseMap", (Texture)(object)albedo); } if (mat.HasProperty("_Diffuse")) { mat.SetTexture("_Diffuse", (Texture)(object)albedo); } } if ((Object)(object)surface != (Object)null) { if (mat.HasProperty("_MetallicTex")) { mat.SetTexture("_MetallicTex", (Texture)(object)surface); } if (mat.HasProperty("_MetallicGlossMap")) { mat.SetTexture("_MetallicGlossMap", (Texture)(object)surface); } SetFloat(mat, "_Metallic", 1f); SetFloat(mat, "_MetallicAlphaGloss", 1f); SetFloat(mat, "_Glossiness", 1f); SetFloat(mat, "_Smoothness", 1f); mat.EnableKeyword("_METALLICGLOSSMAP"); } else { SetFloat(mat, "_Metallic", 0f); SetFloat(mat, "_Glossiness", 0.12f); SetFloat(mat, "_Smoothness", 0.12f); } renderer.sharedMaterial = mat; } private static Material? CopyLit(GameObject prefab, string source) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown Material val = QuietMat(prefab) ?? QuietNamed(source) ?? QuietNamed("piece_chest_wood") ?? QuietNamed("piece_chest"); if ((Object)(object)val != (Object)null) { return new Material(val); } string[] array = new string[2] { "Legacy Shaders/Diffuse", "Diffuse" }; for (int i = 0; i < array.Length; i++) { Shader val2 = Shader.Find(array[i]); if ((Object)(object)val2 != (Object)null) { return new Material(val2); } } Plugin.Log.LogWarning((object)"drawer shader missing — leave vanilla look"); return null; } private static Material? QuietNamed(string name) { PrefabManager instance = PrefabManager.Instance; GameObject val = ((instance != null) ? instance.GetPrefab(name) : null); if (!((Object)(object)val != (Object)null)) { return null; } return QuietMat(val); } private static Material? QuietMat(GameObject? prefab) { //IL_009c: 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_00a5: 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_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)prefab == (Object)null) { return null; } Renderer val = null; float num = -1f; Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null || ((Object)((Component)val2).transform).name == "RestlessDrawerMesh" || (!(val2 is MeshRenderer) && !(val2 is SkinnedMeshRenderer)) || SkipNode(((Component)val2).transform)) { continue; } Material sharedMaterial = val2.sharedMaterial; if (!((Object)(object)((sharedMaterial != null) ? sharedMaterial.shader : null) == (Object)null) && Usable(sharedMaterial)) { Bounds bounds = val2.bounds; float x = ((Bounds)(ref bounds)).size.x; bounds = val2.bounds; float num2 = x * ((Bounds)(ref bounds)).size.y; bounds = val2.bounds; float num3 = num2 * ((Bounds)(ref bounds)).size.z; if (!(num3 <= num)) { num = num3; val = val2; } } } if ((Object)(object)((val != null) ? val.sharedMaterial : null) == (Object)null) { return null; } Plugin.Log.LogInfo((object)("drawer lit " + ((Object)val).name + " / " + ((Object)val.sharedMaterial).name + " / " + ((Object)val.sharedMaterial.shader).name)); return val.sharedMaterial; } private static bool SkipNode(Transform node) { Transform val = node; while ((Object)(object)val != (Object)null) { string name = ((Object)val).name; if (Has(name, "fx") || Has(name, "spark") || Has(name, "glow") || Has(name, "ghost") || Has(name, "particle") || Has(name, "wisp") || Has(name, "snow") || Has(name, "ice") || Has(name, "winter") || Has(name, "stack") || Has(name, "pile") || Has(name, "cover") || Has(name, "overlay")) { return true; } val = val.parent; } return false; } private static bool Usable(Material mat) { //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) string text = ((Object)mat).name + " " + ((Object)mat.shader).name; if (Has(text, "Hidden/") || Has(text, "Particle") || Has(text, "glow") || Has(text, "ghost") || Has(text, "snow") || Has(text, "stack") || Has(text, "pile") || Has(text, "wind") || Has(text, "vegetation") || Has(text, "tree")) { return false; } if (((Object)mat.shader).name == "Standard") { return false; } if (mat.IsKeywordEnabled("_EMISSION") || mat.IsKeywordEnabled("EMISSION")) { return false; } if (mat.HasProperty("_EmissionColor")) { Color color = mat.GetColor("_EmissionColor"); if (((Color)(ref color)).maxColorComponent > 0.02f) { return false; } } return true; } private static void MuteGlow(Material mat) { //IL_0006: 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) SetColor(mat, "_EmissionColor", Color.black); SetColor(mat, "_EmissiveColor", Color.black); SetFloat(mat, "_EnableEmission", 0f); mat.DisableKeyword("_EMISSION"); mat.DisableKeyword("EMISSION"); } private static bool Has(string text, string token) { return text.IndexOf(token, StringComparison.OrdinalIgnoreCase) >= 0; } private static void SetColor(Material mat, string prop, Color color) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (mat.HasProperty(prop)) { mat.SetColor(prop, color); } } private static void SetFloat(Material mat, string prop, float value) { if (mat.HasProperty(prop)) { mat.SetFloat(prop, value); } } } [BepInPlugin("restless.drawers", "RestlessDrawers", "0.1.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "restless.drawers"; public const string PluginName = "RestlessDrawers"; public const string PluginVersion = "0.1.1"; private Harmony? _harmony; internal static Plugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; DrawerPieces.Load(); _harmony = new Harmony("restless.drawers"); _harmony.PatchAll(); Log.LogInfo((object)"RestlessDrawers 0.1.1 loaded."); } private void OnDestroy() { Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } }