Add item auto slot operation and update ui

This commit is contained in:
HungDK
2026-05-19 11:11:01 +07:00
parent f9798d6280
commit 5376b6ad8c
4 changed files with 748 additions and 238 deletions
@@ -59,6 +59,12 @@ namespace BrewMonster.Scripts
public const int IVTRSIZE_BOOTHBPACK_MAX = 20; // Max booth pack for buying
public const int IVTRSIZE_CLIENTCARDPACK = 32; // Client pack for general card collection
// Main bag UI (C++ DlgInventory.h: CECDLGSHOP_PACKMAX / PACKLINEMAX)
public const int IVTRSIZE_PACK_UI_PAGE = 32;
public const int IVTRSIZE_PACK_UI_LINE = 8;
/// <summary>Upper bound for client pack slots (server ivtr_size is byte).</summary>
public const int IVTRSIZE_PACK_MAX = 255;
public const int NUM_NPCIVTR = 8; // NPC inventory number
@@ -26,6 +26,10 @@ namespace BrewMonster.Scripts.Managers
[Header("Pack Buttons (assign in Inspector)")]
[Tooltip("Main slot grid: shows IVTRTYPE_PACK (0) on Item tab and IVTRTYPE_TASKPACK (2) on Task tab.")]
[SerializeField] private List<Button> inventoryPackButtons = new List<Button>();
[Tooltip("Parent of pack slot buttons (auto: first slot's parent). Cloned when server expands bag.")]
[SerializeField] private RectTransform inventorySlotContainer;
[Tooltip("Template for new slots (auto: first pack button).")]
[SerializeField] private Button inventorySlotTemplate;
[SerializeField] private List<Button> equipmentPackButtons = new List<Button>(); // byPackage: 1
[SerializeField] private List<Button> fashionPackButtons = new List<Button>(); // byPackage: 3
@@ -124,6 +128,7 @@ namespace BrewMonster.Scripts.Managers
}
private InventoryBagTab _bagTab = InventoryBagTab.Item;
private bool _inventorySlotTemplateResolved;
private void Awake()
{
@@ -362,7 +367,7 @@ namespace BrewMonster.Scripts.Managers
for (int slot = 0; slot < buttons.Count; slot++)
{
var button = buttons[slot];
if (button == null)
if (button == null || !button.gameObject.activeInHierarchy)
continue;
// Get item at this slot
@@ -389,6 +394,9 @@ namespace BrewMonster.Scripts.Managers
{
lastRefreshTime = Time.time;
int requiredPackSlots = GetRequiredMainPackSlotCount();
EnsureInventoryPackSlotButtons(requiredPackSlots);
var invItems = model.GetInventoryData(PKG_INVENTORY);
var eqpItems = model.GetInventoryData(PKG_EQUIPMENT);
var fshItems = model.GetInventoryData(PKG_FASHION);
@@ -407,6 +415,82 @@ namespace BrewMonster.Scripts.Managers
UpdateCharacterInfo();
}
/// <summary>
/// Match server pack size for the active bag tab (C++ CDlgInventory uses GetPack/GetTaskPack size).
/// </summary>
private int GetRequiredMainPackSlotCount()
{
var host = CECGameRun.Instance?.GetHostPlayer();
if (host == null)
return inventoryPackButtons != null ? inventoryPackButtons.Count : 0;
byte pack = _bagTab == InventoryBagTab.Item ? PKG_INVENTORY : PKG_TASK;
var inv = host.GetInventory(pack);
return inv != null ? Math.Max(0, inv.GetSize()) : 0;
}
/// <summary>
/// Grow/shrink visible slot buttons to match <see cref="EC_Inventory.GetSize"/> (PW: CHANGE_IVTR_SIZE, OWN_IVTR_DATA).
/// </summary>
private void EnsureInventoryPackSlotButtons(int requiredCount)
{
if (requiredCount < 0)
requiredCount = 0;
if (requiredCount > InventoryConst.IVTRSIZE_PACK_MAX)
requiredCount = InventoryConst.IVTRSIZE_PACK_MAX;
ResolveInventorySlotTemplate();
if (inventorySlotTemplate == null || inventorySlotContainer == null)
return;
if (inventoryPackButtons == null)
inventoryPackButtons = new List<Button>();
int prevCount = inventoryPackButtons.Count;
while (inventoryPackButtons.Count < requiredCount)
{
var clone = Instantiate(inventorySlotTemplate, inventorySlotContainer);
clone.gameObject.SetActive(true);
clone.name = $"item ({inventoryPackButtons.Count})";
inventoryPackButtons.Add(clone);
}
if (requiredCount > prevCount && inventorySlotContainer != null)
LayoutRebuilder.ForceRebuildLayoutImmediate(inventorySlotContainer);
for (int i = 0; i < inventoryPackButtons.Count; i++)
{
var btn = inventoryPackButtons[i];
if (btn == null)
continue;
bool show = i < requiredCount;
if (btn.gameObject.activeSelf != show)
btn.gameObject.SetActive(show);
}
}
private void ResolveInventorySlotTemplate()
{
if (_inventorySlotTemplateResolved)
return;
_inventorySlotTemplateResolved = true;
if (inventorySlotTemplate == null && inventoryPackButtons != null)
{
for (int i = 0; i < inventoryPackButtons.Count; i++)
{
if (inventoryPackButtons[i] != null)
{
inventorySlotTemplate = inventoryPackButtons[i];
break;
}
}
}
if (inventorySlotContainer == null && inventorySlotTemplate != null)
inventorySlotContainer = inventorySlotTemplate.transform.parent as RectTransform;
}
/// <summary>
/// Update all configured money text components with the current amount.
/// Call this when GET_OWN_MONEY arrives.
@@ -1063,7 +1147,7 @@ namespace BrewMonster.Scripts.Managers
for (int slot = 0; slot < buttons.Count; slot++)
{
var button = buttons[slot];
if (button == null)
if (button == null || !button.gameObject.activeInHierarchy)
{
continue;
}
File diff suppressed because it is too large Load Diff
+4 -1
View File
@@ -137,12 +137,15 @@ namespace BrewMonster
}
case CommandID.CHANGE_IVTR_SIZE:
{
// C++: resize pack (normal inventory)
// C++ EC_HostMsg.cpp: m_pPack->Resize + FIXMSG_NEW_INVENTORY_SIZE
if (data != null && data.Length >= 4)
{
int newSize = BitConverter.ToInt32(data, 0);
if (m_pPack != null)
m_pPack.Resize(newSize);
EC_Game.GetGameRun()?.AddFixedMessage((int)FixedMsg.FIXMSG_NEW_INVENTORY_SIZE, newSize);
var ui = GameObject.FindFirstObjectByType<EC_InventoryUI>();
ui?.RefreshAll();
}