Files
test/Assets/Scripts/CECPlayer_Inventory.cs
T
2026-03-11 23:14:12 +07:00

565 lines
27 KiB
C#

using System.IO;
using BrewMonster;
using BrewMonster.Network;
using BrewMonster.Scripts;
using BrewMonster.Scripts.Managers;
using ModelRenderer.Scripts.GameData;
using UnityEngine;
namespace BrewMonster
{
public partial class CECPlayer
{
public const int NUM_PROFESSION = (int)Profession.NUM_PROFESSION;
public const int NUM_GENDER = (int)Gender.NUM_GENDER;
public static readonly string _left_hand_weapon = "LeftHand";
public static readonly string _right_hand_weapon = "RightHand";
public static readonly string _wing = "Wing";
public static readonly string _wing2 = "Wing2";
public const string _cc_ride = "CC_Ride";
public static readonly string _cc_ride2 = "CC_Ride2";
public const string _hh_ride = "HH_Ride";
public const string _hanger_ride = "Rider";
public static readonly string _hanger_ride2 = "Rider2";
public static readonly string _hanger_hug = "Hug";
public static readonly string _hh_bind = "HH_Bind";
public static readonly string _cc_bind = "CC_Bind";
public const string _cc_fenghuolun = "CC_feijian";
public const string _hh_left_foot = "HH_左脚";
public const string _hh_right_foot = "HH_右脚";
public static readonly string _hh_left_shoulder_weapon = "HH_leftsword";
public static readonly string _hh_right_shoulder_weapon = "HH_rightsword";
public static readonly string _hh_left_hand_weapon = "HH_lefthandweapon";
public static readonly string _hh_right_hand_weapon = "HH_righthandweapon";
public static readonly string _hh_qiu = "HH_qiu";
public static readonly string _hh_right_hand_nickle_weapon = "HH_weapon";
public static readonly string _cc_weapon = "CC_weapon";
public static readonly string _cc_qiu = "CC_qiu";
public static readonly string _hh_qiu_base = "HH_base";
public static readonly string[] _multiobject_effect = { "绿色连线.gfx", "红色连线.gfx", "黑色连线.gfx" };
public static readonly string[] _equipment_skin =
{
"models/players/装备/男/{0}/男通用{1}",
"models/players/装备/女/{0}/女通用{1}",
"models/players/装备/男/{0}/男通用{1}",
"models/players/装备/女/{0}/女通用{1}",
"models/players/装备/男/{0}/男通用{1}",
"models/players/装备/女/{0}/女通用{1}",
"",
"models/players/装备/女/{0}/妖精{1}",
"models/players/装备/男/{0}/妖兽{1}",
"",
"models/players/装备/男/{0}/男通用{1}",
"models/players/装备/女/{0}/女通用{1}",
"models/players/装备/男/{0}/男通用{1}",
"models/players/装备/女/{0}/女通用{1}",
"models/players/装备/男/{0}/男通用{1}",
"models/players/装备/女/{0}/女通用{1}",
"models/players/装备/男/{0}/男通用{1}",
"models/players/装备/女/{0}/女通用{1}",
"models/players/装备/男/{0}/男通用{1}",
"models/players/装备/女/{0}/女通用{1}",
"models/players/装备/男/{0}/男通用{1}",
"models/players/装备/女/{0}/女通用{1}",
"models/players/装备/男/{0}/男通用{1}",
"models/players/装备/女/{0}/女通用{1}",
};
// Skin index
public enum SkinIndex
{
SKIN_BODY_INDEX = 0,
SKIN_UPPER_BODY_INDEX,
SKIN_WRIST_INDEX,
SKIN_LOWER_INDEX,
SKIN_FOOT_INDEX,
SKIN_HEAD_INDEX,
SKIN_FASHION_UPPER_BODY_INDEX,
SKIN_FASHION_WRIST_INDEX,
SKIN_FASHION_LOWER_INDEX,
SKIN_FASHION_FOOT_INDEX,
NUM_SKIN_INDEX,
}
// Wing types
public enum WingType
{
WINGTYPE_WING, // 锟斤拷锟斤拷锟斤拷锟斤拷锟酵o拷锟斤拷锟??????
WINGTYPE_FLYSWORD, // 锟斤拷锟斤拷锟斤拷锟斤拷锟酵o拷锟缴斤拷
WINGTYPE_DOUBLEWHEEL, // 锟斤拷锟斤拷锟斤拷锟斤拷锟酵o拷双锟脚凤拷锟斤拷锟斤?
}
private static readonly SkinIndex[] _location_skin_map =
{
SkinIndex.SKIN_BODY_INDEX,
SkinIndex.SKIN_UPPER_BODY_INDEX,
SkinIndex.SKIN_WRIST_INDEX,
SkinIndex.SKIN_LOWER_INDEX,
SkinIndex.SKIN_FOOT_INDEX,
SkinIndex.SKIN_UPPER_BODY_INDEX,
SkinIndex.SKIN_UPPER_BODY_INDEX,
SkinIndex.SKIN_LOWER_INDEX,
SkinIndex.SKIN_UPPER_BODY_INDEX
};
// The skeleton builder holds the reference to the player's bones
// We use this to setup the bones for the equipment skinned mesh renderers
private SkeletonBuilder _skeletonBuilder;
private PlayerDefaultEquipments _playerDefaultEquipments;
// Track instantiated armor objects for each slot
private GameObject _currentUpperArmor;
private GameObject _currentLowerArmor;
private GameObject _currentWristArmor;
private GameObject _currentFootArmor;
// Track instantiated weapon objects
private GameObject _currentRightHandWeapon;
private GameObject _currentLeftHandWeapon;
private PlayerDefaultEquipments PlayerDefaultEquipments
{
get
{
if (_playerDefaultEquipments == null)
{
_playerDefaultEquipments = GetComponentInChildren<PlayerDefaultEquipments>();
}
return _playerDefaultEquipments;
}
}
public bool UpdateEquipSkins()
{
int[] aNewEquips = new int[InventoryConst.IVTRSIZE_EQUIPPACK];
EC_IvtrItem pItem = null;
for (int i = 0; i < InventoryConst.IVTRSIZE_EQUIPPACK; i++)
{
// Use host player's equipment inventory (per-instance CECInventory)
var host = CECGameRun.Instance?.GetHostPlayer();
var equipInv = host?.IvtrEquipPack;
pItem = equipInv?.GetItem(i, false);
if (pItem != null)
aNewEquips[i] = pItem.m_tid;
}
ShowEquipments(aNewEquips, true, true);
return true;
}
public async void ShowEquipments(int[] pEquipmentID, bool bLoadAtOnce, bool bForceLoad)
{
var elemendataman = BrewMonster.ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = default;
bool useDefaultUpper = false;
bool useDefaultLower = false;
bool useDefaultWrist = false;
bool useDefaultFoot = false;
for (int i = 0; i < InventoryConst.IVTRSIZE_EQUIPPACK; i++)
{
//TODO: The equipment ids store the stone information, we need to extract the stone information from the equipment id.
/*
int idEquipment = pEquipmentID[i];
if((i >= EQUIPIVTR_FASHION_BODY && i <= EQUIPIVTR_FASHION_WRIST ) ||
i == EQUIPIVTR_FASHION_HEAD || i == EQUIPIVTR_FASHION_WEAPON)
{
WORD wColor = (idEquipment & 0xffff0000) >> 16;
idEquipment &= 0x0000ffff;
color = FASHION_WORDCOLOR_TO_A3DCOLOR(wColor);
}
else
{
if( i == EQUIPIVTR_WEAPON )
{
pResult->stoneWeapon = (idEquipment & 0xffff0000) >> 16;
}
if( i == EQUIPIVTR_BODY )
{
pResult->stoneUpperBody = (idEquipment & 0xffff0000) >> 16;
}
if( i == EQUIPIVTR_WRIST )
{
pResult->stoneWrist = (idEquipment & 0xffff0000) >> 16;
}
if( i == EQUIPIVTR_LEG )
{
pResult->stoneLowerBody = (idEquipment & 0xffff0000) >> 16;
}
if( i == EQUIPIVTR_FOOT )
{
pResult->stoneFoot = (idEquipment & 0xffff0000) >> 16;
}
idEquipment &= 0x0000ffff;
}
*/
if (pEquipmentID[i] != m_aEquips[i])
{
m_aEquips[i] = pEquipmentID[i]; // store the current equipment id
// 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);
object subTypeData = null;
switch (DataType)
{
case DATA_TYPE.DT_WEAPON_ESSENCE:
var weaponData = (WEAPON_ESSENCE)equipData;
subTypeData = elemendataman.get_data_ptr((uint)weaponData.id_sub_type, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
if (subTypeData != null && DataType == DATA_TYPE.DT_WEAPON_SUB_TYPE)
{
var subTypeDataWeapon = (WEAPON_SUB_TYPE)subTypeData;
m_uAttackType = subTypeDataWeapon.action_type;
m_ExtProps.ak.AttackRange = weaponData.attack_range;
}
string fileModelRight = AFile.NormalizePath(weaponData.FileModelRight, true).ToLower();
string fileModelLeft = AFile.NormalizePath(weaponData.FileModelLeft, true).ToLower();
// BMLogger.Log($"ShowEquipments():: Weapon Essence: {fileModelRight} -- {fileModelLeft}");
// Destroy existing right hand weapon before creating new one
if (_currentRightHandWeapon != null)
{
Destroy(_currentRightHandWeapon);
_currentRightHandWeapon = null;
}
// Destroy existing left hand weapon before creating new one
if (_currentLeftHandWeapon != null)
{
Destroy(_currentLeftHandWeapon);
_currentLeftHandWeapon = null;
}
GameObject weaponPrefab = null;
if (!string.IsNullOrEmpty(fileModelRight))
{
weaponPrefab = await AddressableManager.Instance.LoadPrefabAsync(fileModelRight);
var weaponObject = Instantiate(weaponPrefab);
if (weaponObject != null)
{
weaponObject.transform.SetParent(FindChildObjectRecursive(transform, _hh_right_hand_weapon).transform);
weaponObject.transform.localPosition = weaponPrefab.transform.localPosition;
weaponObject.transform.localRotation = weaponPrefab.transform.localRotation;
weaponObject.transform.localScale = Vector3.one;
weaponObject.SetActive(true);
_currentRightHandWeapon = weaponObject;
}
}
if (!string.IsNullOrEmpty(fileModelLeft))
{
weaponPrefab = await AddressableManager.Instance.LoadPrefabAsync(fileModelLeft);
var weaponObject = Instantiate(weaponPrefab);
if (weaponObject != null)
{
weaponObject.transform.SetParent(FindChildObjectRecursive(transform, _hh_left_hand_weapon).transform);
weaponObject.transform.localPosition = weaponPrefab.transform.localPosition;
weaponObject.transform.localRotation = weaponPrefab.transform.localRotation;
weaponObject.transform.localScale = Vector3.one;
weaponObject.SetActive(true);
_currentLeftHandWeapon = weaponObject;
}
}
break;
case DATA_TYPE.DT_ARMOR_ESSENCE:
var pArmor = (ARMOR_ESSENCE)equipData;
var nLocation = pArmor.equip_location;
// BMLogger.Log($"ShowEquipments():: Armor Essence: {pArmor.RealName}");
var armorSkinPath = _GenEquipmentSkinPath(UnityGameSession.Instance.GetRoleInfo().occupation, UnityGameSession.Instance.GetRoleInfo().gender, pArmor.RealName);
if (!armorSkinPath.EndsWith(".ecm"))
{
armorSkinPath += ".ecm";
}
var armorPrefab = await AddressableManager.Instance.LoadPrefabAsync(armorSkinPath);
if (armorPrefab != null)
{
// Destroy existing armor for this slot before creating new one
switch (nLocation)
{
case (uint)SkinIndex.SKIN_UPPER_BODY_INDEX:
if (_currentUpperArmor != null)
{
Destroy(_currentUpperArmor);
_currentUpperArmor = null;
}
break;
case (uint)SkinIndex.SKIN_LOWER_INDEX:
if (_currentLowerArmor != null)
{
Destroy(_currentLowerArmor);
_currentLowerArmor = null;
}
break;
case (uint)SkinIndex.SKIN_WRIST_INDEX:
if (_currentWristArmor != null)
{
Destroy(_currentWristArmor);
_currentWristArmor = null;
}
break;
case (uint)SkinIndex.SKIN_FOOT_INDEX:
if (_currentFootArmor != null)
{
Destroy(_currentFootArmor);
_currentFootArmor = null;
}
break;
}
var armorObject = Instantiate(armorPrefab);
armorObject.transform.SetParent(GetSkeletonBuilder()?.transform);
armorObject.transform.localPosition = Vector3.zero;
armorObject.transform.localRotation = Quaternion.identity;
armorObject.transform.localScale = Vector3.one;
var skinnedMeshRenderer = armorObject.GetComponent<SkinnedMeshRenderer>();
var skinnedMeshRenderereFromDataList = armorObject.GetComponentsInChildren<SkinnedMeshRenderFromData>();
foreach (var skinnedMeshRenderereFromData in skinnedMeshRenderereFromDataList)
{
if (skinnedMeshRenderereFromData != null)
{
skinnedMeshRenderereFromData._skinnedMeshRenderer.bones = GetSkeletonBuilder().GetBones(skinnedMeshRenderereFromData.BoneNames);
skinnedMeshRenderereFromData._skinnedMeshRenderer.rootBone = skinnedMeshRenderereFromData._skinnedMeshRenderer.bones[^1];
}
}
// Store the armor object for this slot
switch (nLocation)
{
case (uint)SkinIndex.SKIN_UPPER_BODY_INDEX:
_currentUpperArmor = armorObject;
useDefaultUpper = false;
break;
case (uint)SkinIndex.SKIN_LOWER_INDEX:
_currentLowerArmor = armorObject;
useDefaultLower = false;
break;
case (uint)SkinIndex.SKIN_WRIST_INDEX:
_currentWristArmor = armorObject;
useDefaultWrist = false;
break;
case (uint)SkinIndex.SKIN_FOOT_INDEX:
_currentFootArmor = armorObject;
useDefaultFoot = false;
break;
}
}
else
{
// disable/enable the default equipment
switch (nLocation)
{
case (uint)SkinIndex.SKIN_UPPER_BODY_INDEX:
useDefaultUpper = true;
break;
case (uint)SkinIndex.SKIN_LOWER_INDEX:
useDefaultLower = true;
break;
case (uint)SkinIndex.SKIN_WRIST_INDEX:
useDefaultWrist = true;
break;
case (uint)SkinIndex.SKIN_FOOT_INDEX:
useDefaultFoot = true;
break;
}
}
break;
case DATA_TYPE.DT_WINGMANWING_ESSENCE:
m_wingType = enumWingType.WINGTYPE_WING;
//ChangeWing(pResult, static_cast<const WINGMANWING_ESSENCE*>(pEquip)->file_model);
var pWingData = (WINGMANWING_ESSENCE)equipData;
var pWingPrefab = await AddressableManager.Instance.LoadPrefabAsync(pWingData.FileModel.ToLower().Replace('\\', '/'));
//Transform parentWing = FindChildRecursive(_pPlayerModel.transform, "HH_chibang");
if(pWingPrefab != null)
{
GameObject parentWing = new GameObject();
parentWing.name = _wing;
parentWing.transform.parent = m_pPlayerModel.transform;
m_Wing = parentWing.transform;
var pWingObject = Instantiate(pWingPrefab, parentWing.transform);
pWingObject.gameObject.SetActive(true);
m_Wing.gameObject.SetActive(false);
//pWingObject.name = _wing;
}
BMLogger.Log($"ShowEquipments():: Wingman Wing Essence: {pWingData.id} {pWingData.Name} -- {pWingData.FileModel}");
break;
case DATA_TYPE.DT_FLYSWORD_ESSENCE:
if (m_Wing != null)
{
Destroy(m_Wing.gameObject);
m_Wing = null;
}
var pFlySword = (FLYSWORD_ESSENCE)equipData;
m_wingType = FlyMode2WingType(pFlySword.fly_mode);
BMLogger.Log($"ShowEquipments():: Flysword Essence: {pFlySword.id} {pFlySword.Name} -- {pFlySword.FileModel}");
string path = AFile.NormalizePath(pFlySword.FileModel, true).ToLower();
//var pflySwordPrefab = await AddressableManager.Instance.LoadPrefabAsync(pFlySword.FileModel.ToLower().Replace('\\', '/'));
var pflySwordPrefab = await AddressableManager.Instance.LoadPrefabAsync(path);
//var parentSword = FindChildRecursive(_pPlayerModel.transform, "HH_feijian");
if(pflySwordPrefab != null)
{
var pflySwordObject = Instantiate(pflySwordPrefab).transform;
pflySwordObject.parent = m_pPlayerCECModel.m_skeletonBuilder.GetHook("HH_feijian").transform;
pflySwordObject.localPosition = Vector3.zero;
pflySwordObject.localRotation = Quaternion.identity;
pflySwordObject.localScale = Vector3.one;
m_Wing = pflySwordObject.transform;
}
break;
default:
break;
}
}
if (m_aEquips[i] == 0)
{
switch (i)
{
case InventoryConst.EQUIPIVTR_WEAPON:
// Destroy weapons when weapon slot is empty
m_uAttackType = 10;
if (_currentRightHandWeapon != null)
{
Destroy(_currentRightHandWeapon);
_currentRightHandWeapon = null;
}
if (_currentLeftHandWeapon != null)
{
Destroy(_currentLeftHandWeapon);
_currentLeftHandWeapon = null;
}
break;
case InventoryConst.EQUIPIVTR_BODY:
useDefaultUpper = true;
break;
case InventoryConst.EQUIPIVTR_LEG:
useDefaultLower = true;
break;
case InventoryConst.EQUIPIVTR_WRIST:
useDefaultWrist = true;
break;
case InventoryConst.EQUIPIVTR_FOOT:
useDefaultFoot = true;
break;
}
}
}
// enable/disable the default equipment
// If using default, destroy non-default equipment if it exists
if (useDefaultUpper)
{
if (_currentUpperArmor != null)
{
Destroy(_currentUpperArmor);
_currentUpperArmor = null;
}
}
PlayerDefaultEquipments.DefaultUpper.SetActive(useDefaultUpper);
if (useDefaultLower)
{
if (_currentLowerArmor != null)
{
Destroy(_currentLowerArmor);
_currentLowerArmor = null;
}
}
PlayerDefaultEquipments.DefaultLower.SetActive(useDefaultLower);
if (useDefaultWrist)
{
if (_currentWristArmor != null)
{
Destroy(_currentWristArmor);
_currentWristArmor = null;
}
}
PlayerDefaultEquipments.DefaultWirst.SetActive(useDefaultWrist);
if (useDefaultFoot)
{
if (_currentFootArmor != null)
{
Destroy(_currentFootArmor);
_currentFootArmor = null;
}
}
PlayerDefaultEquipments.DefaultFoot.SetActive(useDefaultFoot);
}
public enumWingType FlyMode2WingType(uint flymode) {
switch (flymode){
case 0:
return enumWingType.WINGTYPE_FLYSWORD;
case 1:
return enumWingType.WINGTYPE_WING;
case 2:
return enumWingType.WINGTYPE_DOUBLEWHEEL;
default:
BMLogger.LogError($"unknow fly mode: {flymode}");
return enumWingType.WINGTYPE_FLYSWORD;
}
}
protected Transform FindChildRecursive(Transform parent, string name)
{
foreach (Transform child in parent)
{
if (child.name == name)
return child;
Transform found = FindChildRecursive(child, name);
if (found != null)
return found;
}
return null;
}
#region Helper Methods
private GameObject FindChildObjectRecursive(Transform parent, string name)
{
foreach (Transform child in parent)
{
if (child.name == name)
{
return child.gameObject;
}
var childObject = FindChildObjectRecursive(child, name);
if (childObject != null)
{
return childObject;
}
}
return null;
}
private SkeletonBuilder GetSkeletonBuilder()
{
if (_skeletonBuilder == null)
{
_skeletonBuilder = GetComponentInChildren<SkeletonBuilder>();
}
return _skeletonBuilder;
}
#endregion
public static string _GenEquipmentSkinPath(int nProfession, int nGender, string szSkinName)
{
return string.Format(_equipment_skin[nProfession * NUM_GENDER + nGender], szSkinName, szSkinName);
}
}
}