Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Legacy Build Menu v1.0.0
plugins/LegacyBuildMenu/LegacyBuildMenu.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("LegacyBuildMenu")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Azumatt")] [assembly: AssemblyProduct("LegacyBuildMenu")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("9D000134-08B3-4B35-A9C4-A08D6C3D0226")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 LegacyBuildMenu { [RequireComponent(typeof(CanvasGroup))] public class GripHandle : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler, IBeginDragHandler, IDragHandler, IEndDragHandler { public Action<Vector2>? Dragged; public Action? Ended; private CanvasGroup _cg = null; private float _scale = 1f; private bool _dragging; private bool _hovered; private static Sprite? _rounded; private void Awake() { _cg = ((Component)this).GetComponent<CanvasGroup>(); Canvas componentInParent = ((Component)this).GetComponentInParent<Canvas>(); if ((Object)(object)componentInParent != (Object)null && componentInParent.scaleFactor > 0f) { _scale = componentInParent.scaleFactor; } } private void Update() { float num = ((_dragging || _hovered) ? 1f : 0f); _cg.alpha = Mathf.MoveTowards(_cg.alpha, num, Time.unscaledDeltaTime * 8f); } public void OnPointerEnter(PointerEventData eventData) { _hovered = true; } public void OnPointerExit(PointerEventData eventData) { _hovered = false; } public void OnBeginDrag(PointerEventData eventData) { _dragging = true; } public void OnDrag(PointerEventData eventData) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) Dragged?.Invoke(eventData.delta / _scale); } public void OnEndDrag(PointerEventData eventData) { _dragging = false; Ended?.Invoke(); } internal static Sprite RoundedRect() { //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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_rounded != (Object)null) { return _rounded; } Texture2D val = new Texture2D(64, 64) { wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1 }; Color32[] array = (Color32[])(object)new Color32[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { array[i * 64 + j] = (CornerCut(j, i, 64, 14) ? new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)0) : new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue)); } } val.SetPixels32(array); val.Apply(); _rounded = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, new Vector4(14f, 14f, 14f, 14f)); ((Object)_rounded).name = "LegacyBuildMenu_Rounded"; return _rounded; } private static bool CornerCut(int x, int y, int size, int r) { int num = ((x < r) ? r : ((x >= size - r) ? (size - r - 1) : x)); int num2 = ((y < r) ? r : ((y >= size - r) ? (size - r - 1) : y)); int num3 = x - num; int num4 = y - num2; return num3 * num3 + num4 * num4 > r * r; } } [HarmonyPatch] public static class LegacyMenu { private const string PieceManagerHarmonyId = "org.bepinex.helpers.PieceManager"; private const string JotunnHarmonyId = "com.jotunn.jotunn"; private static bool? _tabManagerPresent; private static readonly HashSet<string> _reportedBadPieces = new HashSet<string>(); private static bool Enabled => LegacyBuildMenuPlugin.UseLegacyMenu.Value && !LegacyBuildMenuPlugin.StoodDown; private static bool TabManagerPresent { get { bool valueOrDefault = _tabManagerPresent == true; bool result; if (!_tabManagerPresent.HasValue) { valueOrDefault = Chainloader.PluginInfos.ContainsKey("com.jotunn.jotunn") || AppDomain.CurrentDomain.GetAssemblies().Any(delegate(Assembly a) { try { return a.GetType("PieceManager.PiecePrefabManager", throwOnError: false) != null; } catch { return false; } }); _tabManagerPresent = valueOrDefault; result = valueOrDefault; } else { result = valueOrDefault; } return result; } } private static bool On(Hud? hud) { return Enabled && (Object)(object)hud != (Object)null && (Object)(object)hud.m_pieceSelectionWindow != (Object)null && (Object)(object)hud.m_buildUi != (Object)null; } private static void SetWindow(Hud hud, bool open) { hud.m_pieceSelectionWindow.SetActive(open); if ((Object)(object)hud.m_closePieceSelectionButton != (Object)null) { ((Component)hud.m_closePieceSelectionButton).gameObject.SetActive(open); } } internal static void OnSettingChanged() { Hud instance = Hud.instance; if (!((Object)(object)instance == (Object)null)) { if ((Object)(object)instance.m_pieceSelectionWindow != (Object)null) { SetWindow(instance, open: false); } if ((Object)(object)instance.m_buildUi != (Object)null && ((Component)instance.m_buildUi).gameObject.activeSelf) { instance.m_buildUi.Close(); } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && (Object)(object)localPlayer.m_buildPieces != (Object)null) { localPlayer.UpdateAvailablePiecesList(); } } } [HarmonyPatch(typeof(Hud), "TogglePieceSelection")] [HarmonyPrefix] private static bool Hud_TogglePieceSelection(Hud __instance) { if (!On(__instance)) { return true; } __instance.m_hoveredPiece = null; if (__instance.m_pieceSelectionWindow.activeSelf) { PlayerController.SetTakeInputDelay(0.2f); SetWindow(__instance, open: false); } else { if (((Component)__instance.m_buildUi).gameObject.activeSelf) { __instance.m_buildUi.Close(); } LegacyWindow.EnsureBuilt(__instance); SetWindow(__instance, open: true); LegacyWindow.ApplyWindow(__instance); __instance.UpdateBuild(Player.m_localPlayer, true); } return false; } [HarmonyPatch(typeof(Hud), "HidePieceSelection")] [HarmonyPrefix] private static bool Hud_HidePieceSelection() { Hud instance = Hud.instance; if (!On(instance)) { return true; } instance.m_pressedPiece = null; instance.m_closePieceSelection = 2; return false; } [HarmonyPatch(typeof(Hud), "IsPieceSelectionVisible")] [HarmonyPrefix] private static bool Hud_IsPieceSelectionVisible(ref bool __result) { Hud instance = Hud.instance; if (!On(instance)) { return true; } __result = instance.m_buildHud.activeSelf && instance.m_pieceSelectionWindow.activeSelf; return false; } [HarmonyPatch(typeof(Hud), "InBuildUi")] [HarmonyPostfix] private static void Hud_InBuildUi(ref bool __result) { if (!__result && On(Hud.instance)) { __result = Hud.IsPieceSelectionVisible(); } } [HarmonyPatch(typeof(BuildUi), "OpenBuildMenu")] [HarmonyPrefix] private static bool BuildUi_OpenBuildMenu() { return !On(Hud.instance); } [HarmonyPatch(typeof(Hud), "UpdateBuild")] [HarmonyPrefix] [HarmonyPriority(0)] [HarmonyAfter(new string[] { "org.bepinex.helpers.PieceManager", "com.jotunn.jotunn" })] private static bool Hud_UpdateBuild(Hud __instance, Player player, bool forceUpdateAllBuildStatuses) { if (!On(__instance)) { return true; } try { UpdateBuild(__instance, player, forceUpdateAllBuildStatuses); } catch (Exception ex) { LegacyBuildMenuPlugin.LogErrorOnce("legacy UpdateBuild", ex); } return false; } private static void UpdateBuild(Hud hud, Player player, bool forceUpdateAllBuildStatuses) { //IL_0104: 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) //IL_0110: Unknown result type (might be due to invalid IL or missing references) if (((Component)hud.m_buildUi).gameObject.activeSelf) { hud.m_buildUi.Close(); } if (!((Character)player).InPlaceMode()) { hud.m_hoveredPiece = null; hud.m_buildHud.SetActive(false); SetWindow(hud, open: false); return; } if (hud.m_closePieceSelection > 0) { hud.m_closePieceSelection--; if (hud.m_closePieceSelection <= 0 && hud.m_pieceSelectionWindow.activeSelf) { hud.m_hoveredPiece = null; SetWindow(hud, open: false); Character.SetTakeInputDelay(0.2f); PlayerController.SetTakeInputDelay(0.2f); } } LegacyWindow.EnsureBuilt(hud); LegacyWindow.RefreshColumns(hud); Piece val = default(Piece); Vector2Int val2 = default(Vector2Int); int num = default(int); PieceCategory val3 = default(PieceCategory); PieceTable pieceTable = default(PieceTable); player.GetBuildSelection(ref val, ref val2, ref num, ref val3, ref pieceTable); hud.m_buildHud.SetActive(!hud.m_radialMenu.Active); if (hud.m_pieceSelectionWindow.activeSelf) { hud.UpdatePieceList(player, val2, val3, forceUpdateAllBuildStatuses); UpdateTabs(hud, player, pieceTable, val3); Localization.instance.Localize(hud.m_buildHud.transform); } if ((Object)(object)hud.m_hoveredPiece != (Object)null && (ZInput.IsGamepadActive() || !player.IsPieceAvailable(hud.m_hoveredPiece))) { hud.m_hoveredPiece = null; } hud.SetupPieceInfo(((Object)(object)hud.m_hoveredPiece != (Object)null) ? hud.m_hoveredPiece : val); } [HarmonyPatch(typeof(Hud), "UpdatePieceList")] [HarmonyPrefix] private static bool Hud_UpdatePieceList(Hud __instance, Player player, Vector2Int selectedNr, PieceCategory category, bool updateAllBuildStatuses) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (!On(__instance)) { return true; } try { UpdatePieceList(__instance, player, selectedNr, category, updateAllBuildStatuses); } catch (Exception ex) { LegacyBuildMenuPlugin.LogErrorOnce("legacy UpdatePieceList", ex); } return false; } private static void UpdatePieceList(Hud hud, Player player, Vector2Int selectedNr, PieceCategory category, bool updateAllBuildStatuses) { //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Expected O, but got Unknown //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0159: 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_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) List<Piece> buildPieces = player.GetBuildPieces(); int count = buildPieces.Count; int columns = LegacyWindow.Columns; float num = LegacyWindow.Spacing(hud); while (hud.m_pieceIcons.Count < Mathf.Max(count, 1)) { hud.m_pieceIcons.Add(CreateIcon(hud)); } Vector2 val4 = default(Vector2); for (int i = 0; i < hud.m_pieceIcons.Count; i++) { PieceIconData val = hud.m_pieceIcons[i]; if ((Object)(object)val?.m_go == (Object)null) { continue; } if (i >= count) { val.m_marker.SetActive(false); ((Behaviour)val.m_icon).enabled = false; val.m_tooltip.m_text = ""; val.m_upgrade.SetActive(false); if (val.m_go.activeSelf) { val.m_go.SetActive(false); } continue; } int num2 = i % columns; int num3 = i / columns; Piece val2 = buildPieces[i]; if (!val.m_go.activeSelf) { val.m_go.SetActive(true); } RectTransform val3 = (RectTransform)val.m_go.transform; ((Vector2)(ref val4))..ctor(0f, 1f); val3.anchorMax = val4; val3.anchorMin = val4; val3.anchoredPosition = new Vector2((float)num2 * num, (float)(-num3) * num); val.m_marker.SetActive(new Vector2Int(num2, num3) == selectedNr); val.m_icon.sprite = val2.m_icon; ((Behaviour)val.m_icon).enabled = true; val.m_tooltip.m_text = val2.m_name; val.m_upgrade.SetActive(val2.m_isUpgrade); } LegacyWindow.SetContentHeight(hud, count); UpdateBuildStatus(hud, buildPieces, player); if (updateAllBuildStatuses) { UpdateBuildStatusAll(hud, buildPieces, player); } if (hud.m_lastPieceCategory != category) { hud.m_lastPieceCategory = category; UpdateBuildStatusAll(hud, buildPieces, player); LegacyWindow.ScrollToTop(); } } private static void UpdateBuildStatus(Hud hud, List<Piece> pieces, Player player) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) if (hud.m_pieceIcons.Count != 0) { if (hud.m_pieceIconUpdateIndex >= hud.m_pieceIcons.Count) { hud.m_pieceIconUpdateIndex = 0; } int pieceIconUpdateIndex = hud.m_pieceIconUpdateIndex; PieceIconData val = hud.m_pieceIcons[pieceIconUpdateIndex]; if ((Object)(object)val?.m_icon != (Object)null && pieceIconUpdateIndex < pieces.Count) { ((Graphic)val.m_icon).color = (CanBuild(player, pieces[pieceIconUpdateIndex]) ? Color.white : Hud.s_colorRedBlueZeroAlpha); } hud.m_pieceIconUpdateIndex++; } } private static void UpdateBuildStatusAll(Hud hud, List<Piece> pieces, Player player) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < hud.m_pieceIcons.Count; i++) { PieceIconData val = hud.m_pieceIcons[i]; if (!((Object)(object)val?.m_icon == (Object)null)) { ((Graphic)val.m_icon).color = ((i >= pieces.Count || CanBuild(player, pieces[i])) ? Color.white : Hud.s_colorRedBlueZeroAlpha); } } hud.m_pieceIconUpdateIndex = 0; } private static bool CanBuild(Player player, Piece? piece) { if ((Object)(object)player == (Object)null || (Object)(object)piece == (Object)null) { return false; } try { return player.HaveRequirements(piece, (RequirementMode)0); } catch (Exception ex) { string prefabName = Utils.GetPrefabName(((Component)piece).gameObject); if (_reportedBadPieces.Add(prefabName + "#status")) { LegacyBuildMenuPlugin.Log.LogWarning((object)("Piece '" + prefabName + "' threw in HaveRequirements (" + ex.GetType().Name + "), treating it as unbuildable. Whichever mod adds it has a broken build requirement.")); } return false; } } private static PieceIconData CreateIcon(Hud hud) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(hud.m_pieceIconPrefab, (Transform)(object)hud.m_pieceListRoot); PieceIconData val2 = new PieceIconData { m_go = val, m_tooltip = val.GetComponent<UITooltip>(), m_icon = ((Component)val.transform.Find("icon")).GetComponent<Image>(), m_marker = ((Component)val.transform.Find("selected")).gameObject, m_upgrade = ((Component)val.transform.Find("upgrade")).gameObject }; ((Graphic)val2.m_icon).color = Hud.s_colorRedBlueZeroAlpha; UIInputHandler component = val.GetComponent<UIInputHandler>(); component.m_onLeftDown = (Action<UIInputHandler>)Delegate.Combine(component.m_onLeftDown, new Action<UIInputHandler>(hud.OnLeftClickPiece)); component.m_onRightDown = (Action<UIInputHandler>)Delegate.Combine(component.m_onRightDown, new Action<UIInputHandler>(hud.OnRightClickPiece)); component.m_onPointerEnter = (Action<UIInputHandler>)Delegate.Combine(component.m_onPointerEnter, new Action<UIInputHandler>(hud.OnHoverPiece)); component.m_onPointerExit = (Action<UIInputHandler>)Delegate.Combine(component.m_onPointerExit, new Action<UIInputHandler>(hud.OnHoverPieceExit)); return val2; } [HarmonyPatch(typeof(Hud), "GetSelectedGrid")] [HarmonyPrefix] private static bool Hud_GetSelectedGrid(Hud __instance, UIInputHandler ih, ref Vector2Int __result) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (!On(__instance)) { return true; } int columns = LegacyWindow.Columns; __result = new Vector2Int(-1, -1); for (int i = 0; i < __instance.m_pieceIcons.Count; i++) { if ((Object)(object)__instance.m_pieceIcons[i]?.m_go == (Object)(object)((Component)ih).gameObject) { __result = new Vector2Int(i % columns, i / columns); break; } } return false; } [HarmonyPatch(typeof(PieceTable), "GetPiece", new Type[] { typeof(PieceCategory), typeof(Vector2Int) })] [HarmonyPrefix] private static bool PieceTable_GetPiece(PieceTable __instance, PieceCategory category, Vector2Int p, ref Piece? __result) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected I4, but got Unknown if (!On(Hud.instance)) { return true; } List<List<Piece>> availablePiecesByCategory = __instance.m_availablePiecesByCategory; __result = null; if (availablePiecesByCategory.Count == 0) { return false; } int num = (int)category; if (num >= availablePiecesByCategory.Count) { num = 0; } int num2 = ((Vector2Int)(ref p)).y * LegacyWindow.Columns + ((Vector2Int)(ref p)).x; if (num2 >= 0 && num2 < availablePiecesByCategory[num].Count) { __result = availablePiecesByCategory[num][num2]; } return false; } [HarmonyPatch(typeof(PieceTable), "GetPieceIndex")] [HarmonyPrefix] private static bool PieceTable_GetPieceIndex(PieceTable __instance, Piece p, ref Vector2Int index, ref PieceCategory category, ref bool __result) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected I4, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) if (!On(Hud.instance)) { return true; } string prefabName = Utils.GetPrefabName(((Component)p).gameObject); int num = (int)__instance.GetSelectedCategory(); __result = TryLocate(__instance, num, prefabName, ref index, ref category); int num2 = 0; while (!__result && num2 < __instance.m_availablePiecesByCategory.Count) { if (num2 != num) { __result = TryLocate(__instance, num2, prefabName, ref index, ref category); } num2++; } if (!__result) { index = Vector2Int.zero; category = (PieceCategory)0; } return false; } private static bool TryLocate(PieceTable table, int slot, string prefab, ref Vector2Int index, ref PieceCategory category) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) if (slot < 0 || slot >= table.m_availablePiecesByCategory.Count || !table.m_categories.Contains((PieceCategory)slot)) { return false; } List<Piece> list = table.m_availablePiecesByCategory[slot]; int columns = LegacyWindow.Columns; for (int i = 0; i < list.Count; i++) { if (!((Object)(object)list[i] == (Object)null) && !(Utils.GetPrefabName(((Component)list[i]).gameObject) != prefab)) { index = new Vector2Int(i % columns, i / columns); category = (PieceCategory)slot; return true; } } return false; } [HarmonyPatch(typeof(PieceTable), "LeftPiece")] [HarmonyPrefix] private static bool PieceTable_LeftPiece(PieceTable __instance) { return Nav(__instance, -1, 0); } [HarmonyPatch(typeof(PieceTable), "RightPiece")] [HarmonyPrefix] private static bool PieceTable_RightPiece(PieceTable __instance) { return Nav(__instance, 1, 0); } [HarmonyPatch(typeof(PieceTable), "UpPiece")] [HarmonyPrefix] private static bool PieceTable_UpPiece(PieceTable __instance) { return Nav(__instance, 0, -1); } [HarmonyPatch(typeof(PieceTable), "DownPiece")] [HarmonyPrefix] private static bool PieceTable_DownPiece(PieceTable __instance) { return Nav(__instance, 0, 1); } private static bool Nav(PieceTable table, int dx, int dy) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected I4, but got Unknown //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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) if (!On(Hud.instance)) { return true; } int num = (int)table.GetSelectedCategory(); if (num < 0 || num >= table.m_availablePiecesByCategory.Count || num >= table.m_selectedPiece.Length) { return true; } int count = table.m_availablePiecesByCategory[num].Count; if (count <= 1) { return false; } int columns = LegacyWindow.Columns; int num2 = LegacyWindow.RowCount(count); Vector2Int val = table.m_selectedPiece[num]; ((Vector2Int)(ref val)).x = (((Vector2Int)(ref val)).x + dx + columns) % columns; ((Vector2Int)(ref val)).y = (((Vector2Int)(ref val)).y + dy + num2) % num2; table.m_selectedPiece[num] = val; return false; } [HarmonyPatch(typeof(PieceTable), "UpdateAvailable")] [HarmonyPostfix] [HarmonyPriority(0)] [HarmonyAfter(new string[] { "org.bepinex.helpers.PieceManager", "com.jotunn.jotunn" })] private static void PieceTable_UpdateAvailable_Search(PieceTable __instance) { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: 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) PieceSearch query = LegacyWindow.Query; if (!Enabled || query.IsEmpty || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)Player.m_localPlayer.m_buildPieces != (Object)(object)__instance) { return; } try { List<List<Piece>> availablePiecesByCategory = __instance.m_availablePiecesByCategory; for (int i = 0; i < availablePiecesByCategory.Count; i++) { availablePiecesByCategory[i].RemoveAll((Piece piece) => !query.Matches(piece)); if (i < __instance.m_selectedPiece.Length) { Vector2Int val = __instance.m_selectedPiece[i]; if (((Vector2Int)(ref val)).y * LegacyWindow.Columns + ((Vector2Int)(ref val)).x >= availablePiecesByCategory[i].Count) { __instance.m_selectedPiece[i] = Vector2Int.zero; } } } } catch (Exception ex) { LegacyBuildMenuPlugin.LogErrorOnce("build piece search filter", ex); } } [HarmonyPatch(typeof(Player), "CopyPiece")] [HarmonyPrefix] private static void Player_CopyPiece() { if (On(Hud.instance)) { LegacyWindow.ClearSearch(); } } [HarmonyPatch(typeof(Menu), "IsVisible")] [HarmonyPostfix] private static void Menu_IsVisible(ref bool __result) { if (!__result && On(Hud.instance) && LegacyWindow.IsSearchFocused) { __result = true; } } [HarmonyPatch(typeof(Menu), "IsActive")] [HarmonyPostfix] private static void Menu_IsActive(ref bool __result) { if (!__result && On(Hud.instance) && LegacyWindow.IsSearchFocused) { __result = true; } } [HarmonyPatch(typeof(ZInput), "GetMouseScrollWheel")] [HarmonyPostfix] private static void ZInput_GetMouseScrollWheel(ref float __result) { if (__result != 0f && On(Hud.instance) && Hud.IsPieceSelectionVisible() && LegacyWindow.ShouldEatWheel()) { __result = 0f; } } private static void UpdateTabs(Hud hud, Player player, PieceTable pieceTable, PieceCategory category) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) hud.m_pieceCategoryRoot.SetActive(pieceTable.m_categories.Count > 0); if (pieceTable.m_categories.Count == 0) { return; } EnsureTabCount(hud, pieceTable.m_categories.Count); for (int i = 0; i < hud.m_pieceCategoryTabs.Length; i++) { GameObject val = hud.m_pieceCategoryTabs[i]; bool flag = i < pieceTable.m_categories.Count; val.SetActive(flag); if (!flag) { continue; } PieceCategory val2 = pieceTable.m_categories[i]; string text = $"{TabLabel(pieceTable, i)} [<color=yellow>{player.GetAvailableBuildPiecesInCategory(val2)}</color>]"; Transform val3 = val.transform.Find("Selected"); bool flag2 = val2 == category; if ((Object)(object)val3 != (Object)null) { ((Component)val3).gameObject.SetActive(flag2); if (flag2) { ((Component)val3).GetComponentInChildren<TMP_Text>().text = text; } } if (!flag2 || (Object)(object)val3 == (Object)null) { val.GetComponentInChildren<TMP_Text>().text = text; } } } private static string TabLabel(PieceTable table, int i) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) string text = ((object)table.m_categories[i]/*cast due to .constrained prefix*/).ToString(); string text2 = ((i < table.m_categoryLabels.Count) ? table.m_categoryLabels[i] : ""); if (!string.IsNullOrWhiteSpace(text2) && !string.Equals(text2, text, StringComparison.OrdinalIgnoreCase)) { return text2; } string text3 = "biome_" + text.ToLowerInvariant(); if (Localization.instance.m_translations.ContainsKey(text3)) { return "$" + text3; } return Regex.Replace(text, "(?<=[a-z])(?=[A-Z])", " "); } private static void EnsureTabCount(Hud hud, int needed) { if (TabManagerPresent) { return; } GameObject[] pieceCategoryTabs = hud.m_pieceCategoryTabs; if (pieceCategoryTabs.Length >= needed || pieceCategoryTabs.Length == 0) { return; } GameObject val = pieceCategoryTabs[^1]; GameObject[] array = (GameObject[])(object)new GameObject[needed]; Array.Copy(pieceCategoryTabs, array, pieceCategoryTabs.Length); for (int i = pieceCategoryTabs.Length; i < needed; i++) { GameObject val2 = Object.Instantiate<GameObject>(val, val.transform.parent); ((Object)val2).name = "Tab" + i; UIInputHandler component = val2.GetComponent<UIInputHandler>(); if ((Object)(object)component != (Object)null) { component.m_onLeftDown = (Action<UIInputHandler>)Delegate.Combine(component.m_onLeftDown, new Action<UIInputHandler>(hud.OnLeftClickCategory)); } array[i] = val2; } hud.m_pieceCategoryTabs = array; } [HarmonyPatch(typeof(KeyHints), "UpdateHints")] [HarmonyPostfix] private static void KeyHints_UpdateHints(KeyHints __instance) { if (On(Hud.instance) && Hud.IsPieceSelectionVisible()) { HideFavoriteHints(__instance.m_buildMenuHintsKB); HideFavoriteHints(__instance.m_buildMenuHintsGP); } } private static void HideFavoriteHints(GameObject[]? hints) { if (hints == null) { return; } foreach (GameObject val in hints) { if ((Object)(object)val != (Object)null && val.activeSelf && ((Object)val).name.IndexOf("Favorite", StringComparison.OrdinalIgnoreCase) >= 0) { val.SetActive(false); } } } [HarmonyPatch(typeof(Player), "UpdateBuildGuiInput")] [HarmonyPrefix] private static bool Player_UpdateBuildGuiInput(Player __instance) { if (!On(Hud.instance)) { return true; } try { if (ZInput.IsNonClassicFunctionality() && ZInput.IsGamepadActive()) { AlternativeLayoutInput(__instance); } else { DefaultInput(__instance); } } catch (Exception ex) { LegacyBuildMenuPlugin.LogErrorOnce("legacy build menu input", ex); } return false; } private static void DefaultInput(Player player) { if (!Hud.IsPieceSelectionVisible()) { if (ZInput.GetButtonDown("BuildMenu") && !PlayerController.HasInputDelay && !Hud.InRadial()) { Hud.instance.TogglePieceSelection(); } else if (ZInput.GetButtonDown("JoyUse") && !PlayerController.HasInputDelay && !Hud.InRadial()) { Hud.instance.TogglePieceSelection(); } return; } if (ZInput.GetKeyDown((KeyCode)27, true) || ZInput.GetButtonDown("JoyButtonB") || ZInput.GetButtonDown("BuildMenu")) { Hud.HidePieceSelection(); } if (ZInput.GetButtonDown("JoyUse")) { Hud.HidePieceSelection(); player.PlayButtonSound(); } MenuNavigation(player); } private static void AlternativeLayoutInput(Player player) { //IL_00ce: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) PieceTable buildPieces = player.m_buildPieces; if (!Hud.IsPieceSelectionVisible()) { if (ZInput.GetButtonDown("JoyBuildMenu") && !PlayerController.HasInputDelay && !Hud.InRadial() && player.m_lastBuildStateFrames > 1) { player.m_lastBuildStateFrames = 0; for (int i = 0; i < buildPieces.m_selectedPiece.Length; i++) { buildPieces.m_lastSelectedPiece[i] = buildPieces.m_selectedPiece[i]; } Hud.instance.TogglePieceSelection(); } return; } if (ZInput.GetKeyDown((KeyCode)27, true) || ZInput.GetButtonDown("JoyButtonB") || ZInput.GetButtonDown("BuildMenu")) { for (int j = 0; j < buildPieces.m_selectedPiece.Length; j++) { buildPieces.m_selectedPiece[j] = buildPieces.m_lastSelectedPiece[j]; } Hud.HidePieceSelection(); player.SetupPlacementGhost(); } if (ZInput.GetButtonDown("JoyButtonA")) { Hud.HidePieceSelection(); player.PlayButtonSound(); } MenuNavigation(player); } private static void MenuNavigation(Player player) { PieceTable buildPieces = player.m_buildPieces; player.m_scrollCurrAmount += ZInput.GetMouseScrollWheel(); if (ZInput.GetButtonDown("JoyTabLeft") || ZInput.GetButtonDown("TabLeft") || player.m_scrollCurrAmount > player.m_scrollAmountThreshold) { player.m_scrollCurrAmount = 0f; buildPieces.PrevCategory(); player.UpdateAvailablePiecesList(); } if (ZInput.GetButtonDown("JoyTabRight") || ZInput.GetButtonDown("TabRight") || player.m_scrollCurrAmount < 0f - player.m_scrollAmountThreshold) { player.m_scrollCurrAmount = 0f; buildPieces.NextCategory(); player.UpdateAvailablePiecesList(); } if (ZInput.GetButtonDown("JoyLStickLeft") || ZInput.GetButtonDown("JoyDPadLeft")) { buildPieces.LeftPiece(); player.SetupPlacementGhost(); } if (ZInput.GetButtonDown("JoyLStickRight") || ZInput.GetButtonDown("JoyDPadRight")) { buildPieces.RightPiece(); player.SetupPlacementGhost(); } if (ZInput.GetButtonDown("JoyLStickUp") || ZInput.GetButtonDown("JoyDPadUp")) { buildPieces.UpPiece(); player.SetupPlacementGhost(); } if (ZInput.GetButtonDown("JoyLStickDown") || ZInput.GetButtonDown("JoyDPadDown")) { buildPieces.DownPiece(); player.SetupPlacementGhost(); } } [HarmonyPatch(typeof(PieceTable), "UpdateAvailable")] [HarmonyPrefix] private static void PieceTable_UpdateAvailable(PieceTable __instance) { if (!Enabled) { return; } Piece val = default(Piece); foreach (GameObject piece in __instance.m_pieces) { if ((Object)(object)piece == (Object)null || !piece.TryGetComponent<Piece>(ref val)) { continue; } Requirement[] resources = val.m_resources; if (resources == null) { val.m_resources = Array.Empty<Requirement>(); } else if (!resources.All((Requirement r) => r != null && (Object)(object)r.m_resItem != (Object)null)) { val.m_resources = resources.Where((Requirement r) => r != null && (Object)(object)r.m_resItem != (Object)null).ToArray(); if (_reportedBadPieces.Add(((Object)piece).name)) { LegacyBuildMenuPlugin.Log.LogWarning((object)("Piece '" + ((Object)piece).name + "' had requirements with no item, dropped them (they cost nothing anyway). Whichever mod adds it should fix its recipe.")); } } } } [HarmonyPatch(typeof(Hud), "SetupPieceInfo")] [HarmonyFinalizer] private static Exception? Hud_SetupPieceInfo(Exception? __exception, Piece piece) { if (__exception == null || !Enabled) { return __exception; } string text = (((Object)(object)piece != (Object)null) ? ((Object)piece).name : "<null>"); if (_reportedBadPieces.Add(text + "#info")) { LegacyBuildMenuPlugin.Log.LogWarning((object)("Piece '" + text + "' broke the build menu's info panel (" + __exception.GetType().Name + ": " + __exception.Message + "), ignoring it.")); } return null; } } internal static class LegacyWindow { [CompilerGenerated] private static class <>O { public static Action<Vector2> <0>__OnResizeDrag; public static Action<Vector2> <1>__OnMoveDrag; public static UnityAction<string> <2>__OnSearchChanged; public static UnityAction <3>__ClearSearch; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__48_0; public static Func<Button, bool> <>9__48_1; public static Func<ButtonSfx, bool> <>9__49_0; internal void <StyleVanillaButton>b__48_0() { EventSystem current = EventSystem.current; if (current != null) { current.SetSelectedGameObject((GameObject)null); } } internal bool <StyleVanillaButton>b__48_1(Button b) { Graphic targetGraphic = ((Selectable)b).targetGraphic; Image val = (Image)(((object)((targetGraphic is Image) ? targetGraphic : null)) ?? ((object)((Component)b).GetComponent<Image>())); return (Object)(object)val != (Object)null && (Object)(object)val.sprite != (Object)null && ((Object)val.sprite).name.IndexOf("button", StringComparison.OrdinalIgnoreCase) >= 0; } internal bool <AttachClickSfx>b__49_0(ButtonSfx s) { return (Object)(object)s != (Object)null && (Object)(object)s.m_sfxPrefab != (Object)null; } } private const float SearchStripHeight = 30f; private const float StripGap = 2f; private const float ScrollbarGutter = 10f; private const float SearchDebounce = 0.2f; private static Hud? _builtFor; private static ScrollRect? _scrollRect; private static RectTransform? _searchStrip; private static TMP_InputField? _searchField; private static GameObject? _clearButton; private static Vector2 _origWindowSize; private static Vector2 _origWindowPos; private static Coroutine? _debounce; private static TMP_FontAsset? _font; internal static int Columns { get; private set; } = 15; internal static PieceSearch Query { get; private set; } = PieceSearch.Parse(null); internal static bool IsSearchFocused => (Object)(object)_searchField != (Object)null && _searchField.isFocused; internal static float Spacing(Hud hud) { return (hud.m_pieceIconSpacing > 0f) ? hud.m_pieceIconSpacing : 64f; } internal static int RowCount(int count) { return Mathf.Max(1, Mathf.CeilToInt((float)count / (float)Columns)); } internal static void RefreshColumns(Hud hud) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) float num = Spacing(hud); float num2; if (!((Object)(object)_scrollRect != (Object)null) || !((Object)(object)_scrollRect.viewport != (Object)null)) { num2 = 15f * num + 10f; } else { Rect rect = _scrollRect.viewport.rect; num2 = ((Rect)(ref rect)).width; } float num3 = num2; Columns = Mathf.Clamp(Mathf.FloorToInt((num3 - 10f) / num + 0.01f), 1, 64); } internal static void EnsureBuilt(Hud hud) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: 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_011a: 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_0164: 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) if (_builtFor == hud && (Object)(object)_builtFor != (Object)null) { return; } _builtFor = hud; _scrollRect = null; _searchStrip = null; _searchField = null; _clearButton = null; Query = PieceSearch.Parse(null); ModIndex.Invalidate(); try { RectTransform val = (RectTransform)hud.m_pieceSelectionWindow.transform; _origWindowSize = val.sizeDelta; _origWindowPos = val.anchoredPosition; SetupScrollView(hud); if (LegacyBuildMenuPlugin.ShowSearchBar.Value) { float num = 32f; _origWindowSize += new Vector2(0f, num); _origWindowPos -= new Vector2(0f, num * 0.5f); val.sizeDelta = _origWindowSize; val.anchoredPosition = _origWindowPos; ReserveHeader(hud, num); CreateSearchStrip(hud); } if (LegacyBuildMenuPlugin.ResizableWindow.Value) { CreateGrip(hud, "LegacyBuildMenu_Resize", new Vector2(1f, 0f), new Vector2(-6f, 6f), "◢", OnResizeDrag); CreateGrip(hud, "LegacyBuildMenu_Move", new Vector2(0f, 0f), new Vector2(6f, 6f), "≡", OnMoveDrag); } } catch (Exception arg) { LegacyBuildMenuPlugin.Log.LogError((object)$"Couldn't set up the build menu window: {arg}"); } } private static void SetupScrollView(Hud hud) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Expected O, but got Unknown //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Expected O, but got Unknown //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Expected O, but got Unknown //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Expected O, but got Unknown //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_0282: 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_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) RectTransform pieceListMask = hud.m_pieceListMask; RectTransform pieceListRoot = hud.m_pieceListRoot; if (!((Object)(object)pieceListMask == (Object)null) && !((Object)(object)pieceListRoot == (Object)null)) { pieceListMask.offsetMax += new Vector2(10f, 0f); _scrollRect = ((Component)pieceListMask).GetComponent<ScrollRect>(); if ((Object)(object)_scrollRect == (Object)null) { _scrollRect = ((Component)pieceListMask).gameObject.AddComponent<ScrollRect>(); } _scrollRect.content = pieceListRoot; _scrollRect.viewport = pieceListMask; _scrollRect.horizontal = false; _scrollRect.vertical = true; _scrollRect.movementType = (MovementType)2; _scrollRect.inertia = true; _scrollRect.decelerationRate = 0.135f; _scrollRect.scrollSensitivity = Spacing(hud) * 4f; if ((Object)(object)((Component)pieceListMask).GetComponent<Mask>() == (Object)null && (Object)(object)((Component)pieceListMask).GetComponent<RectMask2D>() == (Object)null) { ((Component)pieceListMask).gameObject.AddComponent<RectMask2D>(); } if ((Object)(object)((Component)pieceListMask).GetComponent<Graphic>() == (Object)null) { Image val = ((Component)pieceListMask).gameObject.AddComponent<Image>(); ((Graphic)val).color = new Color(0f, 0f, 0f, 0f); } GameObject val2 = new GameObject("LegacyBuildMenu_Scrollbar", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent((Transform)(object)pieceListMask, false); RectTransform val3 = (RectTransform)val2.transform; val3.anchorMin = new Vector2(1f, 0f); val3.anchorMax = new Vector2(1f, 1f); val3.pivot = new Vector2(1f, 0.5f); val3.anchoredPosition = new Vector2(-1f, 0f); val3.sizeDelta = new Vector2(9f, 0f); Image val4 = val2.AddComponent<Image>(); StyleTabImage(hud, val4); ((Graphic)val4).color = new Color(0.191f, 0.078f, 0.078f, 1f); GameObject val5 = new GameObject("Handle", new Type[1] { typeof(RectTransform) }); val5.transform.SetParent(val2.transform, false); RectTransform val6 = (RectTransform)val5.transform; val6.anchorMin = Vector2.zero; val6.anchorMax = Vector2.one; val6.sizeDelta = Vector2.zero; Image val7 = val5.AddComponent<Image>(); StyleTabImage(hud, val7); ((Graphic)val7).color = new Color(0.8529f, 0.725f, 0.5331f, 1f); Scrollbar val8 = val2.AddComponent<Scrollbar>(); val8.handleRect = val6; val8.direction = (Direction)2; ((Selectable)val8).targetGraphic = (Graphic)(object)val7; Navigation navigation = default(Navigation); ((Navigation)(ref navigation)).mode = (Mode)0; ((Selectable)val8).navigation = navigation; _scrollRect.verticalScrollbar = val8; _scrollRect.verticalScrollbarVisibility = (ScrollbarVisibility)1; } } internal static void SetContentHeight(Hud hud, int count) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_scrollRect == (Object)null) && !((Object)(object)_scrollRect.content == (Object)null)) { float num = Spacing(hud); _scrollRect.content.sizeDelta = new Vector2((float)Columns * num, (float)RowCount(count) * num + num * 0.25f); } } internal static void ScrollToTop() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_scrollRect == (Object)null) && !((Object)(object)_scrollRect.content == (Object)null)) { _scrollRect.verticalNormalizedPosition = 1f; RectTransform content = _scrollRect.content; content.anchoredPosition = new Vector2(content.anchoredPosition.x, 0f); } } internal static bool ShouldEatWheel() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_scrollRect == (Object)null || (Object)(object)_scrollRect.viewport == (Object)null || (Object)(object)_scrollRect.content == (Object)null) { return false; } Rect rect = _scrollRect.content.rect; float height = ((Rect)(ref rect)).height; rect = _scrollRect.viewport.rect; if (height <= ((Rect)(ref rect)).height + 1f) { return false; } return RectTransformUtility.RectangleContainsScreenPoint(_scrollRect.viewport, Vector2.op_Implicit(Input.mousePosition), (Camera)null); } private static void ReserveHeader(Hud hud, float height) { //IL_000a: 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_0021: Unknown result type (might be due to invalid IL or missing references) RectTransform pieceListMask = hud.m_pieceListMask; pieceListMask.offsetMax = new Vector2(pieceListMask.offsetMax.x, pieceListMask.offsetMax.y - height); } private static void CreateSearchStrip(Hud hud) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown //IL_00c5: 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_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Expected O, but got Unknown //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: 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_0283: Unknown result type (might be due to invalid IL or missing references) TMP_FontAsset val = UiFont(hud); GameObject val2 = new GameObject("LegacyBuildMenu_Search", new Type[1] { typeof(RectTransform) }); val2.SetActive(false); val2.transform.SetParent(hud.m_pieceSelectionWindow.transform, false); _searchStrip = (RectTransform)val2.transform; Image val3 = val2.AddComponent<Image>(); StyleTabImage(hud, val3); ((Graphic)val3).color = new Color(0f, 0f, 0f, 0.65f); GameObject val4 = new GameObject("InputField", new Type[1] { typeof(RectTransform) }); val4.transform.SetParent(val2.transform, false); RectTransform val5 = (RectTransform)val4.transform; val5.anchorMin = Vector2.zero; val5.anchorMax = Vector2.one; val5.offsetMin = new Vector2(6f, 3f); val5.offsetMax = new Vector2(-36f, -3f); _searchField = val4.AddComponent<TMP_InputField>(); GameObject val6 = new GameObject("TextArea", new Type[1] { typeof(RectTransform) }); val6.transform.SetParent(val4.transform, false); RectTransform val7 = (RectTransform)val6.transform; val7.anchorMin = Vector2.zero; val7.anchorMax = Vector2.one; val7.offsetMin = new Vector2(8f, 0f); val7.offsetMax = new Vector2(-8f, 0f); val6.AddComponent<RectMask2D>(); TMP_Text val8 = CreateText((Transform)(object)val7, "Placeholder", val, 14f, new Color(0.6f, 0.6f, 0.6f, 0.6f), (TextAlignmentOptions)4097); val8.text = "Search... @mod !material"; TMP_Text textComponent = CreateText((Transform)(object)val7, "Text", val, 14f, Color.white, (TextAlignmentOptions)4097); _searchField.textViewport = val7; _searchField.textComponent = textComponent; _searchField.placeholder = (Graphic)(object)val8; if ((Object)(object)val != (Object)null) { _searchField.fontAsset = val; } _searchField.pointSize = 14f; _searchField.lineType = (LineType)0; _searchField.characterLimit = 100; TMP_InputField? searchField = _searchField; Navigation navigation = default(Navigation); ((Navigation)(ref navigation)).mode = (Mode)0; ((Selectable)searchField).navigation = navigation; ((UnityEvent<string>)(object)_searchField.onValueChanged).AddListener((UnityAction<string>)OnSearchChanged); CreateClearButton(hud, val2.transform, val); val2.SetActive(true); Relayout(hud); } private static void CreateClearButton(Hud hud, Transform parent, TMP_FontAsset? font) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: 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_00ec: Expected O, but got Unknown _clearButton = new GameObject("Clear", new Type[1] { typeof(RectTransform) }); _clearButton.SetActive(false); _clearButton.transform.SetParent(parent, false); RectTransform val = (RectTransform)_clearButton.transform; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(1f, 0.5f); val.pivot = val2; Vector2 anchorMin = (val.anchorMax = val2); val.anchorMin = anchorMin; val.anchoredPosition = new Vector2(-4f, 0f); val.sizeDelta = new Vector2(26f, 26f); Image img = _clearButton.AddComponent<Image>(); Button val4 = _clearButton.AddComponent<Button>(); StyleVanillaButton(hud, val4, img); ButtonClickedEvent onClick = val4.onClick; object obj = <>O.<3>__ClearSearch; if (obj == null) { UnityAction val5 = ClearSearch; <>O.<3>__ClearSearch = val5; obj = (object)val5; } ((UnityEvent)onClick).AddListener((UnityAction)obj); AttachClickSfx(_clearButton); TMP_Text val6 = CreateText((Transform)(object)val, "Text", font, 18f, Color.white, (TextAlignmentOptions)514); val6.text = "X"; } private static void Relayout(Hud hud) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00d1: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_searchStrip == (Object)null)) { Canvas.ForceUpdateCanvases(); RectTransform val = (RectTransform)hud.m_pieceSelectionWindow.transform; RectTransform pieceListMask = hud.m_pieceListMask; Vector3[] array = (Vector3[])(object)new Vector3[4]; pieceListMask.GetWorldCorners(array); Vector3 val2 = ((Transform)val).InverseTransformPoint(array[1]); RectTransform? searchStrip = _searchStrip; RectTransform? searchStrip2 = _searchStrip; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0.5f, 0.5f); searchStrip2.anchorMax = val3; searchStrip.anchorMin = val3; _searchStrip.pivot = new Vector2(0.5f, 0f); RectTransform? searchStrip3 = _searchStrip; Rect rect = pieceListMask.rect; searchStrip3.sizeDelta = new Vector2(((Rect)(ref rect)).width, 30f); _searchStrip.anchoredPosition = new Vector2(0f, val2.y + 2f); } } private static void OnSearchChanged(string text) { if ((Object)(object)_clearButton != (Object)null) { _clearButton.SetActive(!string.IsNullOrEmpty(text)); } if (!((Object)(object)Hud.instance == (Object)null)) { if (_debounce != null) { ((MonoBehaviour)Hud.instance).StopCoroutine(_debounce); } _debounce = ((MonoBehaviour)Hud.instance).StartCoroutine(ApplySearchLater(text)); } } private static IEnumerator ApplySearchLater(string text) { yield return (object)new WaitForSecondsRealtime(0.2f); _debounce = null; ApplySearch(text); } private static void ApplySearch(string text) { Query = PieceSearch.Parse(text); Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && (Object)(object)localPlayer.m_buildPieces != (Object)null) { localPlayer.UpdateAvailablePiecesList(); } ScrollToTop(); } internal static void ClearSearch() { if (!((Object)(object)_searchField == (Object)null) && !string.IsNullOrEmpty(_searchField.text)) { _searchField.text = ""; if (_debounce != null && (Object)(object)Hud.instance != (Object)null) { ((MonoBehaviour)Hud.instance).StopCoroutine(_debounce); } _debounce = null; ApplySearch(""); } } private static void CreateGrip(Hud hud, string name, Vector2 corner, Vector2 offset, string glyph, Action<Vector2> onDrag) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: 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_00fb: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(hud.m_pieceSelectionWindow.transform, false); RectTransform val2 = (RectTransform)val.transform; Vector2 val3 = (val2.pivot = corner); Vector2 anchorMin = (val2.anchorMax = val3); val2.anchorMin = anchorMin; val2.anchoredPosition = offset; val2.sizeDelta = new Vector2(34f, 34f); Image val6 = val.AddComponent<Image>(); val6.sprite = GripHandle.RoundedRect(); val6.type = (Type)1; ((Graphic)val6).color = new Color(0.565f, 0.792f, 0.976f, 0.85f); val.AddComponent<Shadow>().effectDistance = new Vector2(2f, -2f); TMP_Text val7 = CreateText((Transform)(object)val2, "Icon", UiFont(hud), 22f, Color.white, (TextAlignmentOptions)514); val7.text = glyph; ((Graphic)val7).raycastTarget = false; CanvasGroup val8 = val.AddComponent<CanvasGroup>(); val8.alpha = 0f; GripHandle gripHandle = val.AddComponent<GripHandle>(); gripHandle.Dragged = onDrag; gripHandle.Ended = delegate { KeepOnScreen(hud); }; val.transform.SetAsLastSibling(); } private static Vector2 ClampSizeOffset(Vector2 o) { //IL_0000: 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_002a: Unknown result type (might be due to invalid IL or missing references) return new Vector2(Mathf.Clamp(o.x, -300f, 900f), Mathf.Clamp(o.y, -150f, 600f)); } private static void OnResizeDrag(Vector2 delta) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_0053: Unknown result type (might be due to invalid IL or missing references) Hud instance = Hud.instance; if (!((Object)(object)instance == (Object)null)) { RectTransform val = (RectTransform)instance.m_pieceSelectionWindow.transform; Vector2 val2 = val.sizeDelta - _origWindowSize; LegacyBuildMenuPlugin.WindowSize.Value = ClampSizeOffset(val2 + new Vector2(delta.x, 0f - delta.y)); ApplyWindow(instance); } } private static void OnMoveDrag(Vector2 delta) { //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_0020: Unknown result type (might be due to invalid IL or missing references) Hud instance = Hud.instance; if (!((Object)(object)instance == (Object)null)) { ConfigEntry<Vector2> windowPos = LegacyBuildMenuPlugin.WindowPos; windowPos.Value += delta; ApplyWindow(instance); } } internal static void ApplyWindow(Hud hud) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_003e: 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_0032: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007a: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) if (_builtFor == hud) { RectTransform val = (RectTransform)hud.m_pieceSelectionWindow.transform; Vector2 val2 = (LegacyBuildMenuPlugin.ResizableWindow.Value ? ClampSizeOffset(LegacyBuildMenuPlugin.WindowSize.Value) : Vector2.zero); Vector2 val3 = (LegacyBuildMenuPlugin.ResizableWindow.Value ? LegacyBuildMenuPlugin.WindowPos.Value : Vector2.zero); val.sizeDelta = _origWindowSize + val2; val.anchoredPosition = _origWindowPos + new Vector2(val2.x * 0.5f, (0f - val2.y) * 0.5f) + val3; KeepOnScreen(hud); Relayout(hud); RefreshColumns(hud); } } private static void KeepOnScreen(Hud hud) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0161: 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_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)hud.m_pieceSelectionWindow.transform; if (!((Component)val).gameObject.activeInHierarchy) { return; } Canvas componentInParent = ((Component)val).GetComponentInParent<Canvas>(); if (!((Object)(object)componentInParent == (Object)null)) { RectTransform val2 = (RectTransform)((Component)componentInParent.rootCanvas).transform; Rect rect = val2.rect; Canvas.ForceUpdateCanvases(); Vector3[] array = (Vector3[])(object)new Vector3[4]; val.GetWorldCorners(array); Vector3 val3 = ((Transform)val2).InverseTransformPoint(array[0]); Vector3 val4 = ((Transform)val2).InverseTransformPoint(array[2]); float num = 0f; float num2 = 0f; if (val3.x < ((Rect)(ref rect)).xMin + 8f) { num += ((Rect)(ref rect)).xMin + 8f - val3.x; } if (val4.x > ((Rect)(ref rect)).xMax - 8f) { num -= val4.x - (((Rect)(ref rect)).xMax - 8f); } if (val3.y < ((Rect)(ref rect)).yMin + 8f) { num2 += ((Rect)(ref rect)).yMin + 8f - val3.y; } if (val4.y > ((Rect)(ref rect)).yMax - 8f) { num2 -= val4.y - (((Rect)(ref rect)).yMax - 8f); } if (num != 0f || num2 != 0f) { val.anchoredPosition += new Vector2(num, num2); ConfigEntry<Vector2> windowPos = LegacyBuildMenuPlugin.WindowPos; windowPos.Value += new Vector2(num, num2); } } } private static TMP_FontAsset? UiFont(Hud hud) { if ((Object)(object)_font != (Object)null) { return _font; } _font = (((Object)(object)hud.m_buildSelection != (Object)null) ? hud.m_buildSelection.font : null); if ((Object)(object)_font == (Object)null && (Object)(object)hud.m_pieceDescription != (Object)null) { _font = hud.m_pieceDescription.font; } if ((Object)(object)_font == (Object)null) { TMP_Text componentInChildren = hud.m_pieceSelectionWindow.GetComponentInChildren<TMP_Text>(true); _font = ((componentInChildren != null) ? componentInChildren.font : null); } return _font; } private static TMP_Text CreateText(Transform parent, string name, TMP_FontAsset? font, float size, Color color, TextAlignmentOptions align) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0054: 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_006d: 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_0085: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.SetActive(false); val.transform.SetParent(parent, false); TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>(); if ((Object)(object)font != (Object)null) { ((TMP_Text)val2).font = font; } ((TMP_Text)val2).fontSize = size; ((Graphic)val2).color = color; ((TMP_Text)val2).alignment = align; RectTransform rectTransform = ((TMP_Text)val2).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.sizeDelta = Vector2.zero; val.SetActive(true); return (TMP_Text)(object)val2; } private static void StyleTabImage(Hud hud, Image img) { if (hud.m_pieceCategoryTabs != null && hud.m_pieceCategoryTabs.Length != 0 && !((Object)(object)hud.m_pieceCategoryTabs[0] == (Object)null)) { Image component = hud.m_pieceCategoryTabs[0].GetComponent<Image>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.sprite == (Object)null)) { img.sprite = component.sprite; img.type = (Type)1; } } } private static void StyleVanillaButton(Hud hud, Button btn, Image img) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_00c2: 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_00dc: Unknown result type (might be due to invalid IL or missing references) Navigation navigation = default(Navigation); ((Navigation)(ref navigation)).mode = (Mode)0; ((Selectable)btn).navigation = navigation; ButtonClickedEvent onClick = btn.onClick; object obj = <>c.<>9__48_0; if (obj == null) { UnityAction val = delegate { EventSystem current = EventSystem.current; if (current != null) { current.SetSelectedGameObject((GameObject)null); } }; <>c.<>9__48_0 = val; obj = (object)val; } ((UnityEvent)onClick).AddListener((UnityAction)obj); Button val2 = ((IEnumerable<Button>)Resources.FindObjectsOfTypeAll<Button>()).FirstOrDefault((Func<Button, bool>)delegate(Button b) { Graphic targetGraphic2 = ((Selectable)b).targetGraphic; Image val4 = (Image)(((object)((targetGraphic2 is Image) ? targetGraphic2 : null)) ?? ((object)((Component)b).GetComponent<Image>())); return (Object)(object)val4 != (Object)null && (Object)(object)val4.sprite != (Object)null && ((Object)val4.sprite).name.IndexOf("button", StringComparison.OrdinalIgnoreCase) >= 0; }); if ((Object)(object)val2 == (Object)null) { StyleTabImage(hud, img); ((Selectable)btn).targetGraphic = (Graphic)(object)img; return; } Graphic targetGraphic = ((Selectable)val2).targetGraphic; Image val3 = (Image)(((object)((targetGraphic is Image) ? targetGraphic : null)) ?? ((object)((Component)val2).GetComponent<Image>())); img.sprite = val3.sprite; img.type = (Type)1; ((Selectable)btn).targetGraphic = (Graphic)(object)img; ((Selectable)btn).transition = ((Selectable)val2).transition; ((Selectable)btn).spriteState = ((Selectable)val2).spriteState; ((Selectable)btn).colors = ((Selectable)val2).colors; } private static void AttachClickSfx(GameObject go) { ButtonSfx val = ((IEnumerable<ButtonSfx>)Resources.FindObjectsOfTypeAll<ButtonSfx>()).FirstOrDefault((Func<ButtonSfx, bool>)((ButtonSfx s) => (Object)(object)s != (Object)null && (Object)(object)s.m_sfxPrefab != (Object)null)); if (!((Object)(object)val == (Object)null) && !((Object)(object)go.GetComponent<ButtonSfx>() != (Object)null)) { go.AddComponent<ButtonSfx>().m_sfxPrefab = val.m_sfxPrefab; } } } internal sealed class PieceSearch { private readonly List<string> _words = new List<string>(); private readonly List<string> _mods = new List<string>(); private readonly List<string> _materials = new List<string>(); public bool IsEmpty => _words.Count == 0 && _mods.Count == 0 && _materials.Count == 0; public static PieceSearch Parse(string? text) { PieceSearch pieceSearch = new PieceSearch(); if (string.IsNullOrWhiteSpace(text)) { return pieceSearch; } string[] array = text.ToLowerInvariant().Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries); foreach (string text2 in array) { if (text2.Length > 1 && text2[0] == '@') { pieceSearch._mods.Add(text2.Substring(1)); } else if (text2.Length > 1 && text2[0] == '!') { pieceSearch._materials.Add(text2.Substring(1)); } else if (text2 != "@" && text2 != "!") { pieceSearch._words.Add(text2); } } return pieceSearch; } public bool Matches(Piece piece) { if ((Object)(object)piece == (Object)null) { return false; } if (piece.m_repairPiece || piece.m_removePiece) { return true; } if (_words.Count > 0) { string text = Utils.GetPrefabName(((Component)piece).gameObject).ToLowerInvariant(); string text2 = Localization.instance.Localize(piece.m_name).ToLowerInvariant(); string text3 = piece.m_name.ToLowerInvariant(); string text4 = Localization.instance.Localize(piece.m_description).ToLowerInvariant(); foreach (string word in _words) { if (!text2.Contains(word) && !text.Contains(word) && !text3.Contains(word) && !text4.Contains(word)) { return false; } } } foreach (string material in _materials) { if (!CostsMaterial(piece, material)) { return false; } } if (_mods.Count > 0) { string[] source = ModIndex.KeysFor(piece); foreach (string m in _mods) { if (!source.Any((string k) => k.Contains(m))) { return false; } } } return true; } private static bool CostsMaterial(Piece piece, string token) { Requirement[] resources = piece.m_resources; foreach (Requirement val in resources) { if (!((Object)(object)val?.m_resItem == (Object)null)) { if (Localization.instance.Localize(val.m_resItem.m_itemData.m_shared.m_name).ToLowerInvariant().Contains(token)) { return true; } if (Utils.GetPrefabName(((Component)val.m_resItem).gameObject).ToLowerInvariant().Contains(token)) { return true; } } } return false; } } internal static class ModIndex { private static readonly Dictionary<string, string[]> _byPrefab = new Dictionary<string, string[]>(); private static readonly Dictionary<string, string[]> _cache = new Dictionary<string, string[]>(); private static bool _built; private static readonly Dictionary<PluginInfo, HashSet<string>> _shippedFiles = new Dictionary<PluginInfo, HashSet<string>>(); private static MethodInfo? _jotunnGetPiece; private static object? _jotunnManager; private static bool _jotunnResolved; internal static void Invalidate() { _built = false; _byPrefab.Clear(); _cache.Clear(); } internal static string[] KeysFor(Piece piece) { string prefabName = Utils.GetPrefabName(((Component)piece).gameObject); string key = prefabName.ToLowerInvariant(); if (_cache.TryGetValue(key, out string[] value)) { return value; } if (!_built) { Build(); } if (!_byPrefab.TryGetValue(key, out value)) { value = JotunnKeys(prefabName) ?? Array.Empty<string>(); } _cache[key] = value; return value; } private static void Build() { _built = true; try { List<PluginInfo> source = Chainloader.PluginInfos.Values.Where((PluginInfo p) => (Object)(object)((p != null) ? p.Instance : null) != (Object)null).ToList(); Dictionary<string, string[]> dictionary = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase); AssetBundle[] array = AssetBundle.GetAllLoadedAssetBundles().ToArray(); AssetBundle[] array2 = array; foreach (AssetBundle bundle in array2) { if (!((Object)(object)bundle == (Object)null) && !string.IsNullOrEmpty(((Object)bundle).name)) { PluginInfo val = ((IEnumerable<PluginInfo>)source).FirstOrDefault((Func<PluginInfo, bool>)((PluginInfo p) => ShipsBundle(p, ((Object)bundle).name))); if (val != null) { dictionary[((Object)bundle).name] = KeysOf(val); } } } AssetBundle[] array3 = array; foreach (AssetBundle val2 in array3) { if ((Object)(object)val2 == (Object)null || !dictionary.TryGetValue(((Object)val2).name, out var value)) { continue; } string[] allAssetNames; try { allAssetNames = val2.GetAllAssetNames(); } catch { continue; } string[] array4 = allAssetNames; foreach (string text in array4) { if (text.EndsWith(".prefab", StringComparison.OrdinalIgnoreCase)) { _byPrefab[Path.GetFileNameWithoutExtension(text).ToLowerInvariant()] = value; } } } } catch (Exception ex) { LegacyBuildMenuPlugin.Log.LogWarning((object)("Couldn't map build pieces to mods, @ search will be patchy: " + ex.Message)); } } private static bool ShipsBundle(PluginInfo plugin, string bundleName) { Assembly assembly = ((object)plugin.Instance).GetType().Assembly; try { if (assembly.GetManifestResourceNames().Any((string r) => r.EndsWith(bundleName, StringComparison.OrdinalIgnoreCase))) { return true; } } catch { } if (!_shippedFiles.TryGetValue(plugin, out HashSet<string> value)) { value = new HashSet<string>(StringComparer.OrdinalIgnoreCase); try { string directoryName = Path.GetDirectoryName(plugin.Location); if (!string.IsNullOrEmpty(directoryName) && !string.Equals(Path.GetFullPath(directoryName), Path.GetFullPath(Paths.PluginPath), StringComparison.OrdinalIgnoreCase)) { string[] files = Directory.GetFiles(directoryName, "*", SearchOption.AllDirectories); foreach (string path in files) { value.Add(Path.GetFileName(path)); } } } catch { } _shippedFiles[plugin] = value; } return value.Contains(bundleName); } private static string[] KeysOf(PluginInfo plugin) { string text = ((object)plugin.Instance).GetType().Assembly.GetName().Name ?? ""; return (from s in new string[3] { plugin.Metadata.Name, plugin.Metadata.GUID, text } where !string.IsNullOrEmpty(s) select s.ToLowerInvariant().Replace(" ", "")).Distinct().ToArray(); } private static string[]? JotunnKeys(string prefab) { if (!_jotunnResolved) { _jotunnResolved = true; try { Type type = AccessTools.TypeByName("Jotunn.Managers.PieceManager"); _jotunnManager = type?.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public)?.GetValue(null); _jotunnGetPiece = type?.GetMethod("GetPiece", new Type[1] { typeof(string) }); } catch { _jotunnGetPiece = null; } } if (_jotunnGetPiece == null || _jotunnManager == null) { return null; } try { object obj2 = _jotunnGetPiece.Invoke(_jotunnManager, new object[1] { prefab }); object obj3 = obj2?.GetType().GetProperty("SourceMod")?.GetValue(obj2); BepInPlugin val = (BepInPlugin)((obj3 is BepInPlugin) ? obj3 : null); if (val == null) { return null; } PluginInfo value; PluginInfo val2 = (Chainloader.PluginInfos.TryGetValue(val.GUID, out value) ? value : null); return (val2 != null) ? KeysOf(val2) : new string[2] { val.Name.ToLowerInvariant().Replace(" ", ""), val.GUID.ToLowerInvariant() }; } catch { return null; } } } [BepInPlugin("Azumatt.LegacyBuildMenu", "LegacyBuildMenu", "1.0.0")] public class LegacyBuildMenuPlugin : BaseUnityPlugin { internal const string ModName = "LegacyBuildMenu"; internal const string ModVersion = "1.0.0"; internal const string Author = "Azumatt"; private const string ModGUID = "Azumatt.LegacyBuildMenu"; private const string AAABuildMenuGuid = "Azumatt.AAABuildMenu"; private readonly Harmony _harmony = new Harmony("Azumatt.LegacyBuildMenu"); internal static readonly ManualLogSource Log = Logger.CreateLogSource("LegacyBuildMenu"); private static readonly HashSet<string> _loggedOnce = new HashSet<string>(); internal static ConfigEntry<bool> UseLegacyMenu = null; internal static ConfigEntry<bool> ShowSearchBar = null; internal static ConfigEntry<bool> ResizableWindow = null; internal static ConfigEntry<Vector2> WindowSize = null; internal static ConfigEntry<Vector2> WindowPos = null; internal static bool StoodDown; internal static void LogErrorOnce(string where, Exception ex) { if (_loggedOnce.Add(where)) { Log.LogError((object)$"Error in {where} (only the first one gets logged): {ex}"); } } public void Awake() { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) UseLegacyMenu = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Use Legacy Build Menu", true, "Use the pre-1.0 build menu instead of the one Valheim 1.0 ships. Off gives you the 1.0 menu back without a restart."); UseLegacyMenu.SettingChanged += delegate { LegacyMenu.OnSettingChanged(); }; ShowSearchBar = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Show Search Bar", true, "Search bar above the pieces. @modname finds a mod's pieces, !material finds what costs that material, anything else matches the name. Needs a relog."); ResizableWindow = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Window", "Resizable Window", true, "Drag the bottom-right corner to resize the build menu and the bottom-left one to move it. Off puts it back to the vanilla size and spot."); ResizableWindow.SettingChanged += delegate { if ((Object)(object)Hud.instance != (Object)null) { LegacyWindow.ApplyWindow(Hud.instance); } }; WindowSize = ((BaseUnityPlugin)this).Config.Bind<Vector2>("2 - Window", "Window Size Offset", Vector2.zero, "Set by dragging the resize corner."); WindowPos = ((BaseUnityPlugin)this).Config.Bind<Vector2>("2 - Window", "Window Position Offset", Vector2.zero, "Set by dragging the move corner."); _harmony.PatchAll(Assembly.GetExecutingAssembly()); } private void Start() { if (Chainloader.PluginInfos.ContainsKey("Azumatt.AAABuildMenu")) { StoodDown = true; Log.LogWarning((object)"AAABuildMenu is installed and has its own classic build menu option. LegacyBuildMenu is standing down, use one or the other."); } } } }