311 lines
14 KiB
C#
311 lines
14 KiB
C#
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);
|
||
}
|
||
}
|
||
|
||
} |