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 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 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 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 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(); var skinnedMeshRenderereFromDataList = armorObject.GetComponentsInChildren(); 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(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); } } }