From 2f6e3c751def7dcde35c96cb48356fffde29838b Mon Sep 17 00:00:00 2001 From: VuNgocHaiC7 Date: Fri, 16 Jan 2026 17:28:55 +0700 Subject: [PATCH] update quantity inc, dec, max --- .../Scripts/UI/Dialogs/DlgProduce.cs | 139 +++++++++++++++++- Assets/PerfectWorld/UI/DlgProduce.prefab | 42 +++--- Assets/Scripts/CECHostPlayer.cs | 61 +++++--- 3 files changed, 200 insertions(+), 42 deletions(-) diff --git a/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgProduce.cs b/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgProduce.cs index 844bc44f19..c10f7c9cb8 100644 --- a/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgProduce.cs +++ b/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgProduce.cs @@ -26,6 +26,17 @@ namespace BrewMonster [SerializeField] private Transform itemContainer; [SerializeField] private GameObject itemPb; + [Header("Quantity")] + [SerializeField] private List quantityText; + [SerializeField] private Button quantityIncreaseBtn; + [SerializeField] private Button quantityDecreaseBtn; + [SerializeField] private Button quantityMaxBtn; + + private int currentQuantity = 1; + + private int produceRemainCount = 0; + private bool isProducing = false; + [Header("Material Slots")] [SerializeField] private List materialSlots = new List(); @@ -34,9 +45,9 @@ namespace BrewMonster [Header("Item Info Panel")] public Transform itemInfoRoot; - public TMPro.TextMeshProUGUI infoNameText; - public TMPro.TextMeshProUGUI infoDescText; - public TMPro.TextMeshProUGUI infoExtraText; + public TextMeshProUGUI infoNameText; + public TextMeshProUGUI infoDescText; + public TextMeshProUGUI infoExtraText; private NPC_MAKE_SERVICE? cachedMakeService = null; private int currentTabIndex = 0; @@ -48,6 +59,19 @@ namespace BrewMonster [SerializeField] private Button startProduceBtn; [SerializeField] private Button cancelProduceBtn; + public override void Start() + { + quantityText[0].text = currentQuantity.ToString(); + quantityText[1].text = currentQuantity.ToString(); + quantityDecreaseBtn.onClick.AddListener(OnClickDecreaseBtn); + quantityIncreaseBtn.onClick.AddListener(OnClickIncreaseBtn); + + if(quantityMaxBtn != null) + { + quantityMaxBtn.onClick.AddListener(OnClickMaxBtn); + } + } + public void OpenProduce(uint npcId) { if (!LoadMakeService(npcId)) @@ -450,6 +474,20 @@ namespace BrewMonster return; } + produceRemainCount = currentQuantity; + isProducing = true; + + SendProduceOnce(); + } + + void SendProduceOnce() + { + if(!isProducing || produceRemainCount <= 0) + { + Debug.Log("[DlgProduce] No production needed or already completed"); + return; + } + // Get skill ID from the service (not from recipe) // The second parameter is the recipe ID (not the item ID) int idSkill = (int)cachedMakeService.Value.id_make_skill; @@ -469,6 +507,9 @@ namespace BrewMonster public void CloseProduce() { + isProducing = false; + produceRemainCount = 0; + gameObject.SetActive(false); ClearContainer(tabBtnContainer); ClearContainer(itemContainer); @@ -497,6 +538,17 @@ namespace BrewMonster Debug.Log($"[DlgProduce] OnProduceOnce: type={cmd.type}, amount={cmd.amount}, where={cmd.where}, index={cmd.index}"); // TODO: Update UI counters, progress, skill ability, etc. // This would typically update the remaining count and progress + + produceRemainCount--; + if (produceRemainCount > 0) + { + SendProduceOnce(); + } + else + { + isProducing = false; + Debug.Log("[DlgProduce] Production completed for all items"); + } } // Called when production ends (NOTIFY_PRODUCE_END) @@ -519,6 +571,8 @@ namespace BrewMonster { startProduceBtn.interactable = true; } + isProducing = false; + produceRemainCount = 0; } public void ShowItemInfoByRecipe(uint recipeId) @@ -573,6 +627,30 @@ namespace BrewMonster itemInfoRoot.gameObject.SetActive(false); } + private void UpdateQuantityText(int quantity) + { + if (quantityText != null) + { + quantityText[0].text = quantity.ToString(); + quantityText[1].text = quantity.ToString(); + } + } + + private void OnClickIncreaseBtn() + { + currentQuantity++; + UpdateQuantityText(currentQuantity); + } + + private void OnClickDecreaseBtn() + { + if (currentQuantity > 1) + { + currentQuantity--; + UpdateQuantityText(currentQuantity); + } + } + // Helper to get total count of an item in player's inventory int GetInventoryItemCount(uint itemId) { @@ -599,6 +677,61 @@ namespace BrewMonster return total; } + int CalculateMaxProduceCount(uint recipeId) + { + var edm = ElementDataManProvider.GetElementDataMan(); + if (edm == null) + return 0; + + DATA_TYPE dt = DATA_TYPE.DT_INVALID; + object data = edm.get_data_ptr(recipeId, ID_SPACE.ID_SPACE_RECIPE, ref dt); + + if (data is not RECIPE_ESSENCE recipe || recipe.materials == null) + return 0; + + int maxCount = int.MaxValue; + + foreach (var mat in recipe.materials) + { + if (mat.id == 0 || mat.num <= 0) + continue; + + int owned = GetInventoryItemCount(mat.id); + int canMake = owned / mat.num; + + if (canMake < maxCount) + maxCount = canMake; + } + + if (maxCount == int.MaxValue) + return 0; + + return Mathf.Max(0, maxCount); + } + + void OnClickMaxBtn() + { + if (selectedRecipeId == 0) + return; + + int max = CalculateMaxProduceCount(selectedRecipeId); + + if (max <= 0) + { + currentQuantity = 1; + } + else + { + currentQuantity = max; + } + + UpdateQuantityText(currentQuantity); + ShowRecipeMaterials(selectedRecipeId); + + Debug.Log($"[DlgProduce] Max produce quantity = {currentQuantity}"); + } + + public void OnDestroy() { diff --git a/Assets/PerfectWorld/UI/DlgProduce.prefab b/Assets/PerfectWorld/UI/DlgProduce.prefab index ad3c594bbe..8322b0ee3a 100644 --- a/Assets/PerfectWorld/UI/DlgProduce.prefab +++ b/Assets/PerfectWorld/UI/DlgProduce.prefab @@ -2118,8 +2118,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 1} m_AnchorMax: {x: 0.5, y: 1} - m_AnchoredPosition: {x: 31.1, y: -33} - m_SizeDelta: {x: 131.8979, y: 32.6279} + m_AnchoredPosition: {x: 40, y: -40} + m_SizeDelta: {x: 131.8979, y: 39.2143} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &3890090805096706385 CanvasRenderer: @@ -2149,8 +2149,8 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 + m_Sprite: {fileID: 21300000, guid: 01b79c3dc401e4fdfb17b72d677f9fbd, type: 3} + m_Type: 0 m_PreserveAspect: 0 m_FillCenter: 1 m_FillMethod: 4 @@ -2494,7 +2494,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 1 + m_IsActive: 0 --- !u!224 &3517887537669938751 RectTransform: m_ObjectHideFlags: 0 @@ -2515,7 +2515,7 @@ RectTransform: m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} m_AnchoredPosition: {x: 428, y: -66} - m_SizeDelta: {x: -28.472656, y: 0} + m_SizeDelta: {x: -28.472656, y: -94.8524} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &1044286488259006771 CanvasRenderer: @@ -4049,8 +4049,8 @@ MonoBehaviour: m_fontMaterials: [] m_fontColor32: serializedVersion: 2 - rgba: 4281479730 - m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} m_enableVertexGradient: 0 m_colorMode: 3 m_fontColorGradient: @@ -4075,7 +4075,7 @@ MonoBehaviour: m_fontSizeMax: 72 m_fontStyle: 0 m_HorizontalAlignment: 2 - m_VerticalAlignment: 512 + m_VerticalAlignment: 256 m_textAlignment: 65535 m_characterSpacing: 0 m_wordSpacing: 0 @@ -5257,8 +5257,8 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 + m_Sprite: {fileID: 21300000, guid: 01b79c3dc401e4fdfb17b72d677f9fbd, type: 3} + m_Type: 0 m_PreserveAspect: 0 m_FillCenter: 1 m_FillMethod: 4 @@ -6533,8 +6533,8 @@ MonoBehaviour: m_fontMaterials: [] m_fontColor32: serializedVersion: 2 - rgba: 4281479730 - m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} m_enableVertexGradient: 0 m_colorMode: 3 m_fontColorGradient: @@ -7429,6 +7429,12 @@ MonoBehaviour: tabButtonTextComponentName: Text itemContainer: {fileID: 3338815937298185852} itemPb: {fileID: 3478571236783653060, guid: b89cfffd83c228f4886273562ff4e111, type: 3} + quantityText: + - {fileID: 8510409449905240800} + - {fileID: 2438708416608651158} + quantityIncreaseBtn: {fileID: 7674922603916968347} + quantityDecreaseBtn: {fileID: 8345907553281006269} + quantityMaxBtn: {fileID: 7491161773926273447} materialSlots: - {fileID: 7838759576271800718} - {fileID: 3150666424336034670} @@ -7779,8 +7785,8 @@ MonoBehaviour: m_fontMaterials: [] m_fontColor32: serializedVersion: 2 - rgba: 4281479730 - m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} m_enableVertexGradient: 0 m_colorMode: 3 m_fontColorGradient: @@ -8787,8 +8793,8 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 + m_Sprite: {fileID: 21300000, guid: 01b79c3dc401e4fdfb17b72d677f9fbd, type: 3} + m_Type: 0 m_PreserveAspect: 0 m_FillCenter: 1 m_FillMethod: 4 @@ -11334,7 +11340,7 @@ RectTransform: m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} m_AnchoredPosition: {x: 21, y: -27.713333} - m_SizeDelta: {x: 465.7476, y: 0} + m_SizeDelta: {x: 465.7476, y: 38.28} m_Pivot: {x: 0, y: 0.5} --- !u!222 &2671266570269560597 CanvasRenderer: diff --git a/Assets/Scripts/CECHostPlayer.cs b/Assets/Scripts/CECHostPlayer.cs index 019d3d397a..1a4da28846 100644 --- a/Assets/Scripts/CECHostPlayer.cs +++ b/Assets/Scripts/CECHostPlayer.cs @@ -2021,39 +2021,58 @@ namespace BrewMonster { // Parse cmd_produce_once struct data cmd_produce_once produceCmd = GPDataTypeHelper.FromBytes(data); - + int produceItemId = produceCmd.type; int produceExpireDate = 0; uint produceAmount = produceCmd.amount; byte producePack = produceCmd.where; byte produceSlot = produceCmd.index; - // Create new inventory item data - var produceNewItem = new EC_IvtrItem - { - Package = producePack, - Slot = produceSlot, - m_tid = produceItemId, - m_expire_date = produceExpireDate, - State = 0, - m_iCount = (int)produceAmount, - Crc = 0, - Content = null - }; + Debug.Log($"[PRODUCE_ONCE] Received: itemId={produceItemId}, amount={produceAmount}, pack={producePack}, slot={produceSlot}"); - // Add item to inventory + // Get inventory var produce_ivt = GetInventory(producePack); - if (!produce_ivt.MergeItem(produceItemId, produceExpireDate, (int)produceAmount, out var produceLastSlot, out var produceSlotNum) || - produceLastSlot != produceSlot || produceSlotNum != (int)produceCmd.slot_amount) + if (produce_ivt == null) { - Debug.LogWarning($"[PRODUCE_ONCE] Failed to merge item {produceItemId} to package {producePack}, slot {produceSlot}"); + Debug.LogWarning($"[PRODUCE_ONCE] Invalid inventory package {producePack}"); return; } - produce_ivt.SetItem(produceSlot, produceNewItem); - Debug.Log($"[PRODUCE_ONCE] Successfully added produced item {produceItemId} to package {producePack}, slot {produceSlot} with count {produceAmount}"); + // Check if the slot already has an item + var existingItem = produce_ivt.GetItem(produceSlot, false); - // Trigger UI refresh if an EC_InventoryUI is present in scene + if (existingItem != null) + { + if (existingItem.m_tid == produceItemId) + { + existingItem.m_iCount = (int)produceAmount; + Debug.Log($"[PRODUCE_ONCE] Updated existing item count at slot {produceSlot} to {produceAmount}"); + } + else + { + Debug.LogWarning($"[PRODUCE_ONCE] Slot {produceSlot} already has different item (tid={existingItem.m_tid}), not overwriting with {produceItemId}"); + return; + } + } + else + { + var produceNewItem = new EC_IvtrItem + { + Package = producePack, + Slot = produceSlot, + m_tid = produceItemId, + m_expire_date = produceExpireDate, + State = 0, + m_iCount = (int)produceAmount, + Crc = 0, + Content = null + }; + + produce_ivt.SetItem(produceSlot, produceNewItem); + Debug.Log($"[PRODUCE_ONCE] Created new item at slot {produceSlot} with count {produceAmount}"); + } + + // Trigger UI refresh var produce_ui = GameObject.FindFirstObjectByType(); if (produce_ui != null) { @@ -2062,7 +2081,7 @@ namespace BrewMonster UpdateEquipSkins(); - // Notify DlgProduce about successful produce (NOTIFY_PRODUCE_END_ONE) + // Notify DlgProduce var dlgProduce = GameObject.FindFirstObjectByType(); if (dlgProduce != null) {