Decompiled source of GK2LaboratoryFolioHelper v0.3.2
plugins/GK2KnownFormulaHelper/GK2KnownFormulaHelper.dll
Decompiled a week 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.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GK2LaboratoryFolioHelper.Alchemy; using GK2LaboratoryFolioHelper.Compatibility; using GK2LaboratoryFolioHelper.Configuration; using GK2LaboratoryFolioHelper.Infrastructure; using GK2LaboratoryFolioHelper.Input; using GK2LaboratoryFolioHelper.Patches; using GK2LaboratoryFolioHelper.Runtime; using GK2LaboratoryFolioHelper.UI; using GK2LaboratoryFolioHelper.UI.Typography; using HarmonyLib; using LazyBearTechnology; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("GK2KnownFormulaHelper")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.3.2.0")] [assembly: AssemblyInformationalVersion("0.3.2+fc1450f54322fd546fa6d6f9c5cdede5eb94718c")] [assembly: AssemblyProduct("GK2KnownFormulaHelper")] [assembly: AssemblyTitle("GK2KnownFormulaHelper")] [assembly: AssemblyVersion("0.3.2.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 GK2LaboratoryFolioHelper { [BepInPlugin("w00dst0ckOo.GK2LaboratoryFolioHelper", "GK2 Known Formula Helper", "0.3.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "w00dst0ckOo.GK2LaboratoryFolioHelper"; public const string PluginName = "GK2 Known Formula Helper"; public const string PluginVersion = "0.3.2"; private readonly ModRuntime runtime = new ModRuntime(); public static Plugin Instance { get; private set; } private void Awake() { Instance = this; runtime.Initialize(((BaseUnityPlugin)this).Logger, ((BaseUnityPlugin)this).Config); } private void Update() { runtime.Update(); } private void OnDestroy() { runtime.Shutdown(); if (Instance == this) { Instance = null; } } } } namespace GK2LaboratoryFolioHelper.UI { internal sealed class AlchemyVariantControls { private const float IngredientArrowGap = 10f; private const float CounterIngredientGap = 6f; private static readonly FieldInfo PlusButtonField = AccessTools.Field(typeof(UIAlchemyWindow), "plusBtn"); private static readonly FieldInfo IngredientsField = AccessTools.Field(typeof(UIAlchemyWindow), "ingredients"); private UIAlchemyWindow window; private GameObject controls; private RectTransform controlsRect; private RectTransform leftButtonRect; private RectTransform rightButtonRect; private RectTransform counterRect; private TextMeshProUGUI counter; internal GameObject Root => controls; internal bool Build(UIAlchemyWindow target, UnityAction selectPrevious, UnityAction selectNext) { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) Destroy(); window = target; UIAlchemyWindow obj = window; Transform obj2 = ((obj != null) ? ((Component)obj).transform : null); RectTransform val = (RectTransform)(object)((obj2 is RectTransform) ? obj2 : null); object? obj3 = PlusButtonField?.GetValue(window); LazyButton val2 = (LazyButton)((obj3 is LazyButton) ? obj3 : null); LazyButton val3 = FindQueueButton(useRightArrow: false) ?? val2; LazyButton val4 = FindQueueButton(useRightArrow: true) ?? val2; if ((Object)(object)val == (Object)null || (Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null) { ModLog.Warning($"Could not create laboratory mix controls | window={(Object)(object)val != (Object)null} | queueTemplates={(Object)(object)val3 != (Object)null && (Object)(object)val4 != (Object)null}"); return false; } controls = new GameObject("GK2AlchemyMixVariants", new Type[2] { typeof(RectTransform), typeof(LayoutElement) }); controls.transform.SetParent((Transform)(object)val, false); controlsRect = controls.GetComponent<RectTransform>(); controlsRect.anchorMin = new Vector2(0.5f, 0.5f); controlsRect.anchorMax = new Vector2(0.5f, 0.5f); controlsRect.sizeDelta = Vector2.zero; controlsRect.pivot = new Vector2(0.5f, 0.5f); ((Transform)controlsRect).SetAsLastSibling(); controls.GetComponent<LayoutElement>().ignoreLayout = true; leftButtonRect = CreateButtonClone(val3, "<", selectPrevious, (Object)(object)val3 == (Object)(object)val2); counter = CreateLabel(); counterRect = ((TMP_Text)counter).rectTransform; rightButtonRect = CreateButtonClone(val4, ">", selectNext, (Object)(object)val4 == (Object)(object)val2); Position(); return true; } internal void UpdateCounter(int index, IReadOnlyList<PinnedFormulaManager.LaboratoryMixOption> options) { if (!((Object)(object)counter == (Object)null) && options != null && options.Count != 0 && index >= 0 && index < options.Count) { PinnedFormulaManager.LaboratoryMixOption laboratoryMixOption = options[index]; ((TMP_Text)counter).text = string.Format("{0}/{1}\n{2}", index + 1, options.Count, laboratoryMixOption.IsCraftable ? "Ready" : $"Missing {laboratoryMixOption.MissingItemCount}"); } } internal void Position() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)controlsRect == (Object)null || (Object)(object)window == (Object)null || !(((Component)window).transform is RectTransform)) { return; } controlsRect.anchorMin = new Vector2(0.5f, 0.5f); controlsRect.anchorMax = new Vector2(0.5f, 0.5f); controlsRect.anchoredPosition = Vector2.zero; if ((Object)(object)leftButtonRect == (Object)null || (Object)(object)rightButtonRect == (Object)null || (Object)(object)counterRect == (Object)null) { return; } if (IngredientsField?.GetValue(window) is List<UIAlchemyIngredient> { Count: not 0 } list) { float num = float.MaxValue; float num2 = float.MinValue; float num3 = float.MaxValue; float num4 = float.MinValue; Vector3[] array = (Vector3[])(object)new Vector3[4]; foreach (UIAlchemyIngredient item in list) { object obj; if (item == null) { obj = null; } else { UIItemCell cell = item.cell; obj = ((cell != null) ? ((Component)cell).transform : null); } RectTransform val = (RectTransform)((obj is RectTransform) ? obj : null); if (!((Object)(object)val == (Object)null)) { val.GetWorldCorners(array); Vector3[] array2 = array; foreach (Vector3 val2 in array2) { Vector3 val3 = ((Transform)controlsRect).InverseTransformPoint(val2); num = Mathf.Min(num, val3.x); num2 = Mathf.Max(num2, val3.x); num3 = Mathf.Min(num3, val3.y); num4 = Mathf.Max(num4, val3.y); } } } if (num == float.MaxValue) { SetControlPositions(new Vector2(-48f, 126f), new Vector2(0f, 126f), new Vector2(48f, 126f)); return; } float num5 = (num3 + num4) * 0.5f; float num6 = (num + num2) * 0.5f; float num7 = num - 10f; Rect rect = leftButtonRect.rect; Vector2 leftPosition = new Vector2(num7 - ((Rect)(ref rect)).width * 0.5f, num5); float num8 = num4 + 6f; rect = counterRect.rect; Vector2 counterPosition = new Vector2(num6, num8 + ((Rect)(ref rect)).height * 0.5f); float num9 = num2 + 10f; rect = rightButtonRect.rect; SetControlPositions(leftPosition, counterPosition, new Vector2(num9 + ((Rect)(ref rect)).width * 0.5f, num5)); } else { SetControlPositions(new Vector2(-48f, 126f), new Vector2(0f, 126f), new Vector2(48f, 126f)); } } internal void Destroy() { if ((Object)(object)controls != (Object)null) { Object.Destroy((Object)(object)controls); } window = null; controls = null; controlsRect = null; leftButtonRect = null; rightButtonRect = null; counterRect = null; counter = null; } private RectTransform CreateButtonClone(LazyButton template, string label, UnityAction action, bool replaceText) { //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) //IL_00c2: 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) GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, controls.transform, false); ((Object)val).name = "VariantButton_" + label; val.SetActive(true); LazyButton component = val.GetComponent<LazyButton>(); ((UnityEventBase)((Button)component).onClick).RemoveAllListeners(); ((UnityEvent)((Button)component).onClick).AddListener(action); ((Selectable)component).interactable = true; if (replaceText) { TMP_Text[] componentsInChildren = val.GetComponentsInChildren<TMP_Text>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].text = label; } } LayoutElement val2 = val.GetComponent<LayoutElement>() ?? val.AddComponent<LayoutElement>(); RectTransform component2 = val.GetComponent<RectTransform>(); component2.anchorMin = new Vector2(0.5f, 0.5f); component2.anchorMax = new Vector2(0.5f, 0.5f); component2.pivot = new Vector2(0.5f, 0.5f); component2.sizeDelta = new Vector2(28f, 28f); val2.minWidth = 28f; val2.preferredWidth = 28f; val2.minHeight = 28f; val2.preferredHeight = 28f; return component2; } private TextMeshProUGUI CreateLabel() { //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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: 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_00f4: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("VariantCounter", new Type[3] { typeof(RectTransform), typeof(TextMeshProUGUI), typeof(LayoutElement) }); val.transform.SetParent(controls.transform, false); LayoutElement component = val.GetComponent<LayoutElement>(); component.minWidth = 34f; component.preferredWidth = 34f; component.minHeight = 28f; component.preferredHeight = 28f; TextMeshProUGUI component2 = val.GetComponent<TextMeshProUGUI>(); RectTransform rectTransform = ((TMP_Text)component2).rectTransform; rectTransform.anchorMin = new Vector2(0.5f, 0.5f); rectTransform.anchorMax = new Vector2(0.5f, 0.5f); rectTransform.pivot = new Vector2(0.5f, 0.5f); rectTransform.sizeDelta = new Vector2(34f, 28f); ((TMP_Text)component2).alignment = (TextAlignmentOptions)514; ((TMP_Text)component2).fontSize = 10f; ((Graphic)component2).color = Color.white; ((Graphic)component2).raycastTarget = false; ModTypography.ApplyStatus((TMP_Text)(object)component2); return component2; } private static LazyButton FindQueueButton(bool useRightArrow) { UICraftQueueElementWidget[] array = Resources.FindObjectsOfTypeAll<UICraftQueueElementWidget>(); foreach (UICraftQueueElementWidget val in array) { LazyButton val2 = (useRightArrow ? val.QueueDownButton : val.QueueUpButton); if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).gameObject != (Object)null) { return val2; } } return null; } private void SetControlPositions(Vector2 leftPosition, Vector2 counterPosition, Vector2 rightPosition) { //IL_0006: 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) //IL_001e: Unknown result type (might be due to invalid IL or missing references) leftButtonRect.anchoredPosition = leftPosition; counterRect.anchoredPosition = counterPosition; rightButtonRect.anchoredPosition = rightPosition; } } internal sealed class HudPositionPreview : MonoBehaviour { private static readonly string[] Scenarios = new string[10] { "Off - normal HUD", "Baseline - no external panel", "GK2RecipePin - small panel on the right", "GK2RecipePin - tall panel on the right", "Kebo - right", "Kebo - left (no displacement expected)", "Kebo - center (only displace if overlapping)", "Both panels - use the lowest bottom edge", "Kebo - transparent (no displacement expected)", "Kebo - inactive (no displacement expected)" }; private static HudPositionPreview instance; private GameObject canvasObject; private RectTransform recipePanel; private RectTransform keboPanel; private TextMeshProUGUI status; private int scenario; private static bool IsActive { get { if ((Object)(object)instance != (Object)null && ((Behaviour)instance).isActiveAndEnabled) { return instance.scenario > 0; } return false; } } internal static void Attach(GameObject anchor, TextMeshProUGUI fontSource) { Shutdown(); ConfigEntry<bool> enabled = HudPreviewConfig.Enabled; if (enabled != null && enabled.Value) { instance = anchor.AddComponent<HudPositionPreview>(); instance.Build(fontSource); } } private void Build(TextMeshProUGUI fontSource) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_0075: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: 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) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) canvasObject = new GameObject("FormulaHelper_PositionPreview", new Type[3] { typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler) }); Canvas component = canvasObject.GetComponent<Canvas>(); component.renderMode = (RenderMode)0; component.sortingOrder = 30001; CanvasScaler component2 = canvasObject.GetComponent<CanvasScaler>(); component2.uiScaleMode = (ScaleMode)1; component2.referenceResolution = new Vector2(1920f, 1080f); recipePanel = CreatePanel("GK2RecipePin (simulated)", new Color(0.12f, 0.35f, 0.65f, 0.85f), fontSource); keboPanel = CreatePanel("Kebo Recipe Pins (simulated)", new Color(0.65f, 0.32f, 0.1f, 0.85f), fontSource); RectTransform val = CreatePanel("Position preview", new Color(0.08f, 0.08f, 0.08f, 0.9f), fontSource); Place(val, new Vector2(0f, 0f), new Vector2(16f, 100f), new Vector2(620f, 85f)); status = ((Component)val).GetComponentInChildren<TextMeshProUGUI>(); ApplyScenario(); canvasObject.SetActive(((Behaviour)this).isActiveAndEnabled); } private RectTransform CreatePanel(string title, Color color, TextMeshProUGUI fontSource) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: 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) GameObject val = new GameObject(title, new Type[3] { typeof(RectTransform), typeof(Image), typeof(CanvasGroup) }); val.transform.SetParent(canvasObject.transform, false); Image component = val.GetComponent<Image>(); ((Graphic)component).color = color; ((Graphic)component).raycastTarget = false; CanvasGroup component2 = val.GetComponent<CanvasGroup>(); component2.interactable = false; component2.blocksRaycasts = false; GameObject val2 = new GameObject("Label", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); val2.transform.SetParent(val.transform, false); RectTransform component3 = val2.GetComponent<RectTransform>(); component3.anchorMin = Vector2.zero; component3.anchorMax = Vector2.one; component3.offsetMin = new Vector2(12f, 12f); component3.offsetMax = new Vector2(-12f, -12f); TextMeshProUGUI component4 = val2.GetComponent<TextMeshProUGUI>(); if ((Object)(object)fontSource != (Object)null) { ((TMP_Text)component4).font = ((TMP_Text)fontSource).font; ((TMP_Text)component4).fontSharedMaterial = ((TMP_Text)fontSource).fontSharedMaterial; } ((TMP_Text)component4).text = title; ((TMP_Text)component4).fontSize = 22f; ((Graphic)component4).color = Color.white; ((Graphic)component4).raycastTarget = false; ((TMP_Text)component4).alignment = (TextAlignmentOptions)257; ((TMP_Text)component4).textWrappingMode = (TextWrappingModes)1; ModTypography.ApplyPreviewText((TMP_Text)(object)component4); RectTransform component5 = val.GetComponent<RectTransform>(); LaboratoryPinsLayoutListener.Observe(component5); return component5; } private static void Place(RectTransform panel, Vector2 anchor, Vector2 offset, Vector2 size) { //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) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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) panel.anchorMin = anchor; panel.anchorMax = anchor; panel.pivot = new Vector2(anchor.x, 1f); panel.anchoredPosition = offset; panel.sizeDelta = size; } private void ApplyScenario() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) Place(recipePanel, Vector2.one, new Vector2(-12f, -110f), new Vector2(380f, (scenario == 3) ? 350f : 150f)); Vector2 anchor = (Vector2)((scenario == 5) ? new Vector2(0f, 1f) : ((scenario == 6) ? new Vector2(0.5f, 1f) : Vector2.one)); Place(keboPanel, anchor, new Vector2((scenario == 5) ? 16f : ((scenario == 6) ? 0f : (-16f)), (scenario == 7) ? (-280f) : (-110f)), new Vector2(420f, 240f)); ((Component)recipePanel).gameObject.SetActive(scenario == 2 || scenario == 3 || scenario == 7); ((Component)keboPanel).gameObject.SetActive(scenario >= 4 && scenario <= 8); ((Component)keboPanel).GetComponent<CanvasGroup>().alpha = ((scenario == 8) ? 0f : 1f); ((TMP_Text)status).text = $"HUD position test {scenario}/{Scenarios.Length - 1}: {Scenarios[scenario]}\n{HudPreviewConfig.PreviousScenario.Value}: previous | {HudPreviewConfig.NextScenario.Value}: next"; LaboratoryPinsHud.RequestRefresh(); LaboratoryPinsHud.RequestPositionUpdate(); } private void Update() { //IL_0005: 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) //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) KeyboardShortcut value = HudPreviewConfig.NextScenario.Value; int num; if (!((KeyboardShortcut)(ref value)).IsDown()) { value = HudPreviewConfig.PreviousScenario.Value; num = (((KeyboardShortcut)(ref value)).IsDown() ? (-1) : 0); } else { num = 1; } int num2 = num; if (num2 != 0) { scenario = (scenario + num2 + Scenarios.Length) % Scenarios.Length; ApplyScenario(); } } internal static void IncludeBottom(float left, float right, ref float bottom, ref bool found) { if (IsActive) { ExternalHudCompatibility.IncludeOverlappingBottom(instance.recipePanel, left, right, ref bottom, ref found); ExternalHudCompatibility.IncludeOverlappingBottom(instance.keboPanel, left, right, ref bottom, ref found); } } internal static void AddSampleIfEmpty(List<PinnedFormulaManager.PinnedFormulaViewData> pins) { if (IsActive && pins.Count == 0) { pins.Add(new PinnedFormulaManager.PinnedFormulaViewData { FormulaId = "__hud_position_preview__", Name = "Position test", StatusText = "Preview only" }); } } private void OnEnable() { if ((Object)(object)canvasObject != (Object)null) { canvasObject.SetActive(true); } LaboratoryPinsHud.RequestRefresh(); } private void OnDisable() { if ((Object)(object)canvasObject != (Object)null) { canvasObject.SetActive(false); } LaboratoryPinsHud.RequestRefresh(); LaboratoryPinsHud.RequestPositionUpdate(); } private void OnDestroy() { if ((Object)(object)canvasObject != (Object)null) { Object.Destroy((Object)(object)canvasObject); } if ((Object)(object)instance == (Object)(object)this) { instance = null; } } internal static void Shutdown() { if ((Object)(object)instance != (Object)null) { ((Behaviour)instance).enabled = false; Object.Destroy((Object)(object)instance); instance = null; } } } internal static class HudScreenGeometry { private static readonly Vector3[] Corners = (Vector3[])(object)new Vector3[4]; internal static Camera GetCanvasCamera(RectTransform rect) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Invalid comparison between Unknown and I4 Canvas val = ((rect != null) ? ((Component)rect).GetComponentInParent<Canvas>() : null); if ((Object)(object)val == (Object)null) { return null; } val = val.rootCanvas; if ((int)val.renderMode == 0) { return null; } if (!((Object)(object)val.worldCamera != (Object)null)) { if ((int)val.renderMode != 2) { return null; } return Camera.main; } return val.worldCamera; } internal static bool TryGetScreenRect(RectTransform root, out Rect screenRect) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_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_009e: 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_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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_00d4: 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) screenRect = default(Rect); if (IsVisible(root)) { Rect rect = root.rect; if (!(((Rect)(ref rect)).width <= 0f)) { rect = root.rect; if (!(((Rect)(ref rect)).height <= 0f)) { Camera canvasCamera = GetCanvasCamera(root); root.GetWorldCorners(Corners); Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(float.MaxValue, float.MaxValue); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(float.MinValue, float.MinValue); Vector3[] corners = Corners; foreach (Vector3 val3 in corners) { Vector2 val4 = RectTransformUtility.WorldToScreenPoint(canvasCamera, val3); if (float.IsNaN(val4.x) || float.IsInfinity(val4.x) || float.IsNaN(val4.y) || float.IsInfinity(val4.y)) { return false; } val = Vector2.Min(val, val4); val2 = Vector2.Max(val2, val4); } screenRect = Rect.MinMaxRect(val.x, val.y, val2.x, val2.y); if (((Rect)(ref screenRect)).width > 0f) { return ((Rect)(ref screenRect)).height > 0f; } return false; } } } return false; } internal static void IncludeBottom(RectTransform root, ref float bottomScreenY, ref bool found) { if (TryGetScreenRect(root, out var screenRect)) { bottomScreenY = Mathf.Min(bottomScreenY, ((Rect)(ref screenRect)).yMin); found = true; } } internal static void IncludeOverlappingBottom(RectTransform root, float left, float right, ref float bottom, ref bool found) { if (TryGetScreenRect(root, out var screenRect) && ((Rect)(ref screenRect)).xMax > left && ((Rect)(ref screenRect)).xMin < right) { bottom = Mathf.Min(bottom, ((Rect)(ref screenRect)).yMin); found = true; } } internal static bool IsVisible(RectTransform root) { if ((Object)(object)root == (Object)null || !((Component)root).gameObject.activeInHierarchy) { return false; } Canvas componentInParent = ((Component)root).GetComponentInParent<Canvas>(); if ((Object)(object)componentInParent == (Object)null || !((Behaviour)componentInParent).isActiveAndEnabled || !((Behaviour)componentInParent.rootCanvas).isActiveAndEnabled) { return false; } Transform val = (Transform)(object)root; while ((Object)(object)val != (Object)null) { bool flag = false; CanvasGroup[] components = ((Component)val).GetComponents<CanvasGroup>(); foreach (CanvasGroup val2 in components) { if (((Behaviour)val2).enabled) { if (val2.alpha <= 0f) { return false; } flag |= val2.ignoreParentGroups; } } if (flag) { break; } val = val.parent; } return true; } } internal static class LaboratoryPinCardFactory { private static readonly Color CardColor = new Color(0.14f, 0.15f, 0.18f, 0.96f); internal static void Create(RectTransform contentRoot, PinnedFormulaManager.PinnedFormulaViewData pin) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_0064: 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_00e0: Expected O, but got Unknown //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Expected O, but got Unknown //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Expected O, but got Unknown //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Expected O, but got Unknown //IL_03fd: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Pin_" + pin.FormulaId, new Type[4] { typeof(RectTransform), typeof(Image), typeof(LazyButton), typeof(VerticalLayoutGroup) }); AttachToHud(val, (Transform)(object)contentRoot); Image component = val.GetComponent<Image>(); ((Graphic)component).color = CardColor; ((Graphic)component).raycastTarget = true; LazyButton component2 = val.GetComponent<LazyButton>(); AlchemyFormulaDef formula = ((GameBalanceBase)GameBalance.Me).GetDataOrNull<AlchemyFormulaDef>(pin.FormulaId); if ((Object)(object)component2 != (Object)null && formula != null) { ((Selectable)component2).interactable = true; ((UnityEventBase)((Button)component2).onClick).RemoveAllListeners(); ((UnityEvent)((Button)component2).onClick).AddListener((UnityAction)delegate { PinnedFormulaManager.Toggle(formula); }); } VerticalLayoutGroup component3 = val.GetComponent<VerticalLayoutGroup>(); ((LayoutGroup)component3).padding = new RectOffset(6, 6, 4, 4); ((HorizontalOrVerticalLayoutGroup)component3).spacing = 4f; ((LayoutGroup)component3).childAlignment = (TextAnchor)0; ((HorizontalOrVerticalLayoutGroup)component3).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component3).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component3).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)component3).childForceExpandHeight = false; GameObject val2 = new GameObject("Header", new Type[3] { typeof(RectTransform), typeof(HorizontalLayoutGroup), typeof(LayoutElement) }); AttachToHud(val2, val.transform); LayoutElement component4 = val2.GetComponent<LayoutElement>(); component4.minWidth = 0f; component4.preferredWidth = 0f; component4.flexibleWidth = 1f; component4.minHeight = 30f; HorizontalLayoutGroup component5 = val2.GetComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)component5).spacing = 8f; ((LayoutGroup)component5).childAlignment = (TextAnchor)3; ((HorizontalOrVerticalLayoutGroup)component5).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component5).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component5).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)component5).childForceExpandHeight = false; Transform transform = val2.transform; AlchemyFormulaDef obj = formula; CreateItemIcon(transform, (obj != null) ? obj.ItemDef : null, 30f, framed: true); GameObject val3 = new GameObject("TitleAndStatus", new Type[3] { typeof(RectTransform), typeof(VerticalLayoutGroup), typeof(LayoutElement) }); AttachToHud(val3, val2.transform); LayoutElement component6 = val3.GetComponent<LayoutElement>(); component6.minWidth = 0f; component6.preferredWidth = 0f; component6.flexibleWidth = 1f; VerticalLayoutGroup component7 = val3.GetComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)component7).spacing = 0f; ((HorizontalOrVerticalLayoutGroup)component7).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component7).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component7).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)component7).childForceExpandHeight = false; ((LayoutGroup)component7).childAlignment = (TextAnchor)3; CreateText(val3.transform, pin.Name, 16f, 21f, (TextAlignmentOptions)513, Color.white); ModTypography.ApplyStatus((TMP_Text)(object)CreateText(val3.transform, pin.StatusText, 13f, 16f, (TextAlignmentOptions)513, (Color)(pin.IsCraftable ? new Color(0.5f, 0.84f, 0.42f) : Color.white))); GameObject val4 = new GameObject("Ingredients", new Type[3] { typeof(RectTransform), typeof(VerticalLayoutGroup), typeof(LayoutElement) }); AttachToHud(val4, val.transform); LayoutElement component8 = val4.GetComponent<LayoutElement>(); component8.minWidth = 0f; component8.preferredWidth = 0f; component8.flexibleWidth = 1f; VerticalLayoutGroup component9 = val4.GetComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)component9).spacing = 3f; ((LayoutGroup)component9).childAlignment = (TextAnchor)3; ((HorizontalOrVerticalLayoutGroup)component9).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component9).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component9).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)component9).childForceExpandHeight = false; foreach (PinnedFormulaManager.PinnedIngredientViewData ingredient in pin.Ingredients) { CreateIngredientRow(val4.transform, ingredient); } if (pin.NoPowderIngredients.Count <= 0) { return; } ModTypography.ApplyText((TMP_Text)(object)CreateText(val4.transform, "Alt. recipe", 10f, 13f, (TextAlignmentOptions)513, new Color(0.72f, 0.72f, 0.72f))); foreach (PinnedFormulaManager.PinnedIngredientViewData noPowderIngredient in pin.NoPowderIngredients) { CreateIngredientRow(val4.transform, noPowderIngredient, alternative: true); } } private static void CreateIngredientRow(Transform parent, PinnedFormulaManager.PinnedIngredientViewData ingredient, bool alternative = false) { //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_008e: 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_009a: Expected O, but got Unknown //IL_009a: 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_001f: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) Color color = (ingredient.IsAvailable ? new Color(0.5f, 0.84f, 0.42f) : (ingredient.IsBuyable ? new Color(0.45f, 0.72f, 0.95f) : new Color(0.91f, 0.7f, 0.42f))); GameObject val = new GameObject("Ingredient_" + ingredient.ItemId, new Type[3] { typeof(RectTransform), typeof(HorizontalLayoutGroup), typeof(LayoutElement) }); AttachToHud(val, parent); val.GetComponent<LayoutElement>().minHeight = (alternative ? 14f : 16f); HorizontalLayoutGroup component = val.GetComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)component).spacing = 4f; ((LayoutGroup)component).childAlignment = (TextAnchor)3; ((HorizontalOrVerticalLayoutGroup)component).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = false; CreateItemIcon(item: ((GameBalanceBase)GameBalance.Me).GetDataOrNull<ItemDef>(ingredient.ItemId), parent: val.transform, side: alternative ? 12f : 14f, framed: false); string text = ingredient.Name; if (ingredient.IsBuyable && !string.IsNullOrEmpty(ingredient.VendorName)) { text += $" <size=10>{ingredient.VendorName} ({ingredient.VendorStock})</size>"; } TextMeshProUGUI val2 = CreateText(val.transform, text, alternative ? 11f : 12f, alternative ? 14f : 16f, (TextAlignmentOptions)513, color, wrap: true); if (ingredient.IsBuyable && !string.IsNullOrEmpty(ingredient.VendorName)) { ModTypography.ApplyVendorText((TMP_Text)(object)val2); } else { ModTypography.ApplyText((TMP_Text)(object)val2); } LayoutElement component2 = ((Component)val2).GetComponent<LayoutElement>(); component2.minWidth = 0f; component2.preferredWidth = 0f; component2.flexibleWidth = 1f; TextMeshProUGUI obj = CreateText(val.transform, ingredient.CountText, alternative ? 11f : 12f, alternative ? 14f : 16f, (TextAlignmentOptions)516, color); ModTypography.ApplyCount((TMP_Text)(object)obj); LayoutElement component3 = ((Component)obj).GetComponent<LayoutElement>(); component3.minWidth = 30f; component3.preferredWidth = 30f; component3.flexibleWidth = 0f; } private static void CreateItemIcon(Transform parent, ItemDef item, float side, bool framed) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown //IL_00c8: 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_00da: 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_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("ItemIcon", new Type[2] { typeof(RectTransform), typeof(LayoutElement) }); AttachToHud(val, parent); LayoutElement component = val.GetComponent<LayoutElement>(); component.minWidth = side; component.preferredWidth = side; component.minHeight = side; component.preferredHeight = side; component.flexibleWidth = 0f; component.flexibleHeight = 0f; if (framed) { Image obj = val.AddComponent<Image>(); ((Graphic)obj).color = new Color(0.22f, 0.23f, 0.28f); ((Graphic)obj).raycastTarget = false; } GameObject val2 = new GameObject("Icon", new Type[2] { typeof(RectTransform), typeof(Image) }); AttachToHud(val2, val.transform); RectTransform component2 = val2.GetComponent<RectTransform>(); component2.anchorMin = Vector2.zero; component2.anchorMax = Vector2.one; float num = (framed ? 3f : 0f); component2.offsetMin = new Vector2(num, num); component2.offsetMax = new Vector2(0f - num, 0f - num); Image component3 = val2.GetComponent<Image>(); component3.sprite = ((item == null) ? null : LazySingletonSO<EasySpritesCollection>.Instance.GetSprite(item.iconId, (string)null)); component3.preserveAspect = true; ((Graphic)component3).raycastTarget = false; ((Behaviour)component3).enabled = (Object)(object)component3.sprite != (Object)null; } private static TextMeshProUGUI CreateText(Transform parent, string text, float fontSize, float height, TextAlignmentOptions alignment, Color color, bool wrap = false) { //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_003e: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Text", new Type[3] { typeof(RectTransform), typeof(TextMeshProUGUI), typeof(LayoutElement) }); AttachToHud(val, parent); LayoutElement component = val.GetComponent<LayoutElement>(); component.minHeight = height; component.preferredHeight = (wrap ? (-1f) : height); TextMeshProUGUI component2 = val.GetComponent<TextMeshProUGUI>(); ((TMP_Text)component2).text = text; ((TMP_Text)component2).fontSize = fontSize; ((Graphic)component2).color = color; ((TMP_Text)component2).alignment = alignment; ModTypography.ApplyTitle((TMP_Text)(object)component2); ((TMP_Text)component2).textWrappingMode = (TextWrappingModes)(wrap ? 1 : 0); ((TMP_Text)component2).overflowMode = (TextOverflowModes)(!wrap); return component2; } private static void AttachToHud(GameObject child, Transform parent) { child.layer = ((Component)parent).gameObject.layer; child.transform.SetParent(parent, false); } } internal static class LaboratoryPinsHud { [CompilerGenerated] private static class <>O { public static Action <0>__Refresh; public static WillRenderCanvases <1>__BeforeLayout; public static WillRenderCanvases <2>__AfterLayout; } private const float DefaultCardWidth = 310f; private const float CardScale = 0.8f; private static readonly FieldInfo RightUpGroupField = AccessTools.Field(typeof(HUD), "rightUpGroup"); private static readonly FieldInfo HappinessLabelField = AccessTools.Field(typeof(HUD), "happinessLabel"); private static GameObject panelObject; private static RectTransform contentRoot; private static bool layoutUpdateQueued; private static bool refreshPending; private static bool updatingPosition; private static List<PinnedFormulaManager.PinnedFormulaViewData> renderedPins; public static void Initialize(HUD hud) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_00c6: 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_00f0: 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_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Expected O, but got Unknown //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Expected O, but got Unknown if ((Object)(object)hud == (Object)null) { return; } DestroyExisting(); object? obj = RightUpGroupField?.GetValue(hud); GameObject val = (GameObject)((obj is GameObject) ? obj : null); if ((Object)(object)val == (Object)null) { ModLog.Warning("Could not find HUD.rightUpGroup."); return; } object? obj2 = HappinessLabelField?.GetValue(hud); TextMeshProUGUI val2 = (TextMeshProUGUI)((obj2 is TextMeshProUGUI) ? obj2 : null); if ((Object)(object)val2 != (Object)null) { ModTypography.Initialize(val2); } panelObject = new GameObject("GK2LaboratoryPins", new Type[2] { typeof(RectTransform), typeof(LayoutElement) }); panelObject.GetComponent<LayoutElement>().ignoreLayout = true; AttachToHud(panelObject, val.transform); RectTransform component = panelObject.GetComponent<RectTransform>(); component.anchorMin = new Vector2(1f, 1f); component.anchorMax = new Vector2(1f, 1f); component.pivot = new Vector2(1f, 1f); component.anchoredPosition = LaboratoryPinsPositioner.DefaultPosition; component.sizeDelta = new Vector2(310f, 0f); ((Transform)component).localScale = new Vector3(0.8f, 0.8f, 1f); Transform transform = val.transform; RectTransform val3 = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (val3 != null) { LaboratoryPinsLayoutListener.Observe(val3); } GameObject val4 = new GameObject("Content", new Type[3] { typeof(RectTransform), typeof(VerticalLayoutGroup), typeof(ContentSizeFitter) }); AttachToHud(val4, panelObject.transform); contentRoot = val4.GetComponent<RectTransform>(); contentRoot.anchorMin = new Vector2(0f, 1f); contentRoot.anchorMax = new Vector2(1f, 1f); contentRoot.pivot = new Vector2(0.5f, 1f); contentRoot.anchoredPosition = Vector2.zero; contentRoot.sizeDelta = Vector2.zero; val4.GetComponent<ContentSizeFitter>().verticalFit = (FitMode)2; VerticalLayoutGroup component2 = val4.GetComponent<VerticalLayoutGroup>(); ((LayoutGroup)component2).padding = new RectOffset(0, 0, 0, 0); ((HorizontalOrVerticalLayoutGroup)component2).spacing = 6f; ((LayoutGroup)component2).childAlignment = (TextAnchor)0; ((HorizontalOrVerticalLayoutGroup)component2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandHeight = false; PinnedFormulaManager.PinsChanged -= Refresh; PinnedFormulaManager.PinsChanged += Refresh; PinsInventoryWatcher.Initialize(); HudPositionPreview.Attach(val, val2); Refresh(); ModLog.Debug("Laboratory pins HUD initialized."); } public static void Refresh() { if ((Object)(object)panelObject == (Object)null || (Object)(object)contentRoot == (Object)null) { return; } UpdatePosition(); List<PinnedFormulaManager.PinnedFormulaViewData> pinnedViewData = PinnedFormulaManager.GetPinnedViewData(); HudPositionPreview.AddSampleIfEmpty(pinnedViewData); if (PinnedFormulaContentComparer.AreEqual(renderedPins, pinnedViewData)) { return; } ClearChildren((Transform)(object)contentRoot); foreach (PinnedFormulaManager.PinnedFormulaViewData item in pinnedViewData) { LaboratoryPinCardFactory.Create(contentRoot, item); } renderedPins = pinnedViewData; if (panelObject.activeSelf != pinnedViewData.Count > 0) { panelObject.SetActive(pinnedViewData.Count > 0); } if (pinnedViewData.Count > 0) { LayoutRebuilder.ForceRebuildLayoutImmediate(contentRoot); } } internal static void RequestRefresh() { //IL_002b: 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: Expected O, but got Unknown if (!((Object)(object)panelObject == (Object)null) && !refreshPending) { refreshPending = true; object obj = <>O.<1>__BeforeLayout; if (obj == null) { WillRenderCanvases val = BeforeLayout; <>O.<1>__BeforeLayout = val; obj = (object)val; } Canvas.preWillRenderCanvases += (WillRenderCanvases)obj; } } internal static void RequestPositionUpdate() { //IL_0038: 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_0043: Expected O, but got Unknown if (!((Object)(object)panelObject == (Object)null) && !layoutUpdateQueued && !updatingPosition) { _ = CanvasUpdateRegistry.instance; layoutUpdateQueued = true; object obj = <>O.<2>__AfterLayout; if (obj == null) { WillRenderCanvases val = AfterLayout; <>O.<2>__AfterLayout = val; obj = (object)val; } Canvas.willRenderCanvases += (WillRenderCanvases)obj; } } internal static void Shutdown() { DestroyExisting(); LaboratoryPinsLayoutListener.StopObserving(); } private static void BeforeLayout() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown object obj = <>O.<1>__BeforeLayout; if (obj == null) { WillRenderCanvases val = BeforeLayout; <>O.<1>__BeforeLayout = val; obj = (object)val; } Canvas.preWillRenderCanvases -= (WillRenderCanvases)obj; refreshPending = false; Refresh(); RequestPositionUpdate(); } private static void AfterLayout() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown object obj = <>O.<2>__AfterLayout; if (obj == null) { WillRenderCanvases val = AfterLayout; <>O.<2>__AfterLayout = val; obj = (object)val; } Canvas.willRenderCanvases -= (WillRenderCanvases)obj; layoutUpdateQueued = false; UpdatePosition(); } private static void UpdatePosition() { if ((Object)(object)panelObject == (Object)null || updatingPosition) { return; } updatingPosition = true; try { LaboratoryPinsPositioner.Update(panelObject.GetComponent<RectTransform>()); } finally { updatingPosition = false; } } private static void DestroyExisting() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown HudPositionPreview.Shutdown(); object obj = <>O.<1>__BeforeLayout; if (obj == null) { WillRenderCanvases val = BeforeLayout; <>O.<1>__BeforeLayout = val; obj = (object)val; } Canvas.preWillRenderCanvases -= (WillRenderCanvases)obj; object obj2 = <>O.<2>__AfterLayout; if (obj2 == null) { WillRenderCanvases val2 = AfterLayout; <>O.<2>__AfterLayout = val2; obj2 = (object)val2; } Canvas.willRenderCanvases -= (WillRenderCanvases)obj2; layoutUpdateQueued = false; refreshPending = false; PinnedFormulaManager.PinsChanged -= Refresh; if ((Object)(object)panelObject != (Object)null) { Object.Destroy((Object)(object)panelObject); } panelObject = null; contentRoot = null; renderedPins = null; } private static void ClearChildren(Transform parent) { for (int num = parent.childCount - 1; num >= 0; num--) { ((Component)parent.GetChild(num)).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)parent.GetChild(num)).gameObject); } } private static void AttachToHud(GameObject child, Transform parent) { child.layer = ((Component)parent).gameObject.layer; child.transform.SetParent(parent, false); } } internal sealed class LaboratoryPinsLayoutListener : MonoBehaviour { private static readonly List<LaboratoryPinsLayoutListener> Listeners = new List<LaboratoryPinsLayoutListener>(); internal static void Observe(RectTransform root) { if ((Object)(object)root != (Object)null && (Object)(object)((Component)root).GetComponent<LaboratoryPinsLayoutListener>() == (Object)null) { Listeners.Add(((Component)root).gameObject.AddComponent<LaboratoryPinsLayoutListener>()); } } internal static void StopObserving() { LaboratoryPinsLayoutListener[] array = Listeners.ToArray(); foreach (LaboratoryPinsLayoutListener laboratoryPinsLayoutListener in array) { if ((Object)(object)laboratoryPinsLayoutListener != (Object)null) { Object.Destroy((Object)(object)laboratoryPinsLayoutListener); } } Listeners.Clear(); } private void OnRectTransformDimensionsChange() { LaboratoryPinsHud.RequestPositionUpdate(); } private void OnEnable() { LaboratoryPinsHud.RequestPositionUpdate(); } private void OnCanvasGroupChanged() { LaboratoryPinsHud.RequestPositionUpdate(); } private void OnTransformParentChanged() { LaboratoryPinsHud.RequestPositionUpdate(); } private void OnDisable() { LaboratoryPinsHud.RequestPositionUpdate(); } private void OnDestroy() { Listeners.Remove(this); LaboratoryPinsHud.RequestPositionUpdate(); } } internal static class LaboratoryPinsPositioner { private const float ExternalSpacingPixels = 12f; internal static readonly Vector2 DefaultPosition = new Vector2(-16f, -85f); internal static void Update(RectTransform panelRect) { //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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: 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_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)panelRect == (Object)null) { return; } Transform parent = ((Transform)panelRect).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if (val == null) { return; } Vector2 defaultPosition = DefaultPosition; Camera canvasCamera = ExternalHudCompatibility.GetCanvasCamera(val); Rect rect = val.rect; float num = ((Rect)(ref rect)).xMax + DefaultPosition.x; rect = val.rect; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(num, ((Rect)(ref rect)).yMax + DefaultPosition.y, ((Transform)panelRect).localPosition.z); Vector2 val3 = RectTransformUtility.WorldToScreenPoint(canvasCamera, ((Transform)val).TransformPoint(val2)); Vector3 val4 = val2; rect = panelRect.rect; Vector2 val5 = RectTransformUtility.WorldToScreenPoint(canvasCamera, ((Transform)val).TransformPoint(val4 - new Vector3(((Rect)(ref rect)).width * ((Transform)panelRect).localScale.x, 0f, 0f))); float num2 = Mathf.Abs(val3.x - val5.x); if (ExternalHudCompatibility.TryGetRecipePinScreenRect(out var screenRect)) { val3.x = ((Rect)(ref screenRect)).xMax; } if (!ExternalHudCompatibility.TryGetExternalBottomScreenY(val3.x - num2, val3.x, out var bottomScreenY)) { Apply(panelRect, defaultPosition); return; } val3.y = bottomScreenY - 12f; Vector2 val6 = default(Vector2); if (RectTransformUtility.ScreenPointToLocalPointInRectangle(val, val3, canvasCamera, ref val6)) { float x = val6.x; rect = val.rect; float num3 = x - ((Rect)(ref rect)).xMax; float y = val6.y; rect = val.rect; ((Vector2)(ref defaultPosition))..ctor(num3, y - ((Rect)(ref rect)).yMax); } Apply(panelRect, defaultPosition); } private static void Apply(RectTransform panelRect, Vector2 targetPosition) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (panelRect.anchoredPosition != targetPosition) { panelRect.anchoredPosition = targetPosition; } } } internal static class PinnedFormulaContentComparer { internal static bool AreEqual(List<PinnedFormulaManager.PinnedFormulaViewData> previous, List<PinnedFormulaManager.PinnedFormulaViewData> current) { if (previous == null || previous.Count != current.Count) { return false; } for (int i = 0; i < current.Count; i++) { PinnedFormulaManager.PinnedFormulaViewData pinnedFormulaViewData = previous[i]; PinnedFormulaManager.PinnedFormulaViewData pinnedFormulaViewData2 = current[i]; if (pinnedFormulaViewData.FormulaId != pinnedFormulaViewData2.FormulaId || pinnedFormulaViewData.Name != pinnedFormulaViewData2.Name || pinnedFormulaViewData.StatusText != pinnedFormulaViewData2.StatusText || pinnedFormulaViewData.IsCraftable != pinnedFormulaViewData2.IsCraftable || !IngredientsEqual(pinnedFormulaViewData.Ingredients, pinnedFormulaViewData2.Ingredients) || !IngredientsEqual(pinnedFormulaViewData.NoPowderIngredients, pinnedFormulaViewData2.NoPowderIngredients)) { return false; } } return true; } private static bool IngredientsEqual(List<PinnedFormulaManager.PinnedIngredientViewData> previous, List<PinnedFormulaManager.PinnedIngredientViewData> current) { if (previous == null || current == null) { return previous == current; } if (previous.Count != current.Count) { return false; } for (int i = 0; i < current.Count; i++) { PinnedFormulaManager.PinnedIngredientViewData pinnedIngredientViewData = previous[i]; PinnedFormulaManager.PinnedIngredientViewData pinnedIngredientViewData2 = current[i]; if (pinnedIngredientViewData.ItemId != pinnedIngredientViewData2.ItemId || pinnedIngredientViewData.Name != pinnedIngredientViewData2.Name || pinnedIngredientViewData.CountText != pinnedIngredientViewData2.CountText || pinnedIngredientViewData.IsAvailable != pinnedIngredientViewData2.IsAvailable || pinnedIngredientViewData.IsBuyable != pinnedIngredientViewData2.IsBuyable || pinnedIngredientViewData.VendorName != pinnedIngredientViewData2.VendorName || pinnedIngredientViewData.VendorStock != pinnedIngredientViewData2.VendorStock) { return false; } } return true; } } } namespace GK2LaboratoryFolioHelper.UI.Typography { internal static class ModTypography { internal static void Initialize(TextMeshProUGUI source) { TypographyFontResolver.Initialize(source); } internal static void ApplyTitle(TMP_Text text) { ApplyReadableText(text); } internal static void ApplyText(TMP_Text text) { ApplyReadableText(text); } internal static void ApplyStatus(TMP_Text text) { ApplyReadableText(text); if (TypographyFontResolver.IsSharp && (Object)(object)text != (Object)null) { text.lineSpacing = -1f; } } internal static void ApplyCount(TMP_Text text) { ApplyReadableText(text); } internal static void ApplyVendorText(TMP_Text text) { ApplyReadableText(text); } internal static void ApplyPreviewText(TMP_Text text) { ApplyReadableText(text); } internal static void Shutdown() { TypographyFontResolver.Shutdown(); } private static void ApplyReadableText(TMP_Text text) { if ((Object)(object)text == (Object)null) { return; } TMP_FontAsset val = TypographyFontResolver.ResolveFont(); if ((Object)(object)val != (Object)null) { text.font = val; Material val2 = (((Object)(object)TypographyFontResolver.BundledFont == (Object)(object)val) ? ((TMP_Asset)val).material : TypographyFontResolver.ReferenceMaterial); if ((Object)(object)val2 != (Object)null) { text.fontSharedMaterial = val2; } } else { TypographyFontResolver.WarnMissingReferenceOnce(); } if ((Object)(object)TypographyFontResolver.ReferenceSpriteAsset != (Object)null) { text.spriteAsset = TypographyFontResolver.ReferenceSpriteAsset; } text.richText = true; ((Graphic)text).raycastTarget = false; if (TypographyFontResolver.IsSharp) { text.enableAutoSizing = false; text.fontWeight = (FontWeight)400; text.wordSpacing = 0f; text.lineSpacingAdjustment = 0f; text.extraPadding = false; text.fontStyle = (FontStyles)0; text.characterSpacing = -1f; text.lineSpacing = 0f; } } } internal static class TypographyFontResolver { private const string BundleName = "knownformulahelper_fonts.bundle"; private const string RequiredCharacters = "0123456789<>+-/.,:;!?%()[]{}&'\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÄÖÜäöüẞßÀÁÂÃÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕØŒÙÚÛÝŸàáâãåæçèéêëìíîïðñòóôõøœùúûýÿ"; private static TMP_FontAsset referenceFont; private static Material referenceMaterial; private static TMP_SpriteAsset referenceSpriteAsset; private static TMP_FontAsset bundledFont; private static AssetBundle fontBundle; private static bool inventoryLogged; private static bool bundleAttempted; private static bool fallbackLogged; private static bool missingReferenceLogged; internal static bool IsSharp { get { ConfigEntry<UiFontStyle> fontStyle = UiConfig.FontStyle; if (fontStyle == null) { return false; } return fontStyle.Value == UiFontStyle.Sharp; } } internal static Material ReferenceMaterial => referenceMaterial; internal static TMP_SpriteAsset ReferenceSpriteAsset => referenceSpriteAsset; internal static TMP_FontAsset BundledFont => bundledFont; internal static void Initialize(TextMeshProUGUI source) { if ((Object)(object)source != (Object)null) { if (referenceFont == null) { referenceFont = ((TMP_Text)source).font; } if (referenceMaterial == null) { referenceMaterial = ((TMP_Text)source).fontSharedMaterial; } if (referenceSpriteAsset == null) { referenceSpriteAsset = ((TMP_Text)source).spriteAsset; } } ResolveReferenceFromLoadedUi(); LogLoadedFontsOnce(); TryLoadBundledFont(); } internal static TMP_FontAsset ResolveFont() { ResolveReferenceFromLoadedUi(); TryLoadBundledFont(); if (!IsSharp) { return referenceFont; } return bundledFont ?? referenceFont; } internal static void WarnMissingReferenceOnce() { if (!missingReferenceLogged) { missingReferenceLogged = true; ModLog.Warning("Could not resolve a loaded TMP font for helper UI; retaining TMP defaults."); } } internal static void Shutdown() { if ((Object)(object)fontBundle != (Object)null) { fontBundle.Unload(false); } fontBundle = null; bundledFont = null; referenceFont = null; referenceMaterial = null; referenceSpriteAsset = null; inventoryLogged = false; bundleAttempted = false; fallbackLogged = false; missingReferenceLogged = false; } private static void ResolveReferenceFromLoadedUi() { if ((Object)(object)referenceFont != (Object)null) { return; } TMP_Text[] array = Resources.FindObjectsOfTypeAll<TMP_Text>(); foreach (TMP_Text val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.font == (Object)null)) { referenceFont = val.font; referenceMaterial = val.fontSharedMaterial; referenceSpriteAsset = val.spriteAsset; break; } } } private static void LogLoadedFontsOnce() { if (inventoryLogged) { return; } inventoryLogged = true; TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>(); if (array.Length == 0) { ModLog.Debug("No TMP_FontAsset resources are loaded yet."); return; } HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); TMP_FontAsset[] array2 = array; foreach (TMP_FontAsset val in array2) { if ((Object)(object)val != (Object)null && !string.IsNullOrEmpty(((Object)val).name)) { hashSet.Add(((Object)val).name); } } ModLog.Debug(string.Format("Loaded game TMP fonts ({0}): {1}", hashSet.Count, string.Join(", ", hashSet))); } private static void TryLoadBundledFont() { if (bundleAttempted || !IsSharp) { return; } bundleAttempted = true; string bundlePath = GetBundlePath(); if (!File.Exists(bundlePath)) { LogFallbackOnce("Bundle file was not found: '" + bundlePath + "'."); return; } try { fontBundle = AssetBundle.LoadFromFile(bundlePath); if ((Object)(object)fontBundle == (Object)null) { LogFallbackOnce("AssetBundle.LoadFromFile returned null: '" + bundlePath + "'."); return; } TMP_FontAsset[] array = fontBundle.LoadAllAssets<TMP_FontAsset>(); foreach (TMP_FontAsset val in array) { if (!((Object)(object)val == (Object)null) && ContainsRequiredCharacters(val)) { bundledFont = val; ModLog.Info("Loaded validated helper TMP font '" + ((Object)val).name + "' from '" + bundlePath + "'."); return; } } LogFallbackOnce("The helper font bundle contains no TMP font with the required Latin, German, digit and punctuation glyphs: '" + bundlePath + "'."); } catch (Exception ex) { LogFallbackOnce("Could not load the optional helper font bundle '" + bundlePath + "': " + ex.Message); } } private static bool ContainsRequiredCharacters(TMP_FontAsset font) { string text = "0123456789<>+-/.,:;!?%()[]{}&'\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÄÖÜäöüẞßÀÁÂÃÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕØŒÙÚÛÝŸàáâãåæçèéêëìíîïðñòóôõøœùúûýÿ"; foreach (char character in text) { if (!ContainsCharacter(font, character, new HashSet<TMP_FontAsset>())) { return false; } } return true; } private static bool ContainsCharacter(TMP_FontAsset font, char character, HashSet<TMP_FontAsset> visited) { if ((Object)(object)font == (Object)null || !visited.Add(font)) { return false; } if (font.characterLookupTable.ContainsKey(character)) { return true; } if (font.fallbackFontAssetTable == null) { return false; } foreach (TMP_FontAsset item in font.fallbackFontAssetTable) { if (ContainsCharacter(item, character, visited)) { return true; } } return false; } private static string GetBundlePath() { string text = Path.GetDirectoryName(typeof(ModTypography).Assembly.Location); if (string.IsNullOrEmpty(text)) { text = Path.Combine(Paths.PluginPath, "GK2KnownFormulaHelper"); } return Path.Combine(text, "assets", "knownformulahelper_fonts.bundle"); } private static void LogFallbackOnce(string reason) { if (!fallbackLogged) { fallbackLogged = true; ModLog.Warning("Optional helper font unavailable; using the loaded game font. " + reason); } } } } namespace GK2LaboratoryFolioHelper.Runtime { internal sealed class ModRuntime { private Harmony harmony; internal void Initialize(ManualLogSource logger, ConfigFile config) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown ModLog.Initialize(logger); ModConfig.Bind(config); ModLog.Info("GK2 Known Formula Helper 0.3.2 loading..."); harmony = new Harmony("w00dst0ckOo.GK2LaboratoryFolioHelper"); harmony.PatchAll(); CompatibilityBootstrap.Initialize(harmony); ModLog.Info("GK2 Known Formula Helper loaded."); } internal void Update() { CompatibilityBootstrap.Update(); } internal void Shutdown() { PinsInventoryWatcher.DetachAll(); AlchemyInventoryWatcher.Detach(); CompatibilityBootstrap.Shutdown(); LaboratoryPinsHud.Shutdown(); ModTypography.Shutdown(); Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } harmony = null; } } } namespace GK2LaboratoryFolioHelper.Patches { [HarmonyPatch(typeof(UIAlchemyFolioWindow), "GetFormulaWidget")] internal static class AlchemyFolioPinPatch { private static readonly FieldInfo ItemCellField = AccessTools.Field(typeof(UIAlchemyFormulaWidget), "itemCell"); private static readonly FieldInfo NameLabelField = AccessTools.Field(typeof(UIAlchemyFormulaWidget), "nameLabel"); private static void Postfix(LazyScrollableElement parent, UIAlchemyFormulaWidget __result) { //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Expected O, but got Unknown //IL_01ae: Expected O, but got Unknown //IL_01ae: Expected O, but got Unknown //IL_0107: 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_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)parent == (Object)null || (Object)(object)__result == (Object)null) { return; } object? obj = ItemCellField?.GetValue(__result); UIItemCell val = (UIItemCell)((obj is UIItemCell) ? obj : null); TextMeshProUGUI nameLabel = default(TextMeshProUGUI); ref TextMeshProUGUI reference = ref nameLabel; object? obj2 = NameLabelField?.GetValue(__result); reference = (TextMeshProUGUI)((obj2 is TextMeshProUGUI) ? obj2 : null); if ((Object)(object)val == (Object)null || (Object)(object)nameLabel == (Object)null) { return; } val.ClearCallbacks(); LazyWidgetDataBase data = parent.Data; UIAlchemyFormulaWidgetData widgetData = (UIAlchemyFormulaWidgetData)(object)((data is UIAlchemyFormulaWidgetData) ? data : null); if (widgetData == null) { return; } AlchemyFormulaDef formula = widgetData.AlchemyFormulaDef; if (formula == null) { return; } if (AlchemyFolioSelectionContext.IsActive) { int ingredientSlotCount = AlchemyRecipeLoader.GetIngredientSlotCount(AlchemyFolioSelectionContext.Window); if (ingredientSlotCount <= 0 || !PinnedFormulaManager.TryGetBestMixForLaboratory(((BalanceBaseObject)formula).id, ingredientSlotCount, out var _, out var _)) { ((Selectable)val.LazyButton).interactable = false; if ((Object)(object)parent.GamepadNavigationItem != (Object)null) { parent.GamepadNavigationItem.Active = false; } ((Graphic)nameLabel).color = new Color(((Graphic)nameLabel).color.r, ((Graphic)nameLabel).color.g, ((Graphic)nameLabel).color.b, 0.45f); RefreshPinVisual(); return; } } ((Selectable)val.LazyButton).interactable = true; val.OnItemCellPress = HandleFormulaPress; if ((Object)(object)parent.GamepadNavigationItem != (Object)null) { parent.GamepadNavigationItem.Active = true; parent.GamepadNavigationItem.SetCallbacks(new UnityAction(val.OnGamepadOver), new UnityAction(val.OnGamepadOut), new UnityAction(val.OnGamepadPress)); } RefreshPinVisual(); void HandleFormulaPress(UIItemCell _) { if (AlchemyFolioSelectionContext.IsActive) { SelectFormulaForLaboratory(formula); } else { PinnedFormulaManager.Toggle(formula); RefreshPinVisual(); } } void RefreshPinVisual() { ItemDef displayItemDef = widgetData.GetDisplayItemDef(); if (displayItemDef != null) { ((TMP_Text)nameLabel).text = LLBase.L(((BalanceBaseObject)displayItemDef).id); } } } private static void SelectFormulaForLaboratory(AlchemyFormulaDef formula) { if (formula == null || !AlchemyFolioSelectionContext.IsActive) { return; } UIAlchemyWindow window = AlchemyFolioSelectionContext.Window; int ingredientSlotCount = AlchemyRecipeLoader.GetIngredientSlotCount(window); if (ingredientSlotCount <= 0) { ModLog.Warning("Could not determine laboratory ingredient slot count for '" + ((BalanceBaseObject)formula).id + "'."); return; } if (!PinnedFormulaManager.TryGetBestMixForLaboratory(((BalanceBaseObject)formula).id, ingredientSlotCount, out var mixId, out var isCraftable) || string.IsNullOrEmpty(mixId)) { ModLog.Info("Formula cannot be used at this laboratory | formula='" + ((BalanceBaseObject)formula).id + "' | " + $"slots={ingredientSlotCount}"); return; } UIAlchemyFolioWindow window2 = LazyUI.GetWindow<UIAlchemyFolioWindow>(); if (!isCraftable && !PinnedFormulaManager.IsPinned(((BalanceBaseObject)formula).id)) { PinnedFormulaManager.PinForMissingIngredients(formula); ModLog.Info("Alchemy formula pinned because ingredients are missing | formula='" + ((BalanceBaseObject)formula).id + "' | mix='" + mixId + "'"); } ((LazyWindow<UIAlchemyFolioWindowData>)(object)window2)?.Close(); AlchemyFolioSelectionContext.End(); bool flag = AlchemyRecipeLoader.LoadMix(window, mixId); bool flag2 = flag && AlchemyMixSelectionController.Begin(window, ((BalanceBaseObject)formula).id); ModLog.Info("Alchemy formula selected from folio | formula='" + ((BalanceBaseObject)formula).id + "' | mix='" + mixId + "' | " + $"slots={ingredientSlotCount} | " + $"craftable={isCraftable} | " + $"loaded={flag} | " + $"variants={flag2}"); } } [HarmonyPatch(typeof(UIAlchemyWindow), "Update")] internal static class AlchemyMixSelectionPatch { private static void Postfix(UIAlchemyWindow __instance) { AlchemyMixSelectionController.Tick(__instance); } } [HarmonyPatch(typeof(UIAlchemyWindow), "GetGameKeyDelegates")] internal static class AlchemyMixSelectionGamepadPatch { private static void Postfix(UIAlchemyWindow __instance, ref Dictionary<GameKey, Func<bool>> __result) { __result.TryGetValue(GameKey.DpadLeft, out var left); __result[GameKey.DpadLeft] = () => AlchemyMixSelectionController.TryHandleDpad(__instance, -1, left); __result.TryGetValue(GameKey.DpadRight, out var right); __result[GameKey.DpadRight] = () => AlchemyMixSelectionController.TryHandleDpad(__instance, 1, right); } } [HarmonyPatch(typeof(LazyInput), "Update")] internal static class GlobalPinRemovalPatch { private static void Postfix() { ConfigEntry<bool> removeLastPinWithR = InputConfig.RemoveLastPinWithR3; if (removeLastPinWithR != null && removeLastPinWithR.Value && LazyInput.GetKeyDown(GameKey.RightStick)) { PinnedFormulaManager.RemoveLastPin(); } } } [HarmonyPatch(typeof(UIAlchemyWindow), "Close")] internal static class AlchemyMixSelectionClosePatch { private static void Postfix(UIAlchemyWindow __instance) { AlchemyMixSelectionController.Clear(__instance); } } [HarmonyPatch(typeof(UIAlchemyWindow), "Hide")] internal static class AlchemyMixSelectionHidePatch { private static void Postfix(UIAlchemyWindow __instance) { AlchemyMixSelectionController.Clear(__instance); } } [HarmonyPatch(typeof(UIAlchemyWindow), "Close")] internal static class AlchemyWindowClosePatch { private static void Prefix() { AlchemyInventoryWatcher.Detach(); } } [HarmonyPatch(typeof(UIAlchemyWindow), "RedrawAlchemyTabLite", new Type[] { typeof(AlchemyMixDef) })] internal static class AlchemyWindowPatch { private static readonly FieldInfo ResultField = AccessTools.Field(typeof(UIAlchemyWindow), "result"); private static readonly FieldInfo MixCraftIdField = AccessTools.Field(typeof(UIAlchemyWindow), "mixCraftId"); private static readonly FieldInfo DataField = AccessTools.Field(typeof(UIAlchemyWindow), "data"); private static void Postfix(UIAlchemyWindow __instance, AlchemyMixDef mix) { //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Expected O, but got Unknown //IL_0141: Expected O, but got Unknown //IL_0141: Expected O, but got Unknown UIAlchemyWindowData data = default(UIAlchemyWindowData); ref UIAlchemyWindowData reference = ref data; object? obj = DataField?.GetValue(__instance); reference = (UIAlchemyWindowData)((obj is UIAlchemyWindowData) ? obj : null); UIAlchemyWindowData obj2 = data; object obj3; if (obj2 == null) { obj3 = null; } else { Wgo wgo = obj2.Wgo; obj3 = ((wgo != null) ? wgo.Data : null); } if (obj3 != null) { MultiInventory craftableMultiInventory = data.Wgo.Data.GetCraftableMultiInventory(true); AlchemyInventoryWatcher.Attach(__instance, craftableMultiInventory); } object? obj4 = ResultField?.GetValue(__instance); UIItemCell val = (UIItemCell)((obj4 is UIItemCell) ? obj4 : null); if ((Object)(object)val == (Object)null) { return; } string text = MixCraftIdField?.GetValue(__instance) as string; if ((string.IsNullOrEmpty(text) ? null : GameBalance.GetAlchemyMixDef(text)) == null) { val.DrawEmpty(false, true, false); val.NoSelectionFrames = false; ((Selectable)val.LazyButton).interactable = true; val.OnItemCellPress = delegate { OpenAlchemyFolio(__instance, data); }; if ((Object)(object)val.GamepadNavigationItem != (Object)null) { val.GamepadNavigationItem.Active = true; val.GamepadNavigationItem.SetCallbacks(new UnityAction(val.OnGamepadOver), new UnityAction(val.OnGamepadOut), new UnityAction(val.OnGamepadPress)); } } } private static void OpenAlchemyFolio(UIAlchemyWindow alchemyWindow, UIAlchemyWindowData alchemyData) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown if ((Object)(object)alchemyWindow == (Object)null) { return; } object obj; if (alchemyData == null) { obj = null; } else { Wgo wgo = alchemyData.Wgo; obj = ((wgo != null) ? wgo.Data : null); } if (obj != null) { UIAlchemyFolioWindow window = LazyUI.GetWindow<UIAlchemyFolioWindow>(); if ((Object)(object)window == (Object)null) { ModLog.Warning("Could not obtain UIAlchemyFolioWindow."); return; } UIAlchemyFolioWindowData val = new UIAlchemyFolioWindowData(); val.FillFromGaveSave(alchemyData.Wgo.Data); AlchemyFolioSelectionContext.Begin(alchemyWindow); ((LazyWindow<UIAlchemyFolioWindowData>)(object)window).Open(val); ModLog.Debug("Opened alchemy folio from laboratory."); } } } [HarmonyPatch(typeof(HUD), "Init")] internal static class HudPinsPatch { private static void Postfix(HUD __instance) { LaboratoryPinsHud.Initialize(__instance); } } [HarmonyPatch(typeof(InventoryUIItemMoveOpHandler), "TryMoveItem")] internal static class InventoryMovePatch { [HarmonyPostfix] private static void Postfix(Inventory from, Inventory to, bool __result) { if (__result) { PlayerData playerData = MainGame.PlayerData; Inventory val = ((playerData != null) ? playerData.Inventory : null); if (val != null && (from == val || to == val)) { LaboratoryPinsHud.Refresh(); } } } } internal static class RecipePinCompatibilityPatch { private static bool installed; public static void TryInstall(Harmony harmony) { if (!installed && Chainloader.PluginInfos.TryGetValue("br.pedro.gk2.recipepin", out var value)) { object instance = value.Instance; if (instance != null) { Type type = instance.GetType(); PatchPostfix(harmony, type, "ToggleRecipe"); PatchPostfix(harmony, type, "RemoveRecipe"); PatchPostfix(harmony, type, "ArrangeRecipes"); PatchPostfix(harmony, type, "ResetSession"); installed = true; ModLog.Debug("RecipePin HUD change hooks installed."); } } } private static void PatchPostfix(Harmony harmony, Type type, string methodName) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(type, methodName, (Type[])null, (Type[])null); if (methodInfo == null) { ModLog.Warning("RecipePin method '" + methodName + "' not found."); return; } MethodInfo methodInfo2 = AccessTools.Method(typeof(RecipePinCompatibilityPatch), "AfterRecipePinChanged", (Type[])null, (Type[])null); harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static void AfterRecipePinChanged() { LaboratoryPinsHud.Refresh(); LaboratoryPinsHud.RequestPositionUpdate(); } } internal static class ShoppingListCompatibilityPatch { private static ConfigFile config; private static BaseUnityPlugin plugin; private static Coroutine configRefresh; private static bool installed; public static void TryInstall(Harmony harmony) { //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown if (installed || !Chainloader.PluginInfos.TryGetValue("gk2.shoppinglist", out var value) || (Object)(object)value.Instance == (Object)null) { return; } try { BaseUnityPlugin instance = value.Instance; Type type = ((object)instance).GetType(); Type type2 = AccessTools.Field(type, "_hud")?.FieldType; Type type3 = AccessTools.Field(type, "List")?.FieldType; MethodInfo methodInfo = ((type2 == null || type3 == null) ? null : AccessTools.Method(type2, "Tick", new Type[3] { type3, typeof(bool), typeof(bool) }, (Type[])null)); if (methodInfo == null || AccessTools.Field(type2, "_sig")?.FieldType != typeof(string)) { ModLog.Warning("Shopping List HudPanel.Tick layout hooks were not found."); return; } harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(ShoppingListCompatibilityPatch), "NotifyLayoutChanges", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null); config = instance.Config; plugin = instance; config.SettingChanged += OnSettingChanged; installed = true; ModLog.Debug("Shopping List HUD change hooks installed (no frame polling)."); } catch (Exception ex) { ModLog.Warning("Could not install Shopping List HUD hooks: " + ex.Message); } } private static IEnumerable<CodeInstruction> NotifyLayoutChanges(IEnumerable<CodeInstruction> instructions, MethodBase original) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown FieldInfo objB = AccessTools.Field(original.DeclaringType, "_sig"); MethodInfo methodInfo = AccessTools.Method(typeof(GameObject), "SetActive", (Type[])null, (Type[])null); MethodInfo operand = AccessTools.Method(typeof(ShoppingListCompatibilityPatch), "SetActiveAndNotify", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(LaboratoryPinsHud), "RequestRefresh", (Type[])null, (Type[])null); List<CodeInstruction> list = new List<CodeInstruction>(); int num = 0; int num2 = 0; foreach (CodeInstruction instruction in instructions) { CodeInstruction val = new CodeInstruction(instruction); if (CodeInstructionExtensions.Calls(val, methodInfo)) { val.opcode = OpCodes.Call; val.operand = operand; num++; } list.Add(val); if (instruction.opcode == OpCodes.Stfld && object.Equals(instruction.operand, objB)) { list.Add(new CodeInstruction(OpCodes.Call, (object)methodInfo2)); num2++; } } if (num == 0 || num2 != 1) { throw new InvalidOperationException("Shopping List Tick no longer matches the inspected visibility/redraw branches."); } return list; } private static void SetActiveAndNotify(GameObject target, bool active) { bool num = target.activeSelf != active; target.SetActive(active); if (num) { LaboratoryPinsHud.RequestRefresh(); } } private static void OnSettingChanged(object sender, SettingChangedEventArgs args) { if (args.ChangedSetting.Definition.Section == "HUD" && configRefresh == null && (Object)(object)plugin != (Object)null) { configRefresh = ((MonoBehaviour)plugin).StartCoroutine(RefreshAfterSettingsApplied()); } } private static IEnumerator RefreshAfterSettingsApplied() { yield return null; configRefresh = null; LaboratoryPinsHud.RequestRefresh(); } internal static void Shutdown() { if ((Object)(object)plugin != (Object)null && configRefresh != null) { ((MonoBehaviour)plugin).StopCoroutine(configRefresh); } configRefresh = null; plugin = null; if (config != null) { config.SettingChanged -= OnSettingChanged; config = null; } installed = false; } } } namespace GK2LaboratoryFolioHelper.Integration { public static class KnownFormulaHelperIntegrationApi { public static ConfigEntry<int> MaxMixVariants => LaboratoryConfig.MaxMixVariants; public static ConfigEntry<UiFontStyle> FontStyle => UiConfig.FontStyle; } } namespace GK2LaboratoryFolioHelper.Input { internal sealed class AlchemyVariantNavigation { private sealed class NavigationLink { internal GamepadNavigationItem From; internal GUIDirection Direction; internal GamepadNavigationItem Previous; internal GamepadNavigationItem Applied; } private static readonly FieldInfo IngredientsField = AccessTools.Field(typeof(UIAlchemyWindow), "ingredients"); private static readonly FieldInfo ResultField = AccessTools.Field(typeof(UIAlchemyWindow), "result"); private readonly List<NavigationLink> navigationLinks = new List<NavigationLink>(); private GamepadNavigationController navigationController; private GamepadNavigationItem leftNavigation; private GamepadNavigationItem rightNavigation; internal void Refresh(UIAlchemyWindow window, GameObject controls) { GamepadNavigationController controller = GamepadNavigationHelper.GetController<UIAlchemyWindow>(window); if ((Object)(object)controller == (Object)null || (Object)(object)controls == (Object)null) { return; } navigationController = controller; LazyButton[] componentsInChildren = controls.GetComponentsInChildren<LazyButton>(true); foreach (LazyButton val in componentsInChildren) { GamepadNavigationItem val2 = ((Component)val).GetComponentInChildren<GamepadNavigationItem>(true); if (val2 == null) { val2 = ((Component)val).gameObject.GetComponent<GamepadNavigationItem>(); } if (val2 == null) { val2 = ((Component)val).gameObject.AddComponent<GamepadNavigationItem>(); } ((Behaviour)val2).enabled = true; val2.Active = true; GamepadNavigationHelper.Register(controller, val2, 1f); GamepadNavigationHelper.BindButtonPress(val2, val); if (((Object)((Component)val).gameObject).name == "VariantButton_<") { leftNavigation = val2; } else if (((Object)((Component)val).gameObject).name == "VariantButton_>") { rightNavigation = val2; } } LinkGamepadControls(window, controller); } internal void Clear() { RestoreGamepadNavigation(); if ((Object)(object)navigationController != (Object)null) { GamepadNavigationHelper.Unregister(navigationController, leftNavigation); GamepadNavigationHelper.Unregister(navigationController, rightNavigation); } leftNavigation = null; rightNavigation = null; navigationController = null; } private void LinkGamepadControls(UIAlchemyWindow window, GamepadNavigationController controller) { if ((Object)(object)leftNavigation == (Object)null || (Object)(object)rightNavigation == (Object)null) { return; } List<GamepadNavigationItem> items = GamepadNavigationHelper.GetItems(controller); if (items == null) { return; } GamepadNavigationItem val = FindCraftMaxNavigation(items); GamepadNavigationItem val2 = FindResultNavigation(window); List<GamepadNavigationItem> list = FindIngredientNavigations(window, controller); if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null && list.Count > 0) { LinkLaboratoryRoute(val2, list, val); return; } GamepadNavigationItem val3 = FindNavigationAnchor(leftNavigation, items); GamepadNavigationItem val4 = FindNavigationAnchor(rightNavigation, items); if ((Object)(object)val == (Object)null && (Object)(object)val3 == (Object)null) { val3 = FindClosestNavigationItem(leftNavigation, items); } if ((Object)(object)val4 == (Object)null) { val4 = FindClosestNavigationItem(rightNavigation, items); } if ((Object)(object)val != (Object)null) { leftNavigation.group = val.group; rightNavigation.group = val.group; SetNavigationLink(val, (GUIDirection)3, leftNavigation); SetNavigationLink(leftNavigation, (GUIDirection)2, val); SetNavigationLink(rightNavigation, (GUIDirection)2, val); } if ((Object)(object)val3 != (Object)null && (Object)(object)val == (Object)null) { leftNavigation.group = val3.group; LinkVerticalNeighbors(val3, leftNavigation); } if ((Object)(object)val4 != (Object)null) { rightNavigation.group = val4.group; LinkVerticalNeighbors(val4, rightNavigation); } if ((Object)(object)val4 == (Object)null) { rightNavigation.group = leftNavigation.group; } SetNavigationLink(leftNavigation, (GUIDirection)1, rightNavigation); SetNavigationLink(rightNavigation, (GUIDirection)0, leftNavigation); } private static GamepadNavigationItem FindResultNavigation(UIAlchemyWindow window) { object? obj = ResultField?.GetValue(window); object? obj2 = ((obj is UIItemCell) ? obj : null); if (obj2 == null) { return null; } return ((UIItemCell)obj2).GamepadNavigationItem; } private static List<GamepadNavigationItem> FindIngredientNavigations(UIAlchemyWindow window, GamepadNavigationController controller) { List<GamepadNavigationItem> list = new List<GamepadNavigationItem>(); if (!(IngredientsField?.GetValue(window) is List<UIAlchemyIngredient> list2)) { return list; } foreach (UIAlchemyIngredient item in list2) { object obj; if (item == null) { obj = null; } else { UIItemCell cell = item.cell; obj = ((cell != null) ? cell.GamepadNavigationItem : null); } GamepadNavigationItem val = (GamepadNavigationItem)obj; if (!((Object)(object)val == (Object)null)) { ((Behaviour)val).enabled = true; val.Active = true; GamepadNavigationHelper.Register(controller, val, 1f); list.Add(val); } } return list; } private void LinkLaboratoryRoute(GamepadNavigationItem result, List<GamepadNavigationItem> ingredients, GamepadNavigationItem craftMax) { List<GamepadNavigationItem> list = new List<GamepadNavigationItem>(ingredients.Count + 4) { result, leftNavigation }; list.AddRange(ingredients); list.Add(rightNavigation); list.Add(craftMax); leftNavigation.group = result.group; rightNavigation.group = result.group; for (int i = 0; i < list.Count; i++) { GamepadNavigationItem val = list[i]; GamepadNavigationItem to = list[(i + 1) % list.Count]; GamepadNavigationItem to2 = list[(i - 1 + list.Count) % list.Count]; SetNavigationLink(val, (GUIDirection)1, to); SetNavigationLink(val, (GUIDirection)0, to2); } } private void LinkVerticalNeighbors(GamepadNavigationItem anchor, GamepadNavigationItem target) { //IL_0014: 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_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_0025: 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_0070: 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) if ((Object)(object)anchor == (Object)null || (Object)(object)target == (Object)null) { return; } Vector2 val = target.Pos - anchor.Pos; if (Mathf.Abs(val.y) >= Mathf.Abs(val.x)) { if (val.y >= 0f) { SetNavigationLink(anchor, (GUIDirection)3, target); SetNavigationLink(target, (GUIDirection)2, anchor); } else { SetNavigationLink(anchor, (GUIDirection)2, target); SetNavigationLink(target, (GUIDirection)3, anchor); } } else if (val.x >= 0f) { SetNavigationLink(anchor, (GUIDirection)1, target); SetNavigationLink(target, (GUIDirection)0, anchor); } else { SetNavigationLink(anchor, (GUIDirection)0, target); SetNavigationLink(target, (GUIDirection)1, anchor); } } private GamepadNavigationItem FindClosestNavigationItem(GamepadNavigationItem target, List<GamepadNavigationItem> items) { //IL_0024: 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_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) GamepadNavigationItem result = null; float num = float.MaxValue; for