Update ui, split item, handle split, change button text

This commit is contained in:
HungDK
2026-04-06 17:15:40 +07:00
parent 7881afd2b1
commit 7d303c3fca
8 changed files with 1333 additions and 113 deletions
@@ -39,6 +39,19 @@ namespace BrewMonster.Scripts.Managers
[SerializeField] private Button equipButton;
[SerializeField] private Button dropButton;
[Header("Stack Split UI (assign in Inspector)")]
[SerializeField] private GameObject splitPanelRoot;
[SerializeField] private TMPro.TMP_InputField splitAmountText;
[SerializeField] private Button splitConfirmButton;
[SerializeField] private Button splitCloseButton;
[SerializeField] private Button splitOpenButton;
[SerializeField] private Button splitIncreaseButton;
[SerializeField] private Button splitDecreaseButton;
[SerializeField] private Button splitMaxButton;
private int _splitAmount = 1;
private int _splitMaxAmount = 1;
[Header("Inventory Settings")]
[SerializeField] private bool autoRefresh = true;
[SerializeField] private float refreshInterval = 1.0f;
@@ -112,6 +125,7 @@ namespace BrewMonster.Scripts.Managers
model = new InventoryModel();
view = new InventoryView();
WireBagTabButtons();
WireSplitUI();
//if (currentDragImage == null)
//{
@@ -135,6 +149,7 @@ namespace BrewMonster.Scripts.Managers
{
ShowDetailPanel(false);
}
ShowSplitPanel(false);
// Apply any pending currency values captured before the UI became active
ApplyPendingCurrency();
}
@@ -145,9 +160,125 @@ namespace BrewMonster.Scripts.Managers
ApplyPendingCurrency();
UpdateCharacterInfo();
ShowDetailPanel(false);
ShowSplitPanel(false);
RefreshAll();
}
private void WireSplitUI()
{
if (splitOpenButton != null)
{
splitOpenButton.onClick.RemoveAllListeners();
splitOpenButton.onClick.AddListener(OpenSplitPanelForSelection);
}
if (splitConfirmButton != null)
{
splitConfirmButton.onClick.RemoveAllListeners();
splitConfirmButton.onClick.AddListener(ConfirmSplit);
}
if (splitCloseButton != null)
{
splitCloseButton.onClick.RemoveAllListeners();
splitCloseButton.onClick.AddListener(() => ShowSplitPanel(false));
}
if (splitIncreaseButton != null)
{
splitIncreaseButton.onClick.RemoveAllListeners();
splitIncreaseButton.onClick.AddListener(() => SetSplitAmount(_splitAmount + 1));
}
if (splitDecreaseButton != null)
{
splitDecreaseButton.onClick.RemoveAllListeners();
splitDecreaseButton.onClick.AddListener(() => SetSplitAmount(_splitAmount - 1));
}
if (splitMaxButton != null)
{
splitMaxButton.onClick.RemoveAllListeners();
splitMaxButton.onClick.AddListener(() => SetSplitAmount(_splitMaxAmount));
}
if (splitAmountText != null)
{
splitAmountText.onValueChanged.RemoveAllListeners();
splitAmountText.onValueChanged.AddListener(OnSplitAmountInputChanged);
}
}
private void ShowSplitPanel(bool show)
{
if (splitPanelRoot != null)
splitPanelRoot.SetActive(show);
}
/// <summary>
/// Call this from your UI (or bind it to a button) to open the split panel for current selection.
/// </summary>
public void OpenSplitPanelForSelection()
{
if (currentSelectedItem == null || currentSelectedPackage != PKG_INVENTORY)
{
Debug.LogWarning("[InventoryUI] OpenSplitPanelForSelection: select an inventory stack first");
return;
}
int total = currentSelectedItem.m_iCount;
if (total <= 1)
{
Debug.LogWarning("[InventoryUI] OpenSplitPanelForSelection: item count <= 1");
return;
}
_splitMaxAmount = Math.Max(1, total - 1);
_splitAmount = Mathf.Clamp(_splitAmount, 1, _splitMaxAmount);
UpdateSplitAmountUI();
ShowSplitPanel(true);
}
private void SetSplitAmount(int amount)
{
_splitAmount = Mathf.Clamp(amount, 1, Math.Max(1, _splitMaxAmount));
UpdateSplitAmountUI();
}
private void UpdateSplitAmountUI()
{
if (splitAmountText != null)
splitAmountText.SetTextWithoutNotify(_splitAmount.ToString());
if (splitIncreaseButton != null)
splitIncreaseButton.interactable = _splitAmount < _splitMaxAmount;
if (splitDecreaseButton != null)
splitDecreaseButton.interactable = _splitAmount > 1;
if (splitMaxButton != null)
splitMaxButton.interactable = _splitAmount < _splitMaxAmount;
}
private void OnSplitAmountInputChanged(string raw)
{
if (!int.TryParse(raw, out int v))
return;
v = Mathf.Clamp(v, 1, Math.Max(1, _splitMaxAmount));
if (v == _splitAmount)
return;
_splitAmount = v;
UpdateSplitAmountUI();
}
private void ConfirmSplit()
{
int amount = _splitAmount;
if (amount <= 0) return;
if (SeparateSelectedStack(amount))
{
ShowSplitPanel(false);
}
}
private void WireBagTabButtons()
{
if (tabItemButton != null)
@@ -596,6 +727,69 @@ namespace BrewMonster.Scripts.Managers
RefreshAll();
}
/// <summary>
/// Separate part of the currently selected stack into a new empty slot (C2S MOVE_IVTR_ITEM with partial count).
/// Your UI can call this directly once you've picked the split amount.
/// </summary>
public bool SeparateSelectedStack(int splitAmount, int preferredEmptySlot = -1)
{
if (currentSelectedItem == null)
{
Debug.LogWarning("[InventoryUI] SeparateSelectedStack: no item selected");
return false;
}
// This client-side move command is for the main inventory pack (IVTRTYPE_PACK) like the original client.
// Task pack / other packs may need different commands depending on server implementation.
if (currentSelectedPackage != PKG_INVENTORY)
{
Debug.LogWarning($"[InventoryUI] SeparateSelectedStack: unsupported package {currentSelectedPackage} (only PKG_INVENTORY supported)");
return false;
}
int total = currentSelectedItem.m_iCount;
if (total <= 1)
{
Debug.LogWarning("[InventoryUI] SeparateSelectedStack: item count <= 1");
return false;
}
if (splitAmount <= 0 || splitAmount >= total)
{
Debug.LogWarning($"[InventoryUI] SeparateSelectedStack: invalid splitAmount={splitAmount}, total={total}");
return false;
}
int emptySlot = preferredEmptySlot >= 0 ? preferredEmptySlot : FindEmptySlotInPackage(PKG_INVENTORY);
if (emptySlot < 0)
{
Debug.LogWarning("[InventoryUI] SeparateSelectedStack: no empty slot available");
return false;
}
// Send MOVE_IVTR_ITEM(src, dest, count). When dest is empty and count < stack, server will split.
UnityGameSession.RequestMoveIvtrItem((byte)currentSelectedSlot, (byte)emptySlot, (uint)splitAmount);
// UI will update when S2C item operation arrives; this is a best-effort immediate refresh for responsiveness.
RefreshAll();
return true;
}
private int FindEmptySlotInPackage(byte package)
{
var host = CECGameRun.Instance?.GetHostPlayer();
var inv = host?.GetInventory(package);
if (inv == null) return -1;
int size = inv.GetSize();
for (int i = 0; i < size; i++)
{
if (inv.GetItem(i, false) == null)
return i;
}
return -1;
}
private int FindEmptyInventorySlot()
{
@@ -1128,18 +1322,18 @@ namespace BrewMonster.Scripts.Managers
//if item is @EC_IvtrEquip and is not equipped, show equip button
if(item is EC_IvtrEquip)
{
tmpText.text = "Equip";
tmpText.text = "Trang bị";
equipButton.gameObject.SetActive(true);
}
else
{
tmpText.text = "Use";
tmpText.text = "Sử dụng";
equipButton.gameObject.SetActive(true);
}
}
else if (package == PKG_EQUIPMENT)
{
tmpText.text = "UnEquip";
tmpText.text = "Tháo";
equipButton.gameObject.SetActive(true);
}
else
@@ -1154,18 +1348,18 @@ namespace BrewMonster.Scripts.Managers
{
if(item is EC_IvtrEquip)
{
buttonText.text = "Equip";
buttonText.text = "Trang bị";
equipButton.gameObject.SetActive(true);
}
else
{
buttonText.text = "Use";
buttonText.text = "Sử dụng";
equipButton.gameObject.SetActive(true);
}
}
else if (package == PKG_EQUIPMENT)
{
buttonText.text = "UnEquip";
buttonText.text = "Tháo";
equipButton.gameObject.SetActive(true);
}
else
@@ -1192,7 +1386,7 @@ namespace BrewMonster.Scripts.Managers
{
if (package == PKG_INVENTORY || package == PKG_EQUIPMENT)
{
tmpText.text = "Drop";
tmpText.text = "Vứt";
dropButton.gameObject.SetActive(true);
}
else
@@ -1205,7 +1399,7 @@ namespace BrewMonster.Scripts.Managers
{
if (package == PKG_INVENTORY || package == PKG_EQUIPMENT)
{
buttonText.text = "Drop";
buttonText.text = "Vứt";
dropButton.gameObject.SetActive(true);
}
else