From e7cecb98f9f3b137f9549835078614e0cf15bec9 Mon Sep 17 00:00:00 2001 From: HungDK <> Date: Wed, 27 May 2026 09:25:12 +0700 Subject: [PATCH] Deposit, withdraw account money handler --- .../Scripts/Managers/EC_InventoryUI.cs | 10 +++ .../CSNetwork/C2SCommand/C2SCommandFactory.cs | 10 +++ .../Scripts/Network/UnityGameSession.cs | 5 ++ .../PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs | 3 +- .../Scripts/UI/Dialogs/DlgQuantity.cs | 10 +++ Assets/Scripts/CECHostPlayer.Storage.cs | 66 ++++++++++++++++++- Assets/Scripts/CECUIManager.cs | 52 +++++++++++++++ 7 files changed, 152 insertions(+), 4 deletions(-) diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_InventoryUI.cs b/Assets/PerfectWorld/Scripts/Managers/EC_InventoryUI.cs index a014dc3809..4bd4a5aff2 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_InventoryUI.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_InventoryUI.cs @@ -145,6 +145,11 @@ namespace BrewMonster.Scripts.Managers CECHostPlayer.PopupStorageDialog(true); return; } + if (!value && GetHostPlayer() != null && GetHostPlayer().IsUsingAccountBox()) + { + CECHostPlayer.PopupAccountBoxDialog(true); + return; + } base.Show(value); } @@ -155,6 +160,11 @@ namespace BrewMonster.Scripts.Managers CECHostPlayer.PopupStorageDialog(true); return; } + if (GetHostPlayer() != null && GetHostPlayer().IsUsingAccountBox()) + { + CECHostPlayer.PopupAccountBoxDialog(true); + return; + } base.CloseDialogue(); } diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/C2SCommand/C2SCommandFactory.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/C2SCommand/C2SCommandFactory.cs index ae0e47c343..54eeed262e 100644 --- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/C2SCommand/C2SCommandFactory.cs +++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/C2SCommand/C2SCommandFactory.cs @@ -1268,6 +1268,16 @@ namespace CSNetwork.C2SCommand return octets; } + public static Octets CreateNPCSevOpenAccountBoxCmd() + { + var cmd = new cmd_sevnpc_serve + { + service_type = NPC_service_type.GP_NPCSEV_OPEN_ACCOUNT_BOX, + len = 0 + }; + return SerializeCommand(CommandID.SEVNPC_SERVE, cmd); + } + public static Octets CreateGetOtherEquipCmd(ushort _size, int[] _idlist) { var cmd = new cmd_get_other_equip diff --git a/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs b/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs index 5a9b33cade..5bb555c408 100644 --- a/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs +++ b/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs @@ -979,6 +979,11 @@ namespace BrewMonster.Network Instance._gameSession.c2s_CmdNPCSevOpenTrash(password); } + public static void c2s_CmdNPCSevOpenAccountBox() + { + Instance._gameSession.c2s_CmdNPCSevOpenAccountBox(); + } + public static void c2s_CmdGetTrashBoxData(bool detail, bool accountBox = false) { Instance._gameSession.c2s_CmdGetTrashBoxData(detail, accountBox); diff --git a/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs b/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs index a51b84a603..601c8f3da4 100644 --- a/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs +++ b/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs @@ -3788,7 +3788,8 @@ namespace BrewMonster.UI // GetGameUIMan().ShowErrorMsg(10130); // GetGameUIMan().EndNPCService(); //} - //else g_pGame.GetGameSession().c2s_CmdNPCSevOpenAccountBox(); + UnityGameSession.c2s_CmdNPCSevOpenAccountBox(); + GetGameUIMan().EndNPCService(); } else if (idFunction == (int)SERVICE_TYPE.NPC_ENGRAVE) { diff --git a/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgQuantity.cs b/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgQuantity.cs index b8ba84cf51..86e3dd31c4 100644 --- a/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgQuantity.cs +++ b/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgQuantity.cs @@ -20,6 +20,10 @@ namespace BrewMonster.UI StorageDepositMoney, /// Rút tiền ra — C++ INPUTNO_STORAGE_TRASH_MONEY (Win_Storage choosemoney). StorageWithdrawMoney, + /// Gửi tiền vào kho tài khoản — same C2S as storage, with is_accountbox=1. + AccountStorageDepositMoney, + /// Rút tiền ra từ kho tài khoản — same C2S as storage, with is_accountbox=1. + AccountStorageWithdrawMoney, } [Header("Amount")] @@ -236,6 +240,12 @@ namespace BrewMonster.UI // C++ INPUTNO_STORAGE_TRASH_MONEY: ExgTrashBoxMoney(iTrash=amount, iIvtr=0) UnityGameSession.c2s_CmdExgTrashBoxMoney(0, amount); break; + case QuantityMode.AccountStorageDepositMoney: + UnityGameSession.c2s_CmdExgTrashBoxMoney(amount, 0, true); + break; + case QuantityMode.AccountStorageWithdrawMoney: + UnityGameSession.c2s_CmdExgTrashBoxMoney(0, amount, true); + break; } } diff --git a/Assets/Scripts/CECHostPlayer.Storage.cs b/Assets/Scripts/CECHostPlayer.Storage.cs index 02c5d3e7aa..2b0bfb59eb 100644 --- a/Assets/Scripts/CECHostPlayer.Storage.cs +++ b/Assets/Scripts/CECHostPlayer.Storage.cs @@ -23,10 +23,15 @@ namespace BrewMonster private bool m_bTrashPsw; private bool m_bFirstTBOpen = true; + private bool m_bUsingAccountBox; + private bool m_bFirstAccountBoxOpen = true; private int m_iTrashBoxMoneyCnt; + private int m_iAccountBoxMoneyCnt; public bool TrashBoxHasPsw() => m_bTrashPsw; public int GetTrashBoxMoneyCnt() => m_iTrashBoxMoneyCnt; + public bool IsUsingAccountBox() => m_bUsingAccountBox; + public int GetAccountBoxMoneyCnt() => m_iAccountBoxMoneyCnt; public EC_Inventory GetTrashBox() => m_pTrashBoxPack; public EC_Inventory GetTrashBox2() => m_pTrashBoxPack2; public EC_Inventory GetTrashBox3() => m_pTrashBoxPack3; @@ -54,9 +59,22 @@ namespace BrewMonster { var pCmd = GPDataTypeHelper.FromBytes(data); if (pCmd.is_accountbox != 0) - break; // PW_TODO: account box UI + { + m_bUsingAccountBox = true; + m_bUsingTrashBox = false; + + if (m_bFirstAccountBoxOpen) + { + m_bFirstAccountBoxOpen = false; + UnityGameSession.c2s_CmdGetTrashBoxData(true, true); + } + + PopupAccountBoxDialog(); + break; + } m_bUsingTrashBox = true; + m_bUsingAccountBox = false; InitTrashBoxPacks(); if (m_bFirstTBOpen) @@ -80,7 +98,11 @@ namespace BrewMonster { var pCmd = GPDataTypeHelper.FromBytes(data); if (pCmd.is_accountbox != 0) + { + m_bUsingAccountBox = false; + PopupAccountBoxDialog(true); break; + } m_bUsingTrashBox = false; PopupStorageDialog(true); break; @@ -89,19 +111,31 @@ namespace BrewMonster { var pCmd = GPDataTypeHelper.FromBytes(data); if (pCmd.is_accountbox == 0) + { m_iTrashBoxMoneyCnt = (int)pCmd.money; - EC_StorageUI.RefreshMoneyStatic(); + EC_StorageUI.RefreshMoneyStatic(); + } + else + { + m_iAccountBoxMoneyCnt = (int)pCmd.money; + EC_AccountStorageUI.RefreshMoneyStatic(); + } break; } case CommandID.EXG_TRASH_MONEY: { var pCmd = GPDataTypeHelper.FromBytes(data); + AddMoneyAmount(pCmd.inv_delta); if (pCmd.is_accountbox == 0) { - AddMoneyAmount(pCmd.inv_delta); m_iTrashBoxMoneyCnt += pCmd.tra_delta; } + else + { + m_iAccountBoxMoneyCnt += pCmd.tra_delta; + } EC_StorageUI.RefreshMoneyStatic(); + EC_AccountStorageUI.RefreshMoneyStatic(); var invUi = UnityEngine.Object.FindFirstObjectByType(); invUi?.RefreshAll(); break; @@ -243,6 +277,32 @@ namespace BrewMonster invDlg?.RefreshAll(); } + /// C++ CECGameUIMan::PopupAccountBoxDialog — money-only account warehouse. + public static void PopupAccountBoxDialog(bool close = false) + { + if (close) + { + var host = EC_Game.GetGameRun()?.GetHostPlayer(); + if (host != null) + host.m_bUsingAccountBox = false; + + EC_StorageUI.ClearSelectionStatic(); + var invUi = UnityEngine.Object.FindFirstObjectByType(FindObjectsInactive.Include); + invUi?.DismissItemDetail(); + + CECUIManager.Instance?.HideAccountStorageDialogPair(); + EC_Game.GetGameRun()?.GetUIManager()?.GetInGameUIMan()?.EndNPCService(); + return; + } + + CECUIManager.Instance?.ShowAccountStorageDialogPair(); + var accountDlg = EC_Game.GetGameRun()?.GetUIManager()?.GetInGameUIMan()?.GetDialog("EC_AccountStorageUI") as EC_AccountStorageUI; + accountDlg?.RefreshAll(); + + var invDlg = UnityEngine.Object.FindFirstObjectByType(FindObjectsInactive.Include); + invDlg?.RefreshAll(); + } + /// Transfer between main pack and trash box (C++ CDlgStorage::OnItemDragDrop). public bool TransferPackAndTrash(byte trashWhere, int trashSlot, int invSlot, int amount = -1) { diff --git a/Assets/Scripts/CECUIManager.cs b/Assets/Scripts/CECUIManager.cs index e90d5c7b8d..0399c9e2c4 100644 --- a/Assets/Scripts/CECUIManager.cs +++ b/Assets/Scripts/CECUIManager.cs @@ -361,6 +361,58 @@ public class CECUIManager : MonoSingleton } } + /// + /// Show money-only account warehouse + inventory together. This intentionally uses a + /// separate dialog from EC_StorageUI to avoid enabling warehouse item slots. + /// + public void ShowAccountStorageDialogPair() + { + if (canvasDlg == null) + return; + + var gui = GetInGameUIMan(); + if (gui == null) + return; + + var accountDlg = gui.GetDialog("EC_AccountStorageUI"); + var invDlg = gui.GetDialog("Win_Inventory"); + if (accountDlg == null || invDlg == null) + return; + + _uiStack.Remove("Win_Inventory"); + _uiStack.Remove("EC_AccountStorageUI"); + + invDlg.Show(true); + accountDlg.Show(true); + + _uiStack.Insert(0, "Win_Inventory"); + _uiStack.Insert(0, "EC_AccountStorageUI"); + + invDlg.transform.SetAsLastSibling(); + accountDlg.transform.SetAsLastSibling(); + } + + /// Hide account warehouse pair and restore previous stack top if any. + public void HideAccountStorageDialogPair() + { + _uiStack.Remove("EC_AccountStorageUI"); + _uiStack.Remove("Win_Inventory"); + + var gui = GetInGameUIMan(); + gui?.GetDialog("Win_Inventory")?.Show(false); + gui?.GetDialog("EC_AccountStorageUI")?.Show(false); + + if (_uiStack.Count > 0) + { + var newTop = gui?.GetDialog(_uiStack[0]); + if (newTop != null) + { + newTop.Show(true); + newTop.transform.SetAsLastSibling(); + } + } + } + /// /// Pop the top dialog off the stack: hide it and bring the new top (if any) to front. Returns true if something was popped. ///