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 Cosmetics and Scrap Menu v1.1.0
BepInEx/plugins/BonemansCosmeticsScrapMenu/BonemansCosmeticsScrapMenu.dll
Decompiled 5 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using MoreCompany; using MoreCompany.Behaviors; using MoreCompany.Cosmetics; using TMPro; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; 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("BonemansCosmeticsScrapMenu")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+7b5bfe0675f453a1c5f1ce8ba84f2e8eb12976e4")] [assembly: AssemblyProduct("BonemansCosmeticsScrapMenu")] [assembly: AssemblyTitle("BonemansCosmeticsScrapMenu")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace CosmeticsMenuPlus { internal enum Slot { Wearing, Head, Chest, Hip, RightArm, LeftLeg, RightLeg, All, Suits, Favorites, Outfits, Hidden } internal class CosmeticEntry { public string Id; public string Name; public string Pack; public Slot Slot; public CosmeticInstance Instance; private bool? tintable; public bool Tintable { get { bool valueOrDefault = tintable == true; if (!tintable.HasValue) { valueOrDefault = (Object)(object)Instance != (Object)null && Recolor.CanTint(((Component)Instance).gameObject); tintable = valueOrDefault; return valueOrDefault; } return valueOrDefault; } } } internal static class CosmeticCatalog { public static readonly List<CosmeticEntry> Entries = new List<CosmeticEntry>(); public static readonly Dictionary<string, CosmeticEntry> ById = new Dictionary<string, CosmeticEntry>(); public static readonly List<string> Packs = new List<string>(); private static int builtFor = -1; public static void Refresh() { //IL_00b8: Unknown result type (might be due to invalid IL or missing references) if (builtFor == CosmeticRegistry.cosmeticInstances.Count) { return; } builtFor = CosmeticRegistry.cosmeticInstances.Count; Dictionary<string, string> dictionary = ReadPacksFromLog(); Entries.Clear(); ById.Clear(); foreach (KeyValuePair<string, CosmeticInstance> cosmeticInstance in CosmeticRegistry.cosmeticInstances) { if (!((Object)(object)cosmeticInstance.Value == (Object)null)) { string value; CosmeticEntry cosmeticEntry = new CosmeticEntry { Id = cosmeticInstance.Key, Name = PrettyName(cosmeticInstance.Key), Pack = (dictionary.TryGetValue(cosmeticInstance.Key, out value) ? value : PackFromId(cosmeticInstance.Key)), Slot = SlotOf(cosmeticInstance.Value.cosmeticType), Instance = cosmeticInstance.Value }; Entries.Add(cosmeticEntry); ById[cosmeticEntry.Id] = cosmeticEntry; } } Entries.Sort((CosmeticEntry a, CosmeticEntry b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase)); Packs.Clear(); Packs.AddRange(from p in Entries.Select((CosmeticEntry e) => e.Pack).Distinct() orderby p select p); } public static Slot SlotOf(CosmeticType type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected I4, but got Unknown return (int)type switch { 0 => Slot.Head, 2 => Slot.Chest, 4 => Slot.Hip, 3 => Slot.RightArm, 5 => Slot.LeftLeg, 6 => Slot.RightLeg, _ => Slot.All, }; } public static string SlotLabel(Slot slot) { return slot switch { Slot.Wearing => "Wearing", Slot.RightArm => "Right arm", Slot.LeftLeg => "Left leg", Slot.RightLeg => "Right leg", Slot.All => "All", _ => slot.ToString(), }; } private static Dictionary<string, string> ReadPacksFromLog() { Dictionary<string, string> dictionary = new Dictionary<string, string>(); string path = Path.Combine(Paths.BepInExRootPath, "LogOutput.log"); try { using FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); using StreamReader streamReader = new StreamReader(stream); string text; while ((text = streamReader.ReadLine()) != null) { int num = text.IndexOf("Loaded cosmetic: "); if (num < 0) { continue; } int num2 = text.IndexOf(" from bundle: ", num); if (num2 >= 0) { string key = text.Substring(num + "Loaded cosmetic: ".Length, num2 - num - "Loaded cosmetic: ".Length).Trim(); string text2 = PackFromPath(text.Substring(num2 + " from bundle: ".Length).Trim()); if (text2 != null) { dictionary[key] = text2; } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Couldn't read pack names from the log, grouping by id prefix instead: " + ex.Message)); } return dictionary; } private static string PackFromPath(string bundle) { if (bundle == "morecompany.cosmetics") { return "MoreCompany"; } string[] array = bundle.Replace('/', '\\').Split('\\'); int num = Array.FindLastIndex(array, (string p) => p.Equals("plugins", StringComparison.OrdinalIgnoreCase)); if (num < 0 || num + 1 >= array.Length) { return null; } string text = array[num + 1]; if (text.EndsWith(".cosmetics") || text.Equals("MoreCompanyCosmetics", StringComparison.OrdinalIgnoreCase)) { return "Loose files"; } int num2 = text.IndexOf('-'); if (num2 >= 0 && num2 < text.Length - 1) { text = text.Substring(num2 + 1); } return SplitWords(text.Replace('_', ' ')); } private static string PackFromId(string id) { int num = id.IndexOf('.'); string text = ((num > 0) ? id.Substring(0, num) : "Other"); if (text.Equals("builtin", StringComparison.OrdinalIgnoreCase)) { return "MoreCompany"; } return Capitalize(text); } public static string PrettyName(string id) { string[] array = id.Split('.'); IEnumerable<string> enumerable2; if (array.Length <= 1) { IEnumerable<string> enumerable = array; enumerable2 = enumerable; } else { enumerable2 = array.Skip(1); } IEnumerable<string> values = enumerable2; return Capitalize(SplitWords(string.Join(" ", values).Replace('_', ' ').Replace('-', ' ')).Trim()); } private static string SplitWords(string s) { StringBuilder stringBuilder = new StringBuilder(s.Length + 8); for (int i = 0; i < s.Length; i++) { char c = s[i]; if (i > 0 && char.IsUpper(c) && char.IsLower(s[i - 1])) { stringBuilder.Append(' '); } stringBuilder.Append(c); } return Regex.Replace(stringBuilder.ToString(), " +", " "); } private static string Capitalize(string s) { if (!string.IsNullOrEmpty(s)) { return char.ToUpperInvariant(s[0]) + s.Substring(1); } return s; } } [HarmonyPatch] internal static class DisplayScale { private static Transform model; private static float originalScale; private static float Ratio { get { //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)model != (Object)null) || !(originalScale > 0f)) { return 1f; } return model.lossyScale.x / originalScale; } } public static void Capture(Transform scavengerModel) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) model = scavengerModel; originalScale = (((Object)(object)scavengerModel != (Object)null) ? scavengerModel.lossyScale.x : 0f); } [HarmonyPatch(typeof(CosmeticRegistry), "SpawnCosmeticGUI")] [HarmonyPrefix] private static void BeforeSpawnGui() { model = null; originalScale = 0f; } [HarmonyPatch(typeof(CosmeticRegistry), "UpdateCosmeticsOnDisplayGuy")] [HarmonyPostfix] private static void AfterDisplayUpdate() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) float ratio = Ratio; if (Mathf.Abs(ratio - 1f) < 0.001f || (Object)(object)model == (Object)null) { return; } Transform obj = model.Find("metarig"); CosmeticApplication val = ((obj != null) ? ((Component)obj).GetComponent<CosmeticApplication>() : null); if ((Object)(object)val == (Object)null) { return; } foreach (CosmeticInstance spawnedCosmetic in val.spawnedCosmetics) { if ((Object)(object)spawnedCosmetic != (Object)null) { Transform transform = ((Component)spawnedCosmetic).transform; transform.localScale *= ratio; } } } } [BepInPlugin("kylew.cosmeticsmenuplus", "Boneman's Cosmetics & Scrap Menu", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string GUID = "kylew.cosmeticsmenuplus"; internal static ManualLogSource Log; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<bool> ListMode; internal static ConfigEntry<string> LastSlot; internal static ConfigEntry<string> ActiveOutfit; private void Awake() { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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_00bd: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Replace MoreCompany's cosmetics grid with the slot menu. Turn off to get the original menu back."); ListMode = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "List Mode", false, "Show cosmetics as a list instead of an icon grid."); LastSlot = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Last Slot", "Wearing", "Slot tab shown when the menu opens."); ActiveOutfit = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Active Outfit", "", "Outfit that changes are saved into as you make them. Set by wearing or saving an outfit."); Harmony val = new Harmony("kylew.cosmeticsmenuplus"); val.PatchAll(typeof(Patches)); val.PatchAll(typeof(TintSync)); val.PatchAll(typeof(DisplayScale)); val.PatchAll(typeof(ScrapSpawnFilter)); Log.LogInfo((object)"Boneman's Cosmetics & Scrap Menu loaded"); } } internal static class Patches { private static bool bypass; [HarmonyPatch(typeof(CosmeticRegistry), "PopulateCosmetics")] [HarmonyPrefix] private static bool PopulatePrefix() { if (Plugin.Enabled.Value) { return bypass; } return true; } [HarmonyPatch(typeof(CosmeticRegistry), "SpawnCosmeticGUI")] [HarmonyPostfix] private static void SpawnPostfix(bool mainMenu) { if (!Plugin.Enabled.Value || (Object)(object)CosmeticRegistry.cosmeticGUIGlobalScale == (Object)null) { return; } try { SlotMenu.Build(CosmeticRegistry.cosmeticGUIGlobalScale, !mainMenu); } catch (Exception ex) { Plugin.Log.LogError((object)("Failed to build cosmetics menu, falling back to MoreCompany's: " + ex)); SlotMenu.RestoreOriginal(CosmeticRegistry.cosmeticGUIGlobalScale); bypass = true; try { CosmeticRegistry.PopulateCosmetics(); } finally { bypass = false; } } } [HarmonyPatch(typeof(QuickMenuManager), "OpenQuickMenu")] [HarmonyPatch(typeof(QuickMenuManager), "CloseQuickMenu")] [HarmonyPostfix] private static void QuickMenuToggled(QuickMenuManager __instance) { if (CosmeticRegistry.menuIsInGame) { SlotMenu.SyncScrapButton(__instance.isMenuOpen); } } } internal class PreviewControls : MonoBehaviour { public Transform spinTarget; public Transform holder; public RectTransform space; public RectTransform area; private Vector3 basePos; private Vector3 baseScale; private Quaternion baseRotation; private float zoom = 1f; private bool spinning; private bool panning; private float spinVelocity; private Vector2 lastMouse; private Camera cam; private const float SpinPerPixel = 0.45f; private const float DriftDamping = 2.2f; private const float MinZoom = 0.8f; private const float MaxZoom = 3f; public void Init() { //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_0029: 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_0050: Unknown result type (might be due to invalid IL or missing references) basePos = holder.localPosition; baseScale = holder.localScale; baseRotation = spinTarget.localRotation; Canvas componentInParent = ((Component)area).GetComponentInParent<Canvas>(true); cam = (((Object)(object)componentInParent != (Object)null && (int)componentInParent.rootCanvas.renderMode != 0) ? componentInParent.rootCanvas.worldCamera : null); } public void ResetView() { //IL_001d: 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_003f: Unknown result type (might be due to invalid IL or missing references) zoom = 1f; spinVelocity = 0f; holder.localPosition = basePos; holder.localScale = baseScale; spinTarget.localRotation = baseRotation; } private void Zoom(float scroll, Vector2 screenPos) { //IL_0040: 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_0047: 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_00b3: 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_00c5: 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_0057: 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_0068: 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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_007d: 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_0088: 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.Clamp(zoom * ((scroll > 0f) ? 1.12f : (25f / 28f)), 0.8f, 3f); if (!Mathf.Approximately(num, zoom)) { Vector3 localPosition = holder.localPosition; if (ToLocal(screenPos, out var local)) { Vector2 val = new Vector2(localPosition.x, localPosition.y) - local; Vector2 val2 = local + val * (num / zoom); ((Vector3)(ref localPosition))..ctor(val2.x, val2.y, localPosition.z); } zoom = num; holder.localScale = baseScale * zoom; holder.localPosition = ClampPan(localPosition); } } private void Update() { //IL_0010: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_021f: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: 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_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_0122: 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_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) Mouse current = Mouse.current; if (current == null) { return; } Vector2 val = ((InputControl<Vector2>)(object)((Pointer)current).position).ReadValue(); float num = Mathf.Max(Time.unscaledDeltaTime, 0.0001f); bool num2 = RectTransformUtility.RectangleContainsScreenPoint(area, val, cam); if (num2 && (current.leftButton.wasPressedThisFrame || current.rightButton.wasPressedThisFrame)) { spinning = true; spinVelocity = 0f; } if (num2 && current.middleButton.wasPressedThisFrame) { panning = true; spinning = false; spinVelocity = 0f; } float y = ((InputControl<Vector2>)(object)current.scroll).ReadValue().y; if (num2 && !Mathf.Approximately(y, 0f)) { Zoom(y, val); } if (panning) { Vector2 local; Vector2 local2; if (!current.middleButton.isPressed) { panning = false; } else if (ToLocal(val, out local) && ToLocal(lastMouse, out local2)) { Vector3 localPosition = holder.localPosition; holder.localPosition = ClampPan(localPosition + new Vector3(local.x - local2.x, local.y - local2.y, 0f)); } } else if (spinning) { if (!current.leftButton.isPressed && !current.rightButton.isPressed) { spinning = false; } else { float num3 = (0f - (val.x - lastMouse.x)) * 0.45f; spinTarget.Rotate(0f, num3, 0f, (Space)0); spinVelocity = Mathf.Lerp(spinVelocity, num3 / num, 0.35f); } } if (!spinning && !panning && Mathf.Abs(spinVelocity) > 0.5f) { spinTarget.Rotate(0f, spinVelocity * num, 0f, (Space)0); spinVelocity *= Mathf.Exp(-2.2f * num); } lastMouse = val; } private bool ToLocal(Vector2 screen, out Vector2 local) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return RectTransformUtility.ScreenPointToLocalPointInRectangle(space, screen, cam, ref local); } private Vector3 ClampPan(Vector3 p) { //IL_0033: 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_007d: 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) float num = Mathf.Max(zoom - 1f, 0f); float num2 = 40f + 90f * num; float num3 = 40f + 230f * num; return new Vector3(Mathf.Clamp(p.x, basePos.x - num2, basePos.x + num2), Mathf.Clamp(p.y, basePos.y - num3, basePos.y + num3), p.z); } } internal static class Recolor { private class Originals : MonoBehaviour { public readonly Dictionary<Renderer, Material[]> byRenderer = new Dictionary<Renderer, Material[]>(); } private static readonly string[] ColorProps = new string[3] { "_BaseColor", "_UnlitColor", "_Color" }; private static readonly string[] TextureProps = new string[3] { "_BaseColorMap", "_UnlitColorMap", "_MainTex" }; private const int MaxTextureSize = 1024; private const int PreviewTextureSize = 256; public static bool Preview; private static readonly Dictionary<(int, string), Material> materials = new Dictionary<(int, string), Material>(); private static readonly Dictionary<(int, string), Texture2D> textures = new Dictionary<(int, string), Texture2D>(); public static string PreviewKey(Tint tint) { return tint.Key + "@preview"; } private static string CacheKey(Tint tint) { if (!Preview) { return tint.Key; } return PreviewKey(tint); } public static void Prune(HashSet<string> keysInUse) { foreach (var item in new List<(int, string)>(materials.Keys)) { if (!keysInUse.Contains(item.Item2)) { if ((Object)(object)materials[item] != (Object)null) { Object.Destroy((Object)(object)materials[item]); } materials.Remove(item); } } foreach (var item2 in new List<(int, string)>(textures.Keys)) { if (!keysInUse.Contains(item2.Item2)) { if ((Object)(object)textures[item2] != (Object)null) { Object.Destroy((Object)(object)textures[item2]); } textures.Remove(item2); } } } public static bool CanTint(GameObject go) { foreach (Renderer item in Renderers(go)) { Material[] sharedMaterials = item.sharedMaterials; for (int i = 0; i < sharedMaterials.Length; i++) { if (Tintable(sharedMaterials[i])) { return true; } } } return false; } public static void Apply(GameObject go, Tint tint) { if ((Object)(object)go == (Object)null) { return; } Originals originals = go.GetComponent<Originals>(); if ((Object)(object)originals == (Object)null) { if (tint.IsNone) { return; } originals = go.AddComponent<Originals>(); } foreach (Renderer item in Renderers(go)) { Material[] sharedMaterials = item.sharedMaterials; if (!originals.byRenderer.TryGetValue(item, out var value) || value.Length != sharedMaterials.Length) { value = sharedMaterials; originals.byRenderer[item] = value; } else { for (int i = 0; i < sharedMaterials.Length; i++) { if ((Object)(object)sharedMaterials[i] != (Object)null && (Object)(object)sharedMaterials[i] != (Object)(object)value[i] && !((Object)sharedMaterials[i]).name.Contains("(tint ")) { value[i] = sharedMaterials[i]; } } } Material[] array = (Material[])(object)new Material[value.Length]; for (int j = 0; j < value.Length; j++) { array[j] = ((tint.IsNone || !Tintable(value[j])) ? value[j] : Tinted(value[j], tint)); } item.sharedMaterials = array; } } private static IEnumerable<Renderer> Renderers(GameObject go) { Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (val is MeshRenderer || val is SkinnedMeshRenderer) { yield return val; } } } private static bool Tintable(Material m) { if ((Object)(object)m == (Object)null) { return false; } string[] colorProps = ColorProps; foreach (string text in colorProps) { if (m.HasProperty(text)) { return true; } } colorProps = TextureProps; foreach (string text2 in colorProps) { if (m.HasProperty(text2)) { return true; } } return false; } private static Material Tinted(Material source, Tint tint) { //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_0056: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_0087: 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) (int, string) key = (((Object)source).GetInstanceID(), CacheKey(tint)); if (materials.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } Material val = new Material(source) { name = ((Object)source).name + " (tint " + tint.Key + ")" }; string[] colorProps = ColorProps; foreach (string text in colorProps) { if (val.HasProperty(text)) { Color color = source.GetColor(text); val.SetColor(text, (tint.Mode == TintMode.Tint) ? MultiplyRgb(color, tint.TintColor) : Shift(color, tint)); } } if (tint.Mode == TintMode.HueShift) { colorProps = TextureProps; foreach (string text2 in colorProps) { if (val.HasProperty(text2)) { Texture texture = source.GetTexture(text2); if ((Object)(object)texture != (Object)null) { val.SetTexture(text2, ShiftedTexture(texture, tint)); } } } } materials[key] = val; return val; } private static Color MultiplyRgb(Color a, Color b) { //IL_0000: 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_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_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_0027: 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) return new Color(a.r * b.r, a.g * b.g, a.b * b.b, a.a); } private static Color Shift(Color c, Tint t) { //IL_0000: 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_0043: 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_0051: Unknown result type (might be due to invalid IL or missing references) float num = default(float); float num2 = default(float); float num3 = default(float); Color.RGBToHSV(c, ref num, ref num2, ref num3); Color result = Color.HSVToRGB(Mathf.Repeat(num + t.Hue / 360f, 1f), Mathf.Clamp01(num2 * t.Saturation), Mathf.Clamp01(num3 * t.Brightness)); result.a = c.a; return result; } private static Texture ShiftedTexture(Texture source, Tint tint) { //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_00cb: 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_0128: 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_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) (int, string) key = (((Object)source).GetInstanceID(), CacheKey(tint)); if (textures.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return (Texture)(object)value; } float num = Mathf.Min(1f, (float)(Preview ? 256 : 1024) / (float)Mathf.Max(source.width, source.height)); int num2 = Mathf.Max(1, Mathf.RoundToInt((float)source.width * num)); int num3 = Mathf.Max(1, Mathf.RoundToInt((float)source.height * num)); RenderTexture temporary = RenderTexture.GetTemporary(num2, num3, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2); RenderTexture active = RenderTexture.active; Texture2D val; try { Graphics.Blit(source, temporary); RenderTexture.active = temporary; val = new Texture2D(num2, num3, (TextureFormat)4, true, false); val.ReadPixels(new Rect(0f, 0f, (float)num2, (float)num3), 0, 0, false); } finally { RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); } Color32[] pixels = val.GetPixels32(); float dh = tint.Hue / 360f; float saturation = tint.Saturation; float brightness = tint.Brightness; for (int i = 0; i < pixels.Length; i++) { pixels[i] = ShiftPixel(pixels[i], dh, saturation, brightness); } val.SetPixels32(pixels); ((Texture)val).wrapMode = source.wrapMode; ((Texture)val).filterMode = source.filterMode; ((Texture)val).anisoLevel = source.anisoLevel; ((Object)val).name = ((Object)source).name + " (tint " + tint.Key + ")"; val.Apply(true, true); textures[key] = val; return (Texture)(object)val; } private static Color32 ShiftPixel(Color32 c, float dh, float ds, float dv) { //IL_0000: 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_001c: 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_01de: Unknown result type (might be due to invalid IL or missing references) float num = (float)(int)c.r / 255f; float num2 = (float)(int)c.g / 255f; float num3 = (float)(int)c.b / 255f; float num4 = Mathf.Max(num, Mathf.Max(num2, num3)); float num5 = Mathf.Min(num, Mathf.Min(num2, num3)); float num6 = num4 - num5; float num7 = 0f; if (num6 > 1E-05f) { num7 = ((num4 == num) ? ((num2 - num3) / num6 / 6f) : ((num4 != num2) ? (((num - num2) / num6 + 4f) / 6f) : (((num3 - num) / num6 + 2f) / 6f))); if (num7 < 0f) { num7 += 1f; } } float num8 = ((num4 > 1E-05f) ? (num6 / num4) : 0f); float num9 = num4; num7 += dh; num7 -= Mathf.Floor(num7); num8 = Mathf.Clamp01(num8 * ds); num9 = Mathf.Clamp01(num9 * dv); float num10 = num7 * 6f; int num11 = (int)num10 % 6; float num12 = num10 - Mathf.Floor(num10); float num13 = num9 * (1f - num8); float num14 = num9 * (1f - num8 * num12); float num15 = num9 * (1f - num8 * (1f - num12)); float num16; float num17; float num18; switch (num11) { case 0: num16 = num9; num17 = num15; num18 = num13; break; case 1: num16 = num14; num17 = num9; num18 = num13; break; case 2: num16 = num13; num17 = num9; num18 = num15; break; case 3: num16 = num13; num17 = num14; num18 = num9; break; case 4: num16 = num15; num17 = num13; num18 = num9; break; default: num16 = num9; num17 = num13; num18 = num14; break; } return new Color32((byte)(num16 * 255f + 0.5f), (byte)(num17 * 255f + 0.5f), (byte)(num18 * 255f + 0.5f), c.a); } } internal static class ScrapButtonIcon { private const int S = 128; private static Sprite cached; private static readonly Color Frame = new Color(0.16f, 0.78f, 0.32f, 1f); private static readonly Color Back = new Color(0.02f, 0.11f, 0.04f, 0.92f); private static readonly Color Top = new Color(0.2f, 0.86f, 0.38f, 1f); private static readonly Color Left = new Color(0.12f, 0.6f, 0.25f, 1f); private static readonly Color Right = new Color(0.08f, 0.44f, 0.18f, 1f); private static readonly Color Line = new Color(0.02f, 0.11f, 0.04f, 1f); public static Sprite Get() { //IL_00ed: 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) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_012f: 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_014c: 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_0162: 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_0178: 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_018e: 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_01ab: 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) //IL_01c1: 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) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0241: 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_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_00b0: 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_0070: 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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Expected O, but got Unknown if ((Object)(object)cached != (Object)null) { return cached; } Color[] array = (Color[])(object)new Color[16384]; for (int i = 0; i < 128; i++) { for (int j = 0; j < 128; j++) { float num = RoundedBoxDistance((float)j + 0.5f, (float)i + 0.5f, 4f, 4f, 124f, 124f, 14f); Color val = Color.clear; if (num < 0.5f) { val = Blend(Back, Frame, Mathf.Clamp01(num + 9.5f)); } val.a *= Mathf.Clamp01(0.5f - num); array[Index(j, i)] = val; } } Vector2[] poly = (Vector2[])(object)new Vector2[4] { new Vector2(64f, 26f), new Vector2(100f, 44f), new Vector2(64f, 62f), new Vector2(28f, 44f) }; Vector2[] poly2 = (Vector2[])(object)new Vector2[4] { new Vector2(28f, 44f), new Vector2(64f, 62f), new Vector2(64f, 102f), new Vector2(28f, 84f) }; Vector2[] poly3 = (Vector2[])(object)new Vector2[4] { new Vector2(64f, 62f), new Vector2(100f, 44f), new Vector2(100f, 84f), new Vector2(64f, 102f) }; Fill(array, poly, Top); Fill(array, poly2, Left); Fill(array, poly3, Right); List<(Vector2, Vector2)> list = new List<(Vector2, Vector2)>(); AddLoop(list, poly); AddLoop(list, poly2); AddLoop(list, poly3); list.Add((new Vector2(28f, 64f), new Vector2(64f, 82f))); list.Add((new Vector2(64f, 82f), new Vector2(100f, 64f))); foreach (var (a, b) in list) { Stroke(array, a, b, 5f, Line); } Texture2D val2 = new Texture2D(128, 128, (TextureFormat)4, false) { name = "Scrap button", filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; val2.SetPixels(array); val2.Apply(); cached = Sprite.Create(val2, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 100f); ((Object)cached).name = "Scrap button"; return cached; } private static int Index(int x, int topDownY) { return (127 - topDownY) * 128 + x; } private static Color Blend(Color a, Color b, float t) { //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_0003: Unknown result type (might be due to invalid IL or missing references) return Color.Lerp(a, b, t); } private static float RoundedBoxDistance(float x, float y, float x0, float y0, float x1, float y1, float r) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) float num = (x0 + x1) / 2f; float num2 = (y0 + y1) / 2f; float num3 = (x1 - x0) / 2f - r; float num4 = (y1 - y0) / 2f - r; float num5 = Mathf.Abs(x - num) - num3; float num6 = Mathf.Abs(y - num2) - num4; Vector2 val = new Vector2(Mathf.Max(num5, 0f), Mathf.Max(num6, 0f)); return ((Vector2)(ref val)).magnitude + Mathf.Min(Mathf.Max(num5, num6), 0f) - r; } private static void AddLoop(List<(Vector2, Vector2)> edges, Vector2[] poly) { //IL_0007: 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) for (int i = 0; i < poly.Length; i++) { edges.Add((poly[i], poly[(i + 1) % poly.Length])); } } private static void Fill(Color[] px, Vector2[] poly, Color color) { //IL_0018: 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_002e: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < 128; i++) { for (int j = 0; j < 128; j++) { if (Inside(new Vector2((float)j + 0.5f, (float)i + 0.5f), poly)) { px[Index(j, i)] = color; } } } } private static bool Inside(Vector2 p, Vector2[] poly) { //IL_001b: 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_0039: 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) bool flag = false; int num = 0; int num2 = poly.Length - 1; while (num < poly.Length) { if (poly[num].y > p.y != poly[num2].y > p.y && p.x < (poly[num2].x - poly[num].x) * (p.y - poly[num].y) / (poly[num2].y - poly[num].y) + poly[num].x) { flag = !flag; } num2 = num++; } return flag; } private static void Stroke(Color[] px, Vector2 a, Vector2 b, float width, Color color) { //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_001d: 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_0038: 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_0053: 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_006d: 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) //IL_00a9: 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_00af: Unknown result type (might be due to invalid IL or missing references) //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_00c5: 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_00c9: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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_0119: 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_0122: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Max(0, (int)(Mathf.Min(a.x, b.x) - width)); int num2 = Mathf.Min(127, (int)(Mathf.Max(a.x, b.x) + width)); int num3 = Mathf.Max(0, (int)(Mathf.Min(a.y, b.y) - width)); int num4 = Mathf.Min(127, (int)(Mathf.Max(a.y, b.y) + width)); Vector2 val = b - a; float num5 = Mathf.Max(((Vector2)(ref val)).sqrMagnitude, 0.0001f); for (int i = num3; i <= num4; i++) { for (int j = num; j <= num2; j++) { Vector2 val2 = new Vector2((float)j + 0.5f, (float)i + 0.5f); float num6 = Mathf.Clamp01(Vector2.Dot(val2 - a, val) / num5); Vector2 val3 = val2 - (a + val * num6); float magnitude = ((Vector2)(ref val3)).magnitude; float num7 = Mathf.Clamp01(width / 2f + 0.5f - magnitude); if (!(num7 <= 0f)) { int num8 = Index(j, i); px[num8] = Color.Lerp(px[num8], color, num7); } } } } } internal class ScrapEntry { public Item Item; public string Key; public string Name; public string Source; public int MinValue; public int MaxValue; public int Pounds; public bool TwoHanded; public bool Metal; public string FavoriteKey => "scrap:" + Key; } internal static class ScrapCatalog { private static readonly string DisabledPath = Path.Combine(Paths.ConfigPath, "kylew.cosmeticsmenuplus.scrap-disabled.txt"); public static readonly List<ScrapEntry> Entries = new List<ScrapEntry>(); public static readonly Dictionary<string, ScrapEntry> ByKey = new Dictionary<string, ScrapEntry>(); public static readonly List<string> Sources = new List<string>(); public static readonly HashSet<string> Disabled = new HashSet<string>(); private static bool loaded; public static bool AnyDisabled { get { Load(); return Disabled.Count > 0; } } public static bool IsEnabled(string key) { Load(); return !Disabled.Contains(key); } public static void SetEnabled(string key, bool enabled) { Load(); if (enabled) { Disabled.Remove(key); } else { Disabled.Add(key); } Save(); } public static void SetDisabled(IEnumerable<string> keys) { Load(); Disabled.Clear(); Disabled.UnionWith(keys); Save(); } private static void Load() { if (loaded) { return; } loaded = true; try { if (File.Exists(DisabledPath)) { Disabled.UnionWith(from l in File.ReadAllLines(DisabledPath) select l.Trim() into l where l.Length > 0 select l); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Couldn't read the scrap list: " + ex.Message)); } } private static void Save() { try { File.WriteAllLines(DisabledPath, Disabled.OrderBy((string k) => k)); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Couldn't save the scrap list: " + ex.Message)); } } public static void Refresh() { Load(); List<Item> list = new List<Item>(Resources.FindObjectsOfTypeAll<Item>()); if ((Object)(object)StartOfRound.Instance != (Object)null && (Object)(object)StartOfRound.Instance.allItemsList != (Object)null) { list.AddRange(StartOfRound.Instance.allItemsList.itemsList); } Dictionary<Item, string> dictionary = SourcesFromLevelLoader(); float num = (((Object)(object)RoundManager.Instance != (Object)null && RoundManager.Instance.scrapValueMultiplier > 0f) ? RoundManager.Instance.scrapValueMultiplier : 0.4f); Entries.Clear(); ByKey.Clear(); foreach (Item item in list) { if (!((Object)(object)item == (Object)null) && item.isScrap && !((Object)(object)item.spawnPrefab == (Object)null) && !string.IsNullOrWhiteSpace(item.itemName)) { string text = item.itemName.Trim(); if (!ByKey.ContainsKey(text)) { string value; ScrapEntry scrapEntry = new ScrapEntry { Item = item, Key = text, Name = text, Source = (dictionary.TryGetValue(item, out value) ? value : "Other"), MinValue = Mathf.RoundToInt((float)item.minValue * num), MaxValue = Mathf.RoundToInt((float)item.maxValue * num), Pounds = Mathf.RoundToInt(Mathf.Clamp(item.weight - 1f, 0f, 10f) * 105f), TwoHanded = item.twoHanded, Metal = item.isConductiveMetal }; Entries.Add(scrapEntry); ByKey[text] = scrapEntry; } } } Entries.Sort((ScrapEntry a, ScrapEntry b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase)); Sources.Clear(); Sources.AddRange(from s in Entries.Select((ScrapEntry e) => e.Source).Distinct() orderby (!(s == "Lethal Company")) ? s : "" select s); } private static Dictionary<Item, string> SourcesFromLevelLoader() { Dictionary<Item, string> dictionary = new Dictionary<Item, string>(); try { if (!(AccessTools.TypeByName("LethalLevelLoader.PatchedContent")?.GetProperty("ExtendedItems", BindingFlags.Static | BindingFlags.Public)?.GetValue(null) is IEnumerable enumerable)) { return dictionary; } foreach (object item in enumerable) { Type type = item.GetType(); object? obj = type.GetProperty("Item")?.GetValue(item); Item val = (Item)((obj is Item) ? obj : null); if (val != null) { string text = type.GetProperty("ContentType")?.GetValue(item)?.ToString(); string text2 = type.GetProperty("ModName")?.GetValue(item) as string; dictionary[val] = ((text == "Vanilla") ? "Lethal Company" : (string.IsNullOrWhiteSpace(text2) ? "Modded" : text2.Trim())); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Couldn't read scrap sources from LethalLevelLoader: " + ex.Message)); } return dictionary; } } [HarmonyPatch(typeof(RoundManager), "SpawnScrapInLevel")] internal static class ScrapSpawnFilter { private static readonly List<(SpawnableItemWithRarity entry, int rarity)> changed = new List<(SpawnableItemWithRarity, int)>(); [HarmonyPrefix] [HarmonyPriority(0)] private static void Prefix(RoundManager __instance) { changed.Clear(); List<SpawnableItemWithRarity> list = __instance.currentLevel?.spawnableScrap; if (list == null || !ScrapCatalog.AnyDisabled) { return; } int num = 0; foreach (SpawnableItemWithRarity item in list) { if ((Object)(object)item?.spawnableItem != (Object)null && item.rarity > 0 && ScrapCatalog.IsEnabled(item.spawnableItem.itemName?.Trim() ?? "")) { num += item.rarity; } } if (num <= 0) { Plugin.Log.LogWarning((object)"Every scrap item on this moon is switched off; spawning the normal scrap instead."); return; } foreach (SpawnableItemWithRarity item2 in list) { if (!((Object)(object)item2?.spawnableItem == (Object)null) && item2.rarity > 0 && !ScrapCatalog.IsEnabled(item2.spawnableItem.itemName?.Trim() ?? "")) { changed.Add((item2, item2.rarity)); item2.rarity = 0; } } if (changed.Count > 0) { Plugin.Log.LogInfo((object)$"Scrap library: {changed.Count} switched-off item(s) won't spawn this round."); } } [HarmonyFinalizer] private static void Finalizer() { foreach (var item3 in changed) { SpawnableItemWithRarity item = item3.entry; int item2 = item3.rarity; item.rarity = item2; } changed.Clear(); } } internal static class ScrapThumbnails { public const int Size = 128; private static readonly string Folder = Path.Combine(Paths.CachePath, "CosmeticsMenuPlus", "scrap-v2"); private static readonly Dictionary<string, Texture2D> loaded = new Dictionary<string, Texture2D>(); private static readonly HashSet<string> missing = new HashSet<string>(); public static bool TryGet(string key, out Texture2D texture) { //IL_004e: 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_0065: Expected O, but got Unknown if (loaded.TryGetValue(key, out texture) && (Object)(object)texture != (Object)null) { return true; } texture = null; if (missing.Contains(key)) { return false; } string path = PathFor(key); if (!File.Exists(path)) { missing.Add(key); return false; } try { Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false) { name = "Scrap thumb " + key }; if (!ImageConversion.LoadImage(val, File.ReadAllBytes(path))) { Object.Destroy((Object)(object)val); return false; } loaded[key] = (texture = val); return true; } catch (Exception ex) { Plugin.Log.LogWarning((object)("Couldn't load thumbnail for " + key + ": " + ex.Message)); return false; } } public static bool Has(string key) { Texture2D texture; return TryGet(key, out texture); } public static void ClearAll() { foreach (Texture2D value in loaded.Values) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } } loaded.Clear(); missing.Clear(); try { if (Directory.Exists(Folder)) { string[] files = Directory.GetFiles(Folder, "*.png"); for (int i = 0; i < files.Length; i++) { File.Delete(files[i]); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Couldn't clear thumbnails: " + ex.Message)); } } public static void Capture(string key, Vector2 screenCenter, int side) { //IL_0034: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_00c1: 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_00d9: Expected O, but got Unknown //IL_00fe: Unknown result type (might be due to invalid IL or missing references) Texture2D val = ScreenCapture.CaptureScreenshotAsTexture(); if ((Object)(object)val == (Object)null) { return; } try { side = Mathf.Min(new int[3] { side, ((Texture)val).width, ((Texture)val).height }); int num = Mathf.Clamp(Mathf.RoundToInt(screenCenter.x - (float)side / 2f), 0, ((Texture)val).width - side); int num2 = Mathf.Clamp(Mathf.RoundToInt(screenCenter.y - (float)side / 2f), 0, ((Texture)val).height - side); Texture2D val2 = new Texture2D(side, side, (TextureFormat)4, false); val2.SetPixels(val.GetPixels(num, num2, side, side)); val2.Apply(); RenderTexture temporary = RenderTexture.GetTemporary(128, 128, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2); RenderTexture active = RenderTexture.active; Texture2D val3 = new Texture2D(128, 128, (TextureFormat)4, false) { name = "Scrap thumb " + key }; try { Graphics.Blit((Texture)(object)val2, temporary); RenderTexture.active = temporary; val3.ReadPixels(new Rect(0f, 0f, 128f, 128f), 0, 0, false); val3.Apply(); } finally { RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); Object.Destroy((Object)(object)val2); } Directory.CreateDirectory(Folder); File.WriteAllBytes(PathFor(key), ImageConversion.EncodeToPNG(val3)); if (loaded.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } loaded[key] = val3; missing.Remove(key); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Couldn't capture thumbnail for " + key + ": " + ex.Message)); } finally { Object.Destroy((Object)(object)val); } } private static string PathFor(string key) { char[] bad = Path.GetInvalidFileNameChars(); string arg = new string(key.Select((char c2) => (!bad.Contains(c2)) ? c2 : '_').ToArray()); uint num = 2166136261u; foreach (char c in key) { num = (num ^ c) * 16777619; } return Path.Combine(Folder, $"{arg}_{num:x8}.png"); } } internal static class SlotMenu { private class RightClick : MonoBehaviour, IPointerClickHandler, IEventSystemHandler { public Action action; public void OnPointerClick(PointerEventData e) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 Mouse current = Mouse.current; bool num; if (current == null) { num = (int)e.button == 1; } else { if (!current.rightButton.wasReleasedThisFrame) { return; } num = !current.leftButton.wasReleasedThisFrame; } if (num) { action?.Invoke(); } } } private class SearchDebounce : MonoBehaviour { private static string pending; private static float applyAt; public static void Queue(string text) { pending = text; applyAt = Time.unscaledTime + 0.15f; } public static void Cancel() { pending = null; } private void Update() { if (pending == null || Time.unscaledTime < applyAt) { return; } string text = pending; pending = null; if (!(text == query)) { query = text; if (query.Length > 0) { suitView = false; } Refresh(); } } } private class RefreshOnEnable : MonoBehaviour { private bool first = true; private void OnEnable() { if (first) { first = false; return; } Refresh(); if (inGame) { ApplySuitToPreview(LocalPlayer()?.currentSuitID ?? (-1)); } } } private class HistoryState { public List<string> Worn; public Dictionary<string, Tint> Tints; public int Suit; public HashSet<string> Favorites; public HashSet<string> Hidden; public string ActiveOutfit; } private class HistoryKeys : MonoBehaviour { private void Update() { Keyboard current = Keyboard.current; if (current == null || !current.ctrlKey.isPressed || scrapMode || ((Object)(object)search != (Object)null && search.isFocused)) { return; } EventSystem current2 = EventSystem.current; GameObject val = (((Object)(object)current2 != (Object)null) ? current2.currentSelectedGameObject : null); if ((Object)(object)val != (Object)null && (Object)(object)val.GetComponent<TMP_InputField>() != (Object)null) { return; } if (((ButtonControl)current.zKey).wasPressedThisFrame) { if (current.shiftKey.isPressed) { Redo(); } else { Undo(); } } else if (((ButtonControl)current.yKey).wasPressedThisFrame) { Redo(); } } } private enum ScrapFilter { All, Favorites, OneHanded, TwoHanded, Metal, Heavy, Valuable } private class CornerButtons : MonoBehaviour { private void OnEnable() { Show(visible: false); } private void OnDisable() { bool visible = !inGame; if (inGame) { QuickMenuManager val = Object.FindObjectOfType<QuickMenuManager>(); visible = (Object)(object)val != (Object)null && val.isMenuOpen; } Show(visible); } private static void Show(bool visible) { if ((Object)(object)activateButton != (Object)null) { activateButton.SetActive(visible); } if ((Object)(object)scrapButton != (Object)null) { scrapButton.SetActive(visible); } } } private class ThumbnailRunner : MonoBehaviour { private void OnDisable() { generating = false; } } private class TintDebounce : MonoBehaviour { private static bool dirty; private static bool settlePending; private static bool syncPending; private static float lastChange; private static float syncAt; public static void MarkDirty() { dirty = true; settlePending = true; lastChange = Time.unscaledTime; } public static void FlushNow() { if (dirty || settlePending) { Apply(); } if (syncPending) { Sync(); } } private void OnDisable() { FlushNow(); } private void Update() { if (dirty) { ApplyPreview(); } if (settlePending && Time.unscaledTime - lastChange > 0.2f) { Apply(); } if (syncPending && Time.unscaledTime > syncAt) { Sync(); } } private static void ApplyPreview() { dirty = false; if (tintTarget != null) { Recolor.Preview = true; try { Tints.ReapplyLocal(tintTarget.Id); } finally { Recolor.Preview = false; } HashSet<string> hashSet = Tints.KeysInUse(); hashSet.Add(Recolor.PreviewKey(editing)); Recolor.Prune(hashSet); } } private static void Apply() { dirty = false; settlePending = false; Tints.ReapplyLocal(); Recolor.Prune(Tints.KeysInUse()); Tints.Save(); AutoSaveOutfit(); syncPending = true; syncAt = Time.unscaledTime + 0.5f; } private static void Sync() { syncPending = false; if ((Object)(object)StartOfRound.Instance != (Object)null && (Object)(object)StartOfRound.Instance.localPlayerController != (Object)null) { TintSync.SendLocal(); } } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func<TMP_Text, TMP_FontAsset> <>9__38_0; public static Func<TMP_FontAsset, bool> <>9__38_1; public static Action <>9__41_0; public static Action <>9__41_1; public static UnityAction<string> <>9__41_2; public static Action <>9__43_0; public static Action <>9__43_1; public static Action <>9__45_0; public static Func<string, CosmeticEntry> <>9__59_2; public static Func<CosmeticEntry, bool> <>9__59_3; public static Func<CosmeticEntry, bool> <>9__59_0; public static Func<CosmeticEntry, bool> <>9__59_1; public static Func<UnlockableSuit, bool> <>9__63_0; public static Func<UnlockableSuit, int> <>9__63_1; public static Func<IGrouping<int, UnlockableSuit>, UnlockableSuit> <>9__63_2; public static Func<UnlockableSuit, int> <>9__63_3; public static Func<string, string> <>9__82_0; public static Func<Outfit, bool> <>9__91_0; public static Func<Outfit, string> <>9__95_0; public static Func<string, bool> <>9__97_0; public static Func<string, string> <>9__97_1; public static Action <>9__101_0; public static Action <>9__101_1; public static Action <>9__117_0; public static Action <>9__117_1; public static Action <>9__117_2; public static UnityAction <>9__119_0; public static UnityAction <>9__119_1; public static Func<ScrapEntry, bool> <>9__128_0; public static Func<ScrapEntry, bool> <>9__128_1; public static Func<ScrapEntry, bool> <>9__128_2; public static Func<ScrapEntry, bool> <>9__130_0; public static Func<ScrapEntry, bool> <>9__145_0; public static Action <>9__169_0; public static Action <>9__169_1; public static Action<float> <>9__169_2; public static Action<float> <>9__169_3; public static Action<float> <>9__169_4; internal TMP_FontAsset <Build>b__38_0(TMP_Text t) { return t.font; } internal bool <Build>b__38_1(TMP_FontAsset f) { return (Object)(object)f != (Object)null; } internal void <BuildTabs>b__41_0() { SetView(wearing: false); } internal void <BuildTabs>b__41_1() { SetView(wearing: true); } internal void <BuildTabs>b__41_2(string v) { SearchDebounce.Queue(v.Trim()); } internal void <BuildGridArea>b__43_0() { CyclePack(-1); } internal void <BuildGridArea>b__43_1() { CyclePack(1); } internal void <SetupPreview>b__45_0() { preview?.ResetView(); } internal CosmeticEntry <ItemsForView>b__59_2(string id) { return CosmeticCatalog.ById[id]; } internal bool <ItemsForView>b__59_3(CosmeticEntry e) { return WornInSlot(e, slot); } internal bool <ItemsForView>b__59_0(CosmeticEntry e) { if (query.Length <= 0) { return InSlot(e, slot); } return !Store.Hidden.Contains(e.Id); } internal bool <ItemsForView>b__59_1(CosmeticEntry e) { return e.Pack == pack; } internal bool <AvailableSuits>b__63_0(UnlockableSuit s) { return (Object)(object)s != (Object)null; } internal int <AvailableSuits>b__63_1(UnlockableSuit s) { return s.syncedSuitID.Value; } internal UnlockableSuit <AvailableSuits>b__63_2(IGrouping<int, UnlockableSuit> g) { return g.First(); } internal int <AvailableSuits>b__63_3(UnlockableSuit s) { return s.syncedSuitID.Value; } internal string <Capture>b__82_0(string id) { return id; } internal bool <get_ActiveOutfit>b__91_0(Outfit o) { return o.Name == Plugin.ActiveOutfit.Value; } internal string <NextOutfitName>b__95_0(Outfit o) { return o.Name; } internal bool <Snapshot>b__97_0(string id) { return !CosmeticRegistry.cosmeticInstances.ContainsKey(id); } internal string <Snapshot>b__97_1(string id) { return id; } internal void <ToggleOutfitManager>b__101_0() { CreateOutfitFromCurrent(); ClosePopover(); Refresh(); ToggleOutfitManager(); } internal void <ToggleOutfitManager>b__101_1() { ClosePopover(); UpdateOutfitButton(); } internal void <BuildScrapRail>b__117_0() { SetVisibleScrap(on: true); } internal void <BuildScrapRail>b__117_1() { SetVisibleScrap(on: false); } internal void <BuildScrapRail>b__117_2() { if (!generating) { ScrapThumbnails.ClearAll(); Refresh(); } } internal void <BuildScrapButton>b__119_0() { SetMode(scrap: false); } internal void <BuildScrapButton>b__119_1() { SetMode(scrap: true); ((Component)screen).gameObject.SetActive(true); } internal bool <ScrapForView>b__128_0(ScrapEntry e) { return !ScrapCatalog.IsEnabled(e.Key); } internal bool <ScrapForView>b__128_1(ScrapEntry e) { return InScrapFilter(e, scrapFilter); } internal bool <ScrapForView>b__128_2(ScrapEntry e) { return e.Source == scrapSource; } internal bool <RefreshScrapVisuals>b__130_0(ScrapEntry e) { return !ScrapCatalog.IsEnabled(e.Key); } internal bool <StartThumbnails>b__145_0(ScrapEntry e) { return !ScrapThumbnails.Has(e.Key); } internal void <BuildTintEditor>b__169_0() { SetMode(TintMode.HueShift); } internal void <BuildTintEditor>b__169_1() { SetMode(TintMode.Tint); } internal void <BuildTintEditor>b__169_2(float v) { editing.Hue = v; Changed(); } internal void <BuildTintEditor>b__169_3(float v) { editing.Saturation = v; Changed(); } internal void <BuildTintEditor>b__169_4(float v) { editing.Brightness = v; Changed(); } } private static readonly string[] OriginalParts = new string[7] { "CosmeticsHolderBG", "CosmeticsHolderBorder", "Scrollbar", "CosmeticsHolder", "EnableButton", "DisableButton", "DisableCosmeticsText" }; private static readonly Slot[] RailSlots = new Slot[9] { Slot.All, Slot.Favorites, Slot.Head, Slot.Chest, Slot.Hip, Slot.RightArm, Slot.LeftLeg, Slot.RightLeg, Slot.Hidden }; private const float DesignHalfWidth = 480f; private const float DesignHalfHeight = 265f; private static readonly Vector2 LeftPos = new Vector2(-160f, 0f); private static readonly Vector2 LeftSize = new Vector2(620f, 510f); private static readonly Vector2 PreviewPos = new Vector2(315f, 0f); private static readonly Vector2 PreviewSize = new Vector2(310f, 510f); private static readonly Vector2 GridPos = new Vector2(66f, -19f); private static readonly Vector2 GridSize = new Vector2(468f, 370f); private const int GridColumns = 5; private static bool inGame; private static bool wearingView; private static bool suitView; private static Transform screen; private static Transform holder; private static RectTransform left; private static RectTransform content; private static RectTransform popover; private static ScrollRect scroll; private static TextMeshProUGUI packLabel; private static GameObject packRow; private static TMP_InputField search; private static Button outfitButton; private static Button undoButton; private static Button redoButton; private static TextMeshProUGUI outfitLabel; private static Button browseTab; private static Button wearingTab; private static Button suitButton; private static PreviewControls preview; private static readonly Dictionary<Slot, (Button button, TextMeshProUGUI count)> railButtons = new Dictionary<Slot, (Button, TextMeshProUGUI)>(); private static readonly List<Action> itemRefreshers = new List<Action>(); private static Slot slot = Slot.All; private static string pack; private static string query = ""; private static readonly List<string> removedThisSession = new List<string>(); private static int previewSuitId = -1; private const int HistoryLimit = 60; private static readonly List<HistoryState> undoStack = new List<HistoryState>(); private static readonly List<HistoryState> redoStack = new List<HistoryState>(); private static bool restoring; private static readonly (ScrapFilter filter, string label)[] ScrapRail = new(ScrapFilter, string)[7] { (ScrapFilter.All, "All"), (ScrapFilter.Favorites, "Favorites"), (ScrapFilter.OneHanded, "One-handed"), (ScrapFilter.TwoHanded, "Two-handed"), (ScrapFilter.Metal, "Metal"), (ScrapFilter.Heavy, "Heavy 30lb+"), (ScrapFilter.Valuable, "Worth 80+") }; private static bool scrapMode; private static ScrapFilter scrapFilter = ScrapFilter.All; private static string scrapSource; private static ScrapEntry selectedScrap; private static readonly Dictionary<ScrapFilter, (Button button, TextMeshProUGUI count)> scrapRailButtons = new Dictionary<ScrapFilter, (Button, TextMeshProUGUI)>(); private static GameObject scrapBar; private static Button clearButton; private static Transform scrapHolder; private static Transform scrapSpin; private static PreviewControls scrapPreview; private static TextMeshProUGUI scrapInfo; private static GameObject scrapButton; private static GameObject activateButton; private static readonly string[] HelperLayers = new string[4] { "ScanNode", "Triggers", "InteractableObject", "Ignore Raycast" }; private static readonly string[] HelperNames = new string[6] { "scannode", "scan node", "trigger", "collider", "hitbox", "bounds" }; private static ThumbnailRunner runner; private static bool generating; private static readonly float[] PresetHues = new float[8] { 0f, 30f, 60f, 120f, 180f, 220f, 280f, 330f }; private static RectTransform tintPanel; private static CosmeticEntry tintTarget; private static Tint editing; private static Slider hueSlider; private static Slider satSlider; private static Slider brightSlider; private static TextMeshProUGUI hueValue; private static TextMeshProUGUI satValue; private static TextMeshProUGUI brightValue; private static TextMeshProUGUI tintNote; private static Button shiftButton; private static Button tintModeButton; private static GameObject tintControls; private static bool settingSliders; private static TextMeshProUGUI tintTitle; private static readonly Vector2 TintPos = new Vector2(66f, -2f); private static readonly Vector2 TintSize = new Vector2(468f, 404f); private static bool tintHistoryPushed; private static Outfit ActiveOutfit { get { if (!string.IsNullOrEmpty(Plugin.ActiveOutfit.Value)) { return Store.Outfits.FirstOrDefault((Outfit o) => o.Name == Plugin.ActiveOutfit.Value); } return null; } } public static void Build(Transform globalScale, bool isInGame) { //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) inGame = isInGame; screen = globalScale.Find("CosmeticsScreen"); holder = screen.Find("ObjectHolder"); Ui.Font = (from t in ((Component)globalScale).GetComponentsInChildren<TMP_Text>(true) select t.font).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => (Object)(object)f != (Object)null)); Store.Load(); CosmeticCatalog.Refresh(); railButtons.Clear(); itemRefreshers.Clear(); previewSuitId = -1; query = ""; popover = null; suitView = false; scrapMode = false; selectedScrap = null; if (!Enum.TryParse<Slot>(Plugin.LastSlot.Value, out slot) || Array.IndexOf(RailSlots, slot) < 0) { slot = Slot.All; } string[] originalParts = OriginalParts; foreach (string text in originalParts) { Transform obj = screen.Find(text); if (obj != null) { ((Component)obj).gameObject.SetActive(false); } } if (!MainClass.cosmeticsSyncOther.Value) { MainClass.cosmeticsSyncOther.Value = true; MainClass.StaticConfig.Save(); } DisplayScale.Capture(holder.Find("ScavengerModel")); FitToScreen(); RectTransform val = Ui.Rect("CosmeticsMenuPlus", screen, Vector2.zero, new Vector2(960f, 530f)); ((Component)val).gameObject.AddComponent<RefreshOnEnable>(); ((Component)val).gameObject.AddComponent<HistoryKeys>(); ((Component)val).gameObject.AddComponent<SearchDebounce>(); left = Ui.Rect("Browser", (Transform)(object)val, LeftPos, LeftSize); Ui.Image(left, Ui.Panel); BuildTabs(); BuildRail(); BuildGridArea(); BuildBottomBar(); BuildTintEditor(left); SetupPreview(val); BuildScrapRail(); SetupScrapPreview(); BuildScrapButton(globalScale); Refresh(); Tints.ReapplyLocal(); } private static void FitToScreen() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0026: 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_0059: 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_0070: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)screen; Canvas componentInParent = ((Component)screen).GetComponentInParent<Canvas>(true); Camera val2 = (((Object)(object)componentInParent != (Object)null && (int)componentInParent.rootCanvas.renderMode != 0) ? componentInParent.rootCanvas.worldCamera : null); Vector2 val3 = default(Vector2); Vector2 val4 = default(Vector2); if (RectTransformUtility.ScreenPointToLocalPointInRectangle(val, Vector2.zero, val2, ref val3) && RectTransformUtility.ScreenPointToLocalPointInRectangle(val, new Vector2((float)Screen.width, (float)Screen.height), val2, ref val4)) { float num = (val4.x - val3.x) / 2f; float num2 = (val4.y - val3.y) / 2f; float num3 = Mathf.Min(new float[3] { 1f, (num - 10f) / 480f, (num2 - 5f) / 265f }); if (num3 > 0.2f && num3 < 0.999f) { Transform obj = screen; obj.localScale *= num3; } } } public static void RestoreOriginal(Transform globalScale) { Transform val = globalScale.Find("CosmeticsScreen"); if ((Object)(object)val == (Object)null) { return; } string[] originalParts = OriginalParts; foreach (string text in originalParts) { Transform obj = val.Find(text); if (obj != null) { ((Component)obj).gameObject.SetActive(true); } } originalParts = new string[2] { "CosmeticsMenuPlus", "PreviewPanel" }; foreach (string text2 in originalParts) { Transform val2 = val.Find(text2); if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)((Component)val2).gameObject); } } } private static void BuildTabs() { //IL_0014: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) browseTab = Ui.MakeButton((Transform)(object)left, "Browse", new Vector2(-248f, 225f), new Vector2(104f, 32f), "Browse", delegate { SetView(wearing: false); }, 15f); wearingTab = Ui.MakeButton((Transform)(object)left, "Wearing", new Vector2(-138f, 225f), new Vector2(104f, 32f), "Current", delegate { SetView(wearing: true); }, 15f); search = Ui.InputField((Transform)(object)left, new Vector2(111f, 225f), new Vector2(378f, 32f), "Search cosmetics", 14f); ((UnityEvent<string>)(object)search.onValueChanged).AddListener((UnityAction<string>)delegate(string v) { SearchDebounce.Queue(v.Trim()); }); } private static void BuildRail() { //IL_0048: 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_0088: 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_00b0: 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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) float num = 185f; Slot[] railSlots = RailSlots; for (int i = 0; i < railSlots.Length; i++) { Slot slot = railSlots[i]; Slot captured = slot; Button val = Ui.MakeButton((Transform)(object)left, "Rail_" + slot, new Vector2(-239f, num), new Vector2(122f, 32f), null, delegate { SelectSlot(captured); }); Ui.Label(((Component)val).transform, CosmeticCatalog.SlotLabel(slot), 14f, Ui.Text, (TextAlignmentOptions)513, (Vector2?)new Vector2(-12f, 0f), (Vector2?)new Vector2(90f, 30f)); TextMeshProUGUI item = Ui.Label(((Component)val).transform, "", 13f, Ui.TextMuted, (TextAlignmentOptions)516, (Vector2?)new Vector2(44f, 0f), (Vector2?)new Vector2(26f, 30f)); railButtons[slot] = (val, item); num -= ((slot == Slot.Favorites || slot == Slot.RightLeg) ? 46f : 38f); } } private static void BuildGridArea() { //IL_0019: 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_005a: 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_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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) packRow = ((Component)Ui.Rect("PackFilter", (Transform)(object)left, new Vector2(GridPos.x, 185f), new Vector2(GridSize.x, 32f))).gameObject; Ui.MakeButton(packRow.transform, "PrevPack", new Vector2(-218f, 0f), new Vector2(32f, 32f), "<", delegate { CyclePack(-1); }, 16f); Ui.MakeButton(packRow.transform, "NextPack", new Vector2(218f, 0f), new Vector2(32f, 32f), ">", delegate { CyclePack(1); }, 16f); packLabel = Ui.Label(packRow.transform, "", 14f, Ui.Text, (TextAlignmentOptions)514, (Vector2?)Vector2.zero, (Vector2?)new Vector2(390f, 30f)); content = Ui.ScrollView((Transform)(object)left, GridPos, GridSize, out scroll); } private static void BuildBottomBar() { //IL_0014: 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_0067: 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_00b0: 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) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) outfitButton = Ui.MakeButton((Transform)(object)left, "Outfits", new Vector2(-215f, -228f), new Vector2(170f, 30f), null, ToggleOutfitManager); outfitLabel = Ui.Label(((Component)outfitButton).transform, "", 13f, Ui.Text, (TextAlignmentOptions)514); undoButton = Ui.MakeButton((Transform)(object)left, "Undo", new Vector2(-92f, -228f), new Vector2(60f, 30f), "Undo", Undo, 12f); redoButton = Ui.MakeButton((Transform)(object)left, "Redo", new Vector2(-26f, -228f), new Vector2(60f, 30f), "Redo", Redo, 12f); clearButton = Ui.MakeButton((Transform)(object)left, "ClearAll", new Vector2(270f, -228f), new Vector2(60f, 30f), "Clear", ClearAll, 12f); UpdateHistoryButtons(); } private static void SetupPreview(RectTransform root) { //IL_001a: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_007a: 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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_0103: 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_0188: 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_019d: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Expected O, but got Unknown Transform val = holder.Find("ScavengerModel"); RectTransform val2 = Ui.Rect("PreviewPanel", screen, PreviewPos, PreviewSize); Ui.Image(val2, new Color(0.05f, 0.03f, 0.02f, 0.6f), raycast: false); ((Transform)val2).SetSiblingIndex(holder.GetSiblingIndex()); Vector3 localPosition = holder.localPosition; holder.localPosition = new Vector3(PreviewPos.x, 0f, localPosition.z); Ui.MakeButton((Transform)(object)root, "ResetView", new Vector2(PreviewPos.x + 95f, -228f), new Vector2(100f, 30f), "Reset view", delegate { preview?.ResetView(); }, 12f); suitButton = Ui.MakeButton((Transform)(object)root, "ChangeSuit", new Vector2(PreviewPos.x - 23f, -228f), new Vector2(120f, 30f), "Change suit", ToggleSuitPicker, 12f); ((Component)suitButton).gameObject.SetActive(inGame); Transform obj = screen.Find("ExitButton"); RectTransform val3 = (RectTransform)(object)((obj is RectTransform) ? obj : null); if (val3 != null) { val3.anchoredPosition = new Vector2(PreviewPos.x + 133f, 232f); ((Transform)val3).localScale = Vector3.one * 0.28f; ((Transform)val3).SetAsLastSibling(); } if (!((Object)(object)val == (Object)null)) { Transform val4 = screen.Find("SpinAreaButton"); SpinDragger val5 = (((Object)(object)val4 != (Object)null) ? ((Component)val4).GetComponent<SpinDragger>() : null); Transform spinTarget = (((Object)(object)val5 != (Object)null && (Object)(object)val5.target != (Object)null) ? val5.target.transform : val); if ((Object)(object)val4 != (Object)null) { ((Component)val4).gameObject.SetActive(false); } preview = ((Component)val2).gameObject.AddComponent<PreviewControls>(); preview.spinTarget = spinTarget; preview.holder = holder; preview.space = (RectTransform)screen; preview.area = val2; preview.Init(); if (inGame) { ApplySuitToPreview(LocalPlayer()?.currentSuitID ?? (-1)); } } } private static void SetView(bool wearing) { wearingView = wearing; suitView = false; Refresh(); } private static void SelectSlot(Slot s) { slot = s; suitView = false; Plugin.LastSlot.Value = s.ToString(); SearchDebounce.Cancel(); if (query.Length > 0 || search.text.Length > 0) { search.SetTextWithoutNotify(query = ""); } Refresh(); } private static void CyclePack(int dir) { if (scrapMode) { CycleScrapSource(dir); return; } List<string> packs = CosmeticCatalog.Packs; if (packs.Count == 0) { return; } int num = ((pack == null) ? (-1) : packs.IndexOf(pack)); for (int i = 0; i <= packs.Count; i++) { num += dir; if (num >= packs.Count) { num = -1; } if (num < -1) { num = packs.Count - 1; } pack = ((num < 0) ? null : packs[num]); if (pack == null || ItemsForView().Count > 0) { break; } } Refresh(); } private static void Toggle(string id) { PushHistory(); CosmeticRegistry.ToggleCosmetic(id); AfterEquipChange(); if (CosmeticRegistry.IsEquipped(id)) { removedThisSession.Remove(id); } else if (!removedThisSession.Contains(id)) { removedThisSession.Add(id); } AutoSaveOutfit(); RefreshVisuals(); } private static void ToggleFavorite(string id) { PushHistory(); Store.ToggleFavorite(id); if (slot == Slot.Favorites) { Refresh(); } else { RefreshVisuals(); } } private static void ToggleHidden(string id) { PushHistory(); Store.SetHidden(id, !Store.Hidden.Contains(id)); if (slot == Slot.Hidden && Store.Hidden.Count == 0) { slot = Slot.All; } Refresh(); } private static void ClearAll() { PushHistory(); SetActiveOutfit(null); foreach (string locallySelectedCosmetic in CosmeticRegistry.locallySelectedCosmetics) { if (!removedThisSession.Contains(locallySelectedCosmetic)) { removedThisSession.Add(locallySelectedCosmetic); } } CosmeticRegistry.locallySelectedCosmetics.Clear(); AfterEquipChange(); SyncIfInGame(); Refresh(); } private static void AfterEquipChange() { MainClass.WriteCosmeticsToFile(); CosmeticRegistry.UpdateCosmeticsOnDisplayGuy(true); } private static void SyncIfInGame() { if ((Object)(object)StartOfRound.Instance != (Object)null && (Object)(object)StartOfRound.Instance.localPlayerController != (Object)null) { CosmeticSyncPatch.SyncCosmeticsToOtherClients((PlayerControllerB)null, false, false); } } internal static void Refresh() { if ((Object)(object)content == (Object)null) { return; } HideTintIfOpen(); ClosePopover(); CosmeticCatalog.Refresh(); itemRefreshers.Clear(); Ui.Clear((Transform)(object)content); if (slot == Slot.Hidden && Store.Hidden.Count == 0) { slot = Slot.All; } ApplyModeChrome(); if (scrapMode) { packRow.SetActive(true); BuildScrapView(); scroll.verticalNormalizedPosition = 1f; RefreshVisuals(); return; } packRow.SetActive(!suitView); ((TMP_Text)((Component)suitButton).GetComponentInChildren<TextMeshProUGUI>()).text = (suitView ? "Back" : "Change suit"); if (suitView) { BuildSuits(); } else { List<CosmeticEntry> list = ItemsForView(); if (list.Count == 0) { EmptyNote(EmptyText()); } else { BuildGrid(list); } ((TMP_Text)packLabel).text = (pack ?? "All packs") + " · " + list.Count; } scroll.verticalNormalizedPosition = 1f; UpdateOutfitButton(); RefreshVisuals(); } private static string EmptyText() { if (query.Length > 0) { return "No cosmetics match \"" + query + "\"."; } if (wearingView) { if (slot != Slot.All) { return "Nothing on this slot."; } return "You're not wearing anything yet. Pick some in Browse."; } if (slot == Slot.Favorites) { return "No favorites yet. Click the * on any cosmetic."; } return "No cosmetics here for this pack."; } private static bool InSlot(CosmeticEntry e, Slot s) { switch (s) { case Slot.All: return !Store.Hidden.Contains(e.Id); case Slot.Favorites: if (Store.Favorites.Contains(e.Id)) { return !Store.Hidden.Contains(e.Id); } return false; case Slot.Hidden: return Store.Hidden.Contains(e.Id); default: if (e.Slot == s) { return !Store.Hidden.Contains(e.Id); } return false; } } private static bool WornInSlot(CosmeticEntry e, Slot s) { return s switch { Slot.All => true, Slot.Favorites => Store.Favorites.Contains(e.Id), Slot.Hidden => Store.Hidden.Contains(e.Id), _ => e.Slot == s, }; } private static List<CosmeticEntry> ItemsForView() { IEnumerable<CosmeticEntry> source = ((!wearingView) ? CosmeticCatalog.Entries.Where((CosmeticEntry e) => (query.Length <= 0) ? InSlot(e, slot) : (!Store.Hidden.Contains(e.Id))) : (from id in CosmeticRegistry.locallySelectedCosmetics.Concat(removedThisSession).Distinct().Where(CosmeticCatalog.ById.ContainsKey) select CosmeticCatalog.ById[id] into e where WornInSlot(e, slot) select e)); if (query.Length > 0) { string q = query.ToLowerInvariant(); source = source.Where((CosmeticEntry e) => e.Name.ToLowerInvariant().Contains(q) || e.Pack.ToLowerInvariant().Contains(q) || e.Id.ToLowerInvariant().Contains(q)); } if (pack != null) { source = source.Where((CosmeticEntry e) => e.Pack == pack); } return source.ToList(); } private static void RefreshVisuals() { //IL_005f: 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_007c: 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_00e7: 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) foreach (Action itemRefresher in itemRefreshers) { itemRefresher(); } if (scrapMode) { RefreshScrapVisuals(); return; } List<string> locallySelectedCosmetics = CosmeticRegistry.locallySelectedCosmetics; Ui.SetIdleColor(browseTab, (wearingView || suitView) ? Ui.Button : Ui.AccentDim); Ui.SetIdleColor(wearingTab, (wearingView && !suitView) ? Ui.AccentDim : Ui.Button); foreach (KeyValuePair<Slot, (Button, TextMeshProUGUI)> railButton in railButtons) { Slot s = railButton.Key; Ui.SetIdleColor(railButton.Value.Item1, (s == slot && query.Length == 0 && !suitView) ? Ui.AccentDim : Ui.Button); int num; switch (s) { case Slot.All: num = locallySelectedCosmetics.Count; break; case Slot.Favorites: num = Store.Favorites.Count; break; case Slot.Hidden: num = Store.Hidden.Count; ((Component)railButton.Value.Item1).gameObject.SetActive(num > 0); break; default: { num = locallySelectedCosmetics.Count((string id) => CosmeticCatalog.ById.TryGetValue(id, out var value) && value.Slot == s); break; } } ((TMP_Text)railButton.Value.Item2).text = ((num > 0) ? num.ToString() : ""); } } private static void BuildGrid(List<CosmeticEntry> items) { //IL_001a: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //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_012a: 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_016e: 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_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: 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_0239: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) GridLayoutGroup obj = ((Component)content).gameObject.AddComponent<GridLayoutGroup>(); obj.cellSize = new Vector2(86f, 98f); obj.spacing = new Vector2(6f, 6f); ((LayoutGroup)obj).padding = new RectOffset(6, 6, 6, 6); obj.constraint = (Constraint)1; obj.constraintCount = 5; foreach (CosmeticEntry entry in items) { string id = entry.Id; bool hiddenView = slot == Slot.Hidden && !wearingView; Button cell = Ui.MakeButton((Transform)(object)content, "Item_" + id, Vector2.zero, Vector2.zero, null, delegate { if (hiddenView) { ToggleHidden(id); } else { Toggle(id); } }); ((Component)cell).gameObject.AddComponent<RightClick>().action = delegate { ToggleHidden(id); }; Outline outline = ((Component)cell).gameObject.AddComponent<Outline>(); ((Shadow)outline).effectColor = Ui.Accent; ((Shadow)outline).effectDistance = new Vector2(2f, -2f); Icon(((Component)cell).transform, entry, new Vector2(0f, 9f), 68f); Ui.Label(((Component)cell).transform, entry.Name, 11f, Ui.Text, (TextAlignmentOptions)514, (Vector2?)new Vector2(0f, -39f), (Vector2?)new Vector2(84f, 18f)); Button val = SmallButton(Ui.Rect("Fav", ((Component)cell).transform, new Vector2(-31f, 37f), new Vector2(20f, 20f)), "*", delegate { ToggleFavorite(id); }, 17f); Ui.SetIdleColor(val, new Color(0f, 0f, 0f, 0.35f)); TextMeshProUGUI favText = ((Component)val).GetComponentInChildren<TextMeshProUGUI>(); Button tint = SmallButton(Ui.Rect("Tint", ((Component)cell).transform, new Vector2(28f, 38f), new Vector2(28f, 18f)), "Tint", delegate { OpenTint(entry); }, 9f); RectTransform rt = Ui.Rect("TintDot", ((Component)cell).transform, new Vector2(-1f, 38f), new Vector2(10f, 10f)); Image dot = Ui.Image(rt, Color.white, raycast: false); itemRefreshers.Add(delegate { //IL_0028: 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_0069: 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_00e2: 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) bool flag = CosmeticRegistry.IsEquipped(id); ((Behaviour)outline).enabled = flag; Ui.SetIdleColor(cell, flag ? Ui.AccentDim : Ui.Button); ((Component)tint).gameObject.SetActive(flag && entry.Tintable && !hiddenView); Ui.SetIdleColor(tint, Ui.Button); bool flag2 = !Tints.GetLocal(id).IsNone; ((Behaviour)dot).enabled = flag2; if (flag2) { ((Graphic)dot).color = SwatchColor(id); } ((Graphic)favText).color = (Color)(Store.Favorites.Contains(id) ? Ui.Accent : new Color(1f, 1f, 1f, 0.25f)); }); } } private static PlayerControllerB LocalPlayer() { if (!((Object)(object)GameNetworkManager.Instance != (Object)null)) { return null; } return GameNetworkManager.Instance.localPlayerController; } private static List<UnlockableSuit> AvailableSuits() { if (!inGame || (Object)(object)StartOfRound.Instance == (Object)null) { return new List<UnlockableSuit>(); } return (from s in Object.FindObjectsOfType<UnlockableSuit>(true) where (Object)(object)s != (Object)null group s by s.syncedSuitID.Value into g select g.First() into s orderby s.syncedSuitID.Value select s).ToList(); } private static string SuitName(int suitId) { if ((Object)(object)StartOfRound.Instance == (Object)null || suitId < 0) { return null; } List<UnlockableItem> unlockables = StartOfRound.Instance.unlockablesList.unlockables; if (suitId >= unlockables.Count) { return null; } return unlockables[suitId].unlockableName; } private static void WearSuit(UnlockableSuit suit, int suitId, bool recordHistory = true) { PlayerControllerB val = LocalPlayer(); if (!((Object)(object)val == (Object)null) && !((Object)(object)suit == (Object)null)) { if (recordHistory && val.currentSuitID != suitId) { PushHistory(); } suit.SwitchSuitToThis(val); ApplySuitToPreview(suitId); AutoSaveOutfit(); RefreshVisuals(); } } private static void ToggleSuitPicker() { suitView = !suitView; Refresh(); } private static void BuildSuits() { //IL_0033: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0141: 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_0181: 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_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or m