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 UnlockAwareness v1.2.1
UnlockAwareness.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("UnlockAwareness")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.2.1.0")] [assembly: AssemblyInformationalVersion("1.2.1+a45c570d17c512d77d75166ff42bc1dee72ef243")] [assembly: AssemblyProduct("UnlockAwareness")] [assembly: AssemblyTitle("UnlockAwareness")] [assembly: AssemblyVersion("1.2.1.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 UnlockAwareness { [HarmonyPatch(typeof(Player), "OnSpawned")] internal static class FlagAllKnown { private static readonly FieldRef<Player, HashSet<string>> KnownRecipesRef = AccessTools.FieldRefAccess<Player, HashSet<string>>("m_knownRecipes"); [HarmonyPostfix] private static void Postfix(Player __instance) { if (UnlockAwarenessPlugin.FlagAllKnownOnce.Value && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !((Object)(object)ObjectDB.instance == (Object)null) && UnseenStore.FlagAllOnce(CollectKnownKeys(__instance))) { UnlockAwarenessPlugin.Log.LogInfo((object)"Flagged all known recipes and pieces as new for this character"); } } private static List<string> CollectKnownKeys(Player player) { HashSet<string> hashSet = KnownRecipesRef.Invoke(player); List<string> list = new List<string>(); foreach (Recipe recipe in ObjectDB.instance.m_recipes) { if (!((Object)(object)recipe == (Object)null) && !((Object)(object)recipe.m_item == (Object)null)) { string name = recipe.m_item.m_itemData.m_shared.m_name; if (hashSet.Contains(name)) { list.Add(UnseenStore.MakeKey(UnlockKind.Recipe, name)); } } } foreach (GameObject item in ObjectDB.instance.m_items) { PieceTable val = ((item == null) ? null : item.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_buildPieces); if ((Object)(object)val == (Object)null) { continue; } foreach (GameObject piece in val.m_pieces) { Piece val2 = (((Object)(object)piece != (Object)null) ? piece.GetComponent<Piece>() : null); if ((Object)(object)val2 != (Object)null && hashSet.Contains(val2.m_name)) { list.Add(UnseenStore.MakeKey(UnlockKind.Piece, val2.m_name)); } } } return list; } } [HarmonyPatch] internal static class UnlockTrackingPatches { [HarmonyPatch(typeof(Player), "AddKnownRecipe")] [HarmonyPrefix] private static void AddKnownRecipe_Prefix(Player __instance, Recipe recipe, out bool __state) { __state = !__instance.IsRecipeKnown(recipe.m_item.m_itemData.m_shared.m_name); } [HarmonyPatch(typeof(Player), "AddKnownRecipe")] [HarmonyPostfix] private static void AddKnownRecipe_Postfix(Player __instance, Recipe recipe, bool __state) { string name = recipe.m_item.m_itemData.m_shared.m_name; if (__state && (Object)(object)__instance == (Object)(object)Player.m_localPlayer && __instance.IsRecipeKnown(name)) { UnseenStore.MarkUnseen(UnlockKind.Recipe, name); } } [HarmonyPatch(typeof(Player), "AddKnownPiece")] [HarmonyPrefix] private static void AddKnownPiece_Prefix(Player __instance, Piece piece, out bool __state) { __state = !__instance.IsRecipeKnown(piece.m_name); } [HarmonyPatch(typeof(Player), "AddKnownPiece")] [HarmonyPostfix] private static void AddKnownPiece_Postfix(Player __instance, Piece piece, bool __state) { if (__state && (Object)(object)__instance == (Object)(object)Player.m_localPlayer && __instance.IsRecipeKnown(piece.m_name)) { UnseenStore.MarkUnseen(UnlockKind.Piece, piece.m_name); } } [HarmonyPatch(typeof(Player), "AddKnownItem")] [HarmonyPrefix] private static void AddKnownItem_Prefix(Player __instance, ItemData item, out bool __state) { __state = item != null && !__instance.IsKnownMaterial(item.m_shared.m_name); } [HarmonyPatch(typeof(Player), "AddKnownItem")] [HarmonyPostfix] private static void AddKnownItem_Postfix(Player __instance, ItemData item, bool __state) { if (__state && UnlockAwarenessPlugin.InventoryBadges.Value && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { UnseenStore.MarkUnseen(UnlockKind.Item, item.m_shared.m_name); } } } [HarmonyPatch] internal static class InventoryPatches { private static readonly FieldRef<InventoryGrid, List<InventoryElement>> ElementsRef = AccessTools.FieldRefAccess<InventoryGrid, List<InventoryElement>>("m_elements"); private static readonly FieldRef<InventoryGui, InventoryGrid> ContainerGridRef = AccessTools.FieldRefAccess<InventoryGui, InventoryGrid>("m_containerGrid"); private static readonly Action<Player> UpdateKnownRecipesList = AccessTools.MethodDelegate<Action<Player>>(AccessTools.Method(typeof(Player), "UpdateKnownRecipesList", (Type[])null, (Type[])null), (object)null, true); private static readonly Dictionary<InventoryElement, UnseenBadge> s_badges = new Dictionary<InventoryElement, UnseenBadge>(); private static readonly Dictionary<InventoryElement, GameObject> s_unknownBadges = new Dictionary<InventoryElement, GameObject>(); private static ItemData[] s_slots = (ItemData[])(object)new ItemData[0]; private static int s_width; [HarmonyPatch(typeof(InventoryGrid), "UpdateGui")] [HarmonyPostfix] private static void UpdateGui_Postfix(InventoryGrid __instance) { InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null) { return; } bool flag = (Object)(object)__instance == (Object)(object)ContainerGridRef.Invoke(instance); if (flag || !((Object)(object)__instance != (Object)(object)instance.m_playerGrid)) { if (flag && UnlockAwarenessPlugin.LearnFromContainers.Value) { LearnItems(__instance.GetInventory()); } FillSlots(__instance.GetInventory()); UpdateNewBadges(__instance); if (flag) { UpdateUnknownBadges(__instance); } } } private static void FillSlots(Inventory inventory) { if (inventory == null) { s_width = 0; Array.Clear(s_slots, 0, s_slots.Length); return; } s_width = inventory.GetWidth(); int num = s_width * inventory.GetHeight(); if (s_slots.Length < num) { s_slots = (ItemData[])(object)new ItemData[num]; } Array.Clear(s_slots, 0, s_slots.Length); foreach (ItemData allItem in inventory.GetAllItems()) { int num2 = allItem.m_gridPos.y * s_width + allItem.m_gridPos.x; if (num2 >= 0 && num2 < num) { s_slots[num2] = allItem; } } } private static ItemData ItemIn(InventoryElement element) { //IL_0012: 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) if (!element.m_used || s_width == 0) { return null; } int num = element.Position.y * s_width + element.Position.x; if (num < 0 || num >= s_slots.Length) { return null; } return s_slots[num]; } private static void LearnItems(Inventory inventory) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || inventory == null) { return; } bool flag = false; foreach (ItemData allItem in inventory.GetAllItems()) { if (!localPlayer.IsKnownMaterial(allItem.m_shared.m_name)) { localPlayer.AddKnownItem(allItem); flag = true; } } if (flag) { UpdateKnownRecipesList(localPlayer); } } private static void UpdateNewBadges(InventoryGrid grid) { //IL_008e: 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) bool flag = UnlockAwarenessPlugin.InventoryBadges.Value && UnseenStore.HasAnyUnseen; foreach (InventoryElement item in ElementsRef.Invoke(grid)) { ItemData val = (flag ? ItemIn(item) : null); bool flag2 = val != null && UnseenStore.IsUnseenItem(val.m_shared.m_name); if (!s_badges.TryGetValue(item, out var value) || (Object)(object)value == (Object)null) { if (!flag2) { continue; } value = UiFactory.GetOrCreateBadge(((Component)item).transform, 18f, new Vector2(0.5f, 1f), new Vector2(0f, -10f)); Remember<UnseenBadge>(s_badges, item, value); } if (flag2) { if (!ShowsItem(value, val.m_shared.m_name)) { value.Show(UnseenStore.MakeKey(UnlockKind.Item, val.m_shared.m_name)); } } else if (((Component)value).gameObject.activeSelf) { value.Hide(); } } } private static bool ShowsItem(UnseenBadge badge, string name) { if (((Component)badge).gameObject.activeSelf && badge.Key != null && badge.Key.Length == name.Length + 2 && badge.Key.StartsWith("i:", StringComparison.Ordinal)) { return badge.Key.EndsWith(name, StringComparison.Ordinal); } return false; } private static void UpdateUnknownBadges(InventoryGrid grid) { //IL_00a0: 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) Player localPlayer = Player.m_localPlayer; bool flag = UnlockAwarenessPlugin.ContainerBadges.Value && (Object)(object)localPlayer != (Object)null; foreach (InventoryElement item in ElementsRef.Invoke(grid)) { ItemData val = (flag ? ItemIn(item) : null); bool flag2 = val != null && !localPlayer.IsKnownMaterial(val.m_shared.m_name); if (!s_unknownBadges.TryGetValue(item, out var value) || (Object)(object)value == (Object)null) { if (!flag2) { continue; } value = UiFactory.GetOrCreateUnknownBadge(((Component)item).transform, item.m_amount, 22f, new Vector2(0.5f, 1f), new Vector2(0f, -11f)); Remember<GameObject>(s_unknownBadges, item, value); } if (value.activeSelf != flag2) { value.SetActive(flag2); } } } private static void Remember<T>(Dictionary<InventoryElement, T> badges, InventoryElement element, T badge) where T : Object { badges[element] = badge; if (badges.Count <= 256) { return; } List<InventoryElement> list = new List<InventoryElement>(); foreach (KeyValuePair<InventoryElement, T> badge2 in badges) { if ((Object)(object)badge2.Key == (Object)null || (Object)(object)badge2.Value == (Object)null) { list.Add(badge2.Key); } } foreach (InventoryElement item in list) { badges.Remove(item); } } [HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")] [HarmonyPrefix] private static void OnSelectedItem_Prefix(InventoryGui __instance, InventoryGrid grid, ItemData item) { MarkSeen(__instance, grid, item); } [HarmonyPatch(typeof(InventoryGui), "OnRightClickItem")] [HarmonyPrefix] private static void OnRightClickItem_Prefix(InventoryGui __instance, InventoryGrid grid, ItemData item) { MarkSeen(__instance, grid, item); } private static void MarkSeen(InventoryGui gui, InventoryGrid grid, ItemData item) { if (item != null && ((Object)(object)grid == (Object)(object)gui.m_playerGrid || (Object)(object)grid == (Object)(object)ContainerGridRef.Invoke(gui))) { UnseenStore.MarkSeen(UnseenStore.MakeKey(UnlockKind.Item, item.m_shared.m_name)); } } } [HarmonyPatch(typeof(InventoryGui))] internal static class CraftingPatches { private static MarkAllButton s_markAllButton; private static readonly HashSet<string> s_listedUnseen = new HashSet<string>(); [HarmonyPatch("Awake")] [HarmonyPostfix] private static void Awake_Postfix(InventoryGui __instance) { s_listedUnseen.Clear(); s_markAllButton = UiFactory.CreateCraftingMarkAllButton(__instance, delegate { MarkAllSeen(__instance); }); RefreshButton(); } [HarmonyPatch("UpdateRecipeList")] [HarmonyPrefix] private static void UpdateRecipeList_Prefix() { s_listedUnseen.Clear(); } [HarmonyPatch("UpdateRecipeList")] [HarmonyPostfix] private static void UpdateRecipeList_Postfix() { RefreshButton(); } [HarmonyPatch("AddRecipeToList")] [HarmonyPostfix] private static void AddRecipeToList_Postfix(InventoryGui __instance, Recipe recipe, ItemData item) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) Transform recipeListRoot = (Transform)(object)__instance.m_recipeListRoot; if (recipeListRoot.childCount != 0) { Transform child = recipeListRoot.GetChild(recipeListRoot.childCount - 1); UnseenBadge orCreateBadge = UiFactory.GetOrCreateBadge(child.Find("icon") ?? child, 16f, new Vector2(1f, 1f), new Vector2(-4f, -6f)); string name = recipe.m_item.m_itemData.m_shared.m_name; if (item == null && UnseenStore.IsUnseen(UnlockKind.Recipe, name)) { string text = UnseenStore.MakeKey(UnlockKind.Recipe, name); orCreateBadge.Show(text); s_listedUnseen.Add(text); } else { orCreateBadge.Hide(); } } } [HarmonyPatch("OnSelectedRecipe")] [HarmonyPostfix] private static void OnSelectedRecipe_Postfix(GameObject button) { UnseenBadge unseenBadge = (((Object)(object)button != (Object)null) ? button.GetComponentInChildren<UnseenBadge>(true) : null); if ((Object)(object)unseenBadge == (Object)null) { return; } string key = unseenBadge.Key; if (!unseenBadge.Consume()) { return; } UnseenBadge[] componentsInChildren = ((Component)button.transform.parent).GetComponentsInChildren<UnseenBadge>(true); foreach (UnseenBadge unseenBadge2 in componentsInChildren) { if (unseenBadge2.Key == key) { unseenBadge2.Hide(); } } s_listedUnseen.Remove(key); RefreshButton(); } private static void MarkAllSeen(InventoryGui gui) { UnseenStore.MarkSeen(s_listedUnseen); s_listedUnseen.Clear(); UnseenBadge[] componentsInChildren = ((Component)gui.m_recipeListRoot).GetComponentsInChildren<UnseenBadge>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].Hide(); } RefreshButton(); } private static void RefreshButton() { s_markAllButton?.Refresh(s_listedUnseen.Count); } } [HarmonyPatch] internal static class BuildPatches { private static readonly FieldRef<BuildUi, RectTransform> SpecialButtonsRef; private static readonly FieldRef<BuildUi, GameObject> PieceButtonPrefabRef; private static MarkAllButton s_markAllButton; static BuildPatches() { SpecialButtonsRef = AccessTools.FieldRefAccess<BuildUi, RectTransform>("m_specialButtonsContainer"); PieceButtonPrefabRef = AccessTools.FieldRefAccess<BuildUi, GameObject>("m_pieceButtonPrefab"); UnseenStore.Changed += RefreshButton; } [HarmonyPatch(typeof(BuildUiPieceButton), "Setup")] [HarmonyPostfix] private static void PieceButtonSetup_Postfix(BuildUiPieceButton __instance, Piece pieceInfo) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) UnseenBadge orCreateBadge = UiFactory.GetOrCreateBadge(((Component)__instance).transform, 20f, new Vector2(1f, 1f), new Vector2(-10f, -13f)); if ((Object)(object)pieceInfo != (Object)null && UnseenStore.IsUnseen(UnlockKind.Piece, pieceInfo.m_name)) { orCreateBadge.Show(UnseenStore.MakeKey(UnlockKind.Piece, pieceInfo.m_name)); } else { orCreateBadge.Hide(); } } [HarmonyPatch(typeof(BuildUi), "OnSelectPiece")] [HarmonyPrefix] private static void OnSelectPiece_Prefix(BuildUi __instance, Piece piece) { if (!((Object)(object)piece == (Object)null)) { string key = UnseenStore.MakeKey(UnlockKind.Piece, piece.m_name); UnseenStore.MarkSeen(key); HideBadges(__instance, key); } } [HarmonyPatch(typeof(BuildUi), "OpenBuildMenu")] [HarmonyPostfix] private static void OpenBuildMenu_Postfix(BuildUi __instance) { if ((Object)(object)s_markAllButton?.Button == (Object)null) { RectTransform val = SpecialButtonsRef.Invoke(__instance); s_markAllButton = UiFactory.CreateBuildMarkAllButton(PieceButtonPrefabRef.Invoke(__instance), ((Object)(object)val != (Object)null) ? ((Transform)val).parent : null, delegate { MarkAllSeen(__instance); }); } RefreshButton(); } private static IEnumerable<string> UnseenKeysForCurrentTool() { PieceTable val = (((Object)(object)Player.m_localPlayer != (Object)null) ? Player.m_localPlayer.GetBuildTool() : null); if ((Object)(object)val == (Object)null) { yield break; } foreach (Piece availablePiece in val.m_availablePieces) { if ((Object)(object)availablePiece != (Object)null && UnseenStore.IsUnseen(UnlockKind.Piece, availablePiece.m_name)) { yield return UnseenStore.MakeKey(UnlockKind.Piece, availablePiece.m_name); } } } private static void MarkAllSeen(BuildUi buildUi) { UnseenStore.MarkSeen(UnseenKeysForCurrentTool().ToList()); HideBadges(buildUi, null); } private static void HideBadges(BuildUi buildUi, string key) { UnseenBadge[] componentsInChildren = ((Component)buildUi).GetComponentsInChildren<UnseenBadge>(true); foreach (UnseenBadge unseenBadge in componentsInChildren) { if (key == null || unseenBadge.Key == key) { unseenBadge.Hide(); } } } private static void RefreshButton() { s_markAllButton?.Refresh(UnseenKeysForCurrentTool().Count()); } } [BepInPlugin("com.koendertjh.unlockawareness", "UnlockAwareness", "1.2.1")] public class UnlockAwarenessPlugin : BaseUnityPlugin { public const string ModGuid = "com.koendertjh.unlockawareness"; public const string ModName = "UnlockAwareness"; public const string ModVersion = "1.2.1"; internal static ManualLogSource Log; internal static ConfigEntry<bool> FlagAllKnownOnce; internal static ConfigEntry<bool> InventoryBadges; internal static ConfigEntry<bool> ContainerBadges; internal static ConfigEntry<bool> LearnFromContainers; internal static ConfigEntry<Color> BadgeColor; private Harmony _harmony; private void Awake() { //IL_00af: 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_00d3: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; FlagAllKnownOnce = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "FlagAllKnownOnce", false, "If true, the first time each character loads in, every recipe and piece it already knows is marked as new. Runs once per character; use 'Mark all as seen' to clear them afterwards."); InventoryBadges = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "InventoryBadges", true, "If true, items you pick up for the first time get a '!' marker in your inventory until you click them. If false, no inventory markers are shown and new items are not recorded."); ContainerBadges = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ContainerBadges", true, "If true, items in a chest (or other container) that you have never had in your inventory get a '?' marker. The marker disappears once you take the item. Only used when LearnFromContainers is false."); LearnFromContainers = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "LearnFromContainers", true, "If true, opening a chest (or other container) counts as having the items inside: your character learns them as if picked up, which also unlocks any recipes and pieces they lead to, and they get a '!' right away. If false, unknown items show a '?' (see ContainerBadges) until you take them."); BadgeColor = ((BaseUnityPlugin)this).Config.Bind<Color>("Badge", "Color", new Color(1f, 0.62f, 0.1f, 1f), "Color of the '!' marker shown on newly unlocked recipes, pieces and items."); _harmony = new Harmony("com.koendertjh.unlockawareness"); _harmony.PatchAll(typeof(UnlockAwarenessPlugin).Assembly); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } internal class UnseenBadge : MonoBehaviour { public string Key; public void Show(string key) { Key = key; ((Component)this).gameObject.SetActive(true); } public void Hide() { Key = null; ((Component)this).gameObject.SetActive(false); } public bool Consume() { if (!((Component)this).gameObject.activeSelf || Key == null) { return false; } UnseenStore.MarkSeen(Key); Hide(); return true; } } internal class MarkAllButton { private const string TooltipText = "Mark all as seen"; public Button Button; public Image Icon; public GameObject Glow; public UITooltip Tooltip; private static Color EyeTint => UiFactory.EyeColor; public void Refresh(int count) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Button == (Object)null)) { ((Selectable)Button).interactable = count > 0; if ((Object)(object)Icon != (Object)null) { ((Graphic)Icon).color = (Color)((count > 0) ? EyeTint : new Color(EyeTint.r, EyeTint.g, EyeTint.b, 0.35f)); } if ((Object)(object)Glow != (Object)null) { Glow.SetActive(count > 0); } if ((Object)(object)Tooltip != (Object)null) { Tooltip.m_text = ((count > 0) ? string.Format("{0} ({1})", "Mark all as seen", count) : "Mark all as seen"); } } } public void SetTooltip(UITooltip tooltip) { Tooltip = tooltip; Tooltip.m_topic = ""; Tooltip.m_text = "Mark all as seen"; } } internal static class UiFactory { private const string BadgeName = "UnlockAwareness_Badge"; private const string UnknownBadgeName = "UnlockAwareness_Unknown"; private const string BadgeSpriteName = "exclamation_mark"; internal static readonly Color EyeColor = new Color(0.93f, 0.88f, 0.78f, 1f); private static readonly FieldRef<BuildUiPieceButton, Image> PieceIconRef = AccessTools.FieldRefAccess<BuildUiPieceButton, Image>("m_icon"); private static readonly FieldRef<BuildUiPieceButton, Image> PieceUpgradeArrowRef = AccessTools.FieldRefAccess<BuildUiPieceButton, Image>("m_upgradeArrow"); private static readonly FieldRef<BuildUiPieceButton, Image> PieceFavoriteStarRef = AccessTools.FieldRefAccess<BuildUiPieceButton, Image>("m_favoriteStar"); private static readonly Dictionary<string, Sprite> s_sprites = new Dictionary<string, Sprite>(); private static Sprite s_eyeSprite; public static UnseenBadge GetOrCreateBadge(Transform parent, float height, Vector2 anchor, Vector2 offset) { //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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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_011d: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) Transform val = parent.Find("UnlockAwareness_Badge"); if ((Object)(object)val != (Object)null) { return ((Component)val).GetComponent<UnseenBadge>(); } GameObject val2 = new GameObject("UnlockAwareness_Badge", new Type[3] { typeof(RectTransform), typeof(Image), typeof(UnseenBadge) }); RectTransform val3 = (RectTransform)val2.transform; ((Transform)val3).SetParent(parent, false); Vector2 anchorMin = (val3.anchorMax = anchor); val3.anchorMin = anchorMin; val3.pivot = new Vector2(0.5f, 0.5f); val3.anchoredPosition = offset; ((Transform)val3).SetAsLastSibling(); Image component = val2.GetComponent<Image>(); ((Graphic)component).raycastTarget = false; ((Graphic)component).color = UnlockAwarenessPlugin.BadgeColor.Value; Sprite val5 = FindGameSprite("exclamation_mark"); if ((Object)(object)val5 != (Object)null) { component.sprite = val5; Rect rect = val5.rect; float num = height * ((Rect)(ref rect)).width; rect = val5.rect; val3.sizeDelta = new Vector2(num / ((Rect)(ref rect)).height, height); } else { component.sprite = CreateDotSprite(); val3.sizeDelta = new Vector2(height * 0.8f, height * 0.8f); } Outline obj = val2.AddComponent<Outline>(); ((Shadow)obj).effectColor = new Color(0f, 0f, 0f, 0.9f); ((Shadow)obj).effectDistance = new Vector2(1.2f, -1.2f); UnseenBadge component2 = val2.GetComponent<UnseenBadge>(); component2.Hide(); return component2; } public static GameObject GetOrCreateUnknownBadge(Transform parent, TMP_Text styleSource, float fontSize, Vector2 anchor, Vector2 offset) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_0069: 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_007e: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00df: 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_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Expected O, but got Unknown Transform val = parent.Find("UnlockAwareness_Unknown"); if ((Object)(object)val != (Object)null) { return ((Component)val).gameObject; } GameObject val2 = new GameObject("UnlockAwareness_Unknown", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); RectTransform val3 = (RectTransform)val2.transform; ((Transform)val3).SetParent(parent, false); Vector2 anchorMin = (val3.anchorMax = anchor); val3.anchorMin = anchorMin; val3.pivot = new Vector2(0.5f, 0.5f); val3.anchoredPosition = offset; val3.sizeDelta = new Vector2(fontSize, fontSize); ((Transform)val3).SetAsLastSibling(); TextMeshProUGUI component = val2.GetComponent<TextMeshProUGUI>(); if ((Object)(object)styleSource != (Object)null) { ((TMP_Text)component).font = styleSource.font; ((TMP_Text)component).fontSharedMaterial = styleSource.fontSharedMaterial; } ((TMP_Text)component).text = "?"; ((TMP_Text)component).fontSize = fontSize; ((TMP_Text)component).fontStyle = (FontStyles)1; ((Graphic)component).color = UnlockAwarenessPlugin.BadgeColor.Value; ((TMP_Text)component).alignment = (TextAlignmentOptions)514; ((TMP_Text)component).textWrappingMode = (TextWrappingModes)0; ((Graphic)component).raycastTarget = false; ((TMP_Text)component).outlineColor = Color32.op_Implicit(new Color(0f, 0f, 0f, 0.9f)); ((TMP_Text)component).outlineWidth = 0.25f; val2.SetActive(false); return val2; } public static MarkAllButton CreateCraftingMarkAllButton(InventoryGui gui, Action onClick) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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_009b: 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_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_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Expected O, but got Unknown //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Expected O, but got Unknown Button repairButton = gui.m_repairButton; if ((Object)(object)repairButton == (Object)null) { return null; } RectTransform val = (RectTransform)((Component)repairButton).transform; Transform obj = ((Transform)gui.m_crafting).Find("RepairSimple"); RectTransform val2 = (RectTransform)(object)((obj is RectTransform) ? obj : null); float num = (((Object)(object)val2 != (Object)null) ? val2.sizeDelta.y : (val.sizeDelta.y + 16f)); if ((Object)(object)val2 != (Object)null) { GameObject obj2 = Object.Instantiate<GameObject>(((Component)val2).gameObject, ((Transform)val2).parent, false); ((Object)obj2).name = "UnlockAwareness_MarkAllBacking"; RectTransform val3 = (RectTransform)obj2.transform; val3.anchoredPosition = val2.anchoredPosition - new Vector2(0f, num); ((Transform)val3).SetSiblingIndex(((Transform)val2).GetSiblingIndex() + 1); obj2.SetActive(true); } GameObject val4 = Object.Instantiate<GameObject>(((Component)repairButton).gameObject, ((Component)repairButton).transform.parent, false); ((Object)val4).name = "UnlockAwareness_MarkAllCrafting"; ((RectTransform)val4.transform).anchoredPosition = val.anchoredPosition - new Vector2(0f, num); UIGamePad[] componentsInChildren = val4.GetComponentsInChildren<UIGamePad>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } Transform val5 = val4.transform.Find("gamepad_hint"); if ((Object)(object)val5 != (Object)null) { Object.Destroy((Object)(object)((Component)val5).gameObject); } Transform obj3 = val4.transform.Find("Image"); Image val6 = ((obj3 != null) ? ((Component)obj3).GetComponent<Image>() : null); SetEyeIcon(val6, 46f); MarkAllButton obj4 = new MarkAllButton { Button = val4.GetComponent<Button>(), Icon = val6 }; Transform obj5 = val4.transform.Find("Glow"); obj4.Glow = ((obj5 != null) ? ((Component)obj5).gameObject : null); UITooltip val7 = val4.GetComponent<UITooltip>() ?? val4.AddComponent<UITooltip>(); if ((Object)(object)val7.m_tooltipPrefab == (Object)null) { val7.m_tooltipPrefab = ((Component)repairButton).GetComponent<UITooltip>()?.m_tooltipPrefab; } obj4.SetTooltip(val7); obj4.Button.onClick = new ButtonClickedEvent(); ((UnityEvent)obj4.Button.onClick).AddListener((UnityAction)delegate { onClick(); }); val4.SetActive(true); return obj4; } public static MarkAllButton CreateBuildMarkAllButton(GameObject pieceButtonPrefab, Transform topBar, Action onClick) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Expected O, but got Unknown //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Expected O, but got Unknown if ((Object)(object)pieceButtonPrefab == (Object)null || (Object)(object)topBar == (Object)null) { return null; } GameObject val = new GameObject("UnlockAwareness_Holder"); val.SetActive(false); GameObject val2 = Object.Instantiate<GameObject>(pieceButtonPrefab, val.transform, false); ((Object)val2).name = "UnlockAwareness_MarkAllBuild"; BuildUiPieceButton component = val2.GetComponent<BuildUiPieceButton>(); Image val3 = PieceIconRef.Invoke(component); Image obj = PieceUpgradeArrowRef.Invoke(component); if (obj != null) { ((Component)obj).gameObject.SetActive(false); } Image obj2 = PieceFavoriteStarRef.Invoke(component); if (obj2 != null) { ((Component)obj2).gameObject.SetActive(false); } Object.DestroyImmediate((Object)(object)component); Object.DestroyImmediate((Object)(object)val2.GetComponent<UIInputHandler>()); val2.transform.SetParent(topBar, false); Object.Destroy((Object)(object)val); RectTransform val4 = (RectTransform)val2.transform; Rect rect = ((RectTransform)topBar).rect; float num = Mathf.Max(32f, ((Rect)(ref rect)).height); val4.sizeDelta = new Vector2(num, num); LayoutElement obj3 = val2.GetComponent<LayoutElement>() ?? val2.AddComponent<LayoutElement>(); float minWidth = (obj3.preferredWidth = num); obj3.minWidth = minWidth; minWidth = (obj3.preferredHeight = num); obj3.minHeight = minWidth; minWidth = (obj3.flexibleHeight = 0f); obj3.flexibleWidth = minWidth; val2.transform.SetAsLastSibling(); SetEyeIcon(val3, num * 0.75f); MarkAllButton obj4 = new MarkAllButton { Button = val2.GetComponent<Button>(), Icon = val3 }; ColorBlock colors = ((Selectable)obj4.Button).colors; ((ColorBlock)(ref colors)).disabledColor = ((ColorBlock)(ref colors)).normalColor; ((Selectable)obj4.Button).colors = colors; UITooltip val5 = val2.AddComponent<UITooltip>(); InventoryGui instance = InventoryGui.instance; object tooltipPrefab; if (instance == null) { tooltipPrefab = null; } else { Button repairButton = instance.m_repairButton; tooltipPrefab = ((repairButton == null) ? null : ((Component)repairButton).GetComponent<UITooltip>()?.m_tooltipPrefab); } val5.m_tooltipPrefab = (GameObject)tooltipPrefab; obj4.SetTooltip(val5); obj4.Button.onClick = new ButtonClickedEvent(); ((UnityEvent)obj4.Button.onClick).AddListener((UnityAction)delegate { onClick(); }); val2.SetActive(true); return obj4; } private static void SetEyeIcon(Image image, float width) { //IL_0039: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)image == (Object)null)) { Sprite val = (image.sprite = (((Object)(object)s_eyeSprite != (Object)null) ? s_eyeSprite : (s_eyeSprite = CreateEyeSprite()))); image.preserveAspect = true; ((Graphic)image).color = EyeColor; RectTransform rectTransform = ((Graphic)image).rectTransform; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0.5f, 0.5f); rectTransform.pivot = val3; Vector2 anchorMin = (rectTransform.anchorMax = val3); rectTransform.anchorMin = anchorMin; rectTransform.anchoredPosition = Vector2.zero; RectTransform rectTransform2 = ((Graphic)image).rectTransform; Rect rect = val.rect; float num = width * ((Rect)(ref rect)).height; rect = val.rect; rectTransform2.sizeDelta = new Vector2(width, num / ((Rect)(ref rect)).width); } } private static Sprite FindGameSprite(string name) { if (s_sprites.TryGetValue(name, out var value) && (Object.op_Implicit((Object)(object)value) || value == null)) { return value; } Sprite[] array = Resources.FindObjectsOfTypeAll<Sprite>(); foreach (Sprite val in array) { if (((Object)val).name == name) { return s_sprites[name] = val; } } UnlockAwarenessPlugin.Log.LogWarning((object)("Sprite '" + name + "' not found, using fallback")); return s_sprites[name] = null; } private static Sprite CreateDotSprite() { return CreateSprite(32, 32, delegate(int x, int y) { //IL_0004: 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) float num = Vector2.Distance(new Vector2((float)x, (float)y), new Vector2(15.5f, 15.5f)); return Mathf.Clamp01(15f - num + 0.5f); }); } private static Sprite CreateEyeSprite() { float radius = 155.92592f; float offset = radius - 54f; float cx = 127.5f; float cy = 63.5f; return CreateSprite(256, 128, delegate(int x, int y) { float num = (float)x - cx; float num2 = (float)y - cy; float num3 = Mathf.Max(Hypot(num, num2 + offset) - radius, Hypot(num, num2 - offset) - radius); float signedDistance = Mathf.Abs(num3 + 4.5f) - 4.5f; float num4 = Mathf.Max(Hypot(num, num2) - 33f, num3 + 9f + 7f); float num5 = Hypot(num - 11f, num2 - 11f) - 6.5f; num4 = Mathf.Max(num4, 0f - num5); return Mathf.Max(Coverage(signedDistance), Coverage(num4)); }, mipmaps: true); } private static float Hypot(float x, float y) { return Mathf.Sqrt(x * x + y * y); } private static float Coverage(float signedDistance) { return Mathf.Clamp01(0.5f - signedDistance); } private static Sprite CreateSprite(int width, int height, Func<int, int, float> alpha, bool mipmaps = false) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //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_0040: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(width, height, (TextureFormat)4, mipmaps) { filterMode = (FilterMode)((!mipmaps) ? 1 : 2), wrapMode = (TextureWrapMode)1 }; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { val.SetPixel(j, i, new Color(1f, 1f, 1f, alpha(j, i))); } } val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, (float)width, (float)height), new Vector2(0.5f, 0.5f)); } } public enum UnlockKind { Recipe, Piece, Item } internal static class UnseenStore { private const string CustomDataKey = "UnlockAwareness_Unseen"; private const string FlaggedAllKey = "UnlockAwareness_FlaggedAllKnown"; private const char Separator = ';'; private static readonly HashSet<string> s_unseen = new HashSet<string>(); private static Player s_owner; private static readonly HashSet<string> s_items = new HashSet<string>(); private static int s_version; private static int s_itemsVersion = -1; public static bool HasAnyUnseen { get { if (Sync()) { return s_unseen.Count > 0; } return false; } } public static event Action Changed; public static string MakeKey(UnlockKind kind, string name) { return kind switch { UnlockKind.Piece => "p:", UnlockKind.Recipe => "r:", _ => "i:", } + name; } public static bool IsUnseen(UnlockKind kind, string name) { if (Sync()) { return s_unseen.Contains(MakeKey(kind, name)); } return false; } public static bool IsUnseenItem(string name) { if (!Sync()) { return false; } if (s_itemsVersion != s_version) { s_items.Clear(); foreach (string item in s_unseen) { if (item.StartsWith("i:", StringComparison.Ordinal)) { s_items.Add(item.Substring(2)); } } s_itemsVersion = s_version; } return s_items.Contains(name); } public static void MarkUnseen(UnlockKind kind, string name) { if (Sync() && s_unseen.Add(MakeKey(kind, name))) { Save(); } } public static bool FlagAllOnce(IEnumerable<string> keys) { if (!Sync() || s_owner.m_customData.ContainsKey("UnlockAwareness_FlaggedAllKnown")) { return false; } s_owner.m_customData["UnlockAwareness_FlaggedAllKnown"] = "1"; foreach (string key in keys) { s_unseen.Add(key); } Save(); return true; } public static void MarkSeen(string key) { if (Sync() && s_unseen.Remove(key)) { Save(); } } public static void MarkSeen(IEnumerable<string> keys) { if (!Sync()) { return; } bool flag = false; foreach (string key in keys) { flag |= s_unseen.Remove(key); } if (flag) { Save(); } } private static bool Sync() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return false; } if ((Object)(object)s_owner == (Object)(object)localPlayer) { return true; } s_owner = localPlayer; s_unseen.Clear(); s_version++; if (localPlayer.m_customData.TryGetValue("UnlockAwareness_Unseen", out var value) && !string.IsNullOrEmpty(value)) { string[] array = value.Split(new char[1] { ';' }); foreach (string text in array) { if (text.Length > 0) { s_unseen.Add(text); } } } return true; } private static void Save() { s_version++; if (s_unseen.Count == 0) { s_owner.m_customData.Remove("UnlockAwareness_Unseen"); } else { s_owner.m_customData["UnlockAwareness_Unseen"] = string.Join(';'.ToString(), s_unseen); } UnseenStore.Changed?.Invoke(); } } internal static class PluginInfo { public const string Version = "1.2.1"; } }