Files
2026-04-07 15:27:42 +07:00

311 lines
14 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using BrewMonster.Scripts;
using System.Threading.Tasks;
using UnityEngine;
using Cysharp.Threading.Tasks;
namespace BrewMonster
{
public class CECClonePlayer : CECPlayer
{
protected bool m_bShowCustomize; // ʾԻ
protected bool m_bUseHintModel; // ʹ˵ģ
public CECClonePlayer(){
m_iCID = (int)Class_ID.OCID_CLONED_PLAYER;
m_bCastShadow = true;
m_bShowCustomize= true;
//Todo: add cofig feature to game
//m_bUseHintModel = GetConfigs().GetVideoSettings().bModelLimit;
}
public bool CanClone(CECPlayer player)
{
return player != null
&& (player.IsHostPlayer() || player.IsElsePlayer());
}
public async Task<bool> Clone(CECPlayer player, bool atOnce){
if (!player){
return false;
}
if (player.IsHostPlayer()){
if (await LoadFrom((CECHostPlayer)player, atOnce)){
return true;
}
}
if (player.IsElsePlayer()){
if (await LoadFrom((EC_ElsePlayer)player, atOnce)){
return true;
}
}
return false;
}
protected async Task<bool> LoadFrom(CECHostPlayer player, bool atOnce)
{
int i = 0;
EC_IvtrItem[] aEquipItems = new EC_IvtrItem[InventoryConst.SIZE_ALL_EQUIPIVTR];
// Create equipments
for (i=0; i < player.GetEquipment().GetSize(); i++){
if (!ShouldLoadEquipment(i)){
continue;
}
EC_IvtrItem Equip = player.GetEquipment().GetItem(i);
aEquipItems[i] = Equip;
}
// // Todo: Create goblin
// if( aEquipItems[EQUIPIVTR_GOBLIN] )
// {
// m_pGoblin = new CECGoblin();
// CECIvtrGoblin* pIvtrGoblin = (CECIvtrGoblin*)aEquipItems[EQUIPIVTR_GOBLIN];
// m_pGoblin->Init(pIvtrGoblin->GetTemplateID(), pIvtrGoblin, this);
// }
// Build new equipments id array (must match SIZE_ALL_EQUIPIVTR — LoadPlayerSkeleton iterates full range)
int[] aNewEquips = new int[InventoryConst.SIZE_ALL_EQUIPIVTR];
for (i=0; i < InventoryConst.IVTRSIZE_EQUIPPACK; i++) {
EC_IvtrItem pItem = aEquipItems[i];
if (pItem != null) {
aNewEquips[i] = pItem.GetTemplateID();
if( ((i >= InventoryConst.EQUIPIVTR_FASHION_BODY && i <= InventoryConst.EQUIPIVTR_FASHION_WRIST)
|| i == InventoryConst.EQUIPIVTR_FASHION_HEAD ) &&
pItem.GetClassID() == (int)EC_IvtrEquip.EQUIP_CLASS_ID.ICID_FASHION ) {
EC_IvtrFashion pFashionItem = (EC_IvtrFashion)pItem;
aNewEquips[i] |= (pFashionItem.GetWordColor() << 16) & 0x7fffffff;
}
else {
EC_IvtrEquip pEquip = (EC_IvtrEquip) pItem;
ushort stoneStatus = pEquip != null ? pEquip.GetStoneMask() : (ushort)0;
aNewEquips[i] |= (stoneStatus << 16) & 0x7fffffff;
}
}
else{
aNewEquips[i] = 0;
}
}
m_aEquips = aNewEquips;
return await Load(player, atOnce);
}
protected async Task<bool> LoadFrom(EC_ElsePlayer player, bool atOnce){
// Create equipments
for (int i=0; i < InventoryConst.SIZE_ALL_EQUIPIVTR; i++){
if (!ShouldLoadEquipment(i)){
continue;
}
m_aEquips[i] = player.GetEquipment(i);
}
return await Load(player, atOnce);
}
protected async Task<bool> Load(CECPlayer player, bool atOnce){
player.CloneSimplePropertyTo(this);
OnCloneSimpleProperty();
if (!await LoadPlayerSkeleton(atOnce)){
BMLogger.LogError("CECCloneElsePlayer::Load, Failed to load skeleton.");
return false;
}
await LoadAllPlayerEquipments();
SetNewExtendStates(0, m_aExtStates, OBJECT_EXT_STATE_COUNT);
if (player.GetOriginalShapeID() != 0){
await TransformShape(player.GetShapeMask(), true);
}
return true;
}
protected virtual bool ShouldLoadEquipment(int index)
{
return true;
}
protected virtual void OnCloneSimpleProperty(){}
public virtual CECModel GetRenderModel(){
return m_pPlayerCECModel; //m_pPetModel ? m_pPetModel : m_pPlayerModel;
//Todo: add pet model when implement pet? system
}
public void PlayActionByName(string szActName){
m_pActionController.PlayNonSkillActionWithName((int)PLAYER_ACTION_TYPE.ACT_MAX, szActName);
}
private async UniTask LoadAllPlayerEquipments()
{
var elemendataman = BrewMonster.ElementDataManProvider.GetElementDataMan();
DATA_TYPE DataType = default;
bool useDefaultUpper = true;
bool useDefaultLower = true;
bool useDefaultWrist = true;
bool useDefaultFoot = true;
int equipment = 0;
for(int i = 0; i < m_aEquips.Length; i++)
{
equipment = m_aEquips[i];
var equipData = elemendataman.get_data_ptr((uint)equipment, ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
if (equipData == null)
{
switch (i)
{
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;
}
continue;
}
switch (DataType)
{
case DATA_TYPE.DT_WEAPON_ESSENCE:
var weaponData = (WEAPON_ESSENCE)equipData;
string fileModelRight = AFile.NormalizePath(weaponData.FileModelRight, true).ToLower();
string fileModelLeft = AFile.NormalizePath(weaponData.FileModelLeft, true).ToLower();
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);
}
}
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);
}
}
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(m_iProfession, m_iGender, pArmor.RealName);
if (!armorSkinPath.EndsWith(".ecm"))
{
armorSkinPath += ".ecm";
}
var armorPrefab = await AddressableManager.Instance.LoadPrefabAsync(armorSkinPath);
if (armorPrefab != null)
{
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];
}
}
// disable/enable the default equipment
switch (nLocation)
{
case (uint)CECPlayer.SkinIndex.SKIN_UPPER_BODY_INDEX:
useDefaultUpper = false;
break;
case (uint)CECPlayer.SkinIndex.SKIN_LOWER_INDEX:
useDefaultLower = false;
break;
case (uint)CECPlayer.SkinIndex.SKIN_WRIST_INDEX:
useDefaultWrist = false;
break;
case (uint)CECPlayer.SkinIndex.SKIN_FOOT_INDEX:
useDefaultFoot = false;
break;
}
}
break;
//TODO: Handle Wings later
// 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;
// //string path1 = "models/players/通用装备/翅膀/天鹅之翼/天鹅之翼_Test.ecm";
// //var pWingPrefab = await AddressableManager.Instance.LoadPrefabAsync(path1);
// var pWingPrefab = await AddressableManager.Instance.LoadPrefabAsync(pWingData.FileModel.ToLower().Replace('\\', '/'));
// //Transform parentWing = FindChildRecursive(_pPlayerModel.transform, "HH_chibang");
// if(pWingPrefab != null)
// {
// var pflySwordObject = Instantiate(pWingPrefab).transform;
// pflySwordObject.parent = m_pPlayerCECModel.m_skeletonBuilder.GetHook("HH_chibang").transform;
// pflySwordObject.localPosition = Vector3.zero;
// pflySwordObject.localRotation = Quaternion.identity;
// pflySwordObject.localScale = Vector3.one;
// m_Wing = pflySwordObject.transform;
// m_Wing.gameObject.SetActive(false);
// }
// BMLogger.Log($"ShowEquipments():: Wingman Wing Essence: {pWingData.id} {pWingData.Name} -- {pWingData.FileModel}");
// break;
default:
break;
switch (i)
{
case InventoryConst.EQUIPIVTR_BODY:
useDefaultUpper = false;
break;
case InventoryConst.EQUIPIVTR_LEG:
useDefaultLower = false;
break;
case InventoryConst.EQUIPIVTR_WRIST:
useDefaultWrist = false;
break;
case InventoryConst.EQUIPIVTR_FOOT:
useDefaultFoot = false;
break;
}
}
}
PlayerDefaultEquipments.DefaultUpper.SetActive(useDefaultUpper);
PlayerDefaultEquipments.DefaultLower.SetActive(useDefaultLower);
PlayerDefaultEquipments.DefaultWirst.SetActive(useDefaultWrist);
PlayerDefaultEquipments.DefaultFoot.SetActive(useDefaultFoot);
}
}
}