From f2ab96750b231635c65d0cc50b887e84b3c3c0ef Mon Sep 17 00:00:00 2001 From: HungDK <> Date: Thu, 21 May 2026 17:39:47 +0700 Subject: [PATCH] Add various quantity input ui for every needed feature --- Assets/PerfectWorld/Scripts/UI/AUIManager.cs | 22 +- .../Scripts/UI/Dialogs/DlgQuantity.cs | 251 +++ .../Scripts/UI/Dialogs/DlgQuantity.cs.meta | 2 + Assets/Prefabs/UI/DlgQuantity.prefab | 1640 +++++++++++++++++ Assets/Prefabs/UI/DlgQuantity.prefab.meta | 7 + 5 files changed, 1920 insertions(+), 2 deletions(-) create mode 100644 Assets/PerfectWorld/Scripts/UI/Dialogs/DlgQuantity.cs create mode 100644 Assets/PerfectWorld/Scripts/UI/Dialogs/DlgQuantity.cs.meta create mode 100644 Assets/Prefabs/UI/DlgQuantity.prefab create mode 100644 Assets/Prefabs/UI/DlgQuantity.prefab.meta diff --git a/Assets/PerfectWorld/Scripts/UI/AUIManager.cs b/Assets/PerfectWorld/Scripts/UI/AUIManager.cs index 17c2395458..6ac9842d3a 100644 --- a/Assets/PerfectWorld/Scripts/UI/AUIManager.cs +++ b/Assets/PerfectWorld/Scripts/UI/AUIManager.cs @@ -326,7 +326,10 @@ namespace BrewMonster.UI return null; } var prefab = m_dialogResouce.GetPrefabDialog(pszName); - if(prefab != null) + if (prefab == null) + prefab = TryLoadDialogPrefabFallback(pszName); + + if (prefab != null) { var instance = GameObject.Instantiate(prefab, m_canvas.transform); var dialog = instance.GetComponent(); @@ -336,10 +339,11 @@ namespace BrewMonster.UI m_DlgName[pszName] = dialog; return dialog; } + BMLogger.LogError($"[AUIManager] Prefab '{pszName}' has no AUIDialog component on root."); } else { - BMLogger.LogError($" Không tìm thấy prefab chứa dialog {pszName} "); + BMLogger.LogError($"[AUIManager] Không tìm thấy prefab dialog '{pszName}'. Add id+prefab to DialogScriptTableObject (Resources/UI/DialogScriptTableObject.asset)."); } } @@ -389,5 +393,19 @@ namespace BrewMonster.UI return true; } + + /// + /// Runtime fallback when a dialog exists as prefab but is missing from DialogScriptTableObject. + /// + static GameObject TryLoadDialogPrefabFallback(string pszName) + { + if (string.IsNullOrEmpty(pszName)) + return null; +#if UNITY_EDITOR + return UnityEditor.AssetDatabase.LoadAssetAtPath($"Assets/Prefabs/UI/{pszName}.prefab"); +#else + return null; +#endif + } } } diff --git a/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgQuantity.cs b/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgQuantity.cs new file mode 100644 index 0000000000..b8ba84cf51 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgQuantity.cs @@ -0,0 +1,251 @@ +using BrewMonster.Network; +using BrewMonster.Scripts; +using BrewMonster.Scripts.Managers; +using System; +using TMPro; +using UnityEngine; +using UnityEngine.UI; + +namespace BrewMonster.UI +{ + /// + /// Numeric input dialog (C++ CDlgInputNO / DlgInputNO). Dialog id: DlgQuantity. + /// + public class DlgQuantity : AUIDialog + { + public enum QuantityMode + { + None = 0, + /// Gửi tiền vào kho — C++ INPUTNO_STORAGE_IVTR_MONEY (Win_Inventory choosemoney + storage open). + StorageDepositMoney, + /// Rút tiền ra — C++ INPUTNO_STORAGE_TRASH_MONEY (Win_Storage choosemoney). + StorageWithdrawMoney, + } + + [Header("Amount")] + [SerializeField] private TMP_InputField amountInput; + [SerializeField] private Text amountTextLegacy; + + [Header("Buttons (C++: confirm / IDCANCEL / add / minus / max)")] + [SerializeField] private Button confirmButton; + [SerializeField] private Button cancelButton; + [SerializeField] private Button addButton; + [SerializeField] private Button minusButton; + [SerializeField] private Button maxButton; + + private QuantityMode _mode = QuantityMode.None; + private int _min = 1; + private int _max = 1; + private int _current = 1; + private Action _onConfirmed; + + public static DlgQuantity GetDialog() + { + return EC_Game.GetGameRun()?.GetUIManager()?.GetInGameUIMan()?.GetDialog("DlgQuantity") as DlgQuantity; + } + + /// Open quantity panel; on confirm invokes callback then sends C2S when mode is storage money. + public static void Show(QuantityMode mode, int maxAmount, int defaultAmount = 1, Action onConfirmed = null) + { + var dlg = GetDialog(); + if (dlg == null) + { + Debug.LogError("[DlgQuantity] Dialog 'DlgQuantity' not found. Add prefab to DialogScriptTableObject (id DlgQuantity)."); + return; + } + + CECUIManager.Instance?.ShowDialogOverlay("DlgQuantity"); + dlg.Open(mode, maxAmount, defaultAmount, onConfirmed); + } + + public override void Awake() + { + base.Awake(); + ResolveControls(); + WireButtons(); + } + + void ResolveControls() + { + if (amountInput == null) + { + amountInput = GetComponentInChildren(true); + if (amountInput != null && amountInput.name.Contains("DEFAULT", StringComparison.OrdinalIgnoreCase) == false) + { + var all = GetComponentsInChildren(true); + for (int i = 0; i < all.Length; i++) + { + if (all[i] != null && all[i].name.IndexOf("Txt_No", StringComparison.OrdinalIgnoreCase) >= 0) + { + amountInput = all[i]; + break; + } + } + } + } + + ResolveButton(ref confirmButton, "confirm", "btn_confirm", "ok"); + ResolveButton(ref cancelButton, "cancel", "idcanel", "btn_cancel", "close"); + ResolveButton(ref addButton, "add", "btn_add", "incre", "plus"); + ResolveButton(ref minusButton, "minus", "btn_minus", "reduce", "decre"); + ResolveButton(ref maxButton, "max", "btn_max"); + } + + void ResolveButton(ref Button field, params string[] nameHints) + { + if (field != null) + return; + var buttons = GetComponentsInChildren