Merge branch 'develop' into feature/gfx-action
This commit is contained in:
@@ -63,3 +63,7 @@ MonoBehaviour:
|
||||
prefab: {fileID: 6225996695219405878, guid: 2ed5e05eaa1d87341bf25c3cf111cc01, type: 3}
|
||||
- id: Win_Settings
|
||||
prefab: {fileID: 5193882765232824931, guid: 12e3fbc87fab9044abb62aba808775c8, type: 3}
|
||||
- id: EC_StorageUI
|
||||
prefab: {fileID: 3837460183159982207, guid: 0986049a141406946b0ed97344b84f78, type: 3}
|
||||
- id: DlgQuantity
|
||||
prefab: {fileID: 8147986291757959694, guid: 11d09ee52b0c5f24fb3ef21e177ebe2d, type: 3}
|
||||
|
||||
@@ -12,7 +12,10 @@ namespace BrewMonster.UI
|
||||
|
||||
public GameObject GetPrefabDialog(string id)
|
||||
{
|
||||
return lstPrefabDialog.Find(x => x.id.Equals(id)).prefab;
|
||||
if (string.IsNullOrEmpty(id) || lstPrefabDialog == null)
|
||||
return null;
|
||||
var entry = lstPrefabDialog.Find(x => !string.IsNullOrEmpty(x.id) && x.id.Equals(id));
|
||||
return entry.prefab;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,11 @@ namespace BrewMonster.Scripts
|
||||
public const byte IVTRTYPE_PACK = 0;
|
||||
public const byte IVTRTYPE_EQUIPPACK = 1;
|
||||
public const byte IVTRTYPE_TASKPACK = 2;
|
||||
public const byte IVTRTYPE_TRASHBOX = 3;
|
||||
public const byte IVTRTYPE_TRASHBOX2 = 4;
|
||||
public const byte IVTRTYPE_TRASHBOX3 = 5;
|
||||
public const byte IVTRTYPE_ACCOUNT_BOX = 6;
|
||||
public const byte IVTRTYPE_GENERALCARD_BOX = 7;
|
||||
}
|
||||
public enum Shortcut
|
||||
{
|
||||
|
||||
@@ -43,6 +43,8 @@ namespace BrewMonster.Scripts.Managers
|
||||
[SerializeField] private EC_UIUtility.TextOutlet descriptionText;
|
||||
[SerializeField] private Button equipButton;
|
||||
[SerializeField] private Button dropButton;
|
||||
[Tooltip("Optional. When warehouse is open: Bỏ vào / Lấy ra. If unset, equipButton is reused.")]
|
||||
[SerializeField] private Button storageTransferButton;
|
||||
|
||||
[Header("Stack Split UI (assign in Inspector)")]
|
||||
[SerializeField] private GameObject splitPanelRoot;
|
||||
@@ -113,15 +115,19 @@ namespace BrewMonster.Scripts.Managers
|
||||
}
|
||||
|
||||
// Current selected item for equip/unequip operations
|
||||
private byte currentSelectedPackage;
|
||||
private int currentSelectedSlot;
|
||||
internal byte currentSelectedPackage;
|
||||
internal int currentSelectedSlot;
|
||||
private EC_IvtrItem currentSelectedItem;
|
||||
private EC_IvtrItem currentSelectedEquipment;
|
||||
|
||||
private Transform _detailPanelOriginalParent;
|
||||
private int _detailPanelOriginalSiblingIndex = -1;
|
||||
|
||||
private const byte PKG_INVENTORY = InventoryConst.IVTRTYPE_PACK;
|
||||
private const byte PKG_EQUIPMENT = InventoryConst.IVTRTYPE_EQUIPPACK;
|
||||
private const byte PKG_TASK = InventoryConst.IVTRTYPE_TASKPACK;
|
||||
private const byte PKG_FASHION = 3; // Trash / fashion box slot in legacy client (GetInventory may not resolve; see host)
|
||||
private const byte PKG_TRASHBOX = InventoryConst.IVTRTYPE_TRASHBOX;
|
||||
|
||||
public enum InventoryBagTab
|
||||
{
|
||||
@@ -132,6 +138,26 @@ namespace BrewMonster.Scripts.Managers
|
||||
private InventoryBagTab _bagTab = InventoryBagTab.Item;
|
||||
private bool _inventorySlotTemplateResolved;
|
||||
|
||||
public override void Show(bool value)
|
||||
{
|
||||
if (!value && GetHostPlayer() != null && GetHostPlayer().IsUsingTrashBox())
|
||||
{
|
||||
CECHostPlayer.PopupStorageDialog(true);
|
||||
return;
|
||||
}
|
||||
base.Show(value);
|
||||
}
|
||||
|
||||
public override void CloseDialogue()
|
||||
{
|
||||
if (GetHostPlayer() != null && GetHostPlayer().IsUsingTrashBox())
|
||||
{
|
||||
CECHostPlayer.PopupStorageDialog(true);
|
||||
return;
|
||||
}
|
||||
base.CloseDialogue();
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
model = new InventoryModel();
|
||||
@@ -646,31 +672,42 @@ namespace BrewMonster.Scripts.Managers
|
||||
}
|
||||
}
|
||||
|
||||
private void OnInventoryButtonClicked(byte package, int slot)
|
||||
/// <summary>Show item detail for pack or warehouse slot (click only opens detail).</summary>
|
||||
public void ShowItemDetailForPackage(byte package, int slot)
|
||||
{
|
||||
UnityGameSession.RequestCheckSecurityPassWd("");
|
||||
var data = model.GetInventoryData(package);
|
||||
if (data != null && data.TryGetValue(slot, out var itemData))
|
||||
EC_IvtrItem itemData = null;
|
||||
if (package == PKG_TRASHBOX)
|
||||
{
|
||||
// Store current selection for equip/unequip operations
|
||||
currentSelectedPackage = package;
|
||||
currentSelectedSlot = slot;
|
||||
currentSelectedItem = itemData;
|
||||
|
||||
// Create equipment object if this is equipment
|
||||
currentSelectedEquipment = CreateEquipmentFromItemData(itemData);
|
||||
|
||||
// Position detail panel near the clicked item button
|
||||
|
||||
FillDetailPanel(package, itemData);
|
||||
PositionDetailPanelNearButton(package, slot);
|
||||
var host = CECGameRun.Instance?.GetHostPlayer();
|
||||
itemData = host?.GetTrashBox()?.GetItem(slot, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowDetailPanel(false);
|
||||
var data = model.GetInventoryData(package);
|
||||
data?.TryGetValue(slot, out itemData);
|
||||
}
|
||||
|
||||
if (itemData != null)
|
||||
{
|
||||
currentSelectedPackage = package;
|
||||
currentSelectedSlot = slot;
|
||||
currentSelectedItem = itemData;
|
||||
currentSelectedEquipment = CreateEquipmentFromItemData(itemData);
|
||||
FillDetailPanel(package, itemData);
|
||||
PositionDetailPanelNearButton(package, slot);
|
||||
EC_UIUtility.BringPanelToFront(detailPanelRoot.gameObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
DismissItemDetail();
|
||||
}
|
||||
}
|
||||
|
||||
public void DismissItemDetail() => ShowDetailPanel(false);
|
||||
|
||||
private void OnInventoryButtonClicked(byte package, int slot) =>
|
||||
ShowItemDetailForPackage(package, slot);
|
||||
|
||||
/// <summary>
|
||||
/// Create EC_IvtrEquip object from InventoryItemData
|
||||
/// </summary>
|
||||
@@ -1465,14 +1502,50 @@ namespace BrewMonster.Scripts.Managers
|
||||
|
||||
private void ShowDetailPanel(bool show)
|
||||
{
|
||||
EC_UIUtility.ShowPanel(detailPanelRoot.gameObject, show);
|
||||
if (!show)
|
||||
if (detailPanelRoot == null)
|
||||
return;
|
||||
|
||||
if (show)
|
||||
{
|
||||
AttachDetailPanelToDialogCanvas();
|
||||
EC_UIUtility.ShowPanel(detailPanelRoot.gameObject, true);
|
||||
EC_UIUtility.BringPanelToFront(detailPanelRoot.gameObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
EC_UIUtility.ShowPanel(detailPanelRoot.gameObject, false);
|
||||
RestoreDetailPanelParent();
|
||||
RefreshSplitControlsVisibility(0, null);
|
||||
RefreshCombineControlsVisibility(0, null);
|
||||
}
|
||||
}
|
||||
|
||||
void AttachDetailPanelToDialogCanvas()
|
||||
{
|
||||
var panelTransform = detailPanelRoot.transform;
|
||||
var canvasRoot = CECUIManager.Instance?.DialogCanvasTransform;
|
||||
if (canvasRoot == null || panelTransform.parent == canvasRoot)
|
||||
return;
|
||||
|
||||
_detailPanelOriginalParent = panelTransform.parent;
|
||||
_detailPanelOriginalSiblingIndex = panelTransform.GetSiblingIndex();
|
||||
panelTransform.SetParent(canvasRoot, true);
|
||||
}
|
||||
|
||||
void RestoreDetailPanelParent()
|
||||
{
|
||||
if (_detailPanelOriginalParent == null)
|
||||
return;
|
||||
|
||||
var panelTransform = detailPanelRoot.transform;
|
||||
panelTransform.SetParent(_detailPanelOriginalParent, true);
|
||||
if (_detailPanelOriginalSiblingIndex >= 0)
|
||||
panelTransform.SetSiblingIndex(_detailPanelOriginalSiblingIndex);
|
||||
|
||||
_detailPanelOriginalParent = null;
|
||||
_detailPanelOriginalSiblingIndex = -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Split affordance only for main bag stacks (same as <see cref="SeparateSelectedStack"/>).
|
||||
/// If <c>splitCloseButton</c> is parented under <c>splitPanelRoot</c>, its visibility follows the modal (not this rule).
|
||||
@@ -1531,6 +1604,9 @@ namespace BrewMonster.Scripts.Managers
|
||||
|
||||
private Button GetButtonForSlot(byte package, int slot)
|
||||
{
|
||||
if (package == PKG_TRASHBOX)
|
||||
return EC_StorageUI.GetSlotButtonStatic(slot);
|
||||
|
||||
List<Button> list = null;
|
||||
switch (package)
|
||||
{
|
||||
@@ -1621,9 +1697,9 @@ namespace BrewMonster.Scripts.Managers
|
||||
// 完全按照C++代码获取扩展描述:g_pGame->GetItemExtDesc(m_tid)
|
||||
// C++代码不检查IsInitialized() - 它直接调用GetWideString()
|
||||
|
||||
// Setup equip and drop buttons
|
||||
SetupEquipButton(package, item);
|
||||
SetupDropButton(package, item);
|
||||
SetupStorageTransferButton(package, item);
|
||||
|
||||
// Show panel first
|
||||
// 先显示面板
|
||||
@@ -1640,7 +1716,14 @@ namespace BrewMonster.Scripts.Managers
|
||||
{
|
||||
if (equipButton == null) return;
|
||||
|
||||
// Clear previous listeners
|
||||
var host = CECGameRun.Instance?.GetHostPlayer();
|
||||
if (host != null && host.IsUsingTrashBox() &&
|
||||
(package == PKG_INVENTORY || package == PKG_TRASHBOX))
|
||||
{
|
||||
equipButton.gameObject.SetActive(false);
|
||||
return;
|
||||
}
|
||||
|
||||
equipButton.onClick.RemoveAllListeners();
|
||||
equipButton.onClick.AddListener(OnEquipButtonClicked);
|
||||
|
||||
@@ -1703,10 +1786,119 @@ namespace BrewMonster.Scripts.Managers
|
||||
}
|
||||
}
|
||||
|
||||
void SetupStorageTransferButton(byte package, EC_IvtrItem item)
|
||||
{
|
||||
var btn = storageTransferButton != null ? storageTransferButton : equipButton;
|
||||
if (btn == null)
|
||||
return;
|
||||
|
||||
var host = CECGameRun.Instance?.GetHostPlayer();
|
||||
bool show = host != null && host.IsUsingTrashBox() &&
|
||||
(package == PKG_INVENTORY || package == PKG_TRASHBOX);
|
||||
btn.gameObject.SetActive(show);
|
||||
if (!show)
|
||||
return;
|
||||
|
||||
btn.onClick.RemoveAllListeners();
|
||||
btn.onClick.AddListener(OnStorageTransferButtonClicked);
|
||||
|
||||
string label = package == PKG_INVENTORY ? "Bỏ vào" : "Lấy ra";
|
||||
SetButtonLabel(btn, label);
|
||||
}
|
||||
|
||||
static void SetButtonLabel(Button btn, string label)
|
||||
{
|
||||
var buttonText = btn.GetComponentInChildren<UnityEngine.UI.Text>();
|
||||
if (buttonText != null)
|
||||
buttonText.text = label;
|
||||
else
|
||||
{
|
||||
var tmpText = btn.GetComponentInChildren<TMPro.TextMeshProUGUI>();
|
||||
if (tmpText != null)
|
||||
tmpText.text = label;
|
||||
}
|
||||
}
|
||||
|
||||
void OnStorageTransferButtonClicked()
|
||||
{
|
||||
var host = CECGameRun.Instance?.GetHostPlayer();
|
||||
if (host == null || !host.IsUsingTrashBox() || currentSelectedItem == null)
|
||||
return;
|
||||
|
||||
if (currentSelectedPackage == PKG_INVENTORY && currentSelectedSlot >= 0)
|
||||
{
|
||||
int trashSlot = FindTrashSlotForItem(host, currentSelectedItem);
|
||||
if (trashSlot >= 0)
|
||||
host.TransferPackAndTrash(PKG_TRASHBOX, trashSlot, currentSelectedSlot);
|
||||
}
|
||||
else if (currentSelectedPackage == PKG_TRASHBOX && currentSelectedSlot >= 0)
|
||||
{
|
||||
int invSlot = FindPackSlotForItem(host, currentSelectedItem);
|
||||
if (invSlot >= 0)
|
||||
host.TransferPackAndTrash(PKG_TRASHBOX, currentSelectedSlot, invSlot);
|
||||
}
|
||||
|
||||
DismissItemDetail();
|
||||
}
|
||||
|
||||
static int FindTrashSlotForItem(CECHostPlayer host, EC_IvtrItem item)
|
||||
{
|
||||
var trash = host?.GetTrashBox();
|
||||
if (trash == null || item == null)
|
||||
return -1;
|
||||
int size = trash.GetSize();
|
||||
int pile = item.GetPileLimitInstance();
|
||||
if (pile > 1)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
var dst = trash.GetItem(i);
|
||||
if (dst != null && dst.m_tid == item.m_tid && dst.m_iCount < pile)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
if (trash.GetItem(i) == null)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int FindPackSlotForItem(CECHostPlayer host, EC_IvtrItem item)
|
||||
{
|
||||
var pack = host?.GetPack();
|
||||
if (pack == null || item == null)
|
||||
return -1;
|
||||
int size = pack.GetSize();
|
||||
int pile = item.GetPileLimitInstance();
|
||||
if (pile > 1)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
var dst = pack.GetItem(i);
|
||||
if (dst != null && dst.m_tid == item.m_tid && dst.m_iCount < pile)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
if (pack.GetItem(i) == null)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void SetupDropButton(byte package, EC_IvtrItem item)
|
||||
{
|
||||
if (dropButton == null) return;
|
||||
|
||||
if (package == PKG_TRASHBOX)
|
||||
{
|
||||
dropButton.gameObject.SetActive(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear previous listeners
|
||||
dropButton.onClick.RemoveAllListeners();
|
||||
dropButton.onClick.AddListener(OnDropButtonClicked);
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BrewMonster.Scripts.Managers
|
||||
{
|
||||
/// <summary>Shared stack count label lookup for inventory / storage slot buttons.</summary>
|
||||
public static class EC_SlotStackCountDisplay
|
||||
{
|
||||
public static int ResolveStackCount(EC_IvtrItem item)
|
||||
{
|
||||
if (item == null)
|
||||
return 0;
|
||||
int n = item.GetCount();
|
||||
if (n < 2 && item.m_iCount >= 2)
|
||||
n = item.m_iCount;
|
||||
return n;
|
||||
}
|
||||
|
||||
public static void UpdateButton(Button button, EC_IvtrItem item)
|
||||
{
|
||||
UpdateButton(button, ResolveStackCount(item));
|
||||
}
|
||||
|
||||
public static void UpdateButton(Button button, int count)
|
||||
{
|
||||
if (button == null)
|
||||
return;
|
||||
|
||||
TMPro.TextMeshProUGUI tmpText = null;
|
||||
Text legacyText = null;
|
||||
|
||||
var textTransform = FindStackCountTextTransform(button.transform);
|
||||
if (textTransform != null)
|
||||
{
|
||||
tmpText = textTransform.GetComponent<TMPro.TextMeshProUGUI>();
|
||||
legacyText = textTransform.GetComponent<Text>();
|
||||
}
|
||||
|
||||
if (tmpText == null && legacyText == null)
|
||||
{
|
||||
tmpText = button.GetComponentInChildren<TMPro.TextMeshProUGUI>();
|
||||
if (tmpText == null)
|
||||
legacyText = button.GetComponentInChildren<Text>();
|
||||
}
|
||||
|
||||
if (count > 1)
|
||||
{
|
||||
string countText = count.ToString();
|
||||
if (tmpText != null)
|
||||
{
|
||||
tmpText.text = countText;
|
||||
tmpText.gameObject.SetActive(true);
|
||||
}
|
||||
else if (legacyText != null)
|
||||
{
|
||||
legacyText.text = countText;
|
||||
legacyText.gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tmpText != null)
|
||||
{
|
||||
tmpText.text = "";
|
||||
tmpText.gameObject.SetActive(false);
|
||||
}
|
||||
else if (legacyText != null)
|
||||
{
|
||||
legacyText.text = "";
|
||||
legacyText.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Transform FindStackCountTextTransform(Transform root)
|
||||
{
|
||||
if (root == null)
|
||||
return null;
|
||||
string[] names = { "Txt_Count", "text_quality", "text_quatity", "text_quantity", "image_amount" };
|
||||
for (int n = 0; n < names.Length; n++)
|
||||
{
|
||||
var t = root.Find(names[n]);
|
||||
if (t != null)
|
||||
return t;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 25708cd8c6fa9b941babe1e2446f18ad
|
||||
@@ -0,0 +1,279 @@
|
||||
using BrewMonster;
|
||||
using BrewMonster.Network;
|
||||
using BrewMonster.Scripts;
|
||||
using BrewMonster.Scripts.Managers;
|
||||
using BrewMonster.UI;
|
||||
using CSNetwork.GPDataType;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BrewMonster.Scripts.Managers
|
||||
{
|
||||
/// <summary>
|
||||
/// Warehouse UI (C++ CDlgStorage / Win_Storage). Works with <see cref="EC_InventoryUI"/> for pack↔storage transfer.
|
||||
/// Assign storage slot buttons in Inspector (e.g. clone from inventory grid); dialog name: EC_StorageUI.
|
||||
/// </summary>
|
||||
public class EC_StorageUI : AUIDialog
|
||||
{
|
||||
[SerializeField] private List<Button> storageSlotButtons = new List<Button>();
|
||||
[SerializeField] private Button closeButton;
|
||||
[SerializeField] private List<Text> trashMoneyTextsLegacy = new List<Text>();
|
||||
[SerializeField] private List<TMPro.TextMeshProUGUI> trashMoneyTextsTMP = new List<TMPro.TextMeshProUGUI>();
|
||||
|
||||
[Header("Storage actions (C++ CDlgStorage)")]
|
||||
[Tooltip("Gửi tiền vào kho — C++ INPUTNO_STORAGE_IVTR_MONEY (túi → kho).")]
|
||||
[SerializeField] private Button depositMoneyButton;
|
||||
[Tooltip("Rút tiền ra — C++ INPUTNO_STORAGE_TRASH_MONEY (kho → túi).")]
|
||||
[SerializeField] private Button withdrawMoneyButton;
|
||||
[Tooltip("Sắp xếp kho (IVTRTYPE_TRASHBOX) — C++ CDlgStorage::OnCommand_arrange.")]
|
||||
[SerializeField] private Button sortPackButton;
|
||||
|
||||
private const byte TrashWhere = InventoryConst.IVTRTYPE_TRASHBOX;
|
||||
private int _selectedTrashSlot = -1;
|
||||
private static EC_StorageUI s_instance;
|
||||
private readonly Dictionary<Image, Sprite> _defaultSlotSprites = new Dictionary<Image, Sprite>();
|
||||
|
||||
public override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
s_instance = this;
|
||||
if (closeButton != null)
|
||||
{
|
||||
closeButton.onClick.RemoveAllListeners();
|
||||
closeButton.onClick.AddListener(() => CECHostPlayer.PopupStorageDialog(true));
|
||||
}
|
||||
ResolveStorageActionButtons();
|
||||
WireStorageActionButtons();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (s_instance == this)
|
||||
s_instance = null;
|
||||
}
|
||||
|
||||
public static void RefreshAllStatic()
|
||||
{
|
||||
s_instance?.RefreshAll();
|
||||
}
|
||||
|
||||
public static void RefreshMoneyStatic()
|
||||
{
|
||||
s_instance?.RefreshMoney();
|
||||
}
|
||||
|
||||
public static void ClearSelectionStatic()
|
||||
{
|
||||
if (s_instance != null)
|
||||
s_instance._selectedTrashSlot = -1;
|
||||
}
|
||||
|
||||
public static bool TryGetSelectedTrashSlot(out int slot)
|
||||
{
|
||||
slot = s_instance?._selectedTrashSlot ?? -1;
|
||||
return s_instance != null && slot >= 0;
|
||||
}
|
||||
|
||||
public static Button GetSlotButtonStatic(int slot)
|
||||
{
|
||||
if (s_instance == null || slot < 0 || slot >= s_instance.storageSlotButtons.Count)
|
||||
return null;
|
||||
return s_instance.storageSlotButtons[slot];
|
||||
}
|
||||
|
||||
public void RefreshAll()
|
||||
{
|
||||
var host = CECGameRun.Instance?.GetHostPlayer();
|
||||
var trash = host?.GetTrashBox();
|
||||
if (trash == null)
|
||||
return;
|
||||
|
||||
int size = trash.GetSize();
|
||||
EnsureSlotButtons(size);
|
||||
|
||||
for (int i = 0; i < storageSlotButtons.Count; i++)
|
||||
{
|
||||
var btn = storageSlotButtons[i];
|
||||
if (btn == null)
|
||||
continue;
|
||||
bool active = i < size;
|
||||
btn.gameObject.SetActive(active);
|
||||
if (!active)
|
||||
continue;
|
||||
|
||||
btn.onClick.RemoveAllListeners();
|
||||
int captured = i;
|
||||
btn.onClick.AddListener(() => OnStorageSlotClicked(captured));
|
||||
|
||||
var item = trash.GetItem(i, false);
|
||||
ApplySlotIcon(btn, item);
|
||||
EC_SlotStackCountDisplay.UpdateButton(btn, item);
|
||||
}
|
||||
|
||||
RefreshMoney();
|
||||
}
|
||||
|
||||
void RefreshMoney()
|
||||
{
|
||||
var host = CECGameRun.Instance?.GetHostPlayer();
|
||||
if (host == null)
|
||||
return;
|
||||
string text = host.GetTrashBoxMoneyCnt().ToString();
|
||||
foreach (var t in trashMoneyTextsLegacy)
|
||||
if (t != null) t.text = text;
|
||||
foreach (var t in trashMoneyTextsTMP)
|
||||
if (t != null) t.text = text;
|
||||
}
|
||||
|
||||
void EnsureSlotButtons(int required)
|
||||
{
|
||||
if (required <= 0 || storageSlotButtons.Count == 0)
|
||||
return;
|
||||
var template = storageSlotButtons[0];
|
||||
var parent = template.transform.parent;
|
||||
while (storageSlotButtons.Count < required && template != null && parent != null)
|
||||
{
|
||||
var clone = Instantiate(template, parent);
|
||||
storageSlotButtons.Add(clone);
|
||||
}
|
||||
}
|
||||
|
||||
void ApplySlotIcon(Button btn, EC_IvtrItem item)
|
||||
{
|
||||
var image = GetSlotIconImage(btn);
|
||||
if (image == null)
|
||||
return;
|
||||
|
||||
if (!_defaultSlotSprites.ContainsKey(image))
|
||||
_defaultSlotSprites[image] = image.sprite;
|
||||
|
||||
bool hasItem = item != null && item.m_iCount > 0;
|
||||
if (hasItem)
|
||||
{
|
||||
image.sprite = EC_IvtrItemUtils.Instance.ResolveItemIconSprite(item.m_tid);
|
||||
image.enabled = true;
|
||||
image.color = Color.white;
|
||||
}
|
||||
else
|
||||
{
|
||||
image.sprite = _defaultSlotSprites[image];
|
||||
image.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
static Image GetSlotIconImage(Button btn)
|
||||
{
|
||||
if (btn == null)
|
||||
return null;
|
||||
|
||||
var icon = btn.transform.Find("Icon");
|
||||
if (icon != null && icon.TryGetComponent<Image>(out var iconImg))
|
||||
return iconImg;
|
||||
|
||||
icon = btn.transform.Find("Img_Icon");
|
||||
if (icon != null && icon.TryGetComponent<Image>(out iconImg))
|
||||
return iconImg;
|
||||
|
||||
return btn.GetComponent<Image>();
|
||||
}
|
||||
|
||||
void OnStorageSlotClicked(int slot)
|
||||
{
|
||||
var host = CECGameRun.Instance?.GetHostPlayer();
|
||||
if (host == null || !host.IsUsingTrashBox())
|
||||
return;
|
||||
|
||||
_selectedTrashSlot = -1;
|
||||
var invUi = UnityEngine.Object.FindFirstObjectByType<EC_InventoryUI>();
|
||||
invUi?.ShowItemDetailForPackage(TrashWhere, slot);
|
||||
}
|
||||
|
||||
void ResolveStorageActionButtons()
|
||||
{
|
||||
var buttons = GetComponentsInChildren<Button>(true);
|
||||
for (int i = 0; i < buttons.Length; i++)
|
||||
{
|
||||
var btn = buttons[i];
|
||||
if (btn == null || btn == closeButton)
|
||||
continue;
|
||||
string n = btn.name.ToLowerInvariant();
|
||||
if (depositMoneyButton == null && (n.Contains("deposit") || n.Contains("put_money") || n.Contains("gui_tien")
|
||||
|| n.Contains("send_money") || n == "choosemoney" || n.Contains("btn_put")))
|
||||
depositMoneyButton = btn;
|
||||
if (withdrawMoneyButton == null && (n.Contains("withdraw") || n.Contains("get_money") || n.Contains("rut")
|
||||
|| n.Contains("take_money") || n.Contains("btn_get")))
|
||||
withdrawMoneyButton = btn;
|
||||
if (sortPackButton == null && (n.Contains("arrange") || n.Contains("sort") || n.Contains("sap_xep")
|
||||
|| n == "btn_arrange"))
|
||||
sortPackButton = btn;
|
||||
}
|
||||
}
|
||||
|
||||
void WireStorageActionButtons()
|
||||
{
|
||||
if (depositMoneyButton != null)
|
||||
{
|
||||
depositMoneyButton.onClick.RemoveAllListeners();
|
||||
depositMoneyButton.onClick.AddListener(OnDepositMoneyClicked);
|
||||
}
|
||||
if (withdrawMoneyButton != null)
|
||||
{
|
||||
withdrawMoneyButton.onClick.RemoveAllListeners();
|
||||
withdrawMoneyButton.onClick.AddListener(OnWithdrawMoneyClicked);
|
||||
}
|
||||
if (sortPackButton != null)
|
||||
{
|
||||
sortPackButton.onClick.RemoveAllListeners();
|
||||
sortPackButton.onClick.AddListener(OnSortPackClicked);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gửi tiền vào kho (túi → trash).</summary>
|
||||
void OnDepositMoneyClicked()
|
||||
{
|
||||
var host = CECGameRun.Instance?.GetHostPlayer();
|
||||
if (host == null || !host.IsUsingTrashBox())
|
||||
return;
|
||||
|
||||
int max = (int)Mathf.Min(int.MaxValue, host.GetMoneyAmount());
|
||||
if (max <= 0)
|
||||
return;
|
||||
|
||||
DlgQuantity.Show(DlgQuantity.QuantityMode.StorageDepositMoney, max, Mathf.Min(1, max));
|
||||
}
|
||||
|
||||
/// <summary>Rút tiền ra (trash → túi).</summary>
|
||||
void OnWithdrawMoneyClicked()
|
||||
{
|
||||
var host = CECGameRun.Instance?.GetHostPlayer();
|
||||
if (host == null || !host.IsUsingTrashBox())
|
||||
return;
|
||||
|
||||
int max = host.GetTrashBoxMoneyCnt();
|
||||
if (max <= 0)
|
||||
return;
|
||||
|
||||
DlgQuantity.Show(DlgQuantity.QuantityMode.StorageWithdrawMoney, max, Mathf.Min(1, max));
|
||||
}
|
||||
|
||||
/// <summary>Sắp xếp ô kho (IVTRTYPE_TRASHBOX). C++ CDlgStorage::OnCommand_arrange on Win_Storage.</summary>
|
||||
void OnSortPackClicked()
|
||||
{
|
||||
var host = CECGameRun.Instance?.GetHostPlayer();
|
||||
if (host == null || !host.IsUsingTrashBox())
|
||||
return;
|
||||
|
||||
int cool = host.GetCoolTime((int)CoolTimeIndex.GP_CT_MULTI_EXCHANGE_ITEM, out _);
|
||||
if (cool > 0)
|
||||
{
|
||||
EC_Game.GetGameRun()?.AddFixedMessage((int)FixedMsg.FIXMSG_CMD_INCOOLTIME);
|
||||
return;
|
||||
}
|
||||
|
||||
host.SortPack(TrashWhere);
|
||||
RefreshAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 54080176355858245aee54b7ee47a66f
|
||||
@@ -1667,6 +1667,71 @@ namespace CSNetwork.S2CCommand
|
||||
public ushort size;
|
||||
public int[] idlist;
|
||||
};
|
||||
|
||||
// PW_CPP: EC_GPDataType.h — trash box C2S payloads
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_get_trashbox_info
|
||||
{
|
||||
public byte is_accountbox;
|
||||
public byte detail;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_exg_trashbox_item_c2s
|
||||
{
|
||||
public byte where;
|
||||
public byte index1;
|
||||
public byte index2;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_move_trashbox_item_c2s
|
||||
{
|
||||
public byte where;
|
||||
public byte src;
|
||||
public byte dest;
|
||||
public uint amount;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_exg_trashbox_ivtr_c2s
|
||||
{
|
||||
public byte where;
|
||||
public byte idx_tra;
|
||||
public byte idx_inv;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_trashbox_item_to_ivtr_c2s
|
||||
{
|
||||
public byte where;
|
||||
public byte idx_tra;
|
||||
public byte idx_inv;
|
||||
public uint amount;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_ivtr_item_to_trashbox_c2s
|
||||
{
|
||||
public byte where;
|
||||
public byte idx_inv;
|
||||
public byte idx_tra;
|
||||
public uint amount;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_exg_trashbox_money_c2s
|
||||
{
|
||||
public byte is_accountbox;
|
||||
public uint inv_money;
|
||||
public uint trashbox_money;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct OpenTrashCONTENT
|
||||
{
|
||||
public uint psw_size;
|
||||
}
|
||||
}
|
||||
|
||||
// Player and NPC state
|
||||
@@ -4,6 +4,7 @@ using CSNetwork.S2CCommand;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace CSNetwork.C2SCommand
|
||||
@@ -1188,6 +1189,85 @@ namespace CSNetwork.C2SCommand
|
||||
return SerializeCommand(CommandID.SEVNPC_SERVE, cmd, content);
|
||||
}
|
||||
|
||||
public static Octets CreateCmdGetTrashBoxData(bool detail, bool accountBox = false)
|
||||
{
|
||||
var cmd = new cmd_get_trashbox_info
|
||||
{
|
||||
detail = (byte)(detail ? 1 : 0),
|
||||
is_accountbox = (byte)(accountBox ? 1 : 0)
|
||||
};
|
||||
return SerializeCommand(CommandID.GET_TRASHBOX_INFO, cmd);
|
||||
}
|
||||
|
||||
public static Octets CreateCmdExgTrashBoxItem(byte where, byte index1, byte index2)
|
||||
{
|
||||
var cmd = new cmd_exg_trashbox_item_c2s { where = where, index1 = index1, index2 = index2 };
|
||||
return SerializeCommand(CommandID.EXG_TRASHBOX_ITEM, cmd);
|
||||
}
|
||||
|
||||
public static Octets CreateCmdMoveTrashBoxItem(byte where, byte src, byte dest, uint amount)
|
||||
{
|
||||
var cmd = new cmd_move_trashbox_item_c2s { where = where, src = src, dest = dest, amount = amount };
|
||||
return SerializeCommand(CommandID.MOVE_TRASHBOX_ITEM, cmd);
|
||||
}
|
||||
|
||||
public static Octets CreateCmdExgTrashBoxIvtrItem(byte where, byte idxTra, byte idxInv)
|
||||
{
|
||||
var cmd = new cmd_exg_trashbox_ivtr_c2s { where = where, idx_tra = idxTra, idx_inv = idxInv };
|
||||
return SerializeCommand(CommandID.EXG_TRASHBOX_IVTR, cmd);
|
||||
}
|
||||
|
||||
public static Octets CreateCmdMoveTrashBoxToIvtr(byte where, byte idxTra, byte idxInv, uint amount)
|
||||
{
|
||||
var cmd = new cmd_trashbox_item_to_ivtr_c2s
|
||||
{
|
||||
where = where, idx_tra = idxTra, idx_inv = idxInv, amount = amount
|
||||
};
|
||||
return SerializeCommand(CommandID.TRASHBOX_ITEM_TO_IVTR, cmd);
|
||||
}
|
||||
|
||||
public static Octets CreateCmdMoveIvtrToTrashBox(byte where, byte idxInv, byte idxTra, uint amount)
|
||||
{
|
||||
var cmd = new cmd_ivtr_item_to_trashbox_c2s
|
||||
{
|
||||
where = where, idx_inv = idxInv, idx_tra = idxTra, amount = amount
|
||||
};
|
||||
return SerializeCommand(CommandID.IVTR_ITEM_TO_TRASHBOX, cmd);
|
||||
}
|
||||
|
||||
public static Octets CreateCmdExgTrashBoxMoney(int invMoney, int trashMoney, bool accountBox = false)
|
||||
{
|
||||
var cmd = new cmd_exg_trashbox_money_c2s
|
||||
{
|
||||
is_accountbox = (byte)(accountBox ? 1 : 0),
|
||||
inv_money = (uint)invMoney,
|
||||
trashbox_money = (uint)trashMoney
|
||||
};
|
||||
return SerializeCommand(CommandID.EXG_TRASHBOX_MONEY, cmd);
|
||||
}
|
||||
|
||||
public static Octets CreateNPCSevOpenTrashCmd(string password)
|
||||
{
|
||||
uint passwdSize = 0;
|
||||
byte[] passwordBytes = null;
|
||||
if (!string.IsNullOrEmpty(password))
|
||||
{
|
||||
passwordBytes = Encoding.UTF8.GetBytes(password);
|
||||
passwdSize = (uint)passwordBytes.Length;
|
||||
}
|
||||
|
||||
var cmd = new cmd_sevnpc_serve
|
||||
{
|
||||
service_type = NPC_service_type.GP_NPCSEV_OPENTRASH,
|
||||
len = (uint)Marshal.SizeOf<OpenTrashCONTENT>() + passwdSize
|
||||
};
|
||||
var content = new OpenTrashCONTENT { psw_size = passwdSize };
|
||||
var octets = SerializeCommand(CommandID.SEVNPC_SERVE, cmd, content);
|
||||
if (passwdSize > 0 && passwordBytes != null)
|
||||
octets.Insert(octets.Size, passwordBytes);
|
||||
return octets;
|
||||
}
|
||||
|
||||
public static Octets CreateGetOtherEquipCmd(ushort _size, int[] _idlist)
|
||||
{
|
||||
var cmd = new cmd_get_other_equip
|
||||
|
||||
@@ -3279,4 +3279,97 @@ namespace CSNetwork.GPDataType
|
||||
{
|
||||
public int id;
|
||||
};
|
||||
|
||||
// PW_CPP: EC_GPDataType.h — trash box (warehouse) S2C payloads
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_trashbox_pwd_changed
|
||||
{
|
||||
public byte has_passwd;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_trashbox_pwd_state
|
||||
{
|
||||
public byte has_passwd;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_trashbox_open
|
||||
{
|
||||
public byte is_accountbox;
|
||||
public ushort slot_size;
|
||||
public ushort slot_size2;
|
||||
public ushort slot_size3;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_trashbox_close
|
||||
{
|
||||
public byte is_accountbox;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_trashbox_wealth
|
||||
{
|
||||
public byte is_accountbox;
|
||||
public uint money;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_exg_trashbox_item
|
||||
{
|
||||
public byte where;
|
||||
public byte idx1;
|
||||
public byte idx2;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_move_trashbox_item
|
||||
{
|
||||
public byte where;
|
||||
public byte src;
|
||||
public byte dest;
|
||||
public uint amount;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_exg_trashbox_ivtr
|
||||
{
|
||||
public byte where;
|
||||
public byte idx_tra;
|
||||
public byte idx_inv;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_ivty_item_to_trash
|
||||
{
|
||||
public byte where;
|
||||
public byte src;
|
||||
public byte dest;
|
||||
public uint amount;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_trash_item_to_ivtr
|
||||
{
|
||||
public byte where;
|
||||
public byte src;
|
||||
public byte dest;
|
||||
public uint amount;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_exg_trash_money
|
||||
{
|
||||
public byte is_accountbox;
|
||||
public int inv_delta;
|
||||
public int tra_delta;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_trashbox_size
|
||||
{
|
||||
public byte where;
|
||||
public int iNewSize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1416,6 +1416,21 @@ namespace CSNetwork
|
||||
case CommandID.MINE_GATHERED:
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_PLAYERGATHER, MANAGER_INDEX.MAN_PLAYER, -1, pDataBuf, pCmdHeader);
|
||||
break;
|
||||
case CommandID.TRASHBOX_PWD_CHANGED:
|
||||
case CommandID.TRASHBOX_PWD_STATE:
|
||||
case CommandID.TRASHBOX_OPEN:
|
||||
case CommandID.TRASHBOX_CLOSE:
|
||||
case CommandID.TRASHBOX_WEALTH:
|
||||
case CommandID.EXG_TRASH_MONEY:
|
||||
case CommandID.EXG_TRASHBOX_ITEM:
|
||||
case CommandID.MOVE_TRASHBOX_ITEM:
|
||||
case CommandID.EXG_TRASHBOX_IVTR:
|
||||
case CommandID.IVTR_ITEM_TO_TRASH:
|
||||
case CommandID.TRASH_ITEM_TO_IVTR:
|
||||
case CommandID.TRASHBOX_SIZE:
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_TRASHBOXOP, (int)MANAGER_INDEX.MAN_PLAYER, 0,
|
||||
pDataBuf, pCmdHeader);
|
||||
break;
|
||||
case CommandID.COOLTIME_DATA:
|
||||
EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_COOLTIMEDATA, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader);
|
||||
break;
|
||||
@@ -3102,5 +3117,53 @@ namespace CSNetwork
|
||||
// TODO: C2SCommandFactory.CreateNPCSevCrossServerGetOutCmd() and SendProtocol
|
||||
}
|
||||
|
||||
public void c2s_CmdGetTrashBoxData(bool detail, bool accountBox = false)
|
||||
{
|
||||
var req = new gamedatasend { Data = C2SCommandFactory.CreateCmdGetTrashBoxData(detail, accountBox) };
|
||||
SendProtocol(req);
|
||||
}
|
||||
|
||||
public void c2s_CmdNPCSevOpenTrash(string password)
|
||||
{
|
||||
var req = new gamedatasend { Data = C2SCommandFactory.CreateNPCSevOpenTrashCmd(password ?? "") };
|
||||
SendProtocol(req);
|
||||
}
|
||||
|
||||
public void c2s_CmdExgTrashBoxItem(byte where, byte index1, byte index2)
|
||||
{
|
||||
var req = new gamedatasend { Data = C2SCommandFactory.CreateCmdExgTrashBoxItem(where, index1, index2) };
|
||||
SendProtocol(req);
|
||||
}
|
||||
|
||||
public void c2s_CmdMoveTrashBoxItem(byte where, byte src, byte dest, uint amount)
|
||||
{
|
||||
var req = new gamedatasend { Data = C2SCommandFactory.CreateCmdMoveTrashBoxItem(where, src, dest, amount) };
|
||||
SendProtocol(req);
|
||||
}
|
||||
|
||||
public void c2s_CmdExgTrashBoxIvtrItem(byte where, byte idxTra, byte idxInv)
|
||||
{
|
||||
var req = new gamedatasend { Data = C2SCommandFactory.CreateCmdExgTrashBoxIvtrItem(where, idxTra, idxInv) };
|
||||
SendProtocol(req);
|
||||
}
|
||||
|
||||
public void c2s_CmdMoveTrashBoxToIvtr(byte where, byte idxTra, byte idxInv, uint amount)
|
||||
{
|
||||
var req = new gamedatasend { Data = C2SCommandFactory.CreateCmdMoveTrashBoxToIvtr(where, idxTra, idxInv, amount) };
|
||||
SendProtocol(req);
|
||||
}
|
||||
|
||||
public void c2s_CmdMoveIvtrToTrashBox(byte where, byte idxInv, byte idxTra, uint amount)
|
||||
{
|
||||
var req = new gamedatasend { Data = C2SCommandFactory.CreateCmdMoveIvtrToTrashBox(where, idxInv, idxTra, amount) };
|
||||
SendProtocol(req);
|
||||
}
|
||||
|
||||
public void c2s_CmdExgTrashBoxMoney(int invMoney, int trashMoney, bool accountBox = false)
|
||||
{
|
||||
var req = new gamedatasend { Data = C2SCommandFactory.CreateCmdExgTrashBoxMoney(invMoney, trashMoney, accountBox) };
|
||||
SendProtocol(req);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -654,41 +654,6 @@ namespace BrewMonster.Network
|
||||
{
|
||||
Instance._gameSession.c2s_SendCmdStandUp();
|
||||
}
|
||||
|
||||
public static void c2s_CmdSitDown()
|
||||
{
|
||||
Instance._gameSession.c2s_SendCmdSitDown();
|
||||
}
|
||||
|
||||
public static void c2s_CmdTeamAssistSel(int idTeamMember)
|
||||
{
|
||||
Instance._gameSession.c2s_SendCmdTeamAssistSel(idTeamMember);
|
||||
}
|
||||
|
||||
public static void c2s_CmdActiveRushFly(bool bActive)
|
||||
{
|
||||
Instance._gameSession.c2s_SendCmdActiveRushFly(bActive);
|
||||
}
|
||||
|
||||
public static void c2s_CmdOpenBoothTest()
|
||||
{
|
||||
Instance._gameSession.c2s_SendCmdOpenBoothTest();
|
||||
}
|
||||
|
||||
public static void c2s_CmdBindPlayerRequest(int idTarget)
|
||||
{
|
||||
Instance._gameSession.c2s_SendCmdBindPlayerRequest(idTarget);
|
||||
}
|
||||
|
||||
public static void c2s_CmdBindPlayerInvite(int idTarget)
|
||||
{
|
||||
Instance._gameSession.c2s_SendCmdBindPlayerInvite(idTarget);
|
||||
}
|
||||
|
||||
public static bool trade_Start(int idTarget)
|
||||
{
|
||||
return Instance._gameSession.trade_Start(idTarget);
|
||||
}
|
||||
#region Task
|
||||
public static void c2s_CmdGetAllData(bool byPack, bool byEquip, bool byTask)
|
||||
{
|
||||
@@ -973,6 +938,81 @@ namespace BrewMonster.Network
|
||||
{
|
||||
Instance._gameSession.c2s_SendCmdNPCSevRestorePet(iPetIdx);
|
||||
}
|
||||
|
||||
public static void c2s_CmdSitDown()
|
||||
{
|
||||
Instance._gameSession.c2s_SendCmdSitDown();
|
||||
}
|
||||
|
||||
public static void c2s_CmdTeamAssistSel(int idTeamMember)
|
||||
{
|
||||
Instance._gameSession.c2s_SendCmdTeamAssistSel(idTeamMember);
|
||||
}
|
||||
|
||||
public static void trade_Start(int idTarget)
|
||||
{
|
||||
Instance._gameSession.trade_Start(idTarget);
|
||||
}
|
||||
|
||||
public static void c2s_CmdOpenBoothTest()
|
||||
{
|
||||
Instance._gameSession.c2s_SendCmdOpenBoothTest();
|
||||
}
|
||||
|
||||
public static void c2s_CmdActiveRushFly(bool bActive)
|
||||
{
|
||||
Instance._gameSession.c2s_SendCmdActiveRushFly(bActive);
|
||||
}
|
||||
|
||||
public static void c2s_CmdBindPlayerInvite(int idTarget)
|
||||
{
|
||||
Instance._gameSession.c2s_SendCmdBindPlayerInvite(idTarget);
|
||||
}
|
||||
|
||||
public static void c2s_CmdBindPlayerRequest(int idTarget)
|
||||
{
|
||||
Instance._gameSession.c2s_SendCmdBindPlayerRequest(idTarget);
|
||||
}
|
||||
|
||||
public static void c2s_CmdNPCSevOpenTrash(string password)
|
||||
{
|
||||
Instance._gameSession.c2s_CmdNPCSevOpenTrash(password);
|
||||
}
|
||||
|
||||
public static void c2s_CmdGetTrashBoxData(bool detail, bool accountBox = false)
|
||||
{
|
||||
Instance._gameSession.c2s_CmdGetTrashBoxData(detail, accountBox);
|
||||
}
|
||||
|
||||
public static void c2s_CmdExgTrashBoxItem(byte where, byte index1, byte index2)
|
||||
{
|
||||
Instance._gameSession.c2s_CmdExgTrashBoxItem(where, index1, index2);
|
||||
}
|
||||
|
||||
public static void c2s_CmdMoveTrashBoxItem(byte where, byte src, byte dest, uint amount)
|
||||
{
|
||||
Instance._gameSession.c2s_CmdMoveTrashBoxItem(where, src, dest, amount);
|
||||
}
|
||||
|
||||
public static void c2s_CmdExgTrashBoxIvtrItem(byte where, byte idxTra, byte idxInv)
|
||||
{
|
||||
Instance._gameSession.c2s_CmdExgTrashBoxIvtrItem(where, idxTra, idxInv);
|
||||
}
|
||||
|
||||
public static void c2s_CmdMoveTrashBoxToIvtr(byte where, byte idxTra, byte idxInv, uint amount)
|
||||
{
|
||||
Instance._gameSession.c2s_CmdMoveTrashBoxToIvtr(where, idxTra, idxInv, amount);
|
||||
}
|
||||
|
||||
public static void c2s_CmdMoveIvtrToTrashBox(byte where, byte idxInv, byte idxTra, uint amount)
|
||||
{
|
||||
Instance._gameSession.c2s_CmdMoveIvtrToTrashBox(where, idxInv, idxTra, amount);
|
||||
}
|
||||
|
||||
public static void c2s_CmdExgTrashBoxMoney(int invMoney, int trashMoney, bool accountBox = false)
|
||||
{
|
||||
Instance._gameSession.c2s_CmdExgTrashBoxMoney(invMoney, trashMoney, accountBox);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -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<AUIDialog>();
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runtime fallback when a dialog exists as prefab but is missing from DialogScriptTableObject.
|
||||
/// </summary>
|
||||
static GameObject TryLoadDialogPrefabFallback(string pszName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(pszName))
|
||||
return null;
|
||||
#if UNITY_EDITOR
|
||||
return UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>($"Assets/Prefabs/UI/{pszName}.prefab");
|
||||
#else
|
||||
return null;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2771,8 +2771,9 @@ namespace BrewMonster.UI
|
||||
}
|
||||
else if (iService == CDLGNPC.CDLGNPC_VIEW_TRASHBOX && (pEssence?.combined_services & 0x40000000) != 0)
|
||||
{
|
||||
//GetGameSession().c2s_CmdNPCSevViewTrash();
|
||||
//CloseDialogue();
|
||||
UnityGameSession.c2s_CmdGetTrashBoxData(true);
|
||||
CloseDialogue();
|
||||
GetGameUIMan().EndNPCService();
|
||||
return;
|
||||
}
|
||||
else if (iService == CDLGNPC.CDLGNPC_VIEW_DPS_DPH_RANK && (pEssence?.combined_services & 0x80000000) != 0)
|
||||
@@ -3258,12 +3259,11 @@ namespace BrewMonster.UI
|
||||
// id_dialog = (int)pService.id_dialog;
|
||||
// idFunction = (int)SERVICE_TYPE.NPC_PROXY;
|
||||
// }
|
||||
/*else if (DataType == DATA_TYPE.DT_NPC_STORAGE_SERVICE)
|
||||
else if (DataType == DATA_TYPE.DT_NPC_STORAGE_SERVICE)
|
||||
{
|
||||
NPC_STORAGE_SERVICE pService = (NPC_STORAGE_SERVICE)pData;
|
||||
string strText1 = m_pLst_Main.GetText(nCurSel);
|
||||
string strComp1 = (GetStringFromTable(249)) + (GetStringFromTable(253));
|
||||
string strComp2 = (GetStringFromTable(249)) + (GetStringFromTable(8080));
|
||||
string strComp1 = GetStringFromTable(249) + GetStringFromTable(253);
|
||||
string strComp2 = GetStringFromTable(249) + GetStringFromTable(8080);
|
||||
|
||||
if (string.Equals(strText1, strComp1, StringComparison.OrdinalIgnoreCase))
|
||||
idFunction = (int)SERVICE_TYPE.NPC_STORAGE_PASSWORD;
|
||||
@@ -3271,7 +3271,7 @@ namespace BrewMonster.UI
|
||||
idFunction = (int)SERVICE_TYPE.NPC_ACCOUNT_STORAGE;
|
||||
else
|
||||
idFunction = (int)SERVICE_TYPE.NPC_STORAGE;
|
||||
}*/
|
||||
}
|
||||
else if (DataType == DATA_TYPE.DT_NPC_MAKE_SERVICE)
|
||||
{
|
||||
NPC_MAKE_SERVICE pService = (NPC_MAKE_SERVICE)pData;
|
||||
@@ -3765,13 +3765,16 @@ namespace BrewMonster.UI
|
||||
}
|
||||
else if (idFunction == (int)SERVICE_TYPE.NPC_STORAGE)
|
||||
{
|
||||
//if (GetHostPlayer().TrashBoxHasPsw())
|
||||
//{
|
||||
// pShow1 = m_pAUIManager.GetDialog("Win_InputString");
|
||||
// pShow1.GetDlgItem("DEFAULT_Txt_Input").SetText(_AL(""));
|
||||
//}
|
||||
//else
|
||||
// g_pGame.GetGameSession().c2s_CmdNPCSevOpenTrash("");
|
||||
if (GetHostPlayer().TrashBoxHasPsw())
|
||||
{
|
||||
dialogue1 = "Win_InputString";
|
||||
// PW_TODO: password input → c2s_CmdNPCSevOpenTrash(password)
|
||||
}
|
||||
else
|
||||
{
|
||||
UnityGameSession.c2s_CmdNPCSevOpenTrash("");
|
||||
GetGameUIMan().EndNPCService();
|
||||
}
|
||||
}
|
||||
else if (idFunction == (int)SERVICE_TYPE.NPC_STORAGE_PASSWORD)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Numeric input dialog (C++ CDlgInputNO / DlgInputNO). Dialog id: <c>DlgQuantity</c>.
|
||||
/// </summary>
|
||||
public class DlgQuantity : AUIDialog
|
||||
{
|
||||
public enum QuantityMode
|
||||
{
|
||||
None = 0,
|
||||
/// <summary>Gửi tiền vào kho — C++ INPUTNO_STORAGE_IVTR_MONEY (Win_Inventory choosemoney + storage open).</summary>
|
||||
StorageDepositMoney,
|
||||
/// <summary>Rút tiền ra — C++ INPUTNO_STORAGE_TRASH_MONEY (Win_Storage choosemoney).</summary>
|
||||
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<int, QuantityMode> _onConfirmed;
|
||||
|
||||
public static DlgQuantity GetDialog()
|
||||
{
|
||||
return EC_Game.GetGameRun()?.GetUIManager()?.GetInGameUIMan()?.GetDialog("DlgQuantity") as DlgQuantity;
|
||||
}
|
||||
|
||||
/// <summary>Open quantity panel; on confirm invokes callback then sends C2S when mode is storage money.</summary>
|
||||
public static void Show(QuantityMode mode, int maxAmount, int defaultAmount = 1, Action<int, QuantityMode> 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<TMP_InputField>(true);
|
||||
if (amountInput != null && amountInput.name.Contains("DEFAULT", StringComparison.OrdinalIgnoreCase) == false)
|
||||
{
|
||||
var all = GetComponentsInChildren<TMP_InputField>(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<Button>(true);
|
||||
for (int i = 0; i < buttons.Length; i++)
|
||||
{
|
||||
var btn = buttons[i];
|
||||
if (btn == null)
|
||||
continue;
|
||||
string n = btn.name.ToLowerInvariant();
|
||||
for (int h = 0; h < nameHints.Length; h++)
|
||||
{
|
||||
if (n.Contains(nameHints[h]))
|
||||
{
|
||||
field = btn;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WireButtons()
|
||||
{
|
||||
if (confirmButton != null)
|
||||
{
|
||||
confirmButton.onClick.RemoveAllListeners();
|
||||
confirmButton.onClick.AddListener(OnConfirm);
|
||||
}
|
||||
if (cancelButton != null)
|
||||
{
|
||||
cancelButton.onClick.RemoveAllListeners();
|
||||
cancelButton.onClick.AddListener(OnCancel);
|
||||
}
|
||||
if (addButton != null)
|
||||
{
|
||||
addButton.onClick.RemoveAllListeners();
|
||||
addButton.onClick.AddListener(OnAdd);
|
||||
}
|
||||
if (minusButton != null)
|
||||
{
|
||||
minusButton.onClick.RemoveAllListeners();
|
||||
minusButton.onClick.AddListener(OnMinus);
|
||||
}
|
||||
if (maxButton != null)
|
||||
{
|
||||
maxButton.onClick.RemoveAllListeners();
|
||||
maxButton.onClick.AddListener(OnMax);
|
||||
}
|
||||
|
||||
if (amountInput != null)
|
||||
{
|
||||
amountInput.onValueChanged.RemoveAllListeners();
|
||||
amountInput.onValueChanged.AddListener(OnAmountInputChanged);
|
||||
amountInput.contentType = TMP_InputField.ContentType.IntegerNumber;
|
||||
}
|
||||
}
|
||||
|
||||
public void Open(QuantityMode mode, int maxAmount, int defaultAmount, Action<int, QuantityMode> onConfirmed)
|
||||
{
|
||||
_mode = mode;
|
||||
_onConfirmed = onConfirmed;
|
||||
_max = Mathf.Max(0, maxAmount);
|
||||
_min = _max > 0 ? 1 : 0;
|
||||
_current = Mathf.Clamp(defaultAmount, _min, Mathf.Max(_min, _max));
|
||||
if (_max <= 0)
|
||||
_current = 0;
|
||||
|
||||
ApplyAmountToUi();
|
||||
Show(true);
|
||||
}
|
||||
|
||||
void ApplyAmountToUi()
|
||||
{
|
||||
string text = _current.ToString();
|
||||
if (amountInput != null)
|
||||
amountInput.SetTextWithoutNotify(text);
|
||||
if (amountTextLegacy != null)
|
||||
amountTextLegacy.text = text;
|
||||
}
|
||||
|
||||
int ReadAmountFromUi()
|
||||
{
|
||||
if (amountInput != null && int.TryParse(amountInput.text, out int v))
|
||||
return v;
|
||||
if (amountTextLegacy != null && int.TryParse(amountTextLegacy.text, out v))
|
||||
return v;
|
||||
return _current;
|
||||
}
|
||||
|
||||
void SetAmount(int value)
|
||||
{
|
||||
if (_max <= 0)
|
||||
{
|
||||
_current = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_current = Mathf.Clamp(value, _min, _max);
|
||||
}
|
||||
ApplyAmountToUi();
|
||||
}
|
||||
|
||||
void OnAmountInputChanged(string _)
|
||||
{
|
||||
SetAmount(ReadAmountFromUi());
|
||||
}
|
||||
|
||||
void OnAdd() => SetAmount(_current + 1);
|
||||
void OnMinus() => SetAmount(_current - 1);
|
||||
void OnMax() => SetAmount(_max);
|
||||
|
||||
void OnConfirm()
|
||||
{
|
||||
if (_max <= 0)
|
||||
{
|
||||
OnCancel();
|
||||
return;
|
||||
}
|
||||
|
||||
int n = ReadAmountFromUi();
|
||||
if (n < _min)
|
||||
n = _min;
|
||||
if (n > _max)
|
||||
n = _max;
|
||||
if (n <= 0)
|
||||
return;
|
||||
|
||||
ExecuteMode(n);
|
||||
_onConfirmed?.Invoke(n, _mode);
|
||||
Close();
|
||||
}
|
||||
|
||||
void ExecuteMode(int amount)
|
||||
{
|
||||
switch (_mode)
|
||||
{
|
||||
case QuantityMode.StorageDepositMoney:
|
||||
// C++ INPUTNO_STORAGE_IVTR_MONEY: ExgTrashBoxMoney(iTrash=0, iIvtr=amount)
|
||||
UnityGameSession.c2s_CmdExgTrashBoxMoney(amount, 0);
|
||||
break;
|
||||
case QuantityMode.StorageWithdrawMoney:
|
||||
// C++ INPUTNO_STORAGE_TRASH_MONEY: ExgTrashBoxMoney(iTrash=amount, iIvtr=0)
|
||||
UnityGameSession.c2s_CmdExgTrashBoxMoney(0, amount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnCancel() => Close();
|
||||
|
||||
void Close()
|
||||
{
|
||||
_mode = QuantityMode.None;
|
||||
_onConfirmed = null;
|
||||
CECUIManager.Instance?.HideDialogOverlay("DlgQuantity");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dbd9eed9b75d31f44b114eb840444ae0
|
||||
@@ -125,6 +125,8 @@ namespace BrewMonster.Scripts.UI
|
||||
/// </summary>
|
||||
/// <param name="panel">The GameObject panel to show/hide</param>
|
||||
/// <param name="show">True to show, false to hide</param>
|
||||
public const int OverlayPanelSortOrder = 2000;
|
||||
|
||||
public static void ShowPanel(GameObject panel, bool show)
|
||||
{
|
||||
if (panel == null)
|
||||
@@ -145,6 +147,25 @@ namespace BrewMonster.Scripts.UI
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Draw panel above other UI dialogs (sibling order + canvas sort).</summary>
|
||||
public static void BringPanelToFront(GameObject panel)
|
||||
{
|
||||
if (panel == null)
|
||||
return;
|
||||
|
||||
panel.transform.SetAsLastSibling();
|
||||
|
||||
var canvas = panel.GetComponent<Canvas>();
|
||||
if (canvas == null)
|
||||
canvas = panel.AddComponent<Canvas>();
|
||||
|
||||
canvas.overrideSorting = true;
|
||||
canvas.sortingOrder = OverlayPanelSortOrder;
|
||||
|
||||
if (panel.GetComponent<GraphicRaycaster>() == null)
|
||||
panel.AddComponent<GraphicRaycaster>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper class for managing dual text component support (Legacy Text + TextMeshPro).
|
||||
/// Allows UI components to work with both text systems simultaneously.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 11d09ee52b0c5f24fb3ef21e177ebe2d
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0986049a141406946b0ed97344b84f78
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -12786,6 +12786,7 @@ MonoBehaviour:
|
||||
tmp: {fileID: 6020258894941961325}
|
||||
equipButton: {fileID: 472698755110594484}
|
||||
dropButton: {fileID: 540159372834342487}
|
||||
storageTransferButton: {fileID: 0}
|
||||
splitPanelRoot: {fileID: 3772330938303001319}
|
||||
splitAmountText: {fileID: 3418403519615399396}
|
||||
splitConfirmButton: {fileID: 7942200720793983179}
|
||||
@@ -20626,7 +20627,7 @@ PrefabInstance:
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7209086543831860202, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
|
||||
propertyPath: m_AnchoredPosition.y
|
||||
value: -836.15
|
||||
value: -42
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 8894405194986632892, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
|
||||
propertyPath: m_AnchorMax.y
|
||||
@@ -20646,7 +20647,7 @@ PrefabInstance:
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 8894405194986632892, guid: c56ed80641ff74ce49f91401e3eb8367, type: 3}
|
||||
propertyPath: m_AnchoredPosition.y
|
||||
value: -418.075
|
||||
value: -21
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
|
||||
@@ -8,7 +8,7 @@ using CSNetwork.GPDataType;
|
||||
using CSNetwork.S2CCommand;
|
||||
using System;
|
||||
using BrewMonster.UI;
|
||||
using PerfectWorld.Scripts.Managers;
|
||||
using BrewMonster.Scripts.Managers;
|
||||
using UnityEngine;
|
||||
using static BrewMonster.Scripts.CECHPWork;
|
||||
using static BrewMonster.Scripts.EC_Inventory;
|
||||
@@ -88,9 +88,15 @@ namespace BrewMonster
|
||||
{
|
||||
UpdateEquipSkins();
|
||||
}
|
||||
else if (byPackage == InventoryConst.IVTRTYPE_TRASHBOX && m_bUsingTrashBox)
|
||||
{
|
||||
PopupStorageDialog();
|
||||
}
|
||||
|
||||
var ui = GameObject.FindFirstObjectByType<EC_InventoryUI>();
|
||||
ui?.RefreshAll();
|
||||
if (byPackage == InventoryConst.IVTRTYPE_TRASHBOX)
|
||||
EC_StorageUI.RefreshAllStatic();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -131,6 +137,15 @@ namespace BrewMonster
|
||||
{
|
||||
UpdateEquipSkins();
|
||||
}
|
||||
else if (byPackage == InventoryConst.IVTRTYPE_TRASHBOX && m_bUsingTrashBox)
|
||||
{
|
||||
PopupStorageDialog();
|
||||
}
|
||||
|
||||
var uiDetail = GameObject.FindFirstObjectByType<EC_InventoryUI>();
|
||||
uiDetail?.RefreshAll();
|
||||
if (byPackage == InventoryConst.IVTRTYPE_TRASHBOX)
|
||||
EC_StorageUI.RefreshAllStatic();
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -1598,9 +1613,9 @@ namespace BrewMonster
|
||||
case Inventory_type.IVTRTYPE_PACK: pInventory = m_pPack; break;
|
||||
case Inventory_type.IVTRTYPE_EQUIPPACK: pInventory = m_pEquipPack; break;
|
||||
case Inventory_type.IVTRTYPE_TASKPACK: pInventory = m_pTaskPack; break;
|
||||
//case Inventory_type.IVTRTYPE_TRASHBOX: pInventory = m_pTrashBoxPack; break;
|
||||
//case Inventory_type.IVTRTYPE_TRASHBOX2: pInventory = m_pTrashBoxPack2; break;
|
||||
//case Inventory_type.IVTRTYPE_TRASHBOX3: pInventory = m_pTrashBoxPack3; break;
|
||||
case Inventory_type.IVTRTYPE_TRASHBOX: pInventory = m_pTrashBoxPack; break;
|
||||
case Inventory_type.IVTRTYPE_TRASHBOX2: pInventory = m_pTrashBoxPack2; break;
|
||||
case Inventory_type.IVTRTYPE_TRASHBOX3: pInventory = m_pTrashBoxPack3; break;
|
||||
//case Inventory_type.IVTRTYPE_ACCOUNT_BOX: pInventory = m_pAccountBoxPack; break;
|
||||
//case Inventory_type.IVTRTYPE_GENERALCARD_BOX: pInventory = m_pGeneralCardPack; break;
|
||||
//case IVTRTYPE_PACK_CLIENT_GENERALCAR.IVTRTYPE_CLIENT_GENERALCARD_PACK: pInventory = m_pClientGenCardPack; break;
|
||||
|
||||
@@ -0,0 +1,328 @@
|
||||
using BrewMonster.Managers;
|
||||
using BrewMonster.Network;
|
||||
using BrewMonster.Scripts;
|
||||
using BrewMonster.Scripts.Managers;
|
||||
using CSNetwork;
|
||||
using CSNetwork.GPDataType;
|
||||
using BrewMonster.Scripts.Managers;
|
||||
using BrewMonster.UI;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using static BrewMonster.Scripts.EC_Inventory;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
/// <summary>
|
||||
/// Host player warehouse / trash box (C++ CECHostPlayer::OnMsgHstTrashBoxOperation, GetTrashBox*).
|
||||
/// </summary>
|
||||
public partial class CECHostPlayer
|
||||
{
|
||||
private readonly EC_Inventory m_pTrashBoxPack = new EC_Inventory();
|
||||
private readonly EC_Inventory m_pTrashBoxPack2 = new EC_Inventory();
|
||||
private readonly EC_Inventory m_pTrashBoxPack3 = new EC_Inventory();
|
||||
|
||||
private bool m_bTrashPsw;
|
||||
private bool m_bFirstTBOpen = true;
|
||||
private int m_iTrashBoxMoneyCnt;
|
||||
|
||||
public bool TrashBoxHasPsw() => m_bTrashPsw;
|
||||
public int GetTrashBoxMoneyCnt() => m_iTrashBoxMoneyCnt;
|
||||
public EC_Inventory GetTrashBox() => m_pTrashBoxPack;
|
||||
public EC_Inventory GetTrashBox2() => m_pTrashBoxPack2;
|
||||
public EC_Inventory GetTrashBox3() => m_pTrashBoxPack3;
|
||||
|
||||
void InitTrashBoxPacks()
|
||||
{
|
||||
if (m_pTrashBoxPack.GetSize() == 0)
|
||||
m_pTrashBoxPack.Init(InventoryConst.IVTRSIZE_TRASHBOX);
|
||||
if (m_pTrashBoxPack2.GetSize() == 0)
|
||||
m_pTrashBoxPack2.Init(0);
|
||||
if (m_pTrashBoxPack3.GetSize() == 0)
|
||||
m_pTrashBoxPack3.Init(0);
|
||||
}
|
||||
|
||||
public void OnMsgHstTrashBoxOperation(ECMSG Msg)
|
||||
{
|
||||
var data = Msg.dwParam1 as byte[];
|
||||
if (data == null || data.Length == 0)
|
||||
return;
|
||||
|
||||
int cmd = Convert.ToInt32(Msg.dwParam2);
|
||||
switch (cmd)
|
||||
{
|
||||
case CommandID.TRASHBOX_OPEN:
|
||||
{
|
||||
var pCmd = GPDataTypeHelper.FromBytes<cmd_trashbox_open>(data);
|
||||
if (pCmd.is_accountbox != 0)
|
||||
break; // PW_TODO: account box UI
|
||||
|
||||
m_bUsingTrashBox = true;
|
||||
InitTrashBoxPacks();
|
||||
|
||||
if (m_bFirstTBOpen)
|
||||
{
|
||||
m_bFirstTBOpen = false;
|
||||
UnityGameSession.c2s_CmdGetTrashBoxData(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_pTrashBoxPack.GetSize() < pCmd.slot_size)
|
||||
m_pTrashBoxPack.Resize(pCmd.slot_size);
|
||||
if (m_pTrashBoxPack2.GetSize() < pCmd.slot_size2)
|
||||
m_pTrashBoxPack2.Resize(pCmd.slot_size2);
|
||||
if (m_pTrashBoxPack3.GetSize() < pCmd.slot_size3)
|
||||
m_pTrashBoxPack3.Resize(pCmd.slot_size3);
|
||||
PopupStorageDialog();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CommandID.TRASHBOX_CLOSE:
|
||||
{
|
||||
var pCmd = GPDataTypeHelper.FromBytes<cmd_trashbox_close>(data);
|
||||
if (pCmd.is_accountbox != 0)
|
||||
break;
|
||||
m_bUsingTrashBox = false;
|
||||
PopupStorageDialog(true);
|
||||
break;
|
||||
}
|
||||
case CommandID.TRASHBOX_WEALTH:
|
||||
{
|
||||
var pCmd = GPDataTypeHelper.FromBytes<cmd_trashbox_wealth>(data);
|
||||
if (pCmd.is_accountbox == 0)
|
||||
m_iTrashBoxMoneyCnt = (int)pCmd.money;
|
||||
EC_StorageUI.RefreshMoneyStatic();
|
||||
break;
|
||||
}
|
||||
case CommandID.EXG_TRASH_MONEY:
|
||||
{
|
||||
var pCmd = GPDataTypeHelper.FromBytes<cmd_exg_trash_money>(data);
|
||||
if (pCmd.is_accountbox == 0)
|
||||
{
|
||||
AddMoneyAmount(pCmd.inv_delta);
|
||||
m_iTrashBoxMoneyCnt += pCmd.tra_delta;
|
||||
}
|
||||
EC_StorageUI.RefreshMoneyStatic();
|
||||
var invUi = UnityEngine.Object.FindFirstObjectByType<EC_InventoryUI>();
|
||||
invUi?.RefreshAll();
|
||||
break;
|
||||
}
|
||||
case CommandID.EXG_TRASHBOX_ITEM:
|
||||
{
|
||||
var pCmd = GPDataTypeHelper.FromBytes<cmd_exg_trashbox_item>(data);
|
||||
var pTrash = GetPack(pCmd.where);
|
||||
pTrash?.ExchangeItem(pCmd.idx1, pCmd.idx2);
|
||||
EC_StorageUI.RefreshAllStatic();
|
||||
break;
|
||||
}
|
||||
case CommandID.MOVE_TRASHBOX_ITEM:
|
||||
{
|
||||
var pCmd = GPDataTypeHelper.FromBytes<cmd_move_trashbox_item>(data);
|
||||
var pTrash = GetPack(pCmd.where);
|
||||
pTrash?.MoveItem(pCmd.src, pCmd.dest, (int)pCmd.amount);
|
||||
EC_StorageUI.RefreshAllStatic();
|
||||
break;
|
||||
}
|
||||
case CommandID.EXG_TRASHBOX_IVTR:
|
||||
{
|
||||
var pCmd = GPDataTypeHelper.FromBytes<cmd_exg_trashbox_ivtr>(data);
|
||||
var pTrash = GetPack(pCmd.where);
|
||||
if (pTrash == null || m_pPack == null)
|
||||
break;
|
||||
var pItem1 = m_pPack.GetItem(pCmd.idx_inv, true);
|
||||
var pItem2 = pTrash.GetItem(pCmd.idx_tra, true);
|
||||
m_pPack.SetItem(pCmd.idx_inv, pItem2);
|
||||
pTrash.SetItem(pCmd.idx_tra, pItem1);
|
||||
RefreshStorageAndInventoryUi();
|
||||
break;
|
||||
}
|
||||
case CommandID.IVTR_ITEM_TO_TRASH:
|
||||
{
|
||||
var pCmd = GPDataTypeHelper.FromBytes<cmd_ivty_item_to_trash>(data);
|
||||
var pTrash = GetPack(pCmd.where);
|
||||
if (pTrash == null || m_pPack == null)
|
||||
break;
|
||||
var pItem1 = m_pPack.GetItem(pCmd.src);
|
||||
var pItem2 = pTrash.GetItem(pCmd.dest);
|
||||
if (pItem1 == null)
|
||||
break;
|
||||
if (pItem2 != null)
|
||||
{
|
||||
pItem2.AddAmount((int)pCmd.amount);
|
||||
}
|
||||
else
|
||||
{
|
||||
pItem2 = EC_IvtrItem.CreateItem(pItem1.m_tid, pItem1.m_expire_date, (int)pCmd.amount);
|
||||
pTrash.SetItem(pCmd.dest, pItem2);
|
||||
}
|
||||
m_pPack.RemoveItem(pCmd.src, (int)pCmd.amount);
|
||||
RefreshStorageAndInventoryUi();
|
||||
break;
|
||||
}
|
||||
case CommandID.TRASH_ITEM_TO_IVTR:
|
||||
{
|
||||
var pCmd = GPDataTypeHelper.FromBytes<cmd_trash_item_to_ivtr>(data);
|
||||
var pTrash = GetPack(pCmd.where);
|
||||
if (pTrash == null || m_pPack == null)
|
||||
break;
|
||||
var pItem1 = pTrash.GetItem(pCmd.src);
|
||||
var pItem2 = m_pPack.GetItem(pCmd.dest);
|
||||
if (pItem1 == null)
|
||||
break;
|
||||
if (pItem2 != null)
|
||||
pItem2.AddAmount((int)pCmd.amount);
|
||||
else
|
||||
{
|
||||
pItem2 = EC_IvtrItem.CreateItem(pItem1.m_tid, pItem1.m_expire_date, (int)pCmd.amount);
|
||||
m_pPack.SetItem(pCmd.dest, pItem2);
|
||||
}
|
||||
pTrash.RemoveItem(pCmd.src, (int)pCmd.amount);
|
||||
RefreshStorageAndInventoryUi();
|
||||
break;
|
||||
}
|
||||
case CommandID.TRASHBOX_PWD_CHANGED:
|
||||
case CommandID.TRASHBOX_PWD_STATE:
|
||||
{
|
||||
var pCmd = GPDataTypeHelper.FromBytes<cmd_trashbox_pwd_state>(data);
|
||||
m_bTrashPsw = pCmd.has_passwd > 0;
|
||||
break;
|
||||
}
|
||||
case CommandID.TRASHBOX_SIZE:
|
||||
{
|
||||
var pCmd = GPDataTypeHelper.FromBytes<cmd_trashbox_size>(data);
|
||||
int msg = (int)FixedMsg.FIXMSG_TRASHBOX_EXPAND;
|
||||
int iSize = pCmd.iNewSize;
|
||||
if (pCmd.where == Inventory_type.IVTRTYPE_TRASHBOX2)
|
||||
msg = (int)FixedMsg.FIXMSG_TRASHBOX2_EXPAND;
|
||||
else if (pCmd.where == Inventory_type.IVTRTYPE_TRASHBOX3)
|
||||
{
|
||||
msg = (int)FixedMsg.FIXMSG_TRASHBOX3_EXPAND;
|
||||
m_pTrashBoxPack3?.Resize(pCmd.iNewSize);
|
||||
}
|
||||
else if (pCmd.where == Inventory_type.IVTRTYPE_TRASHBOX)
|
||||
m_pTrashBoxPack?.Resize(pCmd.iNewSize);
|
||||
EC_Game.GetGameRun()?.AddFixedMessage(msg, iSize);
|
||||
EC_StorageUI.RefreshAllStatic();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void RefreshStorageAndInventoryUi()
|
||||
{
|
||||
EC_StorageUI.RefreshAllStatic();
|
||||
UnityEngine.Object.FindFirstObjectByType<EC_InventoryUI>()?.RefreshAll();
|
||||
}
|
||||
|
||||
/// <summary>C++ CECGameUIMan::PopupStorageDialog — show warehouse + inventory.</summary>
|
||||
public static void PopupStorageDialog(bool close = false)
|
||||
{
|
||||
if (close)
|
||||
{
|
||||
var host = EC_Game.GetGameRun()?.GetHostPlayer();
|
||||
bool wasUsingTrash = host != null && host.IsUsingTrashBox();
|
||||
if (host != null)
|
||||
host.m_bUsingTrashBox = false;
|
||||
|
||||
EC_StorageUI.ClearSelectionStatic();
|
||||
var invUi = UnityEngine.Object.FindFirstObjectByType<EC_InventoryUI>(FindObjectsInactive.Include);
|
||||
invUi?.DismissItemDetail();
|
||||
|
||||
CECUIManager.Instance?.HideStorageDialogPair();
|
||||
|
||||
if (wasUsingTrash)
|
||||
UnityGameSession.c2s_CmdCancelAction();
|
||||
EC_Game.GetGameRun()?.GetUIManager()?.GetInGameUIMan()?.EndNPCService();
|
||||
return;
|
||||
}
|
||||
|
||||
CECUIManager.Instance?.ShowStorageDialogPair();
|
||||
var storageDlg = EC_Game.GetGameRun()?.GetUIManager()?.GetInGameUIMan()?.GetDialog("EC_StorageUI") as EC_StorageUI;
|
||||
storageDlg?.RefreshAll();
|
||||
|
||||
var invDlg = UnityEngine.Object.FindFirstObjectByType<EC_InventoryUI>(FindObjectsInactive.Include);
|
||||
invDlg?.RefreshAll();
|
||||
}
|
||||
|
||||
/// <summary>Transfer between main pack and trash box (C++ CDlgStorage::OnItemDragDrop).</summary>
|
||||
public bool TransferPackAndTrash(byte trashWhere, int trashSlot, int invSlot, int amount = -1)
|
||||
{
|
||||
if (trashWhere != InventoryConst.IVTRTYPE_TRASHBOX)
|
||||
return false;
|
||||
|
||||
var trash = GetPack(trashWhere);
|
||||
var pack = m_pPack;
|
||||
if (trash == null || pack == null)
|
||||
return false;
|
||||
if (trashSlot < 0 || invSlot < 0)
|
||||
return false;
|
||||
|
||||
var srcInv = pack.GetItem(invSlot);
|
||||
var dstTrash = trash.GetItem(trashSlot);
|
||||
if (srcInv != null && dstTrash == null)
|
||||
{
|
||||
UnityGameSession.c2s_CmdExgTrashBoxIvtrItem(trashWhere, (byte)trashSlot, (byte)invSlot);
|
||||
return true;
|
||||
}
|
||||
|
||||
var srcTrash = trash.GetItem(trashSlot);
|
||||
var dstInv = pack.GetItem(invSlot);
|
||||
if (srcTrash != null && dstInv == null)
|
||||
{
|
||||
UnityGameSession.c2s_CmdExgTrashBoxIvtrItem(trashWhere, (byte)trashSlot, (byte)invSlot);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (srcInv != null && dstTrash != null &&
|
||||
srcInv.m_tid == dstTrash.m_tid && srcInv.GetPileLimitInstance() > 1)
|
||||
{
|
||||
int moveAmt = amount > 0 ? amount : Math.Min(srcInv.m_iCount,
|
||||
dstTrash.GetPileLimitInstance() - dstTrash.m_iCount);
|
||||
if (moveAmt > 0)
|
||||
{
|
||||
UnityGameSession.c2s_CmdMoveIvtrToTrashBox(trashWhere, (byte)invSlot, (byte)trashSlot, (uint)moveAmt);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (srcTrash != null && dstInv != null &&
|
||||
srcTrash.m_tid == dstInv.m_tid && srcTrash.GetPileLimitInstance() > 1)
|
||||
{
|
||||
int moveAmt = amount > 0 ? amount : Math.Min(srcTrash.m_iCount,
|
||||
dstInv.GetPileLimitInstance() - dstInv.m_iCount);
|
||||
if (moveAmt > 0)
|
||||
{
|
||||
UnityGameSession.c2s_CmdMoveTrashBoxToIvtr(trashWhere, (byte)trashSlot, (byte)invSlot, (uint)moveAmt);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (srcInv != null || srcTrash != null)
|
||||
{
|
||||
UnityGameSession.c2s_CmdExgTrashBoxIvtrItem(trashWhere, (byte)trashSlot, (byte)invSlot);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TransferWithinTrash(byte where, int slotA, int slotB)
|
||||
{
|
||||
var trash = GetPack(where);
|
||||
if (trash == null || slotA < 0 || slotB < 0 || slotA == slotB)
|
||||
return false;
|
||||
var a = trash.GetItem(slotA);
|
||||
var b = trash.GetItem(slotB);
|
||||
if (a != null && b != null && a.m_tid == b.m_tid && a.GetPileLimitInstance() > 1)
|
||||
{
|
||||
int moveAmt = Math.Min(a.m_iCount, b.GetPileLimitInstance() - b.m_iCount);
|
||||
if (moveAmt > 0)
|
||||
{
|
||||
UnityGameSession.c2s_CmdMoveTrashBoxItem(where, (byte)slotA, (byte)slotB, (uint)moveAmt);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
UnityGameSession.c2s_CmdExgTrashBoxItem(where, (byte)slotA, (byte)slotB);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f43b17fb174c9ce4bbcdf1eb7637aa91
|
||||
@@ -139,7 +139,13 @@ namespace BrewMonster
|
||||
// }
|
||||
// }
|
||||
|
||||
if (m_bUsingTrashBox || DoingSessionPose())
|
||||
if (m_bUsingTrashBox)
|
||||
{
|
||||
CECHostPlayer.PopupStorageDialog(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (DoingSessionPose())
|
||||
{
|
||||
UnityGameSession.c2s_CmdCancelAction();
|
||||
return;
|
||||
|
||||
@@ -321,6 +321,12 @@ namespace BrewMonster
|
||||
return m_pEquipPack;
|
||||
case InventoryConst.IVTRTYPE_TASKPACK:
|
||||
return m_pTaskPack;
|
||||
case InventoryConst.IVTRTYPE_TRASHBOX:
|
||||
return m_pTrashBoxPack;
|
||||
case InventoryConst.IVTRTYPE_TRASHBOX2:
|
||||
return m_pTrashBoxPack2;
|
||||
case InventoryConst.IVTRTYPE_TRASHBOX3:
|
||||
return m_pTrashBoxPack3;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -329,6 +335,7 @@ namespace BrewMonster
|
||||
private void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
InitTrashBoxPacks();
|
||||
m_MoveCtrl = new CECHostMove(this);
|
||||
|
||||
// Cache: không bắt buộc, nhưng gọn tay và ít gọi property lặp.
|
||||
@@ -511,6 +518,9 @@ namespace BrewMonster
|
||||
case EC_MsgDef.MSG_HST_ITEMOPERATION:
|
||||
OnMsgHstItemOperation(Msg);
|
||||
break;
|
||||
case EC_MsgDef.MSG_HST_TRASHBOXOP:
|
||||
OnMsgHstTrashBoxOperation(Msg);
|
||||
break;
|
||||
case EC_MsgDef.MSG_HST_PICKUPITEM:
|
||||
OnMsgHstPickupItem(Msg);
|
||||
break;
|
||||
@@ -3088,7 +3098,7 @@ namespace BrewMonster
|
||||
}
|
||||
|
||||
// Is host player open trash box ?
|
||||
bool IsUsingTrashBox()
|
||||
public bool IsUsingTrashBox()
|
||||
{
|
||||
return m_bUsingTrashBox;
|
||||
}
|
||||
@@ -3652,7 +3662,7 @@ namespace BrewMonster
|
||||
|
||||
m_PetOptCnt.IncCounter(iRealTime);
|
||||
// Bind command cool counter
|
||||
if (m_BindCmdCoolCnt.IncCounter(iRealTime))
|
||||
if (m_BindCmdCoolCnt.IncCounter(iRealTime))
|
||||
m_BindCmdCoolCnt.Reset(true);
|
||||
|
||||
/*
|
||||
|
||||
@@ -38,6 +38,8 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
[SerializeField] private DialogScriptTableObject dialogResouce;
|
||||
[SerializeField] private Canvas canvasDlg;
|
||||
|
||||
public Transform DialogCanvasTransform => canvasDlg != null ? canvasDlg.transform : null;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Chat TMP: EmotionLibrarySpriteMap (SO). CECGameUIMan is not a MonoBehaviour — assign here on CECUIManager.")]
|
||||
private EmotionLibrarySpriteMap _emotionLibrarySpriteMap;
|
||||
@@ -248,6 +250,34 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
return Push(componentName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Show a modal on top without hiding stack dialogs (e.g. DlgQuantity over storage + inventory).
|
||||
/// </summary>
|
||||
public AUIDialog ShowDialogOverlay(string componentName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(componentName) || canvasDlg == null)
|
||||
return null;
|
||||
|
||||
var dlg = GetInGameUIMan()?.GetDialog(componentName);
|
||||
if (dlg == null)
|
||||
return null;
|
||||
|
||||
dlg.Show(true);
|
||||
dlg.transform.SetAsLastSibling();
|
||||
EC_UIUtility.BringPanelToFront(dlg.gameObject);
|
||||
return dlg;
|
||||
}
|
||||
|
||||
public void HideDialogOverlay(string componentName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(componentName))
|
||||
return;
|
||||
|
||||
var dlg = GetInGameUIMan()?.GetDialog(componentName);
|
||||
if (dlg != null)
|
||||
dlg.Show(false);
|
||||
}
|
||||
|
||||
public void HideCurrentUIInStack()
|
||||
{
|
||||
Pop();
|
||||
@@ -280,6 +310,57 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
return dlg;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Show warehouse + inventory together without hiding the first dialog (C++ PopupStorageDialog).
|
||||
/// </summary>
|
||||
public void ShowStorageDialogPair()
|
||||
{
|
||||
if (canvasDlg == null)
|
||||
return;
|
||||
|
||||
var gui = GetInGameUIMan();
|
||||
if (gui == null)
|
||||
return;
|
||||
|
||||
var storageDlg = gui.GetDialog("EC_StorageUI");
|
||||
var invDlg = gui.GetDialog("Win_Inventory");
|
||||
if (storageDlg == null || invDlg == null)
|
||||
return;
|
||||
_uiStack.Remove("Win_Inventory");
|
||||
_uiStack.Remove("EC_StorageUI");
|
||||
|
||||
invDlg.Show(true);
|
||||
storageDlg.Show(true);
|
||||
|
||||
_uiStack.Insert(0, "Win_Inventory");
|
||||
_uiStack.Insert(0, "EC_StorageUI");
|
||||
|
||||
// Inventory below, storage on top (detail panel uses EC_UIUtility overlay sort).
|
||||
invDlg.transform.SetAsLastSibling();
|
||||
storageDlg.transform.SetAsLastSibling();
|
||||
}
|
||||
|
||||
/// <summary>Hide warehouse pair and restore previous stack top if any.</summary>
|
||||
public void HideStorageDialogPair()
|
||||
{
|
||||
_uiStack.Remove("EC_StorageUI");
|
||||
_uiStack.Remove("Win_Inventory");
|
||||
|
||||
var gui = GetInGameUIMan();
|
||||
gui?.GetDialog("Win_Inventory")?.Show(false);
|
||||
gui?.GetDialog("EC_StorageUI")?.Show(false);
|
||||
|
||||
if (_uiStack.Count > 0)
|
||||
{
|
||||
var newTop = gui?.GetDialog(_uiStack[0]);
|
||||
if (newTop != null)
|
||||
{
|
||||
newTop.Show(true);
|
||||
newTop.transform.SetAsLastSibling();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pop the top dialog off the stack: hide it and bring the new top (if any) to front. Returns true if something was popped.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user