353 lines
11 KiB
C#
353 lines
11 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace BrewMonster.Scripts
|
|
{
|
|
/// <summary>
|
|
/// C# mirror of C++ CECInventory (EC_Inventory.h / EC_Inventory.cpp).
|
|
/// Instance-based inventory core plus static helpers used by existing client code.
|
|
/// </summary>
|
|
public class EC_Inventory
|
|
{
|
|
// ===== Instance-based inventory (per-pack) =====
|
|
public static int IVTRTYPE_CLIENT_GENERALCARD_PACK = 1024; // �ͻ��˱��ذ����� ���ڿ���ͼ��Ҫ����ѻ�ÿ���ͨ�����췢�͡�Ϊ��ͳһ�������촰�ڵ���Ʒ�����ӱ��ذ�����
|
|
|
|
// Item array: index is slot, null means empty.
|
|
private EC_IvtrItem[] m_aItems = Array.Empty<EC_IvtrItem>();
|
|
|
|
public static class Inventory_type
|
|
{
|
|
public const int IVTRTYPE_PACK = 0, // Normal pack
|
|
IVTRTYPE_EQUIPPACK = 1, // Equipment
|
|
IVTRTYPE_TASKPACK = 2, // Task pack
|
|
IVTRTYPE_TRASHBOX = 3, // Trash box
|
|
IVTRTYPE_TRASHBOX2 = 4, // Trash box - material box
|
|
IVTRTYPE_TRASHBOX3 = 5, // Trash box - fashion box
|
|
IVTRTYPE_ACCOUNT_BOX = 6, // User account box
|
|
IVTRTYPE_GENERALCARD_BOX = 7; // ���ư���
|
|
};
|
|
|
|
public EC_Inventory()
|
|
{
|
|
}
|
|
|
|
public bool Init(int iSize)
|
|
{
|
|
Resize(iSize);
|
|
return true;
|
|
}
|
|
|
|
public void Release()
|
|
{
|
|
// In C++ this deletes all heap-allocated items.
|
|
// Here we simply clear references so GC can collect them.
|
|
RemoveAllItems();
|
|
m_aItems = Array.Empty<EC_IvtrItem>();
|
|
}
|
|
|
|
public void RemoveAllItems()
|
|
{
|
|
for (int i = 0; i < m_aItems.Length; i++)
|
|
{
|
|
m_aItems[i] = null;
|
|
}
|
|
}
|
|
|
|
public virtual void Resize(int iNewSize)
|
|
{
|
|
int oldSize = m_aItems.Length;
|
|
if (iNewSize < 0) iNewSize = 0;
|
|
|
|
if (iNewSize == oldSize)
|
|
return;
|
|
|
|
var newArray = iNewSize > 0 ? new EC_IvtrItem[iNewSize] : Array.Empty<EC_IvtrItem>();
|
|
|
|
if (oldSize > 0 && iNewSize > 0)
|
|
{
|
|
Array.Copy(m_aItems, newArray, Math.Min(oldSize, iNewSize));
|
|
}
|
|
|
|
m_aItems = newArray;
|
|
}
|
|
|
|
public EC_IvtrItem PutItem(int iSlot, EC_IvtrItem pItem)
|
|
{
|
|
if (iSlot < 0 || iSlot >= m_aItems.Length)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var old = m_aItems[iSlot];
|
|
m_aItems[iSlot] = pItem;
|
|
return old;
|
|
}
|
|
|
|
public void SetItem(int iSlot, EC_IvtrItem pItem)
|
|
{
|
|
if (iSlot < 0 || iSlot >= m_aItems.Length)
|
|
{
|
|
return;
|
|
}
|
|
|
|
m_aItems[iSlot] = pItem;
|
|
}
|
|
|
|
public EC_IvtrItem GetItem(int iSlot, bool bRemove = false)
|
|
{
|
|
if (iSlot < 0 || iSlot >= m_aItems.Length)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var pItem = m_aItems[iSlot];
|
|
if (bRemove)
|
|
m_aItems[iSlot] = null;
|
|
return pItem;
|
|
}
|
|
|
|
public void ExchangeItem(int iSlot1, int iSlot2)
|
|
{
|
|
if (iSlot1 < 0 || iSlot1 >= m_aItems.Length ||
|
|
iSlot2 < 0 || iSlot2 >= m_aItems.Length)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (iSlot1 == iSlot2)
|
|
return;
|
|
|
|
var tmp = m_aItems[iSlot1];
|
|
m_aItems[iSlot1] = m_aItems[iSlot2];
|
|
m_aItems[iSlot2] = tmp;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Place or stack item in a specific slot (server-specified slot). Matches C++ expectation that client uses same slot as server.
|
|
/// </summary>
|
|
public bool PutItemInSlot(int iSlot, int tid, int iExpireDate, int iAmount, out int piLastSlot, out int piLastAmount)
|
|
{
|
|
piLastSlot = -1;
|
|
piLastAmount = 0;
|
|
if (iSlot < 0 || iSlot >= m_aItems.Length || iAmount <= 0)
|
|
return false;
|
|
|
|
var slotItem = m_aItems[iSlot];
|
|
if (slotItem == null)
|
|
{
|
|
var newItem = EC_IvtrItem.CreateItem(tid, iExpireDate, iAmount);
|
|
if (newItem == null)
|
|
return false;
|
|
newItem.Slot = iSlot;
|
|
newItem.SetCount(iAmount);
|
|
m_aItems[iSlot] = newItem;
|
|
piLastSlot = iSlot;
|
|
piLastAmount = iAmount;
|
|
return true;
|
|
}
|
|
if (slotItem.GetTemplateID() != tid)
|
|
return false;
|
|
int pileLimit = Math.Max(1, EC_IvtrItem.GetPileLimit(tid));
|
|
int canAdd = Math.Max(0, pileLimit - Math.Max(0, slotItem.GetCount()));
|
|
if (canAdd <= 0)
|
|
return false;
|
|
int add = Math.Min(canAdd, iAmount);
|
|
slotItem.AddAmount(add);
|
|
piLastSlot = iSlot;
|
|
piLastAmount = slotItem.GetCount();
|
|
return true;
|
|
}
|
|
|
|
public bool MergeItem(int tid, int iExpireDate, int iAmount, out int piLastSlot, out int piLastAmount)
|
|
{
|
|
piLastSlot = -1;
|
|
piLastAmount = 0;
|
|
|
|
int firstEmpty = -1;
|
|
|
|
for (int i = 0; i < m_aItems.Length; i++)
|
|
{
|
|
var slotItem = m_aItems[i];
|
|
if (slotItem != null)
|
|
{
|
|
if (slotItem.GetTemplateID() != tid)
|
|
continue;
|
|
|
|
int pileLimit = Math.Max(1, EC_IvtrItem.GetPileLimit(tid));
|
|
int canAdd = Math.Max(0, pileLimit - Math.Max(0, slotItem.GetCount()));
|
|
if (canAdd <= 0) continue;
|
|
|
|
int add = Math.Min(canAdd, iAmount);
|
|
slotItem.AddAmount(add);
|
|
iAmount -= add;
|
|
|
|
if (iAmount == 0)
|
|
{
|
|
piLastSlot = i;
|
|
piLastAmount = slotItem.GetCount();
|
|
return true;
|
|
}
|
|
}
|
|
else if (firstEmpty < 0)
|
|
{
|
|
firstEmpty = i;
|
|
}
|
|
}
|
|
|
|
if (firstEmpty < 0 || iAmount <= 0)
|
|
{
|
|
return false;
|
|
}
|
|
var newItem = EC_IvtrItem.CreateItem(tid, iExpireDate, iAmount);
|
|
if (newItem == null)
|
|
return false;
|
|
newItem.Slot = firstEmpty;
|
|
newItem.SetCount(iAmount);
|
|
|
|
m_aItems[firstEmpty] = newItem;
|
|
piLastSlot = firstEmpty;
|
|
piLastAmount = iAmount;
|
|
return true;
|
|
}
|
|
|
|
public bool MoveItem(int iSrc, int iDest, int iAmount)
|
|
{
|
|
if (iSrc < 0 || iSrc >= m_aItems.Length ||
|
|
iDest < 0 || iDest >= m_aItems.Length)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var pSrc = m_aItems[iSrc];
|
|
var pDst = m_aItems[iDest];
|
|
|
|
if (pSrc == null)
|
|
return false;
|
|
|
|
if (iAmount == 0)
|
|
return false;
|
|
|
|
if (pDst == null)
|
|
{
|
|
var clone = EC_IvtrItem.CreateItem(pSrc.GetTemplateID(), pSrc.GetExpireDate(), iAmount);
|
|
m_aItems[iDest] = clone;
|
|
}
|
|
else
|
|
{
|
|
if (pSrc.GetTemplateID() != pDst.GetTemplateID())
|
|
return false;
|
|
|
|
int pileLimit = Math.Max(1, EC_IvtrItem.GetPileLimit(pDst.GetTemplateID()));
|
|
int canAdd = Math.Max(0, pileLimit - Math.Max(0, pDst.GetCount()));
|
|
int add = Math.Min(canAdd, iAmount);
|
|
if (add <= 0) return false;
|
|
pDst.AddAmount(add);
|
|
iAmount = add;
|
|
}
|
|
|
|
RemoveItem(iSrc, iAmount);
|
|
return true;
|
|
}
|
|
|
|
public bool RemoveItem(int iSlot, int iAmount)
|
|
{
|
|
if (iSlot < 0 || iSlot >= m_aItems.Length)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var pItem = m_aItems[iSlot];
|
|
if (pItem == null)
|
|
return true;
|
|
|
|
int newCount = pItem.AddAmount(-Math.Max(0, iAmount));
|
|
if (newCount <= 0)
|
|
m_aItems[iSlot] = null;
|
|
|
|
return true;
|
|
}
|
|
|
|
public int FindItem(int idItem, int baseIdx = 0)
|
|
{
|
|
if (baseIdx < 0) baseIdx = 0;
|
|
for (int i = baseIdx; i < m_aItems.Length; i++)
|
|
{
|
|
var pItem = m_aItems[i];
|
|
if (pItem != null && pItem.GetTemplateID() == idItem)
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
public int GetItemTotalNum(int idItem)
|
|
{
|
|
int count = 0;
|
|
for (int i = 0; i < m_aItems.Length; i++)
|
|
{
|
|
var pItem = m_aItems[i];
|
|
if (pItem != null && pItem.GetTemplateID() == idItem)
|
|
count += Math.Max(0, pItem.GetCount());
|
|
}
|
|
return count;
|
|
}
|
|
|
|
public int SearchEmpty()
|
|
{
|
|
for (int i = 0; i < m_aItems.Length; i++)
|
|
{
|
|
if (m_aItems[i] == null)
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
public int GetEmptySlotNum()
|
|
{
|
|
int count = 0;
|
|
for (int i = 0; i < m_aItems.Length; i++)
|
|
{
|
|
if (m_aItems[i] == null)
|
|
count++;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
public int CanAddItem(int idItem, int iAmount, bool tryPile)
|
|
{
|
|
int foundEmpty = -1;
|
|
for (int i = 0; i < m_aItems.Length; i++)
|
|
{
|
|
var pItem = m_aItems[i];
|
|
if (pItem == null)
|
|
{
|
|
if (!tryPile) return i;
|
|
if (foundEmpty < 0) foundEmpty = i;
|
|
}
|
|
else if (pItem.GetTemplateID() == idItem)
|
|
{
|
|
int pileLimit = Math.Max(1, EC_IvtrItem.GetPileLimit(idItem));
|
|
if (pItem.GetCount() + iAmount <= pileLimit)
|
|
return i;
|
|
}
|
|
}
|
|
return foundEmpty;
|
|
}
|
|
|
|
public int GetSize()
|
|
{
|
|
return m_aItems.Length;
|
|
}
|
|
// Unfreeze all items
|
|
public void UnfreezeAllItems()
|
|
{
|
|
// Release all items
|
|
for (int i=0; i < m_aItems.Length; i++)
|
|
{
|
|
if (m_aItems[i] != null)
|
|
m_aItems[i].Freeze(false);
|
|
}
|
|
}
|
|
}
|
|
}
|