Add quick sort item feature

This commit is contained in:
HungDK
2026-05-19 11:26:11 +07:00
parent 5376b6ad8c
commit 69575c9489
7 changed files with 357 additions and 8 deletions
+208
View File
@@ -0,0 +1,208 @@
using BrewMonster.Network;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using System.Collections.Generic;
using static BrewMonster.Scripts.EC_Inventory;
namespace BrewMonster
{
public partial class CECHostPlayer
{
/// <summary>
/// C++ CECHostPlayer::SortPack — reorder pack via MULTI_EXCHANGE_ITEM (DlgInventory OnCommand_arrange).
/// </summary>
public void SortPack(int iPack)
{
EC_Inventory pInventory = GetPack(iPack);
if (pInventory == null)
return;
int nIvtrSize = pInventory.GetSize();
if (nIvtrSize <= 0)
return;
if (pInventory.GetEmptySlotNum() == nIvtrSize)
return;
for (int i = 0; i < nIvtrSize; i++)
{
var pItem = pInventory.GetItem(i, false);
if (pItem != null && pItem.IsFrozen())
return;
}
for (int i = 0; i < nIvtrSize; i++)
{
var pItem = pInventory.GetItem(i, false);
pItem?.Freeze(true);
}
try
{
var vecItem = new List<int>(nIvtrSize);
for (int i = 0; i < nIvtrSize; i++)
vecItem.Add(i);
vecItem.Sort((a, b) => ComparePackSortIndices(pInventory, a, b));
var vecExchange = new List<int>();
int pos = 0;
while (pos < nIvtrSize)
{
int j = vecItem[pos];
if (j == pos)
{
pos++;
continue;
}
int k = vecItem[j];
if (pInventory.GetItem(j, false) != null || pInventory.GetItem(k, false) != null)
{
vecExchange.Add(pos);
vecExchange.Add(j);
}
int tmp = vecItem[pos];
vecItem[pos] = vecItem[j];
vecItem[j] = tmp;
}
if (vecExchange.Count > 0)
{
int pairCount = vecExchange.Count / 2;
for (int i = 0, j = vecExchange.Count - 1; i < j; i++, j--)
{
int t = vecExchange[i];
vecExchange[i] = vecExchange[j];
vecExchange[j] = t;
}
UnityGameSession.RequestMultiExchangeItem((byte)iPack, pairCount, vecExchange.ToArray());
}
else
{
var pGameRun = EC_Game.GetGameRun();
pGameRun?.AddChatMessage("Không cần sắp xếp kho đồ.", (int)ChatChannel.GP_CHAT_SYSTEM);
}
}
finally
{
for (int i = 0; i < nIvtrSize; i++)
{
var pItem = pInventory.GetItem(i, false);
pItem?.Freeze(false);
}
}
}
private static int ComparePackSortIndices(EC_Inventory pInventory, int index1, int index2)
{
if (DefaultPackSortLess(pInventory, index1, index2))
return -1;
if (DefaultPackSortLess(pInventory, index2, index1))
return 1;
return 0;
}
/// <summary>Returns true when slot <paramref name="index1"/> should appear before <paramref name="index2"/>.</summary>
private static bool DefaultPackSortLess(EC_Inventory pInventory, int index1, int index2)
{
if (pInventory == null)
return false;
EC_IvtrItem pItem1 = pInventory.GetItem(index1, false);
EC_IvtrItem pItem2 = pInventory.GetItem(index2, false);
if (pItem1 == null)
return false;
if (pItem2 == null)
return true;
int cid1 = pItem1.GetClassID();
int tid1 = pItem1.GetTemplateID();
int cid2 = pItem2.GetClassID();
int tid2 = pItem2.GetTemplateID();
if (cid1 != cid2)
{
int cidOrder1 = GetPackSortClassOrder(cid1);
int cidOrder2 = GetPackSortClassOrder(cid2);
if (cidOrder1 != cidOrder2)
return cidOrder1 > cidOrder2;
return cid1 < cid2;
}
if (cid1 == (int)EC_IvtrItem.InventoryClassId.ICID_WEAPON)
{
if (pItem1 is CECIvtrWeapon w1 && pItem2 is CECIvtrWeapon w2)
{
var e1 = w1.GetDBEssence();
var e2 = w2.GetDBEssence();
if (e1.level != e2.level)
return e1.level > e2.level;
}
}
else if (cid1 == (int)EC_IvtrItem.InventoryClassId.ICID_ARMOR)
{
if (pItem1 is EC_IvtrArmor a1 && pItem2 is EC_IvtrArmor a2)
{
var e1 = a1.GetDBEssence();
var e2 = a2.GetDBEssence();
if (e1.level != e2.level)
return e1.level > e2.level;
}
}
else if (cid1 == (int)EC_IvtrItem.InventoryClassId.ICID_GENERALCARD)
{
if (pItem1 is EC_IvtrGeneralCard c1 && pItem2 is EC_IvtrGeneralCard c2)
{
int t1 = c1.GetEssence().type;
int t2 = c2.GetEssence().type;
if (t1 != t2)
return t1 < t2;
}
}
return tid1 < tid2;
}
private static int GetPackSortClassOrder(int cid)
{
int[] s_CIDs =
{
(int)EC_IvtrItem.InventoryClassId.ICID_WEAPON,
(int)EC_IvtrItem.InventoryClassId.ICID_ARROW,
(int)EC_IvtrItem.InventoryClassId.ICID_TOSSMAT,
(int)EC_IvtrItem.InventoryClassId.ICID_ARMOR,
(int)EC_IvtrItem.InventoryClassId.ICID_DECORATION,
(int)EC_IvtrItem.InventoryClassId.ICID_BIBLE,
(int)EC_IvtrItem.InventoryClassId.ICID_FLYSWORD,
(int)EC_IvtrItem.InventoryClassId.ICID_WING,
(int)EC_IvtrItem.InventoryClassId.ICID_GOBLIN,
(int)EC_IvtrItem.InventoryClassId.ICID_GOBLIN_EQUIP,
(int)EC_IvtrItem.InventoryClassId.ICID_FASHION,
(int)EC_IvtrItem.InventoryClassId.ICID_AUTOHP,
(int)EC_IvtrItem.InventoryClassId.ICID_AUTOMP,
(int)EC_IvtrItem.InventoryClassId.ICID_MEDICINE,
(int)EC_IvtrItem.InventoryClassId.ICID_SKILLMATTER,
(int)EC_IvtrItem.InventoryClassId.ICID_TARGETITEM,
(int)EC_IvtrItem.InventoryClassId.ICID_STONE,
(int)EC_IvtrItem.InventoryClassId.ICID_PETEGG,
(int)EC_IvtrItem.InventoryClassId.ICID_REFINETICKET,
(int)EC_IvtrItem.InventoryClassId.ICID_DYETICKET,
(int)EC_IvtrItem.InventoryClassId.ICID_GOBLIN_EXPPILL,
(int)EC_IvtrItem.InventoryClassId.ICID_GENERALCARD,
(int)EC_IvtrItem.InventoryClassId.ICID_GENERALCARD_DICE,
};
for (int i = 0; i < s_CIDs.Length; i++)
{
if (cid == s_CIDs[i])
return s_CIDs.Length - i;
}
return 0;
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 22d7c6cd009100d44956b805ed093795