Update equip item, send - get work

This commit is contained in:
HungDK
2025-09-22 19:01:45 +07:00
parent 880c49607c
commit cbff89b47a
4 changed files with 182 additions and 23 deletions
Binary file not shown.
@@ -113,7 +113,7 @@ TextureImporter:
customData:
physicsShape: []
bones: []
spriteID:
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
@@ -5,6 +5,7 @@ using UnityEngine.UI;
using System.Reflection;
using BrewMonster.Network;
using BrewMonster;
using ModelRenderer.Scripts.GameData;
namespace PerfectWorld.Scripts.Managers
{
@@ -157,7 +158,7 @@ namespace PerfectWorld.Scripts.Managers
// For equipping, we need to find an empty equipment slot
// The equip location should be determined by the item type or use a default
byte equipLocation = GetEquipLocationForItem(currentSelectedItem.TemplateId);
if (equipLocation == 0)
if (equipLocation >= (byte)IndexOfIteminEquipmentInventory.SIZE_EQUIPIVTR)
{
Debug.LogWarning($"[InventoryUI] Could not determine equip location for item {currentSelectedItem.TemplateId}");
return;
@@ -199,37 +200,114 @@ namespace PerfectWorld.Scripts.Managers
private byte GetEquipLocationForItem(int templateId)
{
// Simple approach: use the template ID to determine equip location
// This is a basic mapping - you may need to adjust based on your game's logic
// Determine exact equipment slot index based on item type/essence
try
{
// Try to get equip location from ESSENCE data first
var edm = ElementDataManProvider.GetElementDataMan();
if (edm != null)
if (edm == null)
{
uint id = unchecked((uint)templateId);
object data = edm.get_data_ptr(id, ID_SPACE.ID_SPACE_ESSENCE);
if (data != null)
Debug.LogWarning("[InventoryUI] ElementDataMan not initialized");
return (byte)IndexOfIteminEquipmentInventory.SIZE_EQUIPIVTR;
}
uint id = unchecked((uint)templateId);
// Weapons
foreach (var it in edm.weapon_essence_array)
{
if (it.id == id) return (byte)IndexOfIteminEquipmentInventory.EQUIPIVTR_WEAPON;
}
// Projectiles (quiver / projectile essence)
foreach (var it in edm.quiver_essence_array)
{
if (it.id == id) return (byte)IndexOfIteminEquipmentInventory.EQUIPIVTR_PROJECTILE;
}
foreach (var it in edm.projectile_essence_array)
{
if (it.id == id) return (byte)IndexOfIteminEquipmentInventory.EQUIPIVTR_PROJECTILE;
}
// Flysword
foreach (var it in edm.flysword_essence_array)
{
if (it.id == id) return (byte)IndexOfIteminEquipmentInventory.EQUIPIVTR_FLYSWORD;
}
// Armor -> derive from sub-type mask
foreach (var it in edm.armor_essence_array)
{
if (it.id == id)
{
var equipLocationField = data.GetType().GetField("equip_location", BindingFlags.Public | BindingFlags.Instance);
if (equipLocationField != null && equipLocationField.FieldType == typeof(uint))
var slot = ResolveArmorSlotBySubtype(edm, it.id_sub_type);
if (slot < IndexOfIteminEquipmentInventory.SIZE_EQUIPIVTR)
{
uint equipLocation = (uint)equipLocationField.GetValue(data);
Debug.Log($"[InventoryUI] Found equip_location {equipLocation} for template {templateId}");
return (byte)equipLocation;
return (byte)slot;
}
break;
}
}
// Fallback: use a simple mapping based on template ID ranges
// This is a basic implementation - adjust based on your game's item system
Debug.Log($"[InventoryUI] Using fallback equip location for template {templateId}");
return GetDefaultEquipLocation(templateId);
// Fashion -> derive from sub-type mask
foreach (var it in edm.fashion_essence_array)
{
if (it.id == id)
{
var slot = ResolveFashionSlotBySubtype(edm, it.id_sub_type);
if (slot < IndexOfIteminEquipmentInventory.SIZE_EQUIPIVTR)
{
return (byte)slot;
}
break;
}
}
// Runes
foreach (var it in edm.damagerune_essence_array)
{
if (it.id == id) return (byte)IndexOfIteminEquipmentInventory.EQUIPIVTR_RUNE;
}
foreach (var it in edm.armorrune_essence_array)
{
if (it.id == id) return (byte)IndexOfIteminEquipmentInventory.EQUIPIVTR_RUNE;
}
// Special slots
foreach (var it in edm.bible_essence_array)
{
if (it.id == id) return (byte)IndexOfIteminEquipmentInventory.EQUIPIVTR_BIBLE;
}
foreach (var it in edm.speaker_essence_array)
{
if (it.id == id) return (byte)IndexOfIteminEquipmentInventory.EQUIPIVTR_SPEAKER;
}
foreach (var it in edm.autohp_essence_array)
{
if (it.id == id) return (byte)IndexOfIteminEquipmentInventory.EQUIPIVTR_AUTOHP;
}
foreach (var it in edm.automp_essence_array)
{
if (it.id == id) return (byte)IndexOfIteminEquipmentInventory.EQUIPIVTR_AUTOMP;
}
foreach (var it in edm.force_token_essence_array)
{
if (it.id == id) return (byte)IndexOfIteminEquipmentInventory.EQUIPIVTR_FORCE_TOKEN;
}
foreach (var it in edm.sell_certificate_essence_array)
{
if (it.id == id) return (byte)IndexOfIteminEquipmentInventory.EQUIPIVTR_CERTIFICATE;
}
// Fashion weapon (if present in your data as essence/config)
// If you add a dedicated essence array for fashion weapons, map it here
Debug.LogWarning($"[InventoryUI] Equip index not found for template {templateId}");
return (byte)IndexOfIteminEquipmentInventory.SIZE_EQUIPIVTR;
}
catch (Exception ex)
{
Debug.LogWarning($"[InventoryUI] Error getting equip location for template {templateId}: {ex.Message}");
return GetDefaultEquipLocation(templateId);
Debug.LogWarning($"[InventoryUI] Error resolving equip index for template {templateId}: {ex.Message}");
return (byte)IndexOfIteminEquipmentInventory.SIZE_EQUIPIVTR;
}
}
@@ -237,7 +315,7 @@ namespace PerfectWorld.Scripts.Managers
{
// Basic equip location mapping based on template ID
// Adjust these ranges based on your game's item system
if (templateId >= 1000 && templateId < 2000) return 1; // Weapon
if (templateId >= 1000 && templateId < 2000) return 0; // Weapon
if (templateId >= 2000 && templateId < 3000) return 2; // Armor
if (templateId >= 3000 && templateId < 4000) return 3; // Accessory
if (templateId >= 4000 && templateId < 5000) return 4; // Ring
@@ -245,7 +323,7 @@ namespace PerfectWorld.Scripts.Managers
// Default to slot 1 if no specific mapping
Debug.Log($"[InventoryUI] Using default equip location 1 for template {templateId}");
return 1;
return 0;
}
private int FindEmptyInventorySlot()
@@ -264,6 +342,84 @@ namespace PerfectWorld.Scripts.Managers
return -1;
}
// === Equipment indices (copy kept local for clarity) ===
private enum IndexOfIteminEquipmentInventory : byte
{
EQUIPIVTR_WEAPON = 0,
EQUIPIVTR_HEAD,
EQUIPIVTR_NECK,
EQUIPIVTR_SHOULDER,
EQUIPIVTR_BODY,
EQUIPIVTR_WAIST,
EQUIPIVTR_LEG,
EQUIPIVTR_FOOT,
EQUIPIVTR_WRIST,
EQUIPIVTR_FINGER1,
EQUIPIVTR_FINGER2,
EQUIPIVTR_PROJECTILE,
EQUIPIVTR_FLYSWORD,
EQUIPIVTR_FASHION_BODY,
EQUIPIVTR_FASHION_LEG,
EQUIPIVTR_FASHION_FOOT,
EQUIPIVTR_FASHION_WRIST,
EQUIPIVTR_RUNE,
EQUIPIVTR_BIBLE,
EQUIPIVTR_SPEAKER,
EQUIPIVTR_AUTOHP,
EQUIPIVTR_AUTOMP,
EQUIPIVTR_POCKET,
EQUIPIVTR_GOBLIN,
EQUIPIVTR_CERTIFICATE,
EQUIPIVTR_FASHION_HEAD,
EQUIPIVTR_FORCE_TOKEN,
EQUIPIVTR_DYNSKILLEQUIP1,
EQUIPIVTR_DYNSKILLEQUIP2,
EQUIPIVTR_FASHION_WEAPON,
SIZE_EQUIPIVTR,
}
private static IndexOfIteminEquipmentInventory ResolveArmorSlotBySubtype(elementdataman edm, uint armorSubTypeId)
{
foreach (var sub in edm.armor_sub_type_array)
{
if (sub.id != armorSubTypeId) continue;
uint mask = sub.equip_mask;
// Map first set bit to equipment index
if ((mask & (1u << (int)IndexOfIteminEquipmentInventory.EQUIPIVTR_HEAD)) != 0) return IndexOfIteminEquipmentInventory.EQUIPIVTR_HEAD;
if ((mask & (1u << (int)IndexOfIteminEquipmentInventory.EQUIPIVTR_NECK)) != 0) return IndexOfIteminEquipmentInventory.EQUIPIVTR_NECK;
if ((mask & (1u << (int)IndexOfIteminEquipmentInventory.EQUIPIVTR_SHOULDER)) != 0) return IndexOfIteminEquipmentInventory.EQUIPIVTR_SHOULDER;
if ((mask & (1u << (int)IndexOfIteminEquipmentInventory.EQUIPIVTR_BODY)) != 0) return IndexOfIteminEquipmentInventory.EQUIPIVTR_BODY;
if ((mask & (1u << (int)IndexOfIteminEquipmentInventory.EQUIPIVTR_WAIST)) != 0) return IndexOfIteminEquipmentInventory.EQUIPIVTR_WAIST;
if ((mask & (1u << (int)IndexOfIteminEquipmentInventory.EQUIPIVTR_LEG)) != 0) return IndexOfIteminEquipmentInventory.EQUIPIVTR_LEG;
if ((mask & (1u << (int)IndexOfIteminEquipmentInventory.EQUIPIVTR_FOOT)) != 0) return IndexOfIteminEquipmentInventory.EQUIPIVTR_FOOT;
if ((mask & (1u << (int)IndexOfIteminEquipmentInventory.EQUIPIVTR_WRIST)) != 0) return IndexOfIteminEquipmentInventory.EQUIPIVTR_WRIST;
if ((mask & (1u << (int)IndexOfIteminEquipmentInventory.EQUIPIVTR_FINGER1)) != 0) return IndexOfIteminEquipmentInventory.EQUIPIVTR_FINGER1;
if ((mask & (1u << (int)IndexOfIteminEquipmentInventory.EQUIPIVTR_FINGER2)) != 0) return IndexOfIteminEquipmentInventory.EQUIPIVTR_FINGER2;
// Default not found
break;
}
return IndexOfIteminEquipmentInventory.SIZE_EQUIPIVTR;
}
private static IndexOfIteminEquipmentInventory ResolveFashionSlotBySubtype(elementdataman edm, uint fashionSubTypeId)
{
foreach (var sub in edm.fashion_sub_type_array)
{
if (sub.id != fashionSubTypeId) continue;
uint mask = sub.equip_fashion_mask;
// Map first set bit to fashion equipment index
if ((mask & (1u << (int)IndexOfIteminEquipmentInventory.EQUIPIVTR_FASHION_HEAD)) != 0) return IndexOfIteminEquipmentInventory.EQUIPIVTR_FASHION_HEAD;
if ((mask & (1u << (int)IndexOfIteminEquipmentInventory.EQUIPIVTR_FASHION_BODY)) != 0) return IndexOfIteminEquipmentInventory.EQUIPIVTR_FASHION_BODY;
if ((mask & (1u << (int)IndexOfIteminEquipmentInventory.EQUIPIVTR_FASHION_LEG)) != 0) return IndexOfIteminEquipmentInventory.EQUIPIVTR_FASHION_LEG;
if ((mask & (1u << (int)IndexOfIteminEquipmentInventory.EQUIPIVTR_FASHION_FOOT)) != 0) return IndexOfIteminEquipmentInventory.EQUIPIVTR_FASHION_FOOT;
if ((mask & (1u << (int)IndexOfIteminEquipmentInventory.EQUIPIVTR_FASHION_WRIST)) != 0) return IndexOfIteminEquipmentInventory.EQUIPIVTR_FASHION_WRIST;
if ((mask & (1u << (int)IndexOfIteminEquipmentInventory.EQUIPIVTR_FASHION_WEAPON)) != 0) return IndexOfIteminEquipmentInventory.EQUIPIVTR_FASHION_WEAPON;
// Default not found
break;
}
return IndexOfIteminEquipmentInventory.SIZE_EQUIPIVTR;
}
// === MVC: Model ===
private class InventoryModel
{
+3
View File
@@ -211,6 +211,9 @@ public class CECHostPlayer : MonoBehaviour
OnMsgHstOwnItemInfo(Msg);
break;
}
case int value when value == EC_MsgDef.MSG_HST_ITEMOPERATION:
Debug.Log("HungDev : MSG_HST_ITEMOPERATION");
break;
}
}
public void OnMsgHstOwnItemInfo(ECMSG Msg)