using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using HarmonyLib;
using Il2CppCharacterCustomization;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using TellMeCosmetics;
using TellMeCosmetics.Config;
using TellMeCosmetics.UI;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: VerifyLoaderVersion(0, 6, 6, true)]
[assembly: MelonInfo(typeof(CustomizationPickupFinderMod), "Tell Me Cosmetics", "0.1.4", "0.1.4", null)]
[assembly: MelonGame("Valko Game Studios", "Labyrinthine")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("TellMeCosmetics")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.1.4.0")]
[assembly: AssemblyInformationalVersion("0.1.4")]
[assembly: AssemblyProduct("Tell Me Cosmetics")]
[assembly: AssemblyTitle("TellMeCosmetics")]
[assembly: AssemblyVersion("0.1.4.0")]
internal static class ModInfo
{
public const string Name = "Tell Me Cosmetics";
public const string Version = "0.1.4";
public const string Author = "LimitBRK";
}
namespace TellMeCosmetics
{
[HarmonyPatch(typeof(CustomizationPickup), "Start")]
internal class Customization_SpawnItemListener
{
private static void Postfix(CustomizationPickup __instance)
{
CustomizationPickupFinderMod.Instance?.Show(__instance);
}
}
[HarmonyPatch(typeof(CustomizationPickup), "Pickup")]
internal class Customization_PickUpListener
{
private static void Postfix(CustomizationPickup __instance)
{
CustomizationPickupFinderMod.Instance?.Pickup(__instance.ItemID);
}
}
[HarmonyPatch(typeof(CustomizationSave), "Load")]
internal class Customization_SaveLoadListener
{
private static void Postfix(CustomizationSave __result)
{
CustomizationPickupFinderMod.Instance?.UpdateSave(__result);
}
}
public class CustomizationPickupFinderMod : MelonMod
{
private CustomizationSave SaveInstance;
private ItemsCollectionSO itemsCollection;
private ItemAlertUI alertui;
private GameplayConfig config;
internal static CustomizationPickupFinderMod Instance { get; private set; }
public override void OnInitializeMelon()
{
config = ConfigManager.Load();
Instance = this;
((MelonBase)this).LoggerInstance.Msg("TellMeCosmetics Mod Loaded!!!");
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName)
{
((MelonBase)this).LoggerInstance.Msg($"SCENE {buildIndex}/{sceneName} Loaded!");
MelonCoroutines.Start(InitItemsCollectionSO());
if (buildIndex >= 3 && sceneName == "LoadingScreen")
{
MelonCoroutines.Start(ClearAlertUIAfterDelay());
}
}
public override void OnSceneWasInitialized(int buildIndex, string sceneName)
{
((MelonBase)this).LoggerInstance.Msg($"SCENE {buildIndex}/{sceneName} Initialized!");
if (buildIndex >= 1 && sceneName == "MainMenu" && (alertui == null || alertui.IsDestroy()))
{
MelonCoroutines.Start(InitUI());
}
}
private IEnumerator InitItemsCollectionSO()
{
if ((Object)(object)itemsCollection == (Object)null)
{
yield return null;
ItemsCollectionSO[] ic = Il2CppArrayBase<ItemsCollectionSO>.op_Implicit(Resources.FindObjectsOfTypeAll<ItemsCollectionSO>());
if (ic.Length != 0)
{
itemsCollection = ic[0];
((MelonBase)this).LoggerInstance.Msg("Init itemsCollectionSO Class");
}
}
}
private IEnumerator InitUI()
{
yield return (object)new WaitForSeconds(1f);
try
{
GameObject tabMenu = GameObject.Find("Global/Global Canvas/Player_UI/Tab Menu");
if ((Object)(object)tabMenu == (Object)null)
{
((MelonBase)this).LoggerInstance.Warning("UI Tab Menu not found!");
yield break;
}
RectTransform ui = tabMenu.GetComponent<RectTransform>();
if ((Object)(object)ui == (Object)null)
{
((MelonBase)this).LoggerInstance.Warning("UI RectTransform missing!");
yield break;
}
itemsCollection = ((IEnumerable<ItemsCollectionSO>)Resources.FindObjectsOfTypeAll<ItemsCollectionSO>()).FirstOrDefault();
if ((Object)(object)itemsCollection == (Object)null)
{
((MelonBase)this).LoggerInstance.Warning("ItemsCollectionSO not found!");
yield break;
}
((MelonBase)this).LoggerInstance.Msg("Initializing UI components...");
alertui = new ItemAlertUI(ui, itemsCollection);
((MelonBase)this).LoggerInstance.Msg("UI initialized successfully.");
}
catch (Exception ex)
{
((MelonBase)this).LoggerInstance.Error($"[InitUI] Exception: {ex}");
}
}
private IEnumerator ClearAlertUIAfterDelay()
{
yield return (object)new WaitForEndOfFrame();
alertui?.Clear();
((MelonBase)this).LoggerInstance.Msg("UI Cleared");
}
internal void Show(CustomizationPickup item)
{
((MelonBase)this).LoggerInstance.Msg($"\ud83d\udce6Spawned Cosmetic ItemID {item.ItemID} {((Object)item).name}!");
if (!config.RevealAll.Value && SaveInstance != null)
{
alertui?.Show(item, SaveInstance.IsItemUnlocked(item.ItemID));
}
else
{
alertui?.Show(item);
}
}
internal void Pickup(ushort itemID)
{
alertui?.Pickup(itemID);
}
internal void UpdateSave(CustomizationSave save)
{
if (save != null)
{
SaveInstance = save;
}
}
}
}
namespace TellMeCosmetics.UI
{
public class ItemAlertUI
{
private static readonly string TAG = "ItemAlert UI";
private readonly CustomizationItem[] itemsCollection;
private readonly TMP_FontAsset fontref;
private readonly GameObject ui_object;
private readonly TextMeshProUGUI myText;
private readonly GameObject iconObject;
private readonly Image iconImage;
private readonly GameObject iconAltObject;
private readonly TextMeshProUGUI iconAltImage;
private ushort itemID;
public ItemAlertUI(RectTransform parentUI, ItemsCollectionSO itemsCollectionSO)
{
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Expected O, but got Unknown
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: 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)
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_0150: Unknown result type (might be due to invalid IL or missing references)
//IL_015a: Expected O, but got Unknown
//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_01e1: Expected O, but got Unknown
//IL_0285: Unknown result type (might be due to invalid IL or missing references)
//IL_0295: Unknown result type (might be due to invalid IL or missing references)
//IL_029c: Expected O, but got Unknown
fontref = UIUtils.GetFontByName("Larke Sans Regular SDF");
itemsCollection = Il2CppArrayBase<CustomizationItem>.op_Implicit((Il2CppArrayBase<CustomizationItem>)(object)((itemsCollectionSO != null) ? itemsCollectionSO.collection : null));
MelonLogger.Msg($"Loaded {itemsCollection.Length} cosmetic assets!");
ui_object = new GameObject(TAG);
ui_object.SetActive(false);
ui_object.transform.SetParent((Transform)(object)parentUI, false);
RectTransform val = ui_object.AddComponent<RectTransform>();
val.anchorMin = new Vector2(0f, 0f);
val.anchorMax = new Vector2(0f, 0f);
val.pivot = new Vector2(0f, 0f);
val.anchoredPosition = new Vector2(0f, 0f);
val.sizeDelta = new Vector2(0f, 50f);
HorizontalLayoutGroup val2 = ui_object.AddComponent<HorizontalLayoutGroup>();
((LayoutGroup)val2).childAlignment = (TextAnchor)3;
((HorizontalOrVerticalLayoutGroup)val2).childControlHeight = false;
((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = false;
((HorizontalOrVerticalLayoutGroup)val2).spacing = 10f;
iconObject = new GameObject("Item Icon");
iconObject.transform.SetParent(ui_object.transform, false);
iconObject.SetActive(false);
iconImage = iconObject.AddComponent<Image>();
iconImage.preserveAspect = true;
iconImage.sprite = null;
RectTransform component = iconObject.GetComponent<RectTransform>();
component.sizeDelta = new Vector2(64f, 64f);
iconAltObject = new GameObject("Item Icon Alt");
iconAltObject.transform.SetParent(ui_object.transform, false);
iconAltObject.SetActive(false);
iconAltImage = iconAltObject.AddComponent<TextMeshProUGUI>();
((TMP_Text)iconAltImage).font = fontref;
((TMP_Text)iconAltImage).fontSize = 60f;
((TMP_Text)iconAltImage).richText = false;
((TMP_Text)iconAltImage).fontWeight = (FontWeight)900;
((TMP_Text)iconAltImage).alignment = (TextAlignmentOptions)4098;
RectTransform component2 = iconAltObject.GetComponent<RectTransform>();
component2.sizeDelta = new Vector2(64f, 64f);
GameObject val3 = new GameObject("Item Name");
val3.transform.SetParent(ui_object.transform, false);
myText = val3.AddComponent<TextMeshProUGUI>();
((TMP_Text)myText).font = fontref;
((TMP_Text)myText).fontSize = 36f;
((TMP_Text)myText).richText = false;
((TMP_Text)myText).alignment = (TextAlignmentOptions)4097;
((TMP_Text)myText).overflowMode = (TextOverflowModes)0;
}
private void SetItemUI(string itemText, Sprite icon = null, char altIcon = '?')
{
((TMP_Text)myText).text = itemText;
((TMP_Text)myText).fontStyle = (FontStyles)0;
iconImage.sprite = icon;
iconObject.SetActive((Object)(object)icon != (Object)null);
((TMP_Text)iconAltImage).text = (((Object)(object)icon == (Object)null) ? altIcon.ToString() : string.Empty);
iconAltObject.SetActive((Object)(object)icon == (Object)null);
ui_object.SetActive(true);
}
public void Show(CustomizationPickup item, bool reveal = true)
{
//IL_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_015f: Unknown result type (might be due to invalid IL or missing references)
//IL_0164: Unknown result type (might be due to invalid IL or missing references)
//IL_0166: Unknown result type (might be due to invalid IL or missing references)
//IL_0168: Unknown result type (might be due to invalid IL or missing references)
//IL_016a: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Invalid comparison between Unknown and I4
itemID = item.ItemID;
if ((Object)(object)ui_object == (Object)null || (Object)(object)myText == (Object)null || (Object)(object)iconImage == (Object)null)
{
return;
}
if (!reveal)
{
SetItemUI("Undiscovered Item");
}
else if (itemsCollection != null && itemsCollection.Length >= 0)
{
if (itemID >= itemsCollection.Length)
{
throw new Exception("Out of itemID index to search");
}
CustomizationItem val = itemsCollection[itemID];
string itemText = $"#{itemID} " + ((!string.IsNullOrEmpty(val.Name)) ? val.Name : ((Object)val.icon).name).Replace("_", " ") + " " + $"({val.ItemRarity})";
BodyPart bodyPart = val.BodyPart;
BodyPart val2 = bodyPart;
if ((int)val2 == 100)
{
SetItemUI(itemText, null, '♫');
}
else
{
SetItemUI(itemText, val.Icon);
}
}
else
{
SetItemUI($"#{itemID} {FilterClone(((Object)item).name)}");
}
}
public void Pickup(ushort itemID)
{
if (this.itemID == itemID)
{
MelonLogger.Msg("Picked item up");
((TMP_Text)myText).fontStyle = (FontStyles)64;
}
}
public void Clear()
{
if (!((Object)(object)ui_object == (Object)null) && !((Object)(object)myText == (Object)null))
{
ui_object.SetActive(false);
((TMP_Text)myText).text = string.Empty;
((TMP_Text)myText).fontStyle = (FontStyles)0;
iconImage.sprite = null;
iconObject.SetActive(false);
((TMP_Text)iconAltImage).text = string.Empty;
iconAltObject.SetActive(false);
}
}
public bool IsDestroy()
{
return (Object)(object)ui_object == (Object)null;
}
private static string FilterClone(string name)
{
if (name.EndsWith("(Clone)"))
{
int length = "(Clone)".Length;
return name.Substring(0, name.Length - length).Replace("_", " ");
}
return name;
}
}
public static class UIUtils
{
public static TMP_FontAsset GetFontByName(string name)
{
return ((IEnumerable<TMP_FontAsset>)Resources.FindObjectsOfTypeAll<TMP_FontAsset>()).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => ((Object)f).name.Equals(name, StringComparison.OrdinalIgnoreCase)));
}
}
}
namespace TellMeCosmetics.Config
{
public static class ConfigManager
{
private static readonly string configPath = Path.Combine(MelonEnvironment.UserDataDirectory, "TellMeCosmetics.cfg");
public static GameplayConfig Load()
{
MelonPreferences_Category val = MelonPreferences.CreateCategory("Gameplay");
val.SetFilePath(configPath);
return new GameplayConfig(val);
}
}
public class GameplayConfig
{
public MelonPreferences_Entry<bool> RevealAll { get; set; }
public GameplayConfig(MelonPreferences_Category category)
{
RevealAll = category.CreateEntry<bool>("RevealAllItems", false, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
}
}
}