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 RecipeHelper v1.0.0
plugins/RecipeHelper/RecipeHelper.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Microsoft.CodeAnalysis; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using RoR2.UI; 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: InternalsVisibleTo("RecipeHelper.Tests")] [assembly: IgnoresAccessChecksTo("RoR2")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("RecipeHelper")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+c265deeb7e73cc1aa7960d20b0b9601e12f961d8")] [assembly: AssemblyProduct("RecipeHelper")] [assembly: AssemblyTitle("RecipeHelper")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [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 RecipeHelper { internal sealed class CraftingPanelWatcher : MonoBehaviour { private HUD hud; private int lastChildCount; private void Awake() { hud = ((Component)this).GetComponent<HUD>(); Log("watching HUD '" + ((Object)this).name + "'"); } private static void Log(string message) { if (RecipeHelperPlugin.Settings.DebugLogging.Value) { RecipeHelperPlugin.Log.LogInfo((object)("Watcher: " + message)); } } private void Update() { Transform val = (Object.op_Implicit((Object)(object)hud) ? hud.mainContainer.transform : null); if (!Object.op_Implicit((Object)(object)val) || val.childCount == lastChildCount) { return; } lastChildCount = val.childCount; CraftingPanel[] componentsInChildren = ((Component)val).GetComponentsInChildren<CraftingPanel>(true); foreach (CraftingPanel val2 in componentsInChildren) { Log($"found CraftingPanel '{((Object)val2).name}' active={((Component)val2).gameObject.activeInHierarchy} sidebar={Object.op_Implicit((Object)(object)((Component)val2).GetComponent<RecipeSidebar>())}"); if (!Object.op_Implicit((Object)(object)((Component)val2).GetComponent<RecipeSidebar>())) { ((Component)val2).gameObject.AddComponent<RecipeSidebar>().Init(hud); } } } } internal sealed class CraftPlan { public PickupIndex Result; public List<CraftStep> Steps; } internal sealed class CraftStep { public RecipeEntry Recipe; public PickupIndex[] Ingredients; public PickupIndex Result => Recipe.result; public int Amount => Recipe.amountToDrop; } internal sealed class InventorySnapshot { private readonly Dictionary<PickupIndex, int> counts; public bool IsEmpty => counts.Count == 0; public InventorySnapshot(Dictionary<PickupIndex, int> counts) { this.counts = counts; } public int Count(PickupIndex pickup) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (!counts.TryGetValue(pickup, out var value)) { return 0; } return value; } public static InventorySnapshot FromInventory(Inventory inventory) { //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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) Dictionary<PickupIndex, int> dictionary = new Dictionary<PickupIndex, int>(); if (!Object.op_Implicit((Object)(object)inventory)) { return new InventorySnapshot(dictionary); } EquipmentIndex equipmentIndex = inventory.GetEquipmentIndex(); if ((int)equipmentIndex != -1) { dictionary[PickupCatalog.FindPickupIndex(equipmentIndex)] = 1; } foreach (ItemIndex item in inventory.itemAcquisitionOrder) { ItemDef itemDef = ItemCatalog.GetItemDef(item); int itemCountPermanent = inventory.GetItemCountPermanent(item); if (Object.op_Implicit((Object)(object)itemDef) && ((itemDef.canRemove && !itemDef.hidden && itemCountPermanent > 0) || itemDef.ContainsTag((ItemTag)30)) && itemCountPermanent > 0) { dictionary[PickupCatalog.FindPickupIndex(item)] = itemCountPermanent; } } return new InventorySnapshot(dictionary); } public InventorySnapshot Apply(CraftStep step) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_003e: 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_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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_0066: Invalid comparison between Unknown and I4 //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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_009a: Invalid comparison between Unknown and I4 //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) Dictionary<PickupIndex, int> dictionary = new Dictionary<PickupIndex, int>(counts); PickupIndex[] ingredients = step.Ingredients; foreach (PickupIndex key in ingredients) { int num = dictionary[key] - 1; if (num > 0) { dictionary[key] = num; } else { dictionary.Remove(key); } } PickupDef pickupDef = PickupCatalog.GetPickupDef(step.Result); if (pickupDef != null && (int)pickupDef.equipmentIndex != -1) { foreach (PickupIndex item in dictionary.Keys.ToList()) { PickupDef pickupDef2 = PickupCatalog.GetPickupDef(item); if (pickupDef2 != null && (int)pickupDef2.equipmentIndex != -1) { dictionary.Remove(item); } } dictionary[step.Result] = 1; } else { dictionary.TryGetValue(step.Result, out var value); dictionary[step.Result] = value + step.Amount; } return new InventorySnapshot(dictionary); } public string Key() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); foreach (KeyValuePair<PickupIndex, int> item in counts.OrderBy((KeyValuePair<PickupIndex, int> p) => p.Key.value)) { stringBuilder.Append(item.Key.value).Append(':').Append(item.Value) .Append(','); } return stringBuilder.ToString(); } public override string ToString() { return string.Join(", ", counts.Select((KeyValuePair<PickupIndex, int> p) => PickupCatalog.GetPickupDef(p.Key)?.internalName + " x" + p.Value)); } } internal static class ListView { public const string Hint = "Click a row to put its first craft in the slots."; private const float ResultSize = 44f; private const float NextSize = 24f; private const int MaxAlternateNames = 3; private const float LaterStepAlpha = 0.55f; private static readonly Color RowHover = new Color(1f, 1f, 1f, 0.09f); private static readonly Color RowInSlots = Color32.op_Implicit(new Color32((byte)143, (byte)163, (byte)199, (byte)41)); private static readonly Color BadgeInSlots = Color32.op_Implicit(new Color32((byte)195, (byte)210, (byte)238, byte.MaxValue)); private static readonly Color BadgeDefault = Color32.op_Implicit(new Color32((byte)143, (byte)163, (byte)199, (byte)38)); private static readonly Color BadgeInSlotsText = Color32.op_Implicit(new Color32((byte)11, (byte)14, (byte)20, byte.MaxValue)); public static List<SidebarBlock> Blocks(List<CraftPlan> plans, InventorySnapshot start, Func<CraftStep, bool> inSlots, Action<CraftStep> fill) { List<SidebarBlock> list = new List<SidebarBlock> { new SidebarBlock { Build = delegate(RectTransform parent, float width) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) Ui.Text((Transform)(object)parent, "Click a row to put its first craft in the slots.", 12f, Ui.Muted); } } }; foreach (CraftPlan plan in plans) { CraftPlan captured = plan; list.Add(new SidebarBlock { Group = GroupLabel(plan.Steps.Count), Results = 1, Build = delegate(RectTransform parent, float width) { Row(parent, captured, StepDetail.Build(start, captured), inSlots(captured.Steps[0]), fill); } }); } return list; } private static string GroupLabel(int steps) { if (steps != 1) { return "IN " + steps + " CRAFTS"; } return "NOW"; } private static void Row(RectTransform parent, CraftPlan plan, List<StepDetail> details, bool inSlots, Action<CraftStep> fill) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Expected O, but got Unknown //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0208: 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) RectTransform val = Ui.Row((Transform)(object)parent, "Recipe", 12f); Ui.Pad(val, 8); ((LayoutGroup)((Component)val).GetComponent<HorizontalLayoutGroup>()).childAlignment = (TextAnchor)3; Image val2 = ((Component)val).gameObject.AddComponent<Image>(); Color val3 = (((Graphic)val2).color = (inSlots ? RowInSlots : Ui.CardBackground)); Ui.Tile((Transform)(object)val, plan.Result, 44f); RectTransform val5 = Ui.Stack((Transform)(object)val, "Body", 5f, (TextAnchor)0); Ui.Flexible(val5); int amount = plan.Steps[plan.Steps.Count - 1].Amount; Ui.Text((Transform)(object)val5, Ui.Name(plan.Result) + ((amount > 1) ? (" x" + amount) : ""), 16f, Ui.TierColor(plan.Result)); for (int i = 0; i < details.Count; i++) { Craft(val5, details[i], (details.Count > 1) ? (i + 1) : 0); string text = ((i == 0) ? AlternateNames(details[0]) : null); if (text != null) { Ui.Text((Transform)(object)val5, text, 11f, Ui.Muted); } } Badge(val, inSlots ? "In slots" : ((plan.Steps.Count == 1) ? "1 craft" : (plan.Steps.Count + " crafts")), inSlots); Button obj = ((Component)val).gameObject.AddComponent<Button>(); ((Selectable)obj).targetGraphic = (Graphic)(object)val2; ((Selectable)obj).transition = (Transition)0; Navigation navigation = default(Navigation); ((Navigation)(ref navigation)).mode = (Mode)0; ((Selectable)obj).navigation = navigation; CraftStep step = plan.Steps[0]; ((UnityEvent)obj.onClick).AddListener((UnityAction)delegate { fill(step); }); HoverColor hoverColor = ((Component)val).gameObject.AddComponent<HoverColor>(); hoverColor.Target = val2; hoverColor.Normal = val3; hoverColor.Hover = (inSlots ? val3 : RowHover); } private static void Craft(RectTransform body, StepDetail detail, int number) { //IL_0038: 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_0090: Unknown result type (might be due to invalid IL or missing references) RectTransform val = Ui.Row((Transform)(object)body, "Craft", 4f); ((LayoutGroup)((Component)val).GetComponent<HorizontalLayoutGroup>()).childAlignment = (TextAnchor)3; if (number > 0) { Ui.Size(((TMP_Text)Ui.Text((Transform)(object)val, number + ".", 11f, Ui.Muted)).rectTransform, 14f, 24f); } if (number > 1) { ((Component)val).gameObject.AddComponent<CanvasGroup>().alpha = 0.55f; } for (int i = 0; i < detail.Slots.Length; i++) { if (i > 0) { Ui.Glyph((Transform)(object)val, "+", 24f); } Ui.Tile((Transform)(object)val, detail.Slots[i].Chosen, 24f, detail.Slots[i].MadeByEarlierStep); } Ui.Glyph((Transform)(object)val, "→", 24f); Ui.Tile((Transform)(object)val, detail.Step.Result, 24f); } private static string AlternateNames(StepDetail next) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) List<string> list = new List<string>(); SlotDetail[] slots = next.Slots; for (int i = 0; i < slots.Length; i++) { foreach (PickupIndex alternate in slots[i].Alternates) { list.Add(Ui.Name(alternate)); } } if (list.Count == 0) { return null; } string text = string.Join(", ", list.GetRange(0, Math.Min(list.Count, 3))); return "or " + text + ((list.Count > 3) ? (" +" + (list.Count - 3) + " more") : ""); } private static void Badge(RectTransform row, string text, bool inSlots) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_002f: 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) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) RectTransform obj = Ui.Row((Transform)(object)row, "Badge", 0f); ((LayoutGroup)((Component)obj).GetComponent<HorizontalLayoutGroup>()).padding = new RectOffset(8, 8, 3, 3); Ui.Background(obj, inSlots ? BadgeInSlots : BadgeDefault); ((TMP_Text)Ui.Text((Transform)(object)obj, text, 11f, inSlots ? BadgeInSlotsText : Ui.Muted)).enableWordWrapping = false; } } internal sealed class HoverColor : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { public Image Target; public Color Normal; public Color Hover; public void OnPointerEnter(PointerEventData eventData) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) ((Graphic)Target).color = Hover; } public void OnPointerExit(PointerEventData eventData) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) ((Graphic)Target).color = Normal; } } internal static class PickupRarity { public static int Rank(PickupIndex index) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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) PickupDef pickupDef = PickupCatalog.GetPickupDef(index); if (pickupDef == null) { return 0; } if ((int)pickupDef.itemIndex != -1) { ItemDef itemDef = ItemCatalog.GetItemDef(pickupDef.itemIndex); if (!Object.op_Implicit((Object)(object)itemDef)) { return 0; } return ItemRank(itemDef.tier); } if ((int)pickupDef.equipmentIndex != -1) { EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(pickupDef.equipmentIndex); if (!Object.op_Implicit((Object)(object)equipmentDef)) { return 0; } if (equipmentDef.isBoss) { return ItemRank((ItemTier)4); } if (equipmentDef.isLunar) { return ItemRank((ItemTier)3); } return 4; } return 0; } private static int ItemRank(ItemTier tier) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected I4, but got Unknown switch ((int)tier) { case 10: return 9; case 2: case 8: return 8; case 4: case 9: return 7; case 3: return 6; case 1: case 7: return 3; case 0: case 6: return 2; default: return 1; } } } internal sealed class PluginConfig { public readonly ConfigEntry<bool> Enabled; public readonly ConfigEntry<int> MaxChainSteps; public readonly ConfigEntry<bool> DebugLogging; public readonly ConfigEntry<bool> DebugAlwaysShow; public readonly ConfigEntry<KeyboardShortcut> DumpKey; public PluginConfig(ConfigFile config) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) Enabled = config.Bind<bool>("Sidebar", "Enabled", true, "Show the list of craftable items beside the Wandering CHEF's crafting dialog."); MaxChainSteps = config.Bind<int>("Sidebar", "MaxChainSteps", 3, new ConfigDescription("The most crafts in a row to look ahead, counting crafts whose results are used as ingredients in later ones.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 5), Array.Empty<object>())); DebugLogging = config.Bind<bool>("Debug", "DebugLogging", false, "Enable the dump key, which logs the recipe catalog size and the plan for your inventory."); DebugAlwaysShow = config.Bind<bool>("Debug", "DebugAlwaysShow", false, "List every recipe regardless of your inventory, for testing the layout."); DumpKey = config.Bind<KeyboardShortcut>("Debug", "DumpKey", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "With DebugLogging on, press to log the recipe catalog size and the plan for your inventory."); } } internal static class RecipeBook { private static Run builtFor; private static RecipePlanner planner; public static RecipePlanner Planner { get { if (planner == null || (Object)(object)builtFor != (Object)(object)Run.instance) { RecipeEntry[] allRecipes = CraftableCatalog.GetAllRecipes(); if (Object.op_Implicit((Object)(object)Run.instance)) { CraftableCatalog.FilterByEntitlement(ref allRecipes); } planner = new RecipePlanner(allRecipes); builtFor = Run.instance; } return planner; } } } [BepInPlugin("sevenstack.RecipeHelper", "RecipeHelper", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class RecipeHelperPlugin : BaseUnityPlugin { public const string PluginGUID = "sevenstack.RecipeHelper"; public const string PluginName = "RecipeHelper"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource Log; internal static PluginConfig Settings; private void Awake() { Log = ((BaseUnityPlugin)this).Logger; Settings = new PluginConfig(((BaseUnityPlugin)this).Config); if (RiskOfOptionsCompat.Enabled) { RiskOfOptionsCompat.Register(Settings); } HUD.onHudTargetChangedGlobal += OnHudTargetChanged; } private void OnDestroy() { HUD.onHudTargetChangedGlobal -= OnHudTargetChanged; } private static void OnHudTargetChanged(HUD hud) { if (Settings.Enabled.Value && Object.op_Implicit((Object)(object)hud) && !Object.op_Implicit((Object)(object)((Component)hud).GetComponent<CraftingPanelWatcher>())) { ((Component)hud).gameObject.AddComponent<CraftingPanelWatcher>(); } } private void Update() { //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) if (Settings.DebugLogging.Value) { KeyboardShortcut value = Settings.DumpKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { Dump(); } } } private static void Dump() { //IL_008c: Unknown result type (might be due to invalid IL or missing references) LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); Inventory inventory = (Object.op_Implicit((Object)(object)((firstLocalUser != null) ? firstLocalUser.cachedMaster : null)) ? firstLocalUser.cachedMaster.inventory : null); RecipePlanner planner = RecipeBook.Planner; InventorySnapshot inventorySnapshot = InventorySnapshot.FromInventory(inventory); Log.LogInfo((object)$"Recipe dump: {CraftableCatalog.GetAllRecipes().Length} recipes, inventory: {inventorySnapshot}"); foreach (CraftPlan item in planner.Plan(inventorySnapshot, Settings.MaxChainSteps.Value, 20000)) { Log.LogInfo((object)string.Format(" {0} in {1}: {2}", PickupCatalog.GetPickupDef(item.Result)?.internalName, item.Steps.Count, string.Join(" ; ", item.Steps.ConvertAll((CraftStep s) => string.Join("+", Array.ConvertAll(s.Ingredients, (PickupIndex i) => PickupCatalog.GetPickupDef(i)?.internalName)) + "->" + PickupCatalog.GetPickupDef(s.Result)?.internalName)))); } } } internal sealed class RecipePlanner { private sealed class Node { public InventorySnapshot State; public List<CraftStep> Path; } private readonly RecipeEntry[] recipes; private readonly HashSet<PickupIndex> intermediates = new HashSet<PickupIndex>(); public bool HitBudget { get; private set; } public RecipePlanner(RecipeEntry[] recipes) { //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) //IL_0058: Unknown result type (might be due to invalid IL or missing references) this.recipes = recipes; for (int i = 0; i < recipes.Length; i++) { IngredientSlotEntry[] possibleIngredients = recipes[i].possibleIngredients; foreach (IngredientSlotEntry val in possibleIngredients) { if (val.pickups != null) { PickupIndex[] pickups = val.pickups; foreach (PickupIndex item in pickups) { intermediates.Add(item); } } } } } public List<CraftPlan> Plan(InventorySnapshot start, int maxSteps, int stateBudget) { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) HitBudget = false; Dictionary<PickupIndex, CraftPlan> dictionary = new Dictionary<PickupIndex, CraftPlan>(); HashSet<string> hashSet = new HashSet<string> { start.Key() }; List<Node> list = new List<Node> { new Node { State = start, Path = new List<CraftStep>() } }; int num = 0; for (int i = 1; i <= maxSteps; i++) { if (list.Count <= 0) { break; } List<Node> list2 = new List<Node>(); foreach (Node item in list) { foreach (CraftStep item2 in EnumerateCrafts(item.State)) { List<CraftStep> list3 = new List<CraftStep>(item.Path) { item2 }; if (!dictionary.ContainsKey(item2.Result)) { dictionary[item2.Result] = new CraftPlan { Result = item2.Result, Steps = list3 }; } if (i == maxSteps || !intermediates.Contains(item2.Result)) { continue; } InventorySnapshot inventorySnapshot = item.State.Apply(item2); if (hashSet.Add(inventorySnapshot.Key())) { if (++num > stateBudget) { HitBudget = true; return Sorted(dictionary); } list2.Add(new Node { State = inventorySnapshot, Path = list3 }); } } } list = list2; } return Sorted(dictionary); } private static List<CraftPlan> Sorted(Dictionary<PickupIndex, CraftPlan> best) { return (from p in best.Values orderby p.Steps.Count, PickupRarity.Rank(p.Result) descending, Language.GetString(PickupCatalog.GetPickupDef(p.Result)?.nameToken ?? "") select p).ToList(); } internal IEnumerable<CraftStep> EnumerateCrafts(InventorySnapshot state) { RecipeEntry[] array = recipes; foreach (RecipeEntry recipe in array) { HashSet<string> emitted = new HashSet<string>(); PickupIndex[] chosen = (PickupIndex[])(object)new PickupIndex[recipe.possibleIngredients.Length]; foreach (PickupIndex[] item2 in Fill(recipe, state, chosen, 0)) { string item = string.Join(",", from p in item2 select p.value into v orderby v select v); if (emitted.Add(item)) { yield return new CraftStep { Recipe = recipe, Ingredients = (PickupIndex[])item2.Clone() }; } } } } private static IEnumerable<PickupIndex[]> Fill(RecipeEntry recipe, InventorySnapshot state, PickupIndex[] chosen, int slot) { if (slot == chosen.Length) { yield return chosen; yield break; } PickupIndex[] pickups = recipe.possibleIngredients[slot].pickups; if (pickups == null) { yield break; } PickupIndex[] array = pickups; foreach (PickupIndex val in array) { int num = 0; for (int j = 0; j < slot; j++) { if (chosen[j] == val) { num++; } } if (state.Count(val) <= num) { continue; } chosen[slot] = val; foreach (PickupIndex[] item in Fill(recipe, state, chosen, slot + 1)) { yield return item; } } } } internal sealed class RecipeSidebar : MonoBehaviour { private const string Header = "You can craft"; private const string ContinuedHeader = "You can craft (continued)"; private const string NothingHeader = "Nothing to craft"; private const int SettleFrames = 3; private CraftingPanel panel; private Inventory inventory; private SidebarColumn left; private SidebarColumn right; private bool rendered; private bool lastTruncated; private bool settled; private int stillFrames; private Rect lastWindow; private int lastSlots; private InventorySnapshot snapshot; internal List<CraftPlan> Plans { get; private set; } = new List<CraftPlan>(); public void Init(HUD owner) { panel = ((Component)this).GetComponent<CraftingPanel>(); left = new SidebarColumn(((Component)this).transform, "RecipeHelperSidebarLeft"); right = new SidebarColumn(((Component)this).transform, "RecipeHelperSidebarRight"); right.Hide(); if (RecipeHelperPlugin.Settings.DebugLogging.Value) { RecipeHelperPlugin.Log.LogInfo((object)("Sidebar: built on '" + ((Object)this).name + "'")); } } private void Update() { CraftingController craftingController = panel.craftingController; object obj; if (craftingController == null) { obj = null; } else { NetworkUIPromptController networkUIPromptController = ((PickupPickerController)craftingController).networkUIPromptController; obj = ((networkUIPromptController != null) ? networkUIPromptController.currentParticipantMaster : null); } CharacterMaster val = (CharacterMaster)obj; Inventory val2 = (Object.op_Implicit((Object)(object)val) ? val.inventory : null); WatchWindow(); WatchSlots(); if (!rendered || !((Object)(object)val2 == (Object)(object)inventory)) { if (Object.op_Implicit((Object)(object)inventory)) { inventory.onInventoryChanged -= Refresh; } inventory = val2; if (Object.op_Implicit((Object)(object)inventory)) { inventory.onInventoryChanged += Refresh; } rendered = true; Refresh(); } } private void WatchWindow() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //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_0017: 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_0026: 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) Rect val = SidebarLayout.Anchor(panel, (RectTransform)((Component)this).transform); if (val != lastWindow) { lastWindow = val; stillFrames = 0; if (settled) { settled = false; left.Hide(); right.Hide(); } } else if (!settled && ++stillFrames >= 3) { settled = true; if (rendered) { Render(lastTruncated); } } } private void WatchSlots() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) CraftingController craftingController = panel.craftingController; PickupIndex[] array = ((craftingController != null) ? craftingController.ingredients : null); int num = 17; if (array != null) { PickupIndex[] array2 = array; foreach (PickupIndex val in array2) { num = num * 31 + val.value; } } if (num != lastSlots) { lastSlots = num; if (rendered && settled) { Render(lastTruncated); } } } private void FillSlots(CraftStep step) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!SlotFiller.Fill(panel.craftingController, ((Component)this).GetComponent<PickupPickerPanel>(), step) && RecipeHelperPlugin.Settings.DebugLogging.Value) { RecipeHelperPlugin.Log.LogInfo((object)("Sidebar: the dialog doesn't offer every ingredient of " + Ui.Name(step.Result) + "; slots left as they were.")); } } private void OnDestroy() { if (Object.op_Implicit((Object)(object)inventory)) { inventory.onInventoryChanged -= Refresh; } } private void Refresh() { PluginConfig settings = RecipeHelperPlugin.Settings; RecipePlanner planner = RecipeBook.Planner; snapshot = (settings.DebugAlwaysShow.Value ? EverythingSnapshot() : InventorySnapshot.FromInventory(inventory)); int maxSteps = (settings.DebugAlwaysShow.Value ? 1 : settings.MaxChainSteps.Value); Plans = planner.Plan(snapshot, maxSteps, 20000); if (planner.HitBudget && settings.DebugLogging.Value) { RecipeHelperPlugin.Log.LogInfo((object)"Recipe search stopped at the state budget; longer chains may be missing."); } Render(planner.HitBudget); } private static InventorySnapshot EverythingSnapshot() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) Dictionary<PickupIndex, int> dictionary = new Dictionary<PickupIndex, int>(); foreach (PickupDef allPickup in PickupCatalog.allPickups) { dictionary[allPickup.pickupIndex] = 2; } return new InventorySnapshot(dictionary); } private void Render(bool truncatedSearch) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown lastTruncated = truncatedSearch; if (!settled) { return; } SidebarLayout sidebarLayout = SidebarLayout.Measure((RectTransform)((Component)this).transform, panel); if (RecipeHelperPlugin.Settings.DebugLogging.Value) { RecipeHelperPlugin.Log.LogInfo((object)string.Format("Sidebar: {0} results, inventory={1}; {2}; screen {3}x{4}", Plans.Count, Object.op_Implicit((Object)(object)inventory) ? "yes" : "none", sidebarLayout, Screen.width, Screen.height)); } left.Place(sidebarLayout.LeftX, sidebarLayout.CenterY, sidebarLayout.LeftWidth); right.Place(sidebarLayout.RightX, sidebarLayout.CenterY, sidebarLayout.RightWidth); if (Plans.Count == 0) { left.Show("Nothing to craft"); right.Hide(); return; } List<SidebarBlock> blocks = ListView.Blocks(Plans, snapshot, (CraftStep step) => SlotFiller.Holds(panel.craftingController, step), FillSlots); Flow(blocks, (!(sidebarLayout.RightWidth > 0f)) ? new SidebarColumn[1] { left } : new SidebarColumn[2] { left, right }, sidebarLayout.Height); if (sidebarLayout.RightWidth <= 0f) { right.Hide(); } } private void Flow(List<SidebarBlock> blocks, SidebarColumn[] columns, float maxHeight) { int num = 0; columns[0].Show("You can craft"); for (int i = 1; i < columns.Length; i++) { columns[i].Hide(); } string text = null; int num2 = 0; int num3 = 0; foreach (SidebarBlock block in blocks) { num3 += block.Results; } for (int j = 0; j < blocks.Count; j++) { SidebarBlock sidebarBlock = blocks[j]; SidebarColumn sidebarColumn = columns[num]; GameObject item = ((sidebarBlock.Group != null && sidebarBlock.Group != text) ? sidebarColumn.AddLabel(sidebarBlock.Group) : null); GameObject item2 = sidebarColumn.Add(sidebarBlock); if (sidebarColumn.Height() <= maxHeight || sidebarColumn.Count <= 2) { text = sidebarBlock.Group; num2 += sidebarBlock.Results; continue; } sidebarColumn.Remove(item2); sidebarColumn.Remove(item); if (num + 1 >= columns.Length) { break; } num++; columns[num].Show("You can craft (continued)"); text = null; j--; } if (num2 < num3) { columns[num].AddText("and " + (num3 - num2) + " more"); } if (lastTruncated) { columns[num].AddText("Longer chains not searched."); } } } internal static class RecipePlannerLimits { public const int StateBudget = 20000; } internal static class RiskOfOptionsCompat { public const string GUID = "com.rune580.riskofoptions"; private const string IconResource = "RecipeHelper.icon.png"; public static bool Enabled => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"); [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void Register(PluginConfig settings) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_0034: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown ModSettingsManager.SetModDescription("Shows what you can craft at the Wandering CHEF."); Sprite val = LoadIcon(); if (Object.op_Implicit((Object)(object)val)) { ModSettingsManager.SetModIcon(val); } ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(settings.Enabled)); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(settings.MaxChainSteps, new IntSliderConfig { min = 1, max = 5 })); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(settings.DebugLogging)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(settings.DebugAlwaysShow)); ModSettingsManager.AddOption((BaseOption)new KeyBindOption(settings.DumpKey)); } private static Sprite LoadIcon() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) using Stream stream = typeof(RiskOfOptionsCompat).Assembly.GetManifestResourceStream("RecipeHelper.icon.png"); if (stream == null) { return null; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, memoryStream.ToArray())) { return null; } return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } } internal sealed class SidebarBlock { public string Group; public int Results; public Action<RectTransform, float> Build; } internal sealed class SidebarColumn { private const int Padding = 12; private const float Spacing = 10f; private const float HeaderFontSize = 24f; private const float LabelFontSize = 13f; private static readonly Color BackgroundColor = new Color(0f, 0f, 0f, 0.62f); public readonly GameObject Root; public readonly RectTransform Rect; private readonly TextMeshProUGUI header; private readonly List<GameObject> content = new List<GameObject>(); public float InnerWidth => Rect.sizeDelta.x - 24f; public int Count => content.Count; public SidebarColumn(Transform parent, string name) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) Rect = Ui.Stack(parent, name, 10f, (TextAnchor)0); Root = ((Component)Rect).gameObject; ((Transform)Rect).SetAsLastSibling(); Ui.Pad(Rect, 12); Ui.Background(Rect, BackgroundColor); Root.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2; header = Ui.Text((Transform)(object)Rect, "", 24f, Color.white); } public void Place(float x, float y, float width) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) RectTransform rect = Rect; Vector2 anchorMin = (Rect.anchorMax = ((RectTransform)((Transform)Rect).parent).pivot); rect.anchorMin = anchorMin; Rect.pivot = new Vector2(0f, 0.5f); Rect.anchoredPosition = new Vector2(x, y); Rect.sizeDelta = new Vector2(width, Rect.sizeDelta.y); } public void Show(string title) { Clear(); Root.SetActive(true); ((TMP_Text)header).text = title; } public void Hide() { Clear(); Root.SetActive(false); } public GameObject AddLabel(string text) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) GameObject gameObject = ((Component)Ui.Text((Transform)(object)Rect, text, 13f, Ui.Muted)).gameObject; content.Add(gameObject); return gameObject; } public GameObject AddText(string text) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) GameObject gameObject = ((Component)Ui.Text((Transform)(object)Rect, text, 13f, Ui.Body)).gameObject; content.Add(gameObject); return gameObject; } public GameObject Add(SidebarBlock block) { block.Build(Rect, InnerWidth); GameObject gameObject = ((Component)((Transform)Rect).GetChild(((Transform)Rect).childCount - 1)).gameObject; content.Add(gameObject); return gameObject; } public void Remove(GameObject item) { if (Object.op_Implicit((Object)(object)item)) { content.Remove(item); item.SetActive(false); Object.Destroy((Object)(object)item); } } public float Height() { LayoutRebuilder.ForceRebuildLayoutImmediate(Rect); return LayoutUtility.GetPreferredHeight(Rect); } private void Clear() { GameObject[] array = content.ToArray(); foreach (GameObject item in array) { Remove(item); } } } internal struct SidebarLayout { private const float Margin = 12f; private const float MinWidth = 160f; private const float FallbackWidth = 360f; public float LeftX; public float LeftWidth; public float RightX; public float RightWidth; public float CenterY; public float Height; public string WindowName; public string Candidates; public static SidebarLayout Measure(RectTransform panelRect, CraftingPanel panel) { //IL_0015: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) Canvas componentInParent = ((Component)panelRect).GetComponentInParent<Canvas>(); Camera val = ((Object.op_Implicit((Object)(object)componentInParent) && (int)componentInParent.rootCanvas.renderMode != 0) ? componentInParent.rootCanvas.worldCamera : null); Vector2 val2 = ToLocal(panelRect, val, Vector2.zero); Vector2 val3 = ToLocal(panelRect, val, new Vector2((float)Screen.width, (float)Screen.height)); SidebarLayout result = new SidebarLayout { CenterY = (val2.y + val3.y) / 2f, Height = val3.y - val2.y - 24f }; StringBuilder stringBuilder = (RecipeHelperPlugin.Settings.DebugLogging.Value ? new StringBuilder() : null); RectTransform val4 = FindWindow(panelRect, panel, val, stringBuilder); result.Candidates = stringBuilder?.ToString(); if (Object.op_Implicit((Object)(object)val4)) { Vector3[] array = (Vector3[])(object)new Vector3[4]; val4.GetWorldCorners(array); Vector2 val5 = ToLocal(panelRect, val, RectTransformUtility.WorldToScreenPoint(val, array[0])); Vector2 val6 = ToLocal(panelRect, val, RectTransformUtility.WorldToScreenPoint(val, array[2])); result.WindowName = ((Object)val4).name; result.LeftX = val2.x + 12f; result.LeftWidth = val5.x - 12f - result.LeftX; result.RightX = val6.x + 12f; result.RightWidth = val3.x - 12f - result.RightX; } if (result.LeftWidth < 160f) { result.LeftX = val2.x + 12f; result.LeftWidth = 360f; result.RightWidth = 0f; } if (result.RightWidth < 160f) { result.RightWidth = 0f; } return result; } public static Rect Anchor(CraftingPanel panel, RectTransform panelRect) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) Canvas componentInParent = ((Component)panelRect).GetComponentInParent<Canvas>(); Camera camera = ((Object.op_Implicit((Object)(object)componentInParent) && (int)componentInParent.rootCanvas.renderMode != 0) ? componentInParent.rootCanvas.worldCamera : null); return ScreenRect(Object.op_Implicit((Object)(object)panel.ingredientContainer) ? panel.ingredientContainer : panelRect, camera); } private static RectTransform FindWindow(RectTransform panelRect, CraftingPanel panel, Camera camera, StringBuilder trace) { //IL_0023: 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) //IL_0030: 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_0063: 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_0088: 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_009b: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)panel.ingredientContainer) || !Object.op_Implicit((Object)(object)panel.inventoryContainer)) { return null; } Rect inner = ScreenRect(panel.ingredientContainer, camera); Rect val = ScreenRect(panel.inventoryContainer, camera); RectTransform result = null; float num = 0f; Image[] componentsInChildren = ((Component)panelRect).GetComponentsInChildren<Image>(); foreach (Image val2 in componentsInChildren) { if (!((Behaviour)val2).enabled || ((Graphic)val2).color.a <= 0f) { continue; } RectTransform rectTransform = ((Graphic)val2).rectTransform; Rect outer = ScreenRect(rectTransform, camera); if (!(((Rect)(ref outer)).width >= (float)Screen.width) && Encloses(outer, inner) && !(((Rect)(ref outer)).xMin > ((Rect)(ref val)).xMin + 1f) && !(((Rect)(ref outer)).xMax < ((Rect)(ref val)).xMax - 1f)) { trace?.Append($" {((Object)rectTransform).name}={((Rect)(ref outer)).width:0}px"); float num2 = ((Rect)(ref outer)).width * ((Rect)(ref outer)).height; if (num2 > num) { result = rectTransform; num = num2; } } } return result; } private static bool Encloses(Rect outer, Rect inner) { if (((Rect)(ref outer)).xMin <= ((Rect)(ref inner)).xMin + 1f && ((Rect)(ref outer)).xMax >= ((Rect)(ref inner)).xMax - 1f && ((Rect)(ref outer)).yMin <= ((Rect)(ref inner)).yMin + 1f) { return ((Rect)(ref outer)).yMax >= ((Rect)(ref inner)).yMax - 1f; } return false; } private static Rect ScreenRect(RectTransform rect, Camera camera) { //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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) Vector3[] array = (Vector3[])(object)new Vector3[4]; rect.GetWorldCorners(array); Vector2 val = RectTransformUtility.WorldToScreenPoint(camera, array[0]); Vector2 val2 = RectTransformUtility.WorldToScreenPoint(camera, array[2]); return Rect.MinMaxRect(val.x, val.y, val2.x, val2.y); } private static Vector2 ToLocal(RectTransform rect, Camera camera, Vector2 screenPoint) { //IL_0001: 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) Vector2 result = default(Vector2); RectTransformUtility.ScreenPointToLocalPointInRectangle(rect, screenPoint, camera, ref result); return result; } public override string ToString() { return string.Format("window='{0}' left x={1:0} w={2:0}, right x={3:0} w={4:0}, height={5:0}; candidates:{6}", WindowName ?? "not found", LeftX, LeftWidth, RightX, RightWidth, Height, Candidates); } } internal static class SlotFiller { public static bool Holds(CraftingController controller, CraftStep step) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) PickupIndex[] array = (Object.op_Implicit((Object)(object)controller) ? controller.ingredients : null); if (array == null || array.Length != step.Ingredients.Length) { return false; } bool[] array2 = new bool[array.Length]; PickupIndex[] ingredients = step.Ingredients; foreach (PickupIndex ingredient in ingredients) { int num = Array.FindIndex(array, (PickupIndex p) => p == ingredient); while (num >= 0 && array2[num]) { num = Array.FindIndex(array, num + 1, (PickupIndex p) => p == ingredient); } if (num < 0) { return false; } array2[num] = true; } return true; } public static bool Fill(CraftingController controller, PickupPickerPanel picker, CraftStep step) { //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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_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_00aa: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)controller) || !Object.op_Implicit((Object)(object)picker) || controller.ingredients == null || controller.ingredients.Length != step.Ingredients.Length) { return false; } if (Holds(controller, step)) { return true; } PickupIndex[] ingredients = step.Ingredients; foreach (PickupIndex pickup in ingredients) { if (ButtonIndex(picker, pickup) < 0) { return false; } } PickupIndex[] ingredients2 = controller.ingredients; for (int j = 0; j < ingredients2.Length; j++) { if (ingredients2[j] != PickupIndex.none) { controller.ClearSlot(j); } } ingredients = step.Ingredients; foreach (PickupIndex pickup2 in ingredients) { int num = ButtonIndex(picker, pickup2); if (num >= 0) { ((PickupPickerController)controller).SubmitChoice(num); } } return true; } private static int ButtonIndex(PickupPickerPanel picker, PickupIndex pickup) { //IL_001c: 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) Option[] pickupOptions = picker.pickupOptions; if (pickupOptions == null) { return -1; } for (int i = 0; i < pickupOptions.Length; i++) { if (pickupOptions[i].pickup.pickupIndex == pickup) { return i; } } return -1; } } internal sealed class SlotDetail { public PickupIndex Chosen; public List<PickupIndex> Alternates = new List<PickupIndex>(); public bool MadeByEarlierStep; } internal sealed class StepDetail { public CraftStep Step; public SlotDetail[] Slots; public static List<StepDetail> Build(InventorySnapshot start, CraftPlan plan) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) List<StepDetail> list = new List<StepDetail>(); HashSet<PickupIndex> hashSet = new HashSet<PickupIndex>(); InventorySnapshot inventorySnapshot = start; foreach (CraftStep step in plan.Steps) { StepDetail stepDetail = new StepDetail { Step = step, Slots = new SlotDetail[step.Ingredients.Length] }; for (int i = 0; i < step.Ingredients.Length; i++) { PickupIndex val = step.Ingredients[i]; SlotDetail slotDetail = new SlotDetail { Chosen = val, MadeByEarlierStep = hashSet.Contains(val) }; PickupIndex[] pickups = step.Recipe.possibleIngredients[i].pickups; if (pickups != null) { PickupIndex[] array = pickups; foreach (PickupIndex val2 in array) { if (val2 != val && inventorySnapshot.Count(val2) > UsedByOtherSlots(step, i, val2)) { slotDetail.Alternates.Add(val2); } } } stepDetail.Slots[i] = slotDetail; } list.Add(stepDetail); hashSet.Add(step.Result); inventorySnapshot = inventorySnapshot.Apply(step); } return list; } private static int UsedByOtherSlots(CraftStep step, int slot, PickupIndex pickup) { //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) int num = 0; for (int i = 0; i < step.Ingredients.Length; i++) { if (i != slot && step.Ingredients[i] == pickup) { num++; } } return num; } } internal static class Ui { public static readonly Color Muted = Color32.op_Implicit(new Color32((byte)143, (byte)163, (byte)199, byte.MaxValue)); public static readonly Color Body = Color32.op_Implicit(new Color32((byte)195, (byte)199, (byte)211, byte.MaxValue)); public static readonly Color CardBackground = new Color(1f, 1f, 1f, 0.05f); private static readonly Color TileBackground = Color32.op_Implicit(new Color32((byte)23, (byte)27, (byte)36, byte.MaxValue)); private const float FrameWidth = 2f; private const float IconInset = 3f; private const float MadeFrameAlpha = 0.4f; public static RectTransform Rect(Transform parent, string name) { //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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown RectTransform val = (RectTransform)new GameObject(name, new Type[1] { typeof(RectTransform) }) { layer = ((Component)parent).gameObject.layer }.transform; ((Transform)val).SetParent(parent, false); return val; } public static RectTransform Row(Transform parent, string name, float spacing) { RectTransform obj = Rect(parent, name); HorizontalLayoutGroup obj2 = ((Component)obj).gameObject.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj2).spacing = spacing; ((LayoutGroup)obj2).childAlignment = (TextAnchor)0; ((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false; return obj; } public static RectTransform Stack(Transform parent, string name, float spacing, TextAnchor alignment = (TextAnchor)0) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 RectTransform obj = Rect(parent, name); VerticalLayoutGroup obj2 = ((Component)obj).gameObject.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj2).spacing = spacing; ((LayoutGroup)obj2).childAlignment = alignment; ((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = (int)alignment == 0; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false; return obj; } public static void Pad(RectTransform rect, int padding) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown ((LayoutGroup)((Component)rect).GetComponent<HorizontalOrVerticalLayoutGroup>()).padding = new RectOffset(padding, padding, padding, padding); } public static void Background(RectTransform rect, Color color) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) Image obj = ((Component)rect).gameObject.AddComponent<Image>(); ((Graphic)obj).color = color; ((Graphic)obj).raycastTarget = false; } public static void Size(RectTransform rect, float width, float height) { LayoutElement obj = Element(rect); float minWidth = (obj.preferredWidth = width); obj.minWidth = minWidth; minWidth = (obj.preferredHeight = height); obj.minHeight = minWidth; minWidth = (obj.flexibleHeight = 0f); obj.flexibleWidth = minWidth; } public static void Flexible(RectTransform rect) { Element(rect).flexibleWidth = 1f; } private static LayoutElement Element(RectTransform rect) { LayoutElement component = ((Component)rect).GetComponent<LayoutElement>(); if (!Object.op_Implicit((Object)(object)component)) { return ((Component)rect).gameObject.AddComponent<LayoutElement>(); } return component; } public static TextMeshProUGUI Text(Transform parent, string text, float fontSize, Color color) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) HGTextMeshProUGUI obj = ((Component)Rect(parent, "Text")).gameObject.AddComponent<HGTextMeshProUGUI>(); ((TMP_Text)obj).richText = true; ((TMP_Text)obj).enableWordWrapping = true; ((TMP_Text)obj).alignment = (TextAlignmentOptions)257; ((TMP_Text)obj).fontSize = fontSize; ((Graphic)obj).color = color; ((Graphic)obj).raycastTarget = false; ((TMP_Text)obj).text = text; return (TextMeshProUGUI)(object)obj; } public static void Glyph(Transform parent, string glyph, float tileSize) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI obj = Text(parent, glyph, 16f, Muted); ((TMP_Text)obj).alignment = (TextAlignmentOptions)514; ((TMP_Text)obj).enableWordWrapping = false; Size(((TMP_Text)obj).rectTransform, 14f, tileSize); } public static RectTransform Tile(Transform parent, PickupIndex pickup, float size, bool madeByEarlierStep = false) { //IL_0000: 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_0029: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) PickupDef pickupDef = PickupCatalog.GetPickupDef(pickup); RectTransform val = Rect(parent, "Tile"); Size(val, size, size); Image obj = ((Component)val).gameObject.AddComponent<Image>(); Color color = pickupDef?.baseColor ?? Muted; color.a = (madeByEarlierStep ? 0.4f : 1f); ((Graphic)obj).color = color; ((Graphic)obj).raycastTarget = false; RectTransform obj2 = Rect((Transform)(object)val, "Background"); Fill(obj2, 2f); Image obj3 = ((Component)obj2).gameObject.AddComponent<Image>(); ((Graphic)obj3).color = TileBackground; ((Graphic)obj3).raycastTarget = false; if (pickupDef != null) { RectTransform obj4 = Rect((Transform)(object)val, "Icon"); Fill(obj4, 3f); Image val2 = ((Component)obj4).gameObject.AddComponent<Image>(); val2.preserveAspect = true; ((Graphic)val2).raycastTarget = false; ((Behaviour)val2).enabled = false; AsyncImage obj5 = ((Component)obj4).gameObject.AddComponent<AsyncImage>(); ((AsyncViewable<Sprite, Image>)(object)obj5).renderer = val2; obj5.SetAssetOrDirectReference((AsyncIconProvider)(object)pickupDef); ((Behaviour)val2).enabled = true; } return val; } public static string Name(PickupIndex pickup) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) PickupDef pickupDef = PickupCatalog.GetPickupDef(pickup); if (pickupDef == null) { return "?"; } return Language.GetString(pickupDef.nameToken); } public static Color TierColor(PickupIndex pickup) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) return PickupCatalog.GetPickupDef(pickup)?.baseColor ?? Muted; } public static void Fill(RectTransform rect, float inset) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_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) rect.anchorMin = Vector2.zero; rect.anchorMax = Vector2.one; rect.offsetMin = new Vector2(inset, inset); rect.offsetMax = new Vector2(0f - inset, 0f - inset); } } internal static class PluginVersionInfo { public const string Version = "1.0.0"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }