initial load all equipments

This commit is contained in:
Le Duc Anh
2025-11-05 16:08:51 +07:00
parent 07f7a36b08
commit f338899f76
16 changed files with 341 additions and 119 deletions
+5
View File
@@ -0,0 +1,5 @@
{
"recommendations": [
"visualstudiotoolsforunity.vstuc"
]
}
+15
View File
@@ -0,0 +1,15 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to Unity",
"type": "unity",
"request": "attach"
},
{
"name": "Attach to Unity",
"type": "vstuc",
"request": "attach"
}
]
}
+60
View File
@@ -0,0 +1,60 @@
{
"files.exclude": {
"**/.DS_Store": true,
"**/.git": true,
"**/.vs": true,
"**/.gitmodules": true,
"**/.vsconfig": true,
"**/*.booproj": true,
"**/*.pidb": true,
"**/*.suo": true,
"**/*.user": true,
"**/*.userprefs": true,
"**/*.unityproj": true,
"**/*.dll": true,
"**/*.exe": true,
"**/*.pdf": true,
"**/*.mid": true,
"**/*.midi": true,
"**/*.wav": true,
"**/*.gif": true,
"**/*.ico": true,
"**/*.jpg": true,
"**/*.jpeg": true,
"**/*.png": true,
"**/*.psd": true,
"**/*.tga": true,
"**/*.tif": true,
"**/*.tiff": true,
"**/*.3ds": true,
"**/*.3DS": true,
"**/*.fbx": true,
"**/*.FBX": true,
"**/*.lxo": true,
"**/*.LXO": true,
"**/*.ma": true,
"**/*.MA": true,
"**/*.obj": true,
"**/*.OBJ": true,
"**/*.asset": true,
"**/*.cubemap": true,
"**/*.flare": true,
"**/*.mat": true,
"**/*.meta": true,
"**/*.prefab": true,
"**/*.unity": true,
"build/": true,
"Build/": true,
"Library/": true,
"library/": true,
"obj/": true,
"Obj/": true,
"Logs/": true,
"logs/": true,
"ProjectSettings/": true,
"UserSettings/": true,
"temp/": true,
"Temp/": true
},
"dotnet.defaultSolution": "perfect-world-unity.sln"
}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 55413edee9f1ea349b29d665bb3e34f3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,65 @@
namespace BrewMonster.Scripts
{
public class InventoryConst
{
// Index of item in equipment inventory
public static int EQUIPIVTR_WEAPON = 0;
public static int EQUIPIVTR_HEAD = 1;
public static int EQUIPIVTR_NECK = 2;
public static int EQUIPIVTR_SHOULDER = 3;
public static int EQUIPIVTR_BODY = 4;
public static int EQUIPIVTR_WAIST = 5;
public static int EQUIPIVTR_LEG = 6;
public static int EQUIPIVTR_FOOT = 7;
public static int EQUIPIVTR_WRIST = 8;
public static int EQUIPIVTR_FINGER1 = 9;
public static int EQUIPIVTR_FINGER2 = 10;
public static int EQUIPIVTR_PROJECTILE = 11;
public static int EQUIPIVTR_FLYSWORD = 12;
public static int EQUIPIVTR_FASHION_BODY = 13;
public static int EQUIPIVTR_FASHION_LEG = 14;
public static int EQUIPIVTR_FASHION_FOOT = 15;
public static int EQUIPIVTR_FASHION_WRIST = 16;
public static int EQUIPIVTR_RUNE = 17;
public static int EQUIPIVTR_BIBLE = 18;
public static int EQUIPIVTR_SPEAKER = 19;
public static int EQUIPIVTR_AUTOHP = 20;
public static int EQUIPIVTR_AUTOMP = 21;
public static int EQUIPIVTR_POCKET = 22;
public static int EQUIPIVTR_GOBLIN = 23;
public static int EQUIPIVTR_CERTIFICATE = 24;
public static int EQUIPIVTR_FASHION_HEAD = 25;
public static int EQUIPIVTR_FORCE_TOKEN = 26;
public static int EQUIPIVTR_DYNSKILLEQUIP1 = 27;
public static int EQUIPIVTR_DYNSKILLEQUIP2 = 28;
public static int EQUIPIVTR_FASHION_WEAPON = 29;
public static int SIZE_EQUIPIVTR = 30;
public static int EQUIPIVTR_UNUSED1 = 30;
public static int EQUIPIVTR_UNUSED2 = 31;
public static int EQUIPIVTR_GENERALCARD1 = 32;
public static int EQUIPIVTR_GENERALCARD2 = 33;
public static int EQUIPIVTR_GENERALCARD3 = 34;
public static int EQUIPIVTR_GENERALCARD4 = 35;
public static int EQUIPIVTR_GENERALCARD5 = 36;
public static int EQUIPIVTR_GENERALCARD6 = 37;
public static int SIZE_ALL_EQUIPIVTR = 38;
public static int SIZE_GENERALCARD_EQUIPIVTR = 6; // SIZE_ALL_EQUIPIVTR - EQUIPIVTR_GENERALCARD1
// Inventory size constants
public static int IVTRSIZE_EQUIPPACK = 32; // Equipment (SIZE_ALL_EQUIPIVTR)
public static int IVTRSIZE_TASKPACK = 32; // Task pack
public static int IVTRSIZE_DEALPACK = 24; // Deal pack
public static int IVTRSIZE_NPCPACK = 32; // NPC pack
public static int IVTRSIZE_TRASHBOX = 16; // Trash box
public static int IVTRSIZE_BUYPACK = 12; // Buy pack
public static int IVTRSIZE_SELLPACK = 12; // Sell pack
public static int IVTRSIZE_BOOTHSPACK = 12; // Default booth pack for selling
public static int IVTRSIZE_BOOTHBPACK = 12; // Default booth pack for buying
public static int IVTRSIZE_BOOTHSPACK_MAX = 20; // Max booth pack for selling (player may use certificate...)
public static int IVTRSIZE_BOOTHBPACK_MAX = 20; // Max booth pack for buying
public static int IVTRSIZE_CLIENTCARDPACK = 32; // Client pack for general card collection
public static int NUM_NPCIVTR = 8; // NPC inventory number
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 7aaaaba042d177642850cd76fced3c78
@@ -8,21 +8,21 @@ namespace BrewMonster.Scripts.Managers
public static class EC_Inventory
{
private static readonly Dictionary<byte, int> _packSizeByPackage = new Dictionary<byte, int>();
private static readonly Dictionary<byte, Dictionary<int, InventoryItemData>> _itemsByPackage = new Dictionary<byte, Dictionary<int, InventoryItemData>>();
private static readonly Dictionary<byte, Dictionary<int, EC_IvtrItem>> _itemsByPackage = new Dictionary<byte, Dictionary<int, EC_IvtrItem>>();
private const int MaxContentHexToLog = 64;
// Package constants to mirror legacy C++ names
public const byte PACK_INVENTORY = 0;
public const byte PACK_EQUIPMENT = 1;
public const byte PACK_TASKINVENTORY = 2;
public const byte IVTRTYPE_PACK = 0;
public const byte IVTRTYPE_EQUIPPACK = 1;
public const byte IVTRTYPE_TASKPACK = 2;
private static string GetPackageName(byte pkg)
{
switch (pkg)
{
case 0: return "PACK_INVENTORY";
case 1: return "PACK_EQUIPMENT";
case 2: return "PACK_TASKINVENTORY";
case 0: return "IVTRTYPE_PACK";
case 1: return "IVTRTYPE_EQUIPPACK";
case 2: return "IVTRTYPE_TASKPACK";
default: return "PACK_UNKNOWN";
}
}
@@ -36,13 +36,18 @@ namespace BrewMonster.Scripts.Managers
return hex;
}
public static InventoryItemData GetItem(int iSlot, bool bRemove)
public static Dictionary<int, EC_IvtrItem> GetPack(byte byPackage)
{
// Backward-compatible overload defaulting to inventory package
return GetItem(PACK_INVENTORY, iSlot, bRemove);
return _itemsByPackage[byPackage];
}
public static InventoryItemData GetItem(byte byPackage, int slot, bool remove)
public static EC_IvtrItem GetItem(int iSlot, bool bRemove)
{
// Backward-compatible overload defaulting to inventory package
return GetItem(IVTRTYPE_PACK, iSlot, bRemove);
}
public static EC_IvtrItem GetItem(byte byPackage, int slot, bool remove)
{
if (!_itemsByPackage.TryGetValue(byPackage, out var slots) || slot < 0)
return null;
@@ -53,11 +58,11 @@ namespace BrewMonster.Scripts.Managers
return item;
}
private static Dictionary<int, InventoryItemData> EnsureSlots(byte byPackage)
private static Dictionary<int, EC_IvtrItem> EnsureSlots(byte byPackage)
{
if (!_itemsByPackage.TryGetValue(byPackage, out var slots) || slots == null)
{
slots = new Dictionary<int, InventoryItemData>();
slots = new Dictionary<int, EC_IvtrItem>();
_itemsByPackage[byPackage] = slots;
}
return slots;
@@ -69,7 +74,7 @@ namespace BrewMonster.Scripts.Managers
EnsureSlots(byPackage);
}
public static InventoryItemData PutItem(byte byPackage, int slot, InventoryItemData item)
public static EC_IvtrItem PutItem(byte byPackage, int slot, EC_IvtrItem item)
{
var slots = EnsureSlots(byPackage);
if (slot < 0) return null;
@@ -78,7 +83,7 @@ namespace BrewMonster.Scripts.Managers
return oldItem;
}
public static void SetItem(byte byPackage, int slot, InventoryItemData item)
public static void SetItem(byte byPackage, int slot, EC_IvtrItem item)
{
var slots = EnsureSlots(byPackage);
if (slot < 0) return;
@@ -100,8 +105,8 @@ namespace BrewMonster.Scripts.Managers
var slots = EnsureSlots(byPackage);
if (!slots.TryGetValue(slot, out var item) || item == null)
return true;
int newCount = Math.Max(0, item.Count - Math.Max(0, amount));
item.Count = newCount;
int newCount = Math.Max(0, item.m_iCount - Math.Max(0, amount));
item.m_iCount = newCount;
if (newCount <= 0)
slots.Remove(slot);
else
@@ -139,7 +144,7 @@ namespace BrewMonster.Scripts.Managers
if (baseIdx < 0) baseIdx = 0;
for (int i = baseIdx; i < size; i++)
{
if (slots.TryGetValue(i, out var it) && it != null && it.TemplateId == templateId)
if (slots.TryGetValue(i, out var it) && it != null && it.m_tid == templateId)
return i;
}
return -1;
@@ -151,8 +156,8 @@ namespace BrewMonster.Scripts.Managers
foreach (var kv in EnsureSlots(byPackage))
{
var it = kv.Value;
if (it != null && it.TemplateId == templateId)
total += Math.Max(0, it.Count);
if (it != null && it.m_tid == templateId)
total += Math.Max(0, it.m_iCount);
}
return total;
}
@@ -163,10 +168,10 @@ namespace BrewMonster.Scripts.Managers
foreach (var kv in EnsureSlots(byPackage))
{
var it = kv.Value;
if (it != null && it.TemplateId == templateId)
if (it != null && it.m_tid == templateId)
{
int pileLimit = Math.Max(1, EC_IvtrItem.GetPileLimit(templateId));
ret += Math.Max(0, pileLimit - Math.Max(0, it.Count));
int pileLimit = Math.Max(1, EC_IvtrItemUtils.GetPileLimit(templateId));
ret += Math.Max(0, pileLimit - Math.Max(0, it.m_iCount));
}
}
return ret;
@@ -175,7 +180,7 @@ namespace BrewMonster.Scripts.Managers
public static int CanAddItem(byte byPackage, int templateId, int amount, bool tryPile)
{
int firstEmpty = -1;
int pileLimit = Math.Max(1, EC_IvtrItem.GetPileLimit(templateId));
int pileLimit = Math.Max(1, EC_IvtrItemUtils.GetPileLimit(templateId));
int size = _packSizeByPackage.TryGetValue(byPackage, out var s) ? s : 0;
var slots = EnsureSlots(byPackage);
for (int i = 0; i < size; i++)
@@ -185,7 +190,7 @@ namespace BrewMonster.Scripts.Managers
if (!tryPile) return i;
if (firstEmpty < 0) firstEmpty = i;
}
else if (it.TemplateId == templateId && it.Count + amount <= pileLimit)
else if (it.m_tid == templateId && it.m_iCount + amount <= pileLimit)
{
return i;
}
@@ -198,7 +203,7 @@ namespace BrewMonster.Scripts.Managers
lastSlot = -1;
slotAmount = 0;
var slots = EnsureSlots(byPackage);
int pileLimit = Math.Max(1, EC_IvtrItem.GetPileLimit(templateId));
int pileLimit = Math.Max(1, EC_IvtrItemUtils.GetPileLimit(templateId));
int firstEmpty = -1;
int size = _packSizeByPackage.TryGetValue(byPackage, out var s) ? s : 0;
for (int i = 0; i < size && amount > 0; i++)
@@ -209,25 +214,25 @@ namespace BrewMonster.Scripts.Managers
if (firstEmpty < 0) firstEmpty = i;
continue;
}
if (slotItem.TemplateId != templateId) continue;
int canAdd = Math.Max(0, pileLimit - Math.Max(0, slotItem.Count));
if (slotItem.m_tid != templateId) continue;
int canAdd = Math.Max(0, pileLimit - Math.Max(0, slotItem.m_iCount));
if (canAdd <= 0) continue;
int add = Math.Min(canAdd, amount);
slotItem.Count += add;
slotItem.m_iCount += add;
amount -= add;
lastSlot = i;
slotAmount = slotItem.Count;
slotAmount = slotItem.m_iCount;
}
if (amount <= 0) return true;
if (firstEmpty < 0) return false;
var newItem = new InventoryItemData
var newItem = new EC_IvtrItem
{
Package = byPackage,
Slot = firstEmpty,
TemplateId = templateId,
ExpireDate = expireDate,
m_tid = templateId,
m_expire_date = expireDate,
State = 0,
Count = amount,
m_iCount = amount,
Crc = 0,
Content = null
};
@@ -248,14 +253,14 @@ namespace BrewMonster.Scripts.Managers
slots.TryGetValue(dest, out var dstItem);
if (dstItem == null)
{
var clone = new InventoryItemData
var clone = new EC_IvtrItem
{
Package = byPackage,
Slot = dest,
TemplateId = srcItem.TemplateId,
ExpireDate = srcItem.ExpireDate,
m_tid = srcItem.m_tid,
m_expire_date = srcItem.m_expire_date,
State = srcItem.State,
Count = amount,
m_iCount = amount,
Crc = srcItem.Crc,
Content = srcItem.Content != null ? (byte[])srcItem.Content.Clone() : null
};
@@ -263,23 +268,23 @@ namespace BrewMonster.Scripts.Managers
}
else
{
if (dstItem.TemplateId != srcItem.TemplateId) return false;
int pileLimit = Math.Max(1, EC_IvtrItem.GetPileLimit(dstItem.TemplateId));
int canAdd = Math.Max(0, pileLimit - Math.Max(0, dstItem.Count));
if (dstItem.m_tid != srcItem.m_tid) return false;
int pileLimit = Math.Max(1, EC_IvtrItemUtils.GetPileLimit(dstItem.m_tid));
int canAdd = Math.Max(0, pileLimit - Math.Max(0, dstItem.m_iCount));
int add = Math.Min(canAdd, amount);
if (add <= 0) return false;
dstItem.Count += add;
dstItem.m_iCount += add;
amount = add;
}
RemoveItem(byPackage, src, amount);
return true;
}
public static void UpdatePack(byte byPackage, int ivtrSize, IEnumerable<InventoryItemData> items)
public static void UpdatePack(byte byPackage, int ivtrSize, IEnumerable<EC_IvtrItem> items)
{
_packSizeByPackage[byPackage] = ivtrSize;
if (!_itemsByPackage.TryGetValue(byPackage, out var slots))
{
slots = new Dictionary<int, InventoryItemData>();
slots = new Dictionary<int, EC_IvtrItem>();
_itemsByPackage[byPackage] = slots;
}
slots.Clear();
@@ -306,7 +311,7 @@ namespace BrewMonster.Scripts.Managers
RemoveAllItems(byPackage);
return true;
}
if (!EC_IvtrItem.TryParseInventoryDetail(data, out var pkg, out var size, out var items))
if (!EC_IvtrItemUtils.TryParseInventoryDetail(data, out var pkg, out var size, out var items))
return false;
// Prefer header values when valid
byte finalPkg = byPackage;
@@ -317,7 +322,7 @@ namespace BrewMonster.Scripts.Managers
}
private static void LogPackInternal(byte byPackage, int ivtrSize, IReadOnlyDictionary<int, InventoryItemData> slots)
private static void LogPackInternal(byte byPackage, int ivtrSize, IReadOnlyDictionary<int, EC_IvtrItem> slots)
{
//Debug.Log($"[Inventory] === Pack {GetPackageName(byPackage)}({byPackage}) size={ivtrSize}, items={(slots?.Count ?? 0)} ===");
if (slots == null || slots.Count == 0)
@@ -328,8 +333,8 @@ namespace BrewMonster.Scripts.Managers
foreach (var kv in slots)
{
var it = kv.Value;
string itemName = EC_IvtrItem.ResolveItemName(it.TemplateId);
string extraHex = it.Content != null && it.Content.Length > 0 ? EC_IvtrItem.BytesToHex(it.Content, MaxContentHexToLog) : "";
string itemName = EC_IvtrItemUtils.ResolveItemName(it.m_tid);
string extraHex = it.Content != null && it.Content.Length > 0 ? EC_IvtrItemUtils.BytesToHex(it.Content, MaxContentHexToLog) : "";
//int extraLen = it.Content?.Length ?? 0;
//Debug.Log(
// $"[Inventory] pkg={GetPackageName(it.Package)}({it.Package}) slot={it.Slot} tid={it.TemplateId}{(string.IsNullOrEmpty(itemName) ? "" : " \"" + itemName + "\"")} count={it.Count} state={it.State} expire={it.ExpireDate} crc={it.Crc} content_len={extraLen}{(extraLen > 0 ? ", content_hex=" + extraHex : "")}"
@@ -173,7 +173,7 @@ namespace BrewMonster.Scripts.Managers
// Current selected item for equip/unequip operations
private byte currentSelectedPackage;
private int currentSelectedSlot;
private InventoryItemData currentSelectedItem;
private EC_IvtrItem currentSelectedItem;
private EC_IvtrEquip currentSelectedEquipment;
private const byte PKG_INVENTORY = 0;
@@ -356,16 +356,16 @@ namespace BrewMonster.Scripts.Managers
/// <summary>
/// Create EC_IvtrEquip object from InventoryItemData
/// </summary>
private EC_IvtrEquip CreateEquipmentFromItemData(InventoryItemData itemData)
private EC_IvtrEquip CreateEquipmentFromItemData(EC_IvtrItem itemData)
{
if (itemData == null)
return null;
var equipment = new EC_IvtrEquip(itemData.TemplateId, itemData.ExpireDate);
var equipment = new EC_IvtrEquip(itemData.m_tid, itemData.m_expire_date);
// Set basic properties (use default values since InventoryItemData doesn't have these)
equipment.Price = 0;
equipment.Count = itemData.Count;
equipment.Count = itemData.m_iCount;
equipment.PriceScale = 1.0f;
equipment.ScaleType = 0;
@@ -378,17 +378,17 @@ namespace BrewMonster.Scripts.Managers
return equipment;
}
private string GetDisplayTextForItem(int slot, InventoryItemData itemData)
private string GetDisplayTextForItem(int slot, EC_IvtrItem itemData)
{
if (itemData == null || itemData.Count <= 0)
if (itemData == null || itemData.m_iCount <= 0)
{
return string.Empty;
}
string itemName = EC_IvtrItem.ResolveItemName(itemData.TemplateId);
string displayText = string.IsNullOrEmpty(itemName) ? $"Item {itemData.TemplateId}" : itemName;
if (itemData.Count > 1)
string itemName = EC_IvtrItemUtils.ResolveItemName(itemData.m_tid);
string displayText = string.IsNullOrEmpty(itemName) ? $"Item {itemData.m_tid}" : itemName;
if (itemData.m_iCount > 1)
{
displayText += $" x{itemData.Count}";
displayText += $" x{itemData.m_iCount}";
}
return displayText;
}
@@ -466,17 +466,17 @@ namespace BrewMonster.Scripts.Managers
// For equipping, we need to find an empty equipment slot
// Use the new method that checks for available slots (especially for finger items)
byte equipLocation = EC_IvtrType.GetAvailableEquipLocationForItem(currentSelectedItem.TemplateId);
byte equipLocation = EC_IvtrType.GetAvailableEquipLocationForItem(currentSelectedItem.m_tid);
if (equipLocation >= (byte)IndexOfIteminEquipmentInventory.SIZE_EQUIPIVTR)
{
Debug.LogWarning($"[InventoryUI] Could not determine equip location for item {currentSelectedItem.TemplateId}");
Debug.LogWarning($"[InventoryUI] Could not determine equip location for item {currentSelectedItem.m_tid}");
return;
}
// Call RequestEquipItemAsync with inventory slot and equip location
UnityGameSession.RequestEquipItemAsync((byte)currentSelectedSlot, equipLocation, () =>
{
Debug.Log($"[InventoryUI] Equip request sent for item {currentSelectedItem.TemplateId} from slot {currentSelectedSlot} to equip location {equipLocation}");
Debug.Log($"[InventoryUI] Equip request sent for item {currentSelectedItem.m_tid} from slot {currentSelectedSlot} to equip location {equipLocation}");
// Refresh inventory after equip
RefreshAll();
});
@@ -501,7 +501,7 @@ namespace BrewMonster.Scripts.Managers
// Call RequestEquipItemAsync with empty inventory slot and current equip location
UnityGameSession.RequestEquipItemAsync((byte)emptySlot, equipLocation, () =>
{
Debug.Log($"[InventoryUI] Unequip request sent for item {currentSelectedItem.TemplateId} from equip location {equipLocation} to inventory slot {emptySlot}");
Debug.Log($"[InventoryUI] Unequip request sent for item {currentSelectedItem.m_tid} from equip location {equipLocation} to inventory slot {emptySlot}");
// Refresh inventory after unequip
RefreshAll();
});
@@ -513,7 +513,7 @@ namespace BrewMonster.Scripts.Managers
// Call RequestDropIvrtItem with slot index and amount
UnityGameSession.RequestDropIvrtItem((byte)currentSelectedSlot, 1);
Debug.Log($"[InventoryUI] Drop request sent for inventory item {currentSelectedItem.TemplateId} from slot {currentSelectedSlot} with amount {currentSelectedItem.Count}");
Debug.Log($"[InventoryUI] Drop request sent for inventory item {currentSelectedItem.m_tid} from slot {currentSelectedSlot} with amount {currentSelectedItem.m_iCount}");
// Refresh inventory after drop
RefreshAll();
@@ -525,7 +525,7 @@ namespace BrewMonster.Scripts.Managers
// Call RequestDropEquipItem with slot index
UnityGameSession.RequestDropEquipItem((byte)currentSelectedSlot);
Debug.Log($"[InventoryUI] Drop request sent for equipment item {currentSelectedItem.TemplateId} from slot {currentSelectedSlot}");
Debug.Log($"[InventoryUI] Drop request sent for equipment item {currentSelectedItem.m_tid} from slot {currentSelectedSlot}");
// Refresh inventory after drop
RefreshAll();
@@ -666,22 +666,22 @@ namespace BrewMonster.Scripts.Managers
}
}
public Dictionary<int, InventoryItemData> GetInventoryData(byte package)
public Dictionary<int, EC_IvtrItem> GetInventoryData(byte package)
{
if (itemsByPackageField == null)
{
return new Dictionary<int, InventoryItemData>();
return new Dictionary<int, EC_IvtrItem>();
}
var itemsByPackage = itemsByPackageField.GetValue(null) as Dictionary<byte, Dictionary<int, InventoryItemData>>;
var itemsByPackage = itemsByPackageField.GetValue(null) as Dictionary<byte, Dictionary<int, EC_IvtrItem>>;
if (itemsByPackage == null)
{
return new Dictionary<int, InventoryItemData>();
return new Dictionary<int, EC_IvtrItem>();
}
if (itemsByPackage.TryGetValue(package, out var packageItems))
{
return packageItems;
}
return new Dictionary<int, InventoryItemData>();
return new Dictionary<int, EC_IvtrItem>();
}
}
@@ -690,7 +690,7 @@ namespace BrewMonster.Scripts.Managers
{
private static readonly Dictionary<Image, Sprite> _defaultSprites = new Dictionary<Image, Sprite>();
public void RenderPackage(List<Button> buttons, Dictionary<int, InventoryItemData> items, byte package, System.Action<byte, int> onClick, System.Func<int, InventoryItemData, string> getDisplayText)
public void RenderPackage(List<Button> buttons, Dictionary<int, EC_IvtrItem> items, byte package, System.Action<byte, int> onClick, System.Func<int, EC_IvtrItem, string> getDisplayText)
{
if (buttons == null)
{
@@ -705,7 +705,7 @@ namespace BrewMonster.Scripts.Managers
continue;
}
InventoryItemData itemData = null;
EC_IvtrItem itemData = null;
bool hasItem = items != null && items.TryGetValue(slot, out itemData);
button.onClick.RemoveAllListeners();
int capturedSlot = slot;
@@ -721,9 +721,9 @@ namespace BrewMonster.Scripts.Managers
}
// Set icon sprite based on item TemplateId
if (hasItem && itemData != null && itemData.Count > 0)
if (hasItem && itemData != null && itemData.m_iCount > 0)
{
var sprite = EC_IvtrItem.ResolveItemIconSprite(itemData.TemplateId);
var sprite = EC_IvtrItemUtils.ResolveItemIconSprite(itemData.m_tid);
image.sprite = sprite;
image.enabled = true;
}
@@ -897,7 +897,7 @@ namespace BrewMonster.Scripts.Managers
panelRect.anchoredPosition = finalPos;
}
private void FillDetailPanel(byte package, InventoryItemData item)
private void FillDetailPanel(byte package, EC_IvtrItem item)
{
if (item == null)
{
@@ -906,24 +906,24 @@ namespace BrewMonster.Scripts.Managers
}
// Get user-friendly text from string tables
string itemName = EC_IvtrItem.ResolveItemName(item.TemplateId);
string itemDescription = GetItemDescription(item.TemplateId);
string itemExtendedDesc = GetItemExtendedDescription(item.TemplateId);
string itemName = EC_IvtrItemUtils.ResolveItemName(item.m_tid);
string itemDescription = GetItemDescription(item.m_tid);
string itemExtendedDesc = GetItemExtendedDescription(item.m_tid);
// Display basic content
nameText?.Set(string.IsNullOrEmpty(itemName) ? $"Item {item.TemplateId}" : itemName);
nameText?.Set(string.IsNullOrEmpty(itemName) ? $"Item {item.m_tid}" : itemName);
descriptionText?.Set(itemDescription ?? "No description available");
extendedDescText?.Set(itemExtendedDesc ?? "");
countText?.Set($"Count: {item.Count}");
countText?.Set($"Count: {item.m_iCount}");
// Format state properly
string stateTextValue = GetItemStateText(item.State);
stateText?.Set(stateTextValue);
// Format expiration date properly
if (item.ExpireDate > 0)
if (item.m_expire_date > 0)
{
DateTime expireDate = DateTimeOffset.FromUnixTimeSeconds(item.ExpireDate).DateTime;
DateTime expireDate = DateTimeOffset.FromUnixTimeSeconds(item.m_expire_date).DateTime;
expireText?.Set($"Expires: {expireDate:yyyy-MM-dd HH:mm}");
}
else
@@ -1075,7 +1075,7 @@ namespace BrewMonster.Scripts.Managers
foreach (int holeTid in currentSelectedEquipment.Holes)
{
if (holeTid == 0) continue;
string stoneName = EC_IvtrItem.ResolveItemName(holeTid);
string stoneName = EC_IvtrItemUtils.ResolveItemName(holeTid);
// Try to fetch a description from string tables; fallback to name if unavailable
string stoneDesc = GetItemDescription(holeTid) ?? stoneName;
if (!string.IsNullOrEmpty(stoneName))
@@ -1169,7 +1169,7 @@ namespace BrewMonster.Scripts.Managers
suiteText?.Set("");
}
private void SetupEquipButton(byte package, InventoryItemData item)
private void SetupEquipButton(byte package, EC_IvtrItem item)
{
if (equipButton == null) return;
@@ -1219,7 +1219,7 @@ namespace BrewMonster.Scripts.Managers
}
}
private void SetupDropButton(byte package, InventoryItemData item)
private void SetupDropButton(byte package, EC_IvtrItem item)
{
if (dropButton == null) return;
@@ -735,7 +735,7 @@ namespace PerfectWorld.Scripts.Managers
/// </summary>
public string GetName()
{
return EC_IvtrItem.ResolveItemName(TemplateId);
return EC_IvtrItemUtils.ResolveItemName(TemplateId);
}
/// <summary>
@@ -2386,7 +2386,7 @@ namespace PerfectWorld.Scripts.Managers
continue;
// Get item name
string itemName = EC_IvtrItem.ResolveItemName(hole);
string itemName = EC_IvtrItemUtils.ResolveItemName(hole);
string descText = "null";
// This would normally check if it's a stone and get its description
@@ -10,20 +10,20 @@ using UnityEngine;
namespace BrewMonster.Scripts.Managers
{
public class InventoryItemData
public class EC_IvtrItem
{
public byte Package;
public int Slot;
public int TemplateId;
public int ExpireDate;
public int m_tid;
public int m_expire_date;
public int State;
public int Count;
public int m_iCount;
public ushort Crc;
public byte[] Content; // variable-length item-specific payload (can be null)
}
public static class EC_IvtrItem
public static class EC_IvtrItemUtils
{
private static readonly Dictionary<int, string> _tidNameCache = new Dictionary<int, string>();
private static readonly Dictionary<int, int> _pileLimitCache = new Dictionary<int, int>();
@@ -376,7 +376,7 @@ namespace BrewMonster.Scripts.Managers
return "";
}
public static bool TryParseInventoryDetail(byte[] buffer, out byte byPackage, out byte ivtrSize, out List<InventoryItemData> items)
public static bool TryParseInventoryDetail(byte[] buffer, out byte byPackage, out byte ivtrSize, out List<EC_IvtrItem> items)
{
byPackage = 0;
ivtrSize = 0;
@@ -399,7 +399,7 @@ namespace BrewMonster.Scripts.Managers
}
if (contentBytes <= 0)
{
items = new List<InventoryItemData>();
items = new List<EC_IvtrItem>();
return true;
}
@@ -413,7 +413,7 @@ namespace BrewMonster.Scripts.Managers
return false;
}
int numItems = BitConverter.ToInt32(content, ci); ci += 4;
items = new List<InventoryItemData>(numItems > 0 ? numItems : 0);
items = new List<EC_IvtrItem>(numItems > 0 ? numItems : 0);
for (int i = 0; i < numItems; i++)
{
@@ -460,14 +460,14 @@ namespace BrewMonster.Scripts.Managers
ci += extraLen;
}
var item = new InventoryItemData
var item = new EC_IvtrItem
{
Package = byPackage,
Slot = slotIndex,
TemplateId = tid,
ExpireDate = expireDate,
m_tid = tid,
m_expire_date = expireDate,
State = state,
Count = amount,
m_iCount = amount,
Crc = crc,
Content = extra
};
@@ -443,14 +443,14 @@ namespace BrewMonster.Scripts.Managers
private static IndexOfIteminEquipmentInventory GetAvailableFingerSlot()
{
// Check if FINGER1 slot is empty
var finger1Item = EC_Inventory.GetItem(EC_Inventory.PACK_EQUIPMENT, (int)IndexOfIteminEquipmentInventory.EQUIPIVTR_FINGER1, false);
var finger1Item = EC_Inventory.GetItem(EC_Inventory.IVTRTYPE_EQUIPPACK, (int)IndexOfIteminEquipmentInventory.EQUIPIVTR_FINGER1, false);
if (finger1Item == null)
{
return IndexOfIteminEquipmentInventory.EQUIPIVTR_FINGER1;
}
// Check if FINGER2 slot is empty
var finger2Item = EC_Inventory.GetItem(EC_Inventory.PACK_EQUIPMENT, (int)IndexOfIteminEquipmentInventory.EQUIPIVTR_FINGER2, false);
var finger2Item = EC_Inventory.GetItem(EC_Inventory.IVTRTYPE_EQUIPPACK, (int)IndexOfIteminEquipmentInventory.EQUIPIVTR_FINGER2, false);
if (finger2Item == null)
{
return IndexOfIteminEquipmentInventory.EQUIPIVTR_FINGER2;
@@ -76,7 +76,7 @@ public class ShopItemPanel : MonoBehaviour
}
// Use the existing icon loading system from EC_IvtrItem
Sprite iconSprite = EC_IvtrItem.ResolveItemIconSprite(itemId);
Sprite iconSprite = EC_IvtrItemUtils.ResolveItemIconSprite(itemId);
if (iconSprite != null)
{
+1 -1
View File
@@ -215,7 +215,7 @@ public class pickupItem : MonoBehaviour
TextMeshPro textMesh = textObject.AddComponent<TextMeshPro>();
// Get the item name
string itemName = EC_IvtrItem.ResolveItemName(tid);
string itemName = EC_IvtrItemUtils.ResolveItemName(tid);
if (string.IsNullOrEmpty(itemName))
{
itemName = $"Item {tid}";
+24 -17
View File
@@ -25,8 +25,9 @@ using UnityEngine.SceneManagement;
using UnityEngine.UI;
using static UnityEditor.PlayerSettings;
using Scene = UnityEngine.SceneManagement.Scene;
using BrewMonster.Scripts;
public class CECHostPlayer : CECPlayer
public partial class CECHostPlayer : CECPlayer
{
[SerializeField] private CharacterController controller;
@@ -521,14 +522,14 @@ public class CECHostPlayer : CECPlayer
byte where = data[16]; // Package index
byte index = data[17]; // Slot index in that package
// Create new inventory item data
var newItem = new InventoryItemData
var newItem = new EC_IvtrItem
{
Package = where,
Slot = index,
TemplateId = type,
ExpireDate = expire_date,
m_tid = type,
m_expire_date = expire_date,
State = 0,
Count = (int)amount,
m_iCount = (int)amount,
Crc = 0,
Content = null
};
@@ -572,14 +573,14 @@ public class CECHostPlayer : CECPlayer
}
// Create new inventory item data
var newItem = new InventoryItemData
var newItem = new EC_IvtrItem
{
Package = byPackage,
Slot = bySlot,
TemplateId = tid,
ExpireDate = expire_date,
m_tid = tid,
m_expire_date = expire_date,
State = 0,
Count = (int)iAmount,
m_iCount = (int)iAmount,
Crc = 0,
Content = null
};
@@ -656,20 +657,20 @@ public class CECHostPlayer : CECPlayer
byte index_inv = data[0];
byte index_equip = data[1];
// Update client-side data: move item between PACK_INVENTORY and PACK_EQUIPMENT
var invItem = EC_Inventory.GetItem(EC_Inventory.PACK_INVENTORY, index_inv, true);
var equipItem = EC_Inventory.GetItem(EC_Inventory.PACK_EQUIPMENT, index_equip, true);
var invItem = EC_Inventory.GetItem(EC_Inventory.IVTRTYPE_PACK, index_inv, true);
var equipItem = EC_Inventory.GetItem(EC_Inventory.IVTRTYPE_EQUIPPACK, index_equip, true);
if (invItem != null)
{
invItem.Package = EC_Inventory.PACK_EQUIPMENT;
invItem.Package = EC_Inventory.IVTRTYPE_EQUIPPACK;
invItem.Slot = index_equip;
EC_Inventory.SetItem(EC_Inventory.PACK_EQUIPMENT, index_equip, invItem);
EC_Inventory.SetItem(EC_Inventory.IVTRTYPE_EQUIPPACK, index_equip, invItem);
}
if (equipItem != null)
{
equipItem.Package = EC_Inventory.PACK_INVENTORY;
equipItem.Package = EC_Inventory.IVTRTYPE_PACK;
equipItem.Slot = index_inv;
EC_Inventory.SetItem(EC_Inventory.PACK_INVENTORY, index_inv, equipItem);
EC_Inventory.SetItem(EC_Inventory.IVTRTYPE_PACK, index_inv, equipItem);
}
// Trigger UI refresh if an EC_InventoryUI is present in scene
@@ -715,17 +716,23 @@ public class CECHostPlayer : CECPlayer
}
case CommandID.OWN_IVTR_DETAIL_DATA:
{
EC_Inventory.LogInventoryPacket("OWN_IVTR_DETAIL_DATA", data, hostId);
// EC_Inventory.LogInventoryPacket("OWN_IVTR_DETAIL_DATA", data, hostId);
// Parse and store
if (data != null && data.Length >= 6)
{
byte byPackage = data[0];
byte ivtrSize = data[1];
if (EC_IvtrItem.TryParseInventoryDetail(data, out var pkg,
if (EC_IvtrItemUtils.TryParseInventoryDetail(data, out var pkg,
out var size, out var items))
{
EC_Inventory.UpdatePack(pkg, size, items);
}
// check if we got the item from the Equipment Pack. If so, we have to load the equipment items
if (byPackage == EC_Inventory.IVTRTYPE_EQUIPPACK)
{
UpdateEquipSkins();
}
}
break;
+53
View File
@@ -0,0 +1,53 @@
using BrewMonster;
using BrewMonster.Scripts;
using BrewMonster.Scripts.Managers;
using ModelRenderer.Scripts.GameData;
public partial class CECHostPlayer
{
public int[] m_aEquips = new int[InventoryConst.IVTRSIZE_EQUIPPACK];
public bool UpdateEquipSkins()
{
var equipPack = EC_Inventory.GetPack(EC_Inventory.IVTRTYPE_EQUIPPACK);
int[] aNewEquips = new int[InventoryConst.IVTRSIZE_EQUIPPACK];
EC_IvtrItem pItem = null;
for (int i = 0; i < InventoryConst.IVTRSIZE_EQUIPPACK; i++)
{
if (equipPack.TryGetValue(i, out pItem))
{
aNewEquips[i] = pItem.m_tid;
}
}
ShowEquipments(aNewEquips, true, true);
return true;
}
public void ShowEquipments(int[] pEquipmentID, bool bLoadAtOnce, bool bForceLoad)
{
var elemendataman = BrewMonster.ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = default;
for (int i = 0; i < InventoryConst.IVTRSIZE_EQUIPPACK; i++)
{
if (pEquipmentID[i] != m_aEquips[i])
{
// new equipment. Need to load and equip to host player
var equipData = elemendataman.get_data_ptr((uint)pEquipmentID[i], ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
switch (DataType)
{
case DATA_TYPE.DT_WEAPON_ESSENCE:
var equip = (WEAPON_ESSENCE)equipData;
BMLogger.Log($"ShowEquipments():: Weapon Essence: {equip.FileModelRight} -- {equip.FileModelLeft}");
break;
default:
break;
}
}
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: dc1282c835bed1b43bc32a2a09563390