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 PinThoseRecipes v1.0.0
plugins/PinThoseRecipes.dll
Decompiled 4 days 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.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using PinThoseRecipes.Patches; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("PinThoseRecipes")] [assembly: AssemblyDescription("Middle-click recipes in a crafting station to pin them to a Subnautica-style panel under the minimap.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("PinThoseRecipes")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("7b2c4e1a-9d3f-4b6e-8a21-1c5d9f0e7a34")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [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 PinThoseRecipes { [BepInPlugin("shadymods.pinthoserecipes", "Pin Those Recipes", "1.0.0")] public sealed class PinThoseRecipesPlugin : BaseUnityPlugin { internal const string Guid = "shadymods.pinthoserecipes"; internal const string Name = "Pin Those Recipes"; internal const string Version = "1.0.0"; private static GameObject _controllerGo; private Harmony _harmony; internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; PinConfig.Init(((BaseUnityPlugin)this).Config); _harmony = new Harmony("shadymods.pinthoserecipes"); try { _harmony.PatchAll(typeof(PinThoseRecipesPlugin).Assembly); } catch (Exception ex) { Log.LogError((object)("Harmony patching failed (some features may be disabled): " + ex)); } _controllerGo = new GameObject("PinThoseRecipes_Controller"); Object.DontDestroyOnLoad((Object)(object)_controllerGo); ((Object)_controllerGo).hideFlags = (HideFlags)61; _controllerGo.AddComponent<PinnedPanelController>(); Log.LogInfo((object)"Pin Those Recipes 1.0.0 loaded."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } if ((Object)(object)_controllerGo != (Object)null) { Object.Destroy((Object)(object)_controllerGo); _controllerGo = null; } } } internal static class PinConfig { private static bool _resettingClearToggle; private static Color _satisfied = new Color(0.3f, 0.88f, 0.3f, 1f); private static Color _missing = new Color(1f, 0.42f, 0.42f, 1f); private static Color _name = Color.white; internal static ConfigEntry<bool> Enabled { get; private set; } internal static ConfigEntry<bool> PlayPinSound { get; private set; } internal static ConfigEntry<int> MaxPinnedRecipes { get; private set; } internal static ConfigEntry<float> PanelScale { get; private set; } internal static ConfigEntry<float> OffsetX { get; private set; } internal static ConfigEntry<float> ExtraOffsetBelowMinimap { get; private set; } internal static ConfigEntry<float> InventoryOpenShiftLeft { get; private set; } internal static ConfigEntry<float> InventoryOpenShiftDown { get; private set; } internal static ConfigEntry<string> SatisfiedColorHex { get; private set; } internal static ConfigEntry<string> MissingColorHex { get; private set; } internal static ConfigEntry<string> NameColorHex { get; private set; } internal static ConfigEntry<bool> ClearActiveCharacterPins { get; private set; } internal static Color SatisfiedColor => _satisfied; internal static Color MissingColor => _missing; internal static Color NameColor => _name; internal static event Action Changed; internal static void Init(ConfigFile config) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown Enabled = config.Bind<bool>("General", "Enabled", true, "Master toggle for Pin Those Recipes. When false, no pinning UI is shown or created."); PlayPinSound = config.Bind<bool>("General", "PlayPinSound", true, "Play a soft UI sound when you pin or unpin a recipe."); MaxPinnedRecipes = config.Bind<int>("Panel", "MaxPinnedRecipes", 8, new ConfigDescription("How many pinned recipes are shown in the side panel at once. Extra pins are kept and shown as a '+X more' row.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), Array.Empty<object>())); PanelScale = config.Bind<float>("Panel", "PanelScale", 1f, new ConfigDescription("Overall scale of the pinned-recipes panel content.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>())); OffsetX = config.Bind<float>("Panel", "OffsetX", -14f, "Horizontal offset of the panel from the top-right corner (negative moves left, in UI units)."); ExtraOffsetBelowMinimap = config.Bind<float>("Panel", "ExtraOffsetBelowMinimap", -14f, "Additional vertical offset applied below the minimap (negative moves further down, in UI units)."); InventoryOpenShiftLeft = config.Bind<float>("Panel", "InventoryOpenShiftLeft", 640f, "How far LEFT the panel moves while the inventory/crafting screen is open, so it clears the crafting panel on the right (otherwise the pins are hidden behind it). Higher number = further left. Set to 0 to keep it on the right. (Negative moves right.)"); InventoryOpenShiftDown = config.Bind<float>("Panel", "InventoryOpenShiftDown", 170f, "How far DOWN the panel moves while the inventory/crafting screen is open. Higher number = further down. Default drops it below the repair button; increase it to clear other mods' inventory UI (e.g. Extra Slots by shudnal). (Negative moves up.)"); SatisfiedColorHex = config.Bind<string>("Colors", "SatisfiedColor", "#4CE04C", "Color of a material count when you have enough."); MissingColorHex = config.Bind<string>("Colors", "MissingColor", "#FF6B6B", "Color of a material count when you are missing some."); NameColorHex = config.Bind<string>("Colors", "NameColor", "#FFFFFF", "Color of the pinned item name text."); ClearActiveCharacterPins = config.Bind<bool>("Maintenance", "ClearActiveCharacterPins", false, "Set to true to clear ALL pins for the currently loaded character. Resets itself to false afterwards. Useful for removing stale/unresolved pins."); ClearActiveCharacterPins.SettingChanged += OnClearPinsToggled; ReparseColors(); config.SettingChanged += OnAnySettingChanged; } private static void OnAnySettingChanged(object sender, SettingChangedEventArgs e) { ReparseColors(); PinConfig.Changed?.Invoke(); } private static void OnClearPinsToggled(object sender, EventArgs e) { if (_resettingClearToggle || ClearActiveCharacterPins == null || !ClearActiveCharacterPins.Value) { return; } PinStore.ClearActivePins(); _resettingClearToggle = true; try { ClearActiveCharacterPins.Value = false; } finally { _resettingClearToggle = false; } } private static void ReparseColors() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_0056: 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) _satisfied = ParseOr(SatisfiedColorHex?.Value, _satisfied); _missing = ParseOr(MissingColorHex?.Value, _missing); _name = ParseOr(NameColorHex?.Value, _name); } private static Color ParseOr(string hex, Color fallback) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) Color result = default(Color); if (!string.IsNullOrEmpty(hex) && ColorUtility.TryParseHtmlString(hex, ref result)) { return result; } return fallback; } } internal sealed class PinStoreFile { public int Version = 1; public List<CharacterPinData> Characters = new List<CharacterPinData>(); } internal sealed class CharacterPinData { public string Profile; public List<string> Pins = new List<string>(); public List<string> BuildPins = new List<string>(); public List<string> Collapsed = new List<string>(); } internal static class PinStore { private static readonly List<string> _activePins = new List<string>(); private static readonly List<string> _activeBuildPins = new List<string>(); private static readonly HashSet<string> _collapsed = new HashSet<string>(); private static string _activeProfileKey; private static bool _loggedMalformed; private static string FilePath => Path.Combine(Paths.ConfigPath, "PinThoseRecipes_pins.json"); internal static bool HasActiveProfile => !string.IsNullOrEmpty(_activeProfileKey); internal static int TotalPinCount => _activePins.Count + _activeBuildPins.Count; internal static event Action PinsChanged; internal static IReadOnlyList<string> GetPins() { return _activePins; } internal static IReadOnlyList<string> GetBuildPins() { return _activeBuildPins; } internal static string CraftCollapseKey(string pinKey) { return pinKey; } internal static string BuildCollapseKey(string prefabName) { return "b:" + prefabName; } internal static string CraftPinKey(string prefabName) { return prefabName; } internal static string UpgradePinKey(string prefabName, int targetQuality) { return "u:" + prefabName + ":" + targetQuality; } internal static bool TryParseCraftPinKey(string pinKey, out string prefabName, out int upgradeQuality) { prefabName = null; upgradeQuality = 0; if (string.IsNullOrEmpty(pinKey)) { return false; } if (pinKey.Length > 2 && pinKey[0] == 'u' && pinKey[1] == ':') { int num = pinKey.LastIndexOf(':'); if (num <= 2 || num >= pinKey.Length - 1) { return false; } if (!int.TryParse(pinKey.Substring(num + 1), out var result) || result < 2) { return false; } prefabName = pinKey.Substring(2, num - 2); if (string.IsNullOrEmpty(prefabName)) { return false; } upgradeQuality = result; return true; } prefabName = pinKey; upgradeQuality = 0; return true; } internal static bool IsPinned(string pinKey) { if (!string.IsNullOrEmpty(pinKey)) { return _activePins.Contains(pinKey); } return false; } internal static bool IsBuildPinned(string prefabName) { if (!string.IsNullOrEmpty(prefabName)) { return _activeBuildPins.Contains(prefabName); } return false; } internal static bool IsCollapsed(string collapseKey) { if (!string.IsNullOrEmpty(collapseKey)) { return _collapsed.Contains(collapseKey); } return false; } internal static bool ToggleCollapsed(string collapseKey, bool isBuild, string prefabName) { if (string.IsNullOrEmpty(collapseKey) || !HasActiveProfile) { return true; } if (isBuild ? (!IsBuildPinned(prefabName)) : (!IsPinned(prefabName))) { return true; } bool result; if (_collapsed.Contains(collapseKey)) { _collapsed.Remove(collapseKey); result = true; } else { _collapsed.Add(collapseKey); result = false; } Save(); return result; } internal static int GetPinIndex(string prefabName) { if (string.IsNullOrEmpty(prefabName)) { return int.MaxValue; } int num = _activePins.IndexOf(prefabName); if (num >= 0) { return num; } return int.MaxValue; } internal static bool Toggle(string pinKey) { if (string.IsNullOrEmpty(pinKey) || !HasActiveProfile) { return false; } bool result; if (_activePins.Contains(pinKey)) { _activePins.Remove(pinKey); _collapsed.Remove(CraftCollapseKey(pinKey)); result = false; } else { _activePins.Add(pinKey); result = true; } Save(); PinStore.PinsChanged?.Invoke(); return result; } internal static bool ToggleBuild(string prefabName) { if (string.IsNullOrEmpty(prefabName) || !HasActiveProfile) { return false; } bool result; if (_activeBuildPins.Contains(prefabName)) { _activeBuildPins.Remove(prefabName); _collapsed.Remove(BuildCollapseKey(prefabName)); result = false; } else { _activeBuildPins.Add(prefabName); result = true; } Save(); PinStore.PinsChanged?.Invoke(); return result; } internal static void ClearActive() { bool num = _activePins.Count > 0 || _activeBuildPins.Count > 0; _activePins.Clear(); _activeBuildPins.Clear(); _collapsed.Clear(); _activeProfileKey = null; if (num) { PinStore.PinsChanged?.Invoke(); } } internal static void ClearActivePins() { if (HasActiveProfile && (_activePins.Count != 0 || _activeBuildPins.Count != 0)) { _activePins.Clear(); _activeBuildPins.Clear(); _collapsed.Clear(); Save(); PinStore.PinsChanged?.Invoke(); } } internal static void LoadForProfile(string profileKey) { profileKey = Normalize(profileKey); if (string.IsNullOrEmpty(profileKey)) { ClearActive(); } else { if (profileKey == _activeProfileKey) { return; } _activeProfileKey = profileKey; _activePins.Clear(); _activeBuildPins.Clear(); _collapsed.Clear(); CharacterPinData characterPinData = ReadFile().Characters.Find((CharacterPinData c) => c != null && Normalize(c.Profile) == profileKey); if (characterPinData?.Pins != null) { foreach (string pin in characterPinData.Pins) { if (!string.IsNullOrEmpty(pin) && !_activePins.Contains(pin)) { _activePins.Add(pin); } } } if (characterPinData?.BuildPins != null) { foreach (string buildPin in characterPinData.BuildPins) { if (!string.IsNullOrEmpty(buildPin) && !_activeBuildPins.Contains(buildPin)) { _activeBuildPins.Add(buildPin); } } } if (characterPinData?.Collapsed != null) { foreach (string item2 in characterPinData.Collapsed) { if (string.IsNullOrEmpty(item2)) { continue; } if (item2.StartsWith("b:", StringComparison.Ordinal)) { string item = item2.Substring(2); if (_activeBuildPins.Contains(item)) { _collapsed.Add(item2); } } else if (_activePins.Contains(item2)) { _collapsed.Add(item2); } } } ManualLogSource log = PinThoseRecipesPlugin.Log; if (log != null) { log.LogInfo((object)$"Loaded {_activePins.Count} craft pin(s) and {_activeBuildPins.Count} build pin(s) for profile '{profileKey}'."); } PinStore.PinsChanged?.Invoke(); } } private static void Save() { if (!HasActiveProfile) { return; } try { PinStoreFile pinStoreFile = ReadFile(); CharacterPinData characterPinData = pinStoreFile.Characters.Find((CharacterPinData c) => c != null && Normalize(c.Profile) == _activeProfileKey); if (characterPinData == null) { characterPinData = new CharacterPinData { Profile = _activeProfileKey }; pinStoreFile.Characters.Add(characterPinData); } characterPinData.Pins = new List<string>(_activePins); characterPinData.BuildPins = new List<string>(_activeBuildPins); characterPinData.Collapsed = new List<string>(_collapsed); string contents = ToJson(pinStoreFile); string directoryName = Path.GetDirectoryName(FilePath); if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } string text = FilePath + ".tmp"; File.WriteAllText(text, contents); if (File.Exists(FilePath)) { File.Delete(FilePath); } File.Move(text, FilePath); } catch (Exception ex) { ManualLogSource log = PinThoseRecipesPlugin.Log; if (log != null) { log.LogError((object)("Failed to save pins: " + ex)); } } } private static PinStoreFile ReadFile() { try { if (!File.Exists(FilePath)) { return new PinStoreFile(); } string text = File.ReadAllText(FilePath); if (string.IsNullOrWhiteSpace(text)) { return new PinStoreFile(); } PinStoreFile pinStoreFile = FromJson(text); if (pinStoreFile == null) { throw new InvalidDataException("Deserialized to null."); } if (pinStoreFile.Characters == null) { pinStoreFile.Characters = new List<CharacterPinData>(); } return pinStoreFile; } catch (Exception ex) { if (!_loggedMalformed) { _loggedMalformed = true; ManualLogSource log = PinThoseRecipesPlugin.Log; if (log != null) { log.LogWarning((object)("Pin data unreadable, starting fresh (a .bak backup was made): " + ex.Message)); } } TryBackupCorrupt(); return new PinStoreFile(); } } private static string ToJson(PinStoreFile file) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("{"); stringBuilder.Append(" \"Version\": ").Append(file.Version).AppendLine(","); stringBuilder.AppendLine(" \"Characters\": ["); for (int i = 0; i < file.Characters.Count; i++) { CharacterPinData characterPinData = file.Characters[i]; if (characterPinData == null) { continue; } stringBuilder.AppendLine(" {"); stringBuilder.Append(" \"Profile\": ").Append(Quote(characterPinData.Profile)).AppendLine(","); stringBuilder.Append(" \"Pins\": ["); List<string> list = characterPinData.Pins ?? new List<string>(); for (int j = 0; j < list.Count; j++) { if (j > 0) { stringBuilder.Append(", "); } stringBuilder.Append(Quote(list[j])); } stringBuilder.AppendLine("],"); stringBuilder.Append(" \"BuildPins\": ["); List<string> list2 = characterPinData.BuildPins ?? new List<string>(); for (int k = 0; k < list2.Count; k++) { if (k > 0) { stringBuilder.Append(", "); } stringBuilder.Append(Quote(list2[k])); } stringBuilder.AppendLine("],"); stringBuilder.Append(" \"Collapsed\": ["); List<string> list3 = characterPinData.Collapsed ?? new List<string>(); for (int l = 0; l < list3.Count; l++) { if (l > 0) { stringBuilder.Append(", "); } stringBuilder.Append(Quote(list3[l])); } stringBuilder.AppendLine("]"); stringBuilder.Append(" }"); if (i < file.Characters.Count - 1) { stringBuilder.Append(","); } stringBuilder.AppendLine(); } stringBuilder.AppendLine(" ]"); stringBuilder.Append("}"); return stringBuilder.ToString(); } private static PinStoreFile FromJson(string json) { PinStoreFile pinStoreFile = new PinStoreFile(); Match match = Regex.Match(json, "\"Version\"\\s*:\\s*(\\d+)"); if (match.Success) { int.TryParse(match.Groups[1].Value, out pinStoreFile.Version); } Match match2 = Regex.Match(json, "\"Characters\"\\s*:\\s*\\[(.*)\\]", RegexOptions.Singleline); if (!match2.Success) { return pinStoreFile; } foreach (Match item in Regex.Matches(match2.Groups[1].Value, "\\{[^{}]*\\}")) { string value = item.Value; Match match3 = Regex.Match(value, "\"Profile\"\\s*:\\s*\"((?:\\\\.|[^\"\\\\])*)\""); if (!match3.Success) { continue; } CharacterPinData characterPinData = new CharacterPinData { Profile = Unescape(match3.Groups[1].Value), Pins = new List<string>(), BuildPins = new List<string>(), Collapsed = new List<string>() }; Match match4 = Regex.Match(value, "\"Pins\"\\s*:\\s*\\[(.*?)\\]", RegexOptions.Singleline); if (match4.Success) { foreach (Match item2 in Regex.Matches(match4.Groups[1].Value, "\"((?:\\\\.|[^\"\\\\])*)\"")) { string text = Unescape(item2.Groups[1].Value); if (!string.IsNullOrEmpty(text) && !characterPinData.Pins.Contains(text)) { characterPinData.Pins.Add(text); } } } Match match5 = Regex.Match(value, "\"BuildPins\"\\s*:\\s*\\[(.*?)\\]", RegexOptions.Singleline); if (match5.Success) { foreach (Match item3 in Regex.Matches(match5.Groups[1].Value, "\"((?:\\\\.|[^\"\\\\])*)\"")) { string text2 = Unescape(item3.Groups[1].Value); if (!string.IsNullOrEmpty(text2) && !characterPinData.BuildPins.Contains(text2)) { characterPinData.BuildPins.Add(text2); } } } Match match6 = Regex.Match(value, "\"Collapsed\"\\s*:\\s*\\[(.*?)\\]", RegexOptions.Singleline); if (match6.Success) { foreach (Match item4 in Regex.Matches(match6.Groups[1].Value, "\"((?:\\\\.|[^\"\\\\])*)\"")) { string text3 = Unescape(item4.Groups[1].Value); if (!string.IsNullOrEmpty(text3) && !characterPinData.Collapsed.Contains(text3)) { characterPinData.Collapsed.Add(text3); } } } pinStoreFile.Characters.Add(characterPinData); } return pinStoreFile; } private static string Quote(string s) { if (s == null) { return "\"\""; } return "\"" + s.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\n", "\\n") .Replace("\r", "\\r") + "\""; } private static string Unescape(string s) { return s.Replace("\\\"", "\"").Replace("\\\\", "\\").Replace("\\n", "\n") .Replace("\\r", "\r"); } private static void TryBackupCorrupt() { try { if (File.Exists(FilePath)) { string text = FilePath + ".bak"; if (File.Exists(text)) { File.Delete(text); } File.Copy(FilePath, text); } } catch { } } private static string Normalize(string key) { if (!string.IsNullOrWhiteSpace(key)) { return key.Trim(); } return null; } } internal sealed class ResolvedRequirement { public Sprite Icon; public string SharedName; public string DisplayName; public int Need; } internal sealed class ResolvedRecipe { public string PrefabName; public string ItemPrefabName; public Sprite Icon; public string DisplayName; public int OutputAmount; public bool IsBuild; public bool IsUpgrade; public int UpgradeQuality; public readonly List<ResolvedRequirement> Requirements = new List<ResolvedRequirement>(); } internal static class RecipeResolver { private static readonly Dictionary<string, List<Recipe>> _byPrefab = new Dictionary<string, List<Recipe>>(); private static readonly HashSet<string> _loggedUnresolved = new HashSet<string>(); private static ObjectDB _cachedInstance; internal static void InvalidateCache() { _byPrefab.Clear(); _loggedUnresolved.Clear(); _cachedInstance = null; } private static bool EnsureCache() { ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null) { return false; } if (instance != _cachedInstance || _byPrefab.Count == 0) { Rebuild(instance); } return true; } private static void Rebuild(ObjectDB db) { _byPrefab.Clear(); _loggedUnresolved.Clear(); _cachedInstance = db; if (db.m_recipes == null) { return; } foreach (Recipe recipe in db.m_recipes) { if ((Object)(object)recipe == (Object)null || (Object)(object)recipe.m_item == (Object)null) { continue; } string name = ((Object)((Component)recipe.m_item).gameObject).name; if (!string.IsNullOrEmpty(name)) { if (!_byPrefab.TryGetValue(name, out var value)) { value = new List<Recipe>(); _byPrefab[name] = value; } value.Add(recipe); } } } internal static List<Recipe> GetRecipes(string prefabName) { if (string.IsNullOrEmpty(prefabName) || !EnsureCache()) { return null; } if (!_byPrefab.TryGetValue(prefabName, out var value)) { return null; } return value; } internal static Recipe GetPreferredRecipe(string prefabName) { List<Recipe> recipes = GetRecipes(prefabName); if (recipes == null || recipes.Count == 0) { return null; } if (recipes.Count == 1) { return recipes[0]; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { List<Recipe> list = new List<Recipe>(); localPlayer.GetAvailableRecipes(ref list); foreach (Recipe item in recipes) { if (list.Contains(item)) { return item; } } foreach (Recipe item2 in recipes) { if ((Object)(object)item2.m_item != (Object)null && localPlayer.IsRecipeKnown(item2.m_item.m_itemData.m_shared.m_name)) { return item2; } } } List<Recipe> list2 = new List<Recipe>(recipes); list2.Sort(delegate(Recipe a, Recipe b) { int num = string.CompareOrdinal(((Object)a).name, ((Object)b).name); if (num != 0) { return num; } string strA = (((Object)(object)a.m_craftingStation != (Object)null) ? ((Object)a.m_craftingStation).name : ""); string strB = (((Object)(object)b.m_craftingStation != (Object)null) ? ((Object)b.m_craftingStation).name : ""); return string.CompareOrdinal(strA, strB); }); return list2[0]; } internal static ResolvedRecipe Resolve(string pinKey) { if (!PinStore.TryParseCraftPinKey(pinKey, out var prefabName, out var upgradeQuality)) { LogUnresolvedOnce(pinKey); return null; } Recipe preferredRecipe = GetPreferredRecipe(prefabName); if ((Object)(object)preferredRecipe == (Object)null || (Object)(object)preferredRecipe.m_item == (Object)null) { LogUnresolvedOnce(pinKey); return null; } bool flag = upgradeQuality >= 2; int num = ((!flag) ? 1 : upgradeQuality); string text = Localize(preferredRecipe.m_item.m_itemData.m_shared.m_name); if (flag) { text = text + " ★" + upgradeQuality; } ResolvedRecipe resolvedRecipe = new ResolvedRecipe { PrefabName = pinKey, ItemPrefabName = prefabName, Icon = preferredRecipe.m_item.m_itemData.GetIcon(), DisplayName = text, OutputAmount = (flag ? 1 : Mathf.Max(1, preferredRecipe.m_amount)), IsUpgrade = flag, UpgradeQuality = (flag ? upgradeQuality : 0) }; if (preferredRecipe.m_resources != null) { Requirement[] resources = preferredRecipe.m_resources; foreach (Requirement val in resources) { if (val != null && !((Object)(object)val.m_resItem == (Object)null)) { int amount = val.GetAmount(num); if (amount > 0) { string name = val.m_resItem.m_itemData.m_shared.m_name; resolvedRecipe.Requirements.Add(new ResolvedRequirement { Icon = val.m_resItem.m_itemData.GetIcon(), SharedName = name, DisplayName = Localize(name), Need = amount }); } } } } return resolvedRecipe; } private static void LogUnresolvedOnce(string prefabName) { if (!string.IsNullOrEmpty(prefabName) && !_loggedUnresolved.Contains(prefabName)) { _loggedUnresolved.Add(prefabName); ManualLogSource log = PinThoseRecipesPlugin.Log; if (log != null) { log.LogInfo((object)("Pinned recipe '" + prefabName + "' is not resolvable yet (missing prefab/recipe or ObjectDB not ready); kept and hidden.")); } } } private static string Localize(string token) { if (string.IsNullOrEmpty(token)) { return ""; } if (Localization.instance == null) { return token; } return Localization.instance.Localize(token); } } internal static class PieceResolver { private static readonly Dictionary<string, Piece> _byPrefab = new Dictionary<string, Piece>(); private static readonly HashSet<string> _loggedUnresolved = new HashSet<string>(); private static ZNetScene _cachedScene; internal static void InvalidateCache() { _byPrefab.Clear(); _loggedUnresolved.Clear(); _cachedScene = null; } private static void EnsureCache() { ZNetScene instance = ZNetScene.instance; if (!((Object)(object)instance == (Object)null) && (instance != _cachedScene || _byPrefab.Count == 0)) { Rebuild(instance); } } private static void Rebuild(ZNetScene scene) { _byPrefab.Clear(); _loggedUnresolved.Clear(); _cachedScene = scene; Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { PieceTable val = TraverseBuildPieces(localPlayer); if ((Object)(object)val != (Object)null && val.m_pieces != null) { foreach (GameObject piece in val.m_pieces) { IndexPiece(piece); } } } foreach (string buildPin in PinStore.GetBuildPins()) { if (!_byPrefab.ContainsKey(buildPin)) { IndexPiece(scene.GetPrefab(buildPin)); } } } private static PieceTable TraverseBuildPieces(Player player) { try { object? obj = AccessTools.Field(typeof(Player), "m_buildPieces")?.GetValue(player); return (PieceTable)((obj is PieceTable) ? obj : null); } catch { return null; } } private static void IndexPiece(GameObject go) { if ((Object)(object)go == (Object)null) { return; } Piece component = go.GetComponent<Piece>(); if (!((Object)(object)component == (Object)null)) { string text = Utils.GetPrefabName(go); if (string.IsNullOrEmpty(text)) { text = ((Object)go).name; } if (!_byPrefab.ContainsKey(text)) { _byPrefab[text] = component; } } } internal static Piece GetPiece(string prefabName) { if (string.IsNullOrEmpty(prefabName)) { return null; } EnsureCache(); if (_byPrefab.TryGetValue(prefabName, out var value) && (Object)(object)value != (Object)null) { return value; } ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance != (Object)null) { GameObject prefab = instance.GetPrefab(prefabName); value = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Piece>() : null); if ((Object)(object)value != (Object)null) { _byPrefab[prefabName] = value; return value; } } return null; } internal static ResolvedRecipe Resolve(string prefabName) { Piece piece = GetPiece(prefabName); if ((Object)(object)piece == (Object)null) { if (!string.IsNullOrEmpty(prefabName) && !_loggedUnresolved.Contains(prefabName)) { _loggedUnresolved.Add(prefabName); ManualLogSource log = PinThoseRecipesPlugin.Log; if (log != null) { log.LogInfo((object)("Pinned build piece '" + prefabName + "' is not resolvable yet; kept and hidden.")); } } return null; } ResolvedRecipe resolvedRecipe = new ResolvedRecipe { PrefabName = prefabName, Icon = piece.m_icon, DisplayName = Localize(piece.m_name), OutputAmount = 1, IsBuild = true }; if (piece.m_resources != null) { Requirement[] resources = piece.m_resources; foreach (Requirement val in resources) { if (val != null && !((Object)(object)val.m_resItem == (Object)null)) { int amount = val.GetAmount(1); if (amount > 0) { string name = val.m_resItem.m_itemData.m_shared.m_name; resolvedRecipe.Requirements.Add(new ResolvedRequirement { Icon = val.m_resItem.m_itemData.GetIcon(), SharedName = name, DisplayName = Localize(name), Need = amount }); } } } } return resolvedRecipe; } private static string Localize(string token) { if (string.IsNullOrEmpty(token)) { return ""; } if (Localization.instance == null) { return token; } return Localization.instance.Localize(token); } } internal static class PinIcon { private const string EmbeddedName = "PinThoseRecipes.pin.png"; private static Sprite _sprite; private static Sprite _buildSprite; private static bool _resolved; internal static Sprite Sprite { get { Ensure(); return _sprite; } } internal static Sprite BuildSprite { get { Ensure(); return _buildSprite; } } internal static void Ensure() { if (_resolved) { return; } _resolved = true; try { _sprite = LoadEmbedded() ?? BuildStarFallback(); } catch (Exception ex) { ManualLogSource log = PinThoseRecipesPlugin.Log; if (log != null) { log.LogWarning((object)("PinIcon load failed, using fallback: " + ex.Message)); } try { _sprite = BuildStarFallback(); } catch { _sprite = null; } } try { _buildSprite = BuildDiamondFallback(); } catch { _buildSprite = _sprite; } } private static Sprite LoadEmbedded() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown using Stream stream = typeof(PinIcon).Assembly.GetManifestResourceStream("PinThoseRecipes.pin.png"); if (stream == null) { return null; } byte[] array = new byte[stream.Length]; int num; for (int i = 0; i < array.Length; i += num) { num = stream.Read(array, i, array.Length - i); if (num <= 0) { break; } } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!LoadImageInto(val, array)) { Object.Destroy((Object)(object)val); return null; } ((Object)val).name = "PinThoseRecipes_PinEmbedded"; ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).wrapMode = (TextureWrapMode)1; return MakeSprite(val, "PinThoseRecipes_PinEmbedded"); } private static Sprite BuildStarFallback() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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_0025: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_00e3: 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_0104: 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_0106: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false) { name = "PinThoseRecipes_PinFallback", filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; Color32 val2 = default(Color32); ((Color32)(ref val2))..ctor((byte)0, (byte)0, (byte)0, (byte)0); Color32[] array = (Color32[])(object)new Color32[4096]; for (int i = 0; i < array.Length; i++) { array[i] = val2; } Vector2 center = new Vector2(32f, 32f); float num = 29.44f; float num2 = num * 0.42f; Vector2[] poly = BuildStar(center, num, num2); Vector2[] poly2 = BuildStar(center, num * 0.8f, num2 * 0.8f); Color32 val3 = default(Color32); ((Color32)(ref val3))..ctor(byte.MaxValue, (byte)205, (byte)60, byte.MaxValue); Color32 val4 = default(Color32); ((Color32)(ref val4))..ctor((byte)60, (byte)40, (byte)5, byte.MaxValue); Vector2 p = default(Vector2); for (int j = 0; j < 64; j++) { for (int k = 0; k < 64; k++) { ((Vector2)(ref p))..ctor((float)k + 0.5f, (float)j + 0.5f); if (PolygonContains(poly, p)) { array[j * 64 + k] = (PolygonContains(poly2, p) ? val3 : val4); } } } val.SetPixels32(array); val.Apply(false, false); return MakeSprite(val, "PinThoseRecipes_Pin"); } private static Sprite BuildDiamondFallback() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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_0025: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0108: 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_0163: 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_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false) { name = "PinThoseRecipes_BuildPinFallback", filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; Color32 val2 = default(Color32); ((Color32)(ref val2))..ctor((byte)0, (byte)0, (byte)0, (byte)0); Color32[] array = (Color32[])(object)new Color32[4096]; for (int i = 0; i < array.Length; i++) { array[i] = val2; } float num = 32f; float num2 = 32f; float num3 = 26.88f; float num4 = num3 * 0.72f; Vector2[] poly = (Vector2[])(object)new Vector2[4] { new Vector2(num, num2 + num3), new Vector2(num + num3, num2), new Vector2(num, num2 - num3), new Vector2(num - num3, num2) }; Vector2[] poly2 = (Vector2[])(object)new Vector2[4] { new Vector2(num, num2 + num4), new Vector2(num + num4, num2), new Vector2(num, num2 - num4), new Vector2(num - num4, num2) }; Color32 val3 = default(Color32); ((Color32)(ref val3))..ctor((byte)70, (byte)210, (byte)200, byte.MaxValue); Color32 val4 = default(Color32); ((Color32)(ref val4))..ctor((byte)10, (byte)50, (byte)55, byte.MaxValue); Vector2 p = default(Vector2); for (int j = 0; j < 64; j++) { for (int k = 0; k < 64; k++) { ((Vector2)(ref p))..ctor((float)k + 0.5f, (float)j + 0.5f); if (PolygonContains(poly, p)) { array[j * 64 + k] = (PolygonContains(poly2, p) ? val3 : val4); } } } val.SetPixels32(array); val.Apply(false, false); return MakeSprite(val, "PinThoseRecipes_BuildPin"); } private static Vector2[] BuildStar(Vector2 center, float outer, float inner) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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) Vector2[] array = (Vector2[])(object)new Vector2[10]; for (int i = 0; i < 10; i++) { float num = ((i % 2 == 0) ? outer : inner); float num2 = (float)Math.PI / 2f + (float)i * (float)Math.PI / 5f; array[i] = new Vector2(center.x + Mathf.Cos(num2) * num, center.y + Mathf.Sin(num2) * num); } return array; } private static bool PolygonContains(Vector2[] poly, Vector2 p) { //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 = poly.Length - 1; int num2 = 0; while (num2 < poly.Length) { if (poly[num2].y > p.y != poly[num].y > p.y && p.x < (poly[num].x - poly[num2].x) * (p.y - poly[num2].y) / (poly[num].y - poly[num2].y) + poly[num2].x) { flag = !flag; } num = num2++; } return flag; } private static bool LoadImageInto(Texture2D tex, byte[] data) { MethodInfo methodInfo = typeof(ImageConversion).GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[3] { typeof(Texture2D), typeof(byte[]), typeof(bool) }, null) ?? typeof(ImageConversion).GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[2] { typeof(Texture2D), typeof(byte[]) }, null); if (methodInfo == null) { return false; } object[] parameters = ((methodInfo.GetParameters().Length != 3) ? new object[2] { tex, data } : new object[3] { tex, data, false }); return (bool)methodInfo.Invoke(null, parameters); } private static Sprite MakeSprite(Texture2D tex, string name) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) Sprite obj = Sprite.Create(tex, new Rect(0f, 0f, (float)((Texture)tex).width, (float)((Texture)tex).height), new Vector2(0.5f, 0.5f), 100f); ((Object)obj).name = name; return obj; } } internal static class UiUtils { private static TMP_FontAsset _cachedFont; internal static TMP_FontAsset ResolveFont() { if ((Object)(object)_cachedFont != (Object)null) { return _cachedFont; } InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.m_recipeName != (Object)null && (Object)(object)instance.m_recipeName.font != (Object)null) { _cachedFont = instance.m_recipeName.font; } return _cachedFont; } internal static RectTransform NewRect(Transform parent, string name) { //IL_0014: 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_0032: Unknown result type (might be due to invalid IL or missing references) RectTransform component = new GameObject(name, new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>(); ((Transform)component).SetParent(parent, false); ((Transform)component).localScale = Vector3.one; component.anchoredPosition = Vector2.zero; return component; } internal static Image NewImage(Transform parent, string name, Sprite sprite = null, bool raycast = false) { Image obj = ((Component)NewRect(parent, name)).gameObject.AddComponent<Image>(); obj.sprite = sprite; ((Graphic)obj).raycastTarget = raycast; obj.preserveAspect = true; return obj; } internal static TextMeshProUGUI NewText(Transform parent, string name, float fontSize, TextAlignmentOptions align) { //IL_0030: 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_0071: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI val = ((Component)NewRect(parent, name)).gameObject.AddComponent<TextMeshProUGUI>(); TMP_FontAsset val2 = ResolveFont(); if ((Object)(object)val2 != (Object)null) { ((TMP_Text)val).font = val2; } ((TMP_Text)val).fontSize = fontSize; ((TMP_Text)val).alignment = align; ((TMP_Text)val).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)val).overflowMode = (TextOverflowModes)0; ((Graphic)val).raycastTarget = false; ((Graphic)val).color = Color.white; ((TMP_Text)val).fontStyle = (FontStyles)0; ((TMP_Text)val).outlineWidth = 0.15f; ((TMP_Text)val).outlineColor = new Color32((byte)0, (byte)0, (byte)0, (byte)200); return val; } internal static void SetAnchors(RectTransform rt, Vector2 min, Vector2 max, Vector2 pivot) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) rt.anchorMin = min; rt.anchorMax = max; rt.pivot = pivot; } } internal sealed class RecipePinInteraction : MonoBehaviour, IPointerClickHandler, IEventSystemHandler { internal string PinKey; internal Recipe Recipe; internal Image PinImage; internal InventoryGui Owner; public void OnPointerClick(PointerEventData eventData) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 if (eventData != null && (int)eventData.button == 2 && ((Behaviour)this).isActiveAndEnabled && !string.IsNullOrEmpty(PinKey) && PinStore.HasActiveProfile) { PinStore.Toggle(PinKey); RefreshPinVisual(); PinSound.Play(); } } internal void RefreshPinVisual() { if (!((Object)(object)PinImage == (Object)null)) { bool flag = PinStore.IsPinned(PinKey); if (((Component)PinImage).gameObject.activeSelf != flag) { ((Component)PinImage).gameObject.SetActive(flag); } } } internal static void RefreshAllPinVisuals() { RecipePinInteraction[] array = Object.FindObjectsByType<RecipePinInteraction>((FindObjectsSortMode)0); for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] != (Object)null) { array[i].RefreshPinVisual(); } } } } internal static class PinSound { internal static void Play() { //IL_0047: 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) if (PinConfig.PlayPinSound == null || !PinConfig.PlayPinSound.Value) { return; } try { InventoryGui instance = InventoryGui.instance; Player localPlayer = Player.m_localPlayer; if ((Object)(object)instance != (Object)null && (Object)(object)localPlayer != (Object)null && instance.m_moveItemEffects != null) { instance.m_moveItemEffects.Create(((Component)localPlayer).transform.position, Quaternion.identity, (Transform)null, 1f, -1); } } catch { } } } internal sealed class PinnedPanelController : MonoBehaviour { internal sealed class EntryView { public RectTransform Root; public RectTransform ReqsRoot; public TextMeshProUGUI ArrowLabel; public string PrefabName; public string CollapseKey; public bool IsBuild; public bool Expanded = true; public readonly List<ReqView> Reqs = new List<ReqView>(); public void ApplyExpanded(bool expanded) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) Expanded = expanded; if ((Object)(object)ReqsRoot != (Object)null) { ((Component)ReqsRoot).gameObject.SetActive(expanded); } if ((Object)(object)ArrowLabel != (Object)null) { ((TMP_Text)ArrowLabel).text = (expanded ? "▼" : "▶"); ((Graphic)ArrowLabel).color = new Color(0.85f, 0.85f, 0.85f, 1f); } } } internal sealed class ReqView { public string SharedName; public int Need; public TextMeshProUGUI Label; } private const float CountRefreshInterval = 0.25f; private const float ProfileSyncInterval = 0.5f; private const float UnresolvedRetryInterval = 1f; private const float ItemIconSize = 40f; private const float MatIconSize = 26f; private const float ArrowSize = 22f; private RectTransform _root; private CanvasGroup _canvasGroup; private RectTransform _content; private Transform _boundParent; private RectTransform _contextMenu; private string _contextMenuPrefab; private bool _contextMenuIsBuild; private TextMeshProUGUI _contextMenuLabel; private static string _hoverTipText; private static bool _hoverTipVisible; private readonly List<EntryView> _entries = new List<EntryView>(); private bool _dirty = true; private float _nextCountRefresh; private float _nextProfileSync; private float _nextUnresolvedRetry; private bool _hasUnresolved; private bool _wasInventoryOpen; private readonly Vector3[] _cornersParent = (Vector3[])(object)new Vector3[4]; private readonly Vector3[] _cornersMinimap = (Vector3[])(object)new Vector3[4]; private readonly Vector3[] _cornersShipHud = (Vector3[])(object)new Vector3[4]; private void Awake() { PinIcon.Ensure(); PinStore.PinsChanged += OnPinsChanged; PinConfig.Changed += OnConfigChanged; } private void OnDestroy() { PinStore.PinsChanged -= OnPinsChanged; PinConfig.Changed -= OnConfigChanged; DestroyRoot(); HideMaterialTip(); } private void OnPinsChanged() { HideContextMenu(); _dirty = true; RecipePinInteraction.RefreshAllPinVisuals(); } private void OnConfigChanged() { _dirty = true; ApplyScale(); } private void Update() { if (Time.unscaledTime >= _nextProfileSync) { _nextProfileSync = Time.unscaledTime + 0.5f; ProfileLifecyclePatches.SyncProfile(); } EnsureHudBinding(); if ((Object)(object)_root == (Object)null) { return; } bool flag = ShouldShowPanel(); _canvasGroup.alpha = (flag ? 1f : 0f); _canvasGroup.blocksRaycasts = flag; _canvasGroup.interactable = flag; if (!flag) { HideContextMenu(); HideMaterialTip(); return; } if (_dirty || (_hasUnresolved && Time.unscaledTime >= _nextUnresolvedRetry)) { HideContextMenu(); HideMaterialTip(); RebuildPanel(); } if (Time.unscaledTime >= _nextCountRefresh) { _nextCountRefresh = Time.unscaledTime + 0.25f; RefreshCounts(); } UpdatePosition(); bool flag2 = IsInventoryOpen(); if (_wasInventoryOpen && !flag2) { HideContextMenu(); } _wasInventoryOpen = flag2; if ((Object)(object)_contextMenu != (Object)null && ((Component)_contextMenu).gameObject.activeSelf && (Input.GetKeyDown((KeyCode)27) || Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(2)) && !IsPointerOverContextMenu()) { HideContextMenu(); } } private bool IsPointerOverContextMenu() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_contextMenu == (Object)null || !Object.op_Implicit((Object)(object)EventSystem.current)) { return false; } List<RaycastResult> list = new List<RaycastResult>(); PointerEventData val = new PointerEventData(EventSystem.current) { position = Vector2.op_Implicit(Input.mousePosition) }; EventSystem.current.RaycastAll(val, list); foreach (RaycastResult item in list) { RaycastResult current = item; if ((Object)(object)((RaycastResult)(ref current)).gameObject != (Object)null && ((RaycastResult)(ref current)).gameObject.transform.IsChildOf((Transform)(object)_contextMenu)) { return true; } } return false; } private Transform ResolveParent() { Minimap instance = Minimap.instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.m_smallRoot != (Object)null) { return instance.m_smallRoot.transform.parent; } return null; } private void EnsureHudBinding() { if (PinConfig.Enabled != null && !PinConfig.Enabled.Value) { DestroyRoot(); return; } Transform val = ResolveParent(); if ((!((Object)(object)val == (Object)null) || (!((Object)(object)_root == (Object)null) && !((Object)(object)_boundParent == (Object)null))) && (!((Object)(object)_root != (Object)null) || !((Object)(object)_boundParent == (Object)(object)val))) { DestroyRoot(); if (!((Object)(object)val == (Object)null)) { BuildRoot(val); } } } private void BuildRoot(Transform parent) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_005b: 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_0079: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_0125: 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_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Expected O, but got Unknown _boundParent = parent; GameObject val = new GameObject("PinThoseRecipes_PanelRoot", new Type[2] { typeof(RectTransform), typeof(CanvasGroup) }); _root = val.GetComponent<RectTransform>(); ((Transform)_root).SetParent(parent, false); UiUtils.SetAnchors(_root, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(1f, 1f)); _root.sizeDelta = new Vector2(0f, 0f); ((Transform)_root).localScale = Vector3.one; Canvas obj = val.AddComponent<Canvas>(); obj.overrideSorting = true; obj.sortingOrder = 1200; val.AddComponent<GraphicRaycaster>(); _canvasGroup = val.GetComponent<CanvasGroup>(); _canvasGroup.alpha = 0f; _canvasGroup.blocksRaycasts = false; _canvasGroup.interactable = false; _content = UiUtils.NewRect((Transform)(object)_root, "Content"); UiUtils.SetAnchors(_content, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(1f, 1f)); _content.anchoredPosition = Vector2.zero; Image obj2 = ((Component)_content).gameObject.AddComponent<Image>(); ((Graphic)obj2).color = new Color(0f, 0f, 0f, 0.55f); ((Graphic)obj2).raycastTarget = false; VerticalLayoutGroup obj3 = ((Component)_content).gameObject.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj3).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj3).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)obj3).spacing = 8f; ((LayoutGroup)obj3).padding = new RectOffset(10, 10, 8, 8); ((LayoutGroup)obj3).childAlignment = (TextAnchor)2; ContentSizeFitter obj4 = ((Component)_content).gameObject.AddComponent<ContentSizeFitter>(); obj4.horizontalFit = (FitMode)2; obj4.verticalFit = (FitMode)2; BuildContextMenu(); ApplyScale(); _dirty = true; } private void BuildContextMenu() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00e7: 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_0117: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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_016c: 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_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: 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_0205: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Expected O, but got Unknown _contextMenu = UiUtils.NewRect((Transform)(object)_root, "ContextMenu"); UiUtils.SetAnchors(_contextMenu, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(0f, 1f)); _contextMenu.sizeDelta = new Vector2(150f, 42f); ((Component)_contextMenu).gameObject.SetActive(false); Image obj = ((Component)_contextMenu).gameObject.AddComponent<Image>(); ((Graphic)obj).color = new Color(0.1f, 0.09f, 0.07f, 0.96f); ((Graphic)obj).raycastTarget = true; Outline obj2 = ((Component)_contextMenu).gameObject.AddComponent<Outline>(); ((Shadow)obj2).effectColor = new Color(0.85f, 0.72f, 0.35f, 1f); ((Shadow)obj2).effectDistance = new Vector2(1.5f, -1.5f); RectTransform val = UiUtils.NewRect((Transform)(object)_contextMenu, "UnpinButton"); UiUtils.SetAnchors(val, Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f)); val.offsetMin = new Vector2(3f, 3f); val.offsetMax = new Vector2(-3f, -3f); Image val2 = ((Component)val).gameObject.AddComponent<Image>(); ((Graphic)val2).color = new Color(0.18f, 0.16f, 0.12f, 1f); ((Graphic)val2).raycastTarget = true; Button obj3 = ((Component)val).gameObject.AddComponent<Button>(); ((Selectable)obj3).targetGraphic = (Graphic)(object)val2; ColorBlock colors = ((Selectable)obj3).colors; ((ColorBlock)(ref colors)).normalColor = new Color(0.18f, 0.16f, 0.12f, 1f); ((ColorBlock)(ref colors)).highlightedColor = new Color(0.32f, 0.28f, 0.18f, 1f); ((ColorBlock)(ref colors)).pressedColor = new Color(0.45f, 0.3f, 0.12f, 1f); ((ColorBlock)(ref colors)).selectedColor = ((ColorBlock)(ref colors)).highlightedColor; ((Selectable)obj3).colors = colors; UnpinMenuItem unpinMenuItem = ((Component)val).gameObject.AddComponent<UnpinMenuItem>(); unpinMenuItem.Owner = this; ((UnityEvent)obj3.onClick).AddListener(new UnityAction(unpinMenuItem.OnClick)); _contextMenuLabel = null; } private void EnsureContextMenuLabel() { //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_008c: 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_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_contextMenu == (Object)null || (Object)(object)_contextMenuLabel != (Object)null) { return; } Transform val = ((Transform)_contextMenu).Find("UnpinButton"); if (!((Object)(object)val == (Object)null)) { TextMeshProUGUI componentInChildren = ((Component)val).GetComponentInChildren<TextMeshProUGUI>(true); if ((Object)(object)componentInChildren != (Object)null) { _contextMenuLabel = componentInChildren; return; } _contextMenuLabel = UiUtils.NewText(val, "Label", 20f, (TextAlignmentOptions)514); UiUtils.SetAnchors(((TMP_Text)_contextMenuLabel).rectTransform, Vector2.zero, Vector2.one, new Vector2(0.5f, 0.5f)); ((TMP_Text)_contextMenuLabel).rectTransform.offsetMin = Vector2.zero; ((TMP_Text)_contextMenuLabel).rectTransform.offsetMax = Vector2.zero; ((TMP_Text)_contextMenuLabel).text = "Unpin"; ((TMP_Text)_contextMenuLabel).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)_contextMenuLabel).overflowMode = (TextOverflowModes)0; ((TMP_Text)_contextMenuLabel).outlineWidth = 0.2f; ((TMP_Text)_contextMenuLabel).outlineColor = new Color32((byte)0, (byte)0, (byte)0, byte.MaxValue); ((TMP_Text)_contextMenuLabel).fontStyle = (FontStyles)1; ((Graphic)_contextMenuLabel).raycastTarget = false; } } private void StyleContextMenuLabel() { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) EnsureContextMenuLabel(); if ((Object)(object)_contextMenuLabel == (Object)null) { return; } TMP_FontAsset val = UiUtils.ResolveFont(); if ((Object)(object)val != (Object)null) { ((TMP_Text)_contextMenuLabel).font = val; } string text = null; if (!string.IsNullOrEmpty(_contextMenuPrefab)) { ResolvedRecipe resolvedRecipe = (_contextMenuIsBuild ? PieceResolver.Resolve(_contextMenuPrefab) : RecipeResolver.Resolve(_contextMenuPrefab)); if (resolvedRecipe != null && !string.IsNullOrEmpty(resolvedRecipe.DisplayName)) { text = resolvedRecipe.DisplayName; } } ((TMP_Text)_contextMenuLabel).text = (string.IsNullOrEmpty(text) ? "Unpin" : ("Unpin " + text)); ((Graphic)_contextMenuLabel).color = new Color(1f, 0.88f, 0.35f, 1f); ((Behaviour)_contextMenuLabel).enabled = true; ((Component)_contextMenuLabel).gameObject.SetActive(true); ((TMP_Text)_contextMenuLabel).ForceMeshUpdate(true, false); if ((Object)(object)_contextMenu != (Object)null) { float num = Mathf.Clamp(((TMP_Text)_contextMenuLabel).preferredWidth + 28f, 150f, 420f); _contextMenu.sizeDelta = new Vector2(num, 42f); } } private void ApplyScale() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_content != (Object)null && PinConfig.PanelScale != null) { float num = Mathf.Clamp(PinConfig.PanelScale.Value, 0.25f, 3f); ((Transform)_content).localScale = new Vector3(num, num, 1f); } } private void DestroyRoot() { _entries.Clear(); HideContextMenu(); if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)((Component)_root).gameObject); } _root = null; _content = null; _canvasGroup = null; _boundParent = null; _contextMenu = null; _contextMenuPrefab = null; _contextMenuIsBuild = false; _contextMenuLabel = null; } private bool ShouldShowPanel() { if (PinConfig.Enabled != null && !PinConfig.Enabled.Value) { return false; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).InCutscene()) { return false; } if ((Object)(object)Hud.instance == (Object)null || Hud.IsUserHidden()) { return false; } if ((Object)(object)Minimap.instance == (Object)null || Minimap.IsOpen()) { return false; } if ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) { return false; } if (Console.IsVisible() || Menu.IsVisible()) { return false; } if (_entries.Count <= 0) { return PinStore.TotalPinCount > 0; } return true; } private void RebuildPanel() { _dirty = false; _hasUnresolved = false; if ((Object)(object)_content == (Object)null) { return; } foreach (EntryView entry in _entries) { if ((Object)(object)entry.Root != (Object)null) { Object.Destroy((Object)(object)((Component)entry.Root).gameObject); } } _entries.Clear(); List<(ResolvedRecipe, bool)> list = new List<(ResolvedRecipe, bool)>(); foreach (string pin in PinStore.GetPins()) { ResolvedRecipe resolvedRecipe = RecipeResolver.Resolve(pin); if (resolvedRecipe == null) { _hasUnresolved = true; } else { list.Add((resolvedRecipe, false)); } } foreach (string buildPin in PinStore.GetBuildPins()) { ResolvedRecipe resolvedRecipe2 = PieceResolver.Resolve(buildPin); if (resolvedRecipe2 == null) { _hasUnresolved = true; } else { list.Add((resolvedRecipe2, true)); } } int num = Mathf.Min((PinConfig.MaxPinnedRecipes != null) ? PinConfig.MaxPinnedRecipes.Value : 8, list.Count); for (int i = 0; i < num; i++) { _entries.Add(BuildEntry(list[i].Item1, list[i].Item2)); } int num2 = list.Count - num; if (num2 > 0) { BuildMoreRow(num2); } if (_hasUnresolved) { _nextUnresolvedRetry = Time.unscaledTime + 1f; } RefreshCounts(); } private EntryView BuildEntry(ResolvedRecipe recipe, bool isBuild) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Expected O, but got Unknown //IL_02e5: Unknown result type (might be due to invalid IL or missing references) EntryView entryView = new EntryView { PrefabName = recipe.PrefabName, IsBuild = isBuild, CollapseKey = (isBuild ? PinStore.BuildCollapseKey(recipe.PrefabName) : PinStore.CraftCollapseKey(recipe.PrefabName)) }; RectTransform val = (entryView.Root = UiUtils.NewRect((Transform)(object)_content, "Entry_" + (isBuild ? "B_" : "C_") + recipe.PrefabName)); Image obj = ((Component)val).gameObject.AddComponent<Image>(); ((Graphic)obj).color = new Color(1f, 1f, 1f, 0f); ((Graphic)obj).raycastTarget = true; PanelEntryInteraction panelEntryInteraction = ((Component)val).gameObject.AddComponent<PanelEntryInteraction>(); panelEntryInteraction.PrefabName = recipe.PrefabName; panelEntryInteraction.IsBuild = isBuild; panelEntryInteraction.Owner = this; VerticalLayoutGroup obj2 = ((Component)val).gameObject.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)obj2).spacing = 2f; ((LayoutGroup)obj2).childAlignment = (TextAnchor)0; RectTransform val2 = UiUtils.NewRect((Transform)(object)val, "Header"); HorizontalLayoutGroup obj3 = ((Component)val2).gameObject.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj3).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj3).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)obj3).spacing = 4f; ((LayoutGroup)obj3).childAlignment = (TextAnchor)3; TextMeshProUGUI val3 = UiUtils.NewText((Transform)(object)val2, "Arrow", 18f, (TextAlignmentOptions)4098); ((Graphic)val3).raycastTarget = true; AddLayoutSize(((Component)val3).gameObject, 22f, 40f); ((Component)val3).gameObject.AddComponent<ExpandArrowInteraction>().Entry = entryView; entryView.ArrowLabel = val3; AddLayoutSize(((Component)UiUtils.NewImage((Transform)(object)val2, "Icon", recipe.Icon)).gameObject, 40f, 40f); if (isBuild) { AddLayoutSize(((Component)UiUtils.NewImage((Transform)(object)val2, "BuildBadge", PinIcon.BuildSprite)).gameObject, 16f, 16f); } string text = recipe.DisplayName; if (!isBuild && !recipe.IsUpgrade && recipe.OutputAmount > 1) { text = text + " x" + recipe.OutputAmount; } TextMeshProUGUI obj4 = UiUtils.NewText((Transform)(object)val2, "Name", 18f, (TextAlignmentOptions)4097); ((TMP_Text)obj4).text = text; ((Graphic)obj4).color = PinConfig.NameColor; AddLayoutHeight(((Component)obj4).gameObject, 40f); RectTransform val4 = (entryView.ReqsRoot = UiUtils.NewRect((Transform)(object)val, "Requirements")); VerticalLayoutGroup obj5 = ((Component)val4).gameObject.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj5).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj5).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj5).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj5).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)obj5).spacing = 2f; ((LayoutGroup)obj5).childAlignment = (TextAnchor)0; ((LayoutGroup)obj5).padding = new RectOffset(26, 0, 0, 0); foreach (ResolvedRequirement requirement in recipe.Requirements) { RectTransform obj6 = UiUtils.NewRect((Transform)(object)val4, "Req"); Image obj7 = ((Component)obj6).gameObject.AddComponent<Image>(); ((Graphic)obj7).color = new Color(1f, 1f, 1f, 0f); ((Graphic)obj7).raycastTarget = true; string topic = ((!string.IsNullOrEmpty(requirement.DisplayName)) ? requirement.DisplayName : (requirement.SharedName ?? "")); ((Component)obj6).gameObject.AddComponent<ReqHoverProbe>().Topic = topic; HorizontalLayoutGroup obj8 = ((Component)obj6).gameObject.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj8).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj8).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj8).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj8).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)obj8).spacing = 4f; ((LayoutGroup)obj8).childAlignment = (TextAnchor)3; AddLayoutSize(((Component)UiUtils.NewImage((Transform)(object)obj6, "MatIcon", requirement.Icon)).gameObject, 26f, 26f); TextMeshProUGUI val5 = UiUtils.NewText((Transform)(object)obj6, "Count", 16f, (TextAlignmentOptions)4097); AddLayoutHeight(((Component)val5).gameObject, 26f); entryView.Reqs.Add(new ReqView { SharedName = requirement.SharedName, Need = requirement.Need, Label = val5 }); } entryView.ApplyExpanded(!PinStore.IsCollapsed(entryView.CollapseKey)); return entryView; } private void BuildMoreRow(int extra) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) RectTransform val = UiUtils.NewRect((Transform)(object)_content, "MoreRow"); HorizontalLayoutGroup obj = ((Component)val).gameObject.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false; ((LayoutGroup)obj).childAlignment = (TextAnchor)5; TextMeshProUGUI obj2 = UiUtils.NewText((Transform)(object)val, "MoreLabel", 15f, (TextAlignmentOptions)4100); ((TMP_Text)obj2).text = "+" + extra + " more"; ((Graphic)obj2).color = new Color(0.8f, 0.8f, 0.8f, 1f); AddLayoutHeight(((Component)obj2).gameObject, 20f); _entries.Add(new EntryView { Root = val, PrefabName = null }); } private void RefreshCounts() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) Inventory val = (((Object)(object)Player.m_localPlayer != (Object)null) ? ((Humanoid)Player.m_localPlayer).GetInventory() : null); Color satisfiedColor = PinConfig.SatisfiedColor; Color missingColor = PinConfig.MissingColor; foreach (EntryView entry in _entries) { foreach (ReqView req in entry.Reqs) { if (!((Object)(object)req.Label == (Object)null)) { int num = ((val != null) ? val.CountItems(req.SharedName, -1, true) : 0); ((TMP_Text)req.Label).text = num + "/" + req.Need; ((Graphic)req.Label).color = ((num >= req.Need) ? satisfiedColor : missingColor); } } } } internal static void ToggleCollapsed(EntryView view) { if (view != null && !string.IsNullOrEmpty(view.PrefabName)) { bool expanded = PinStore.ToggleCollapsed(view.CollapseKey, view.IsBuild, view.PrefabName); view.ApplyExpanded(expanded); } } internal void ShowContextMenu(string prefabName, bool isBuild, Vector2 screenPos) { //IL_0081: 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_0092: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_contextMenu == (Object)null) && !((Object)(object)_root == (Object)null) && !string.IsNullOrEmpty(prefabName)) { _contextMenuPrefab = prefabName; _contextMenuIsBuild = isBuild; ((Component)_contextMenu).gameObject.SetActive(true); ((Transform)_contextMenu).SetAsLastSibling(); StyleContextMenuLabel(); Camera val = null; Canvas componentInParent = ((Component)_root).GetComponentInParent<Canvas>(); if ((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) { val = componentInParent.worldCamera; } Vector2 anchoredPosition = default(Vector2); if (RectTransformUtility.ScreenPointToLocalPointInRectangle(_root, screenPos, val, ref anchoredPosition)) { _contextMenu.anchoredPosition = anchoredPosition; } } } internal void HideContextMenu() { _contextMenuPrefab = null; _contextMenuIsBuild = false; if ((Object)(object)_contextMenu != (Object)null) { ((Component)_contextMenu).gameObject.SetActive(false); } } internal void ConfirmUnpinFromMenu() { string contextMenuPrefab = _contextMenuPrefab; bool contextMenuIsBuild = _contextMenuIsBuild; HideContextMenu(); if (string.IsNullOrEmpty(contextMenuPrefab) || !PinStore.HasActiveProfile) { return; } if (contextMenuIsBuild) { if (!PinStore.IsBuildPinned(contextMenuPrefab)) { return; } PinStore.ToggleBuild(contextMenuPrefab); } else { if (!PinStore.IsPinned(contextMenuPrefab)) { return; } PinStore.Toggle(contextMenuPrefab); } PinSound.Play(); } private void UpdatePosition() { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: 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_01cb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root == (Object)null || (Object)(object)_boundParent == (Object)null) { return; } Transform boundParent = _boundParent; RectTransform val = (RectTransform)(object)((boundParent is RectTransform) ? boundParent : null); Minimap instance = Minimap.instance; RectTransform val2 = (RectTransform)(((Object)(object)instance != (Object)null && (Object)(object)instance.m_smallRoot != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); float num = ((PinConfig.OffsetX != null) ? PinConfig.OffsetX.Value : (-14f)); float num2 = ((PinConfig.ExtraOffsetBelowMinimap != null) ? PinConfig.ExtraOffsetBelowMinimap.Value : (-14f)); float num3 = -260f; if ((Object)(object)val != (Object)null && ((Transform)val).lossyScale.y != 0f) { val.GetWorldCorners(_cornersParent); float y = _cornersParent[1].y; float num4 = float.NaN; if ((Object)(object)val2 != (Object)null && instance.m_smallRoot.activeInHierarchy) { val2.GetWorldCorners(_cornersMinimap); num4 = _cornersMinimap[0].y; } RectTransform activeShipHudRect = GetActiveShipHudRect(); if ((Object)(object)activeShipHudRect != (Object)null) { activeShipHudRect.GetWorldCorners(_cornersShipHud); float y2 = _cornersShipHud[0].y; if (float.IsNaN(num4) || y2 < num4) { num4 = y2; } } if (!float.IsNaN(num4)) { num3 = 0f - (y - num4) / ((Transform)val).lossyScale.y; } } Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(num, num3 + num2); if (IsInventoryOpen()) { float num5 = ((PinConfig.InventoryOpenShiftLeft != null) ? PinConfig.InventoryOpenShiftLeft.Value : 640f); float num6 = ((PinConfig.InventoryOpenShiftDown != null) ? PinConfig.InventoryOpenShiftDown.Value : 170f); val3 += new Vector2(0f - num5, 0f - num6); } _root.anchoredPosition = val3; } private static RectTransform GetActiveShipHudRect() { Hud instance = Hud.instance; if ((Object)(object)instance == (Object)null) { return null; } if ((Object)(object)instance.m_shipHudRoot != (Object)null && instance.m_shipHudRoot.activeInHierarchy) { Transform transform = instance.m_shipHudRoot.transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (val != null) { return val; } } if ((Object)(object)instance.m_shipWindIndicatorRoot != (Object)null && ((Component)instance.m_shipWindIndicatorRoot).gameObject.activeInHierarchy) { return instance.m_shipWindIndicatorRoot; } return null; } private static bool IsInventoryOpen() { return InventoryGui.IsVisible(); } private void OnGUI() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_0071: Expected O, but got Unknown //IL_008b: 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_00a0: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_00e5: 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_00f3: Unknown result type (might be due to invalid IL or missing references) if (_hoverTipVisible && !string.IsNullOrEmpty(_hoverTipText)) { Vector3 mousePosition = Input.mousePosition; float num = mousePosition.x + 16f; float num2 = (float)Screen.height - mousePosition.y + 16f; GUIStyle val = new GUIStyle(GUI.skin.box) { fontSize = 16, alignment = (TextAnchor)3, wordWrap = false, padding = new RectOffset(10, 10, 6, 6) }; val.normal.textColor = new Color(1f, 0.88f, 0.35f, 1f); GUIContent val2 = new GUIContent(_hoverTipText); Vector2 val3 = val.CalcSize(val2); val3.x = Mathf.Clamp(val3.x + 4f, 60f, 420f); val3.y = Mathf.Max(val3.y, 28f); GUI.Box(new Rect(num, num2, val3.x, val3.y), val2, val); } } internal static void ShowMaterialTip(string displayName) { if (!string.IsNullOrEmpty(displayName)) { _hoverTipText = displayName; _hoverTipVisible = true; } } internal static void HideMaterialTip() { _hoverTipVisible = false; _hoverTipText = null; } private static void AddLayoutSize(GameObject go, float w, float h) { LayoutElement obj = go.AddComponent<LayoutElement>(); obj.preferredWidth = w; obj.preferredHeight = h; obj.minWidth = w; obj.minHeight = h; } private static void AddLayoutHeight(GameObject go, float h) { LayoutElement obj = go.AddComponent<LayoutElement>(); obj.preferredHeight = h; obj.minHeight = h; } } internal sealed class ReqHoverProbe : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { internal string Topic; public void OnPointerEnter(PointerEventData eventData) { PinnedPanelController.ShowMaterialTip(Topic); } public void OnPointerExit(PointerEventData eventData) { PinnedPanelController.HideMaterialTip(); } } internal sealed class ExpandArrowInteraction : MonoBehaviour, IPointerClickHandler, IEventSystemHandler { internal PinnedPanelController.EntryView Entry; public void OnPointerClick(PointerEventData eventData) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) if (eventData != null && (int)eventData.button == 0 && Entry != null && !string.IsNullOrEmpty(Entry.PrefabName)) { PinnedPanelController.ToggleCollapsed(Entry); ((AbstractEventData)eventData).Use(); } } } internal sealed class PanelEntryInteraction : MonoBehaviour, IPointerClickHandler, IEventSystemHandler { internal string PrefabName; internal bool IsBuild; internal PinnedPanelController Owner; public void OnPointerClick(PointerEventData eventData) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_0043: Unknown result type (might be due to invalid IL or missing references) if (eventData != null && (int)eventData.button == 1 && !string.IsNullOrEmpty(PrefabName) && !((Object)(object)Owner == (Object)null) && PinStore.HasActiveProfile) { Owner.ShowContextMenu(PrefabName, IsBuild, eventData.position); ((AbstractEventData)eventData).Use(); } } } internal sealed class UnpinMenuItem : MonoBehaviour { internal PinnedPanelController Owner; public void OnClick() { Owner?.ConfirmUnpinFromMenu(); } } } namespace PinThoseRecipes.Patches { internal static class InventoryGuiRecipeListPatches { [HarmonyPatch] private static class AddRecipeToListPatch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(InventoryGui), "AddRecipeToList", new Type[4] { typeof(Player), typeof(Recipe), typeof(ItemData), typeof(bool) }, (Type[])null); } private static bool Prepare() { if (TargetMethod() == null) { ManualLogSource log = PinThoseRecipesPlugin.Log; if (log != null) { log.LogError((object)"InventoryGui.AddRecipeToList(Player,Recipe,ItemData,bool) not found; pin icons in the craft list are disabled."); } return false; } return true; } private static void Prefix(InventoryGui __instance, out int __state) { __state = GetAvailableRecipes(__instance)?.Count ?? 0; } private static void Postfix(InventoryGui __instance, Recipe recipe, ItemData item, int __state) { if (PinConfig.Enabled != null && !PinConfig.Enabled.Value) { return; } IList availableRecipes = GetAvailableRecipes(__instance); if (availableRecipes == null || availableRecipes.Count <= __state) { return; } EnsurePairAccessors(availableRecipes[__state]); GameObject val = null; for (int i = __state; i < availableRecipes.Count; i++) { if (_getPairRecipe(availableRecipes[i]) == recipe) { val = _getPairElement(availableRecipes[i]); break; } } if ((Object)(object)val == (Object)null) { val = _getPairElement(availableRecipes[__state]); } if (!((Object)(object)val == (Object)null)) { AttachPin(__instance, val, recipe, item); } } } [HarmonyPatch(typeof(InventoryGui), "UpdateRecipeList")] private static class UpdateRecipeListPatch { private static void Postfix(InventoryGui __instance) { if (PinConfig.Enabled == null || PinConfig.Enabled.Value) { ReorderPinned(__instance); } } } private struct Entry { public object Pair; public GameObject Element; public string PinKey; public int Original; } internal static bool IsReordering; private static FieldInfo _fAvailableRecipes; private static Func<object, Recipe> _getPairRecipe; private static Func<object, ItemData> _getPairItemData; private static Func<object, GameObject> _getPairElement; private static FieldInfo AvailableRecipesField => _fAvailableRecipes ?? (_fAvailableRecipes = AccessTools.Field(typeof(InventoryGui), "m_availableRecipes")); private static IList GetAvailableRecipes(InventoryGui gui) { return AvailableRecipesField?.GetValue(gui) as IList; } private static void EnsurePairAccessors(object samplePair) { if (_getPairRecipe != null || samplePair == null) { return; } Type type = samplePair.GetType(); PropertyInfo pRecipe = AccessTools.Property(type, "Recipe"); if (pRecipe != null) { _getPairRecipe = delegate(object o) { object? value = pRecipe.GetValue(o, null); return (Recipe)((value is Recipe) ? value : null); }; } else { FieldInfo f = AccessTools.Field(type, "Recipe") ?? AccessTools.Field(type, "<Recipe>k__BackingField"); _getPairRecipe = delegate(object o) { object? obj = f?.GetValue(o); return (Recipe)((obj is Recipe) ? obj : null); }; } PropertyInfo pItem = AccessTools.Property(type, "ItemData"); if (pItem != null) { _getPairItemData = delegate(object o) { object? value = pItem.GetValue(o, null); return (ItemData)((value is ItemData) ? value : null); }; } else { FieldInfo f2 = AccessTools.Field(type, "ItemData") ?? AccessTools.Field(type, "<ItemData>k__BackingField"); _getPairItemData = delegate(object o) { object? obj = f2?.GetValue(o); return (ItemData)((obj is ItemData) ? obj : null); }; } PropertyInfo pElement = AccessTools.Property(type, "InterfaceElement"); if (pElement != null) { _getPairElement = delegate(object o) { object? value = pElement.GetValue(o, null); return (GameObject)((value is GameObject) ? value : null); }; return; } FieldInfo f3 = AccessTools.Field(type, "InterfaceElement") ?? AccessTools.Field(type, "<InterfaceElement>k__BackingField"); _getPairElement = delegate(object o) { object? obj = f3?.GetValue(o); return (GameObject)((obj is GameObject) ? obj : null); }; } private static string PrefabNameOf(Recipe recipe) { if (!((Object)(object)recipe != (Object)null) || !((Object)(object)recipe.m_item != (Object)null)) { return null; } return ((Object)((Component)recipe.m_item).gameObject).name; } internal static string PinKeyFor(Recipe recipe, ItemData upgradeItem) { string text = PrefabNameOf(recipe); if (string.IsNullOrEmpty(text)) { return null; } if (upgradeItem != null && upgradeItem.m_quality >= 1) { int num = upgradeItem.m_quality + 1; if (num >= 2) { return PinStore.UpgradePinKey(text, num); } } return PinStore.CraftPinKey(text); } private static void AttachPin(InventoryGui gui, GameObject element, Recipe recipe, ItemData upgradeItem) { //IL_0065: 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_0083: 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_00ad: Unknown result type (might be due to invalid IL or missing references) RecipePinInteraction recipePinInteraction = element.GetComponent<RecipePinInteraction>() ?? element.AddComponent<RecipePinInteraction>(); recipePinInteraction.Owner = gui; recipePinInteraction.Recipe = recipe; recipePinInteraction.PinKey = PinKeyFor(recipe, upgradeItem); if ((Object)(object)recipePinInteraction.PinImage == (Object)null) { Image val = UiUtils.NewImage(element.transform, "PinThoseRecipes_PinIcon", PinIcon.Sprite); RectTransform rectTransform = ((Graphic)val).rectTransform; UiUtils.SetAnchors(rectTransform, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(1f, 1f)); rectTransform.sizeDelta = new Vector2(20f, 20f); rectTransform.anchoredPosition = new Vector2(-4f, -4f); ((Transform)rectTransform).SetAsLastSibling(); recipePinInteraction.PinImage = val; } else if ((Object)(object)recipePinInteraction.PinImage.sprite == (Object)null) { recipePinInteraction.PinImage.sprite = PinIcon.Sprite; } recipePinInteraction.RefreshPinVisual(); } private static void ReorderPinned(InventoryGui gui) { //IL_017f: Unknown result type (might be due to invalid IL or missing references) if (IsReordering) { return; } IList availableRecipes = GetAvailableRecipes(gui); if (availableRecipes == null || availableRecipes.Count == 0) { return; } IsReordering = true; try { EnsurePairAccessors(availableRecipes[0]); float recipeListSpace = gui.m_recipeListSpace; int count = availableRecipes.Count; List<Entry> list = new List<Entry>(count); for (int i = 0; i < count; i++) { object obj = availableRecipes[i]; Recipe recipe = _getPairRecipe(obj); ItemData upgradeItem = ((_getPairItemData != null) ? _getPairItemData(obj) : null); list.Add(new Entry { Pair = obj, Element = _getPairElement(obj), PinKey = PinKeyFor(recipe, upgradeItem), Original = i }); } List<Entry> list2 = (from e in list orderby (!PinStore.IsPinned(e.PinKey)) ? 1 : 0, (!PinStore.IsPinned(e.PinKey)) ? e.Original : PinStore.GetPinIndex(e.PinKey) select e).ToList(); for (int num = 0; num < list2.Count; num++) { Entry entry = list2[num]; availableRecipes[num] = entry.Pair; if ((Object)(object)entry.Element != (Object)null) { entry.Element.transform.SetSiblingIndex(num); Transform transform = entry.Element.transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (val != null) { val.anchoredPosition = new Vector2(0f, (float)num * (0f - recipeListSpace)); } entry.Element.GetComponent<RecipePinInteraction>()?.RefreshPinVisual(); } } } catch (Exception ex) { ManualLogSource log = PinThoseRecipesPlugin.Log; if (log != null) { log.LogError((object)("Reorder failed: " + ex)); } } finally { IsReordering = false; } } } internal static class ProfileLifecyclePatches { [HarmonyPatch(typeof(Game), "Start")] private static class GameStartPatch { private static void Postfix() { SyncProfile(); } } [HarmonyPatch(typeof(Game), "Logout")] private static class GameLogoutPatch { private static bool Prepare() { return AccessTools.Method(typeof(Game), "Logout", (Type[])null, (Type[])null) != null; } private static void Prefix() { PinStore.ClearActive(); RecipeResolver.InvalidateCache(); } } internal static void SyncProfile() { Game instance = Game.instance; if ((Object)(object)instance == (Object)null) { PinStore.ClearActive(); return; } PlayerProfile playerProfile = instance.GetPlayerProfile(); string text = ((playerProfile != null) ? playerProfile.GetFilename() : null); if (string.IsNullOrEmpty(text)) { text = ((playerProfile != null) ? playerProfile.GetName() : null); } if (!string.IsNullOrEmpty(text)) { PinStore.LoadForProfile(text); } } } internal static class ObjectDbPatches { [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDbAwakePatch { private static void Postfix() { RecipeResolver.InvalidateCache(); PieceResolver.InvalidateCache(); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] private static class ObjectDbCopyOtherPatch { private static bool Prepare() { return AccessTools.Method(typeof(ObjectDB), "CopyOtherDB", (Type[])null, (Type[])null) != null; } private static void Postfix() { RecipeResolver.InvalidateCache(); PieceResolver.InvalidateCache(); } } } internal static class HudPiecePatches { [HarmonyPatch(typeof(Hud), "OnRightClickPiece")] private static class OnRightClickPiecePatch { private static bool Prepare() { return AccessTools.Method(typeof(Hud), "OnRightClickPiece", (Type[])null, (Type[])null) != null; } private static bool Prefix(Hud __instance, UIInputHandler ih) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) if (PinConfig.Enabled != null && !PinConfig.Enabled.Value) { return true; } if ((Object)(object)ih == (Object)null || !PinStore.HasActiveProfile || (Object)(object)Player.m_localPlayer == (Object)null) { return true; } MethodInfo methodInfo = AccessTools.Method(typeof(Hud), "GetSelectedGrid", (Type[])null, (Type[])null); if (methodInfo == null) { return true; } if (!(methodInfo.Invoke(__instance, new object[1] { ih }) is Vector2Int val) || ((Vector2Int)(ref val)).x < 0) { return true; } Piece piece = Player.m_localPlayer.GetPiece(val); if ((Object)(object)piece == (Object)null) { return true; } string text = Utils.GetPrefabName(((Component)piece).gameObject); if (string.IsNullOrEmpty(text)) { text = ((Object)((Component)piece).gameObject).name; } PinStore.ToggleBuild(text); PinSound.Play(); PiecePinOverlay.Refresh(((Component)ih).gameObject, text); return false; } } [HarmonyPatch(typeof(Hud), "UpdatePieceList")] private static class UpdatePieceListPatch { private static bool Prepare() { return AccessTools.Method(typeof(Hud), "UpdatePieceList", (Type[])null, (Type[])null) != null; } private static void Postfix(Hud __instance) { if (PinConfig.Enabled != null && !PinConfig.Enabled.Value) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !(PieceIconsField?.GetValue(__instance) is IList { Count: not 0 } list)) { return; } if (_fGo == null && list.Count > 0) { _fGo = AccessTools.Field(list[0].GetType(), "m_go"); } List<Piece> buildPieces = localPlayer.GetBuildPieces(); for (int i = 0; i < list.Count; i++) { object? obj = _fGo?.GetValue(list[i]); GameObject val = (GameObject)((obj is GameObject) ? obj : null); if ((Object)(object)val == (Object)null) { continue; } if (buildPieces != null && i < buildPieces.Count && (Object)(object)buildPieces[i] != (Object)null) { string text = Utils.GetPrefabName(((Component)buildPieces[i]).gameObject); if (string.IsNullOrEmpty(text)) { text = ((Object)((Component)buildPieces[i]).gameObject).name; } PiecePinOverlay.Refresh(val, text); } else { PiecePinOverlay.Hide(val); } } } } private static FieldInfo _fPieceIcons; private static FieldInfo _fGo; private static FieldInfo PieceIconsField => _fPieceIcons ?? (_fPieceIcons = AccessTools.Field(typeof(Hud), "m_pieceIcons")); } internal static class PiecePinOverlay { private const string ChildName = "PinThoseRecipes_BuildPin"; internal static void Refresh(GameObject pieceIconGo, string prefabName) { if (!((Object)(object)pieceIconGo == (Object)null)) { Image val = EnsureImage(pieceIconGo); bool flag = PinStore.IsBuildPinned(prefabName); if (((Component)val).gameObject.activeSelf != flag) { ((Component)val).gameObject.SetActive(flag); } if (flag && (Object)(object)val.sprite == (Object)null) { val.sprite = PinIcon.BuildSprite; } } } internal static void Hide(GameObject pieceIconGo) { if (!((Object)(object)pieceIconGo == (Object)null)) { Transform val = pieceIconGo.transform.Find("PinThoseRecipes_BuildPin"); if ((Object)(object)val != (Object)null && ((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(false); } } } private static Image EnsureImage(GameObject pieceIconGo) { //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) //IL_0068: 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_0092: Unknown result type (might be due to invalid IL or missing references) Transform val = pieceIconGo.transform.Find("PinThoseRecipes_BuildPin"); Image val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Image>() : UiUtils.NewImage(pieceIconGo.transform, "PinThoseRecipes_BuildPin", PinIcon.Buil