diff --git a/Assets/PerfectWorld/Prefab/UIManager.prefab b/Assets/PerfectWorld/Prefab/UIManager.prefab index 6fa0100e2f..da7ae39923 100644 --- a/Assets/PerfectWorld/Prefab/UIManager.prefab +++ b/Assets/PerfectWorld/Prefab/UIManager.prefab @@ -4828,7 +4828,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 1 + m_IsActive: 0 --- !u!224 &7306104429597638794 RectTransform: m_ObjectHideFlags: 0 @@ -7768,7 +7768,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!4 &330835371656537333 Transform: m_ObjectHideFlags: 0 @@ -11315,7 +11315,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 1 + m_IsActive: 0 --- !u!224 &5823843793071880086 RectTransform: m_ObjectHideFlags: 0 diff --git a/Assets/PerfectWorld/Resources/UI/LoginScreenCharacterRT.renderTexture b/Assets/PerfectWorld/Resources/UI/LoginScreenCharacterRT.renderTexture index 4accc2f58e..bcbb5508fb 100644 --- a/Assets/PerfectWorld/Resources/UI/LoginScreenCharacterRT.renderTexture +++ b/Assets/PerfectWorld/Resources/UI/LoginScreenCharacterRT.renderTexture @@ -12,8 +12,8 @@ RenderTexture: Hash: 00000000000000000000000000000000 m_IsAlphaChannelOptional: 0 serializedVersion: 6 - m_Width: 512 - m_Height: 512 + m_Width: 1024 + m_Height: 1024 m_AntiAliasing: 1 m_MipCount: -1 m_DepthStencilFormat: 90 diff --git a/Assets/PerfectWorld/Scripts/Managers/A3DSkillGfxMan.cs b/Assets/PerfectWorld/Scripts/Managers/A3DSkillGfxMan.cs index d19c956ff4..0a5ce5450e 100644 --- a/Assets/PerfectWorld/Scripts/Managers/A3DSkillGfxMan.cs +++ b/Assets/PerfectWorld/Scripts/Managers/A3DSkillGfxMan.cs @@ -146,7 +146,6 @@ namespace BrewMonster pEvent.SetDelay(dwDelayTime); pEvent.SetReverse(bReverse); pEvent.SetParam(param); - BMLogger.LogError("[HoangDev] bTraceTarget=" + bTraceTarget); pEvent.SetTraceTarget(bTraceTarget); pEvent.SetModifier(dwModifier); pEvent.SetIsCluster(bCluster); diff --git a/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs b/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs index c449c659f8..70749e0773 100644 --- a/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs +++ b/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs @@ -3159,6 +3159,8 @@ namespace BrewMonster try { await SetPlayerModel((byte)m_iProfession, (byte)m_iGender); + + // load all equipments } catch (Exception ex) { diff --git a/Assets/PerfectWorld/Scripts/Objet/Shortcut/CECShortcutSet.cs b/Assets/PerfectWorld/Scripts/Objet/Shortcut/CECShortcutSet.cs index d32fa88ab6..3bf69f4fbd 100644 --- a/Assets/PerfectWorld/Scripts/Objet/Shortcut/CECShortcutSet.cs +++ b/Assets/PerfectWorld/Scripts/Objet/Shortcut/CECShortcutSet.cs @@ -506,14 +506,14 @@ namespace BrewMonster // TODO: implement other shortcut types switch ((CECShortcut.ShortcutType)pSC.GetType()) { - /* case CECShortcut.ShortcutType.SCT_COMMAND: - { - CECSCCommand cmdSC = (CECSCCommand)pSC; - data.AddRange(BitConverter.GetBytes(cmdSC.GetCommandID())); - data.AddRange(BitConverter.GetBytes((int)cmdSC.GetParam())); - break; - } - */ + case CECShortcut.ShortcutType.SCT_COMMAND: + { + CECSCCommand cmdSC = (CECSCCommand)pSC; + data.AddRange(BitConverter.GetBytes(cmdSC.GetCommandID())); + data.AddRange(BitConverter.GetBytes((int)cmdSC.GetParam())); + break; + } + case CECShortcut.ShortcutType.SCT_SKILL: { CECSCSkill skillSC = (CECSCSkill)pSC; @@ -600,7 +600,7 @@ namespace BrewMonster switch ((CECShortcut.ShortcutType)iSCType) { - /*case CECShortcut.ShortcutType.SCT_COMMAND: + case CECShortcut.ShortcutType.SCT_COMMAND: { int iCommand = BitConverter.ToInt32(pDataBuf, offset); offset += sizeof(int); @@ -612,17 +612,15 @@ namespace BrewMonster offset += sizeof(int); } - CECSCCommand pCmdSC = null; - if (iCommand == CECSCCommand.CMD_PLAYPOSE) - pCmdSC = pGameRun.GetPoseCmdShortcut(iParam); - else - pCmdSC = pGameRun.GetCmdShortcut(iCommand); - - if (pCmdSC != null) - CreateClonedShortcut(iSlot, pCmdSC); + // Recreate command shortcut from serialized command id + param. + // This is required so "action/command" shortcuts on quickbar persist after relog. + var cmd = new CECSCCommand(iCommand); + if (dwVer >= 2) + cmd.SetParam((uint)iParam); + SetShortcut(iSlot, cmd); break; - }*/ + } case CECShortcut.ShortcutType.SCT_SKILL: { @@ -935,6 +933,8 @@ namespace BrewMonster } public CECSCCommand(CECSCCommand src) { + // Keep shortcut type when cloning + m_iSCType = src.m_iSCType; m_iCommand = src.m_iCommand; m_dwParam = src.m_dwParam; } diff --git a/Assets/PerfectWorld/Scripts/Players/CECPlayerClone.cs b/Assets/PerfectWorld/Scripts/Players/CECPlayerClone.cs index db2433f3d4..940d8c3160 100644 --- a/Assets/PerfectWorld/Scripts/Players/CECPlayerClone.cs +++ b/Assets/PerfectWorld/Scripts/Players/CECPlayerClone.cs @@ -1,7 +1,7 @@ using BrewMonster.Scripts; using System.Threading.Tasks; using UnityEngine; -using CSNetwork.GPDataType; +using Cysharp.Threading.Tasks; namespace BrewMonster { public class CECClonePlayer : CECPlayer @@ -37,6 +37,7 @@ namespace BrewMonster } return false; } + protected async Task LoadFrom(CECHostPlayer player, bool atOnce) { int i = 0; @@ -87,6 +88,7 @@ namespace BrewMonster 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++){ @@ -97,6 +99,7 @@ namespace BrewMonster } return await Load(player, atOnce); } + protected async Task Load(CECPlayer player, bool atOnce){ player.CloneSimplePropertyTo(this); OnCloneSimpleProperty(); @@ -104,24 +107,205 @@ namespace BrewMonster 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); + } } } \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Skills/SkillStubs1/skill88.cs b/Assets/PerfectWorld/Scripts/Skills/SkillStubs1/skill88.cs index 3179f32537..5749a3b41c 100644 --- a/Assets/PerfectWorld/Scripts/Skills/SkillStubs1/skill88.cs +++ b/Assets/PerfectWorld/Scripts/Skills/SkillStubs1/skill88.cs @@ -86,9 +86,9 @@ namespace BrewMonster public Skill88Stub() : base(88) { cls = 1; - name = "ӿȪ"; - nativename = "ӿȪ"; - icon = "ӿȪ"; + name = "涌泉"; + nativename = "涌泉"; + icon = "涌泉"; max_level = 10; type = 1; apcost = 0; @@ -109,11 +109,40 @@ namespace BrewMonster long_range = 0; restrict_corpse = 0; allow_forms = 1; - effect = "ӿȪ"; + effect = "涌泉"; doenchant = 1; dobless = 0; commoncooldown = 0; commoncooldowntime = 0; + m_szFlyGfxPath = string.Empty; + m_szHitGrndGfxPath = string.Empty; + m_szHitGfxPath = "策划联入/人物技能/飞行/涌泉中招.gfx"; + + // GFX Movement and Behavior Parameters / GFX移动和行为参数 + m_MoveMode = (GfxMoveMode)0; + m_TargetMode = (GfxTargetMode)0; + m_AttFlyMode = (GfxAttackMode)0; + m_AttHitMode = (GfxAttackMode)0; + m_dwFlyTime = 0; + m_bTraceTarget = false; + m_FlyClusterCount = 1; + m_FlyClusterInterval = 0; + m_HitClusterCount = 1; + m_HitClusterInterval = 0; + m_bOneHit = true; + m_bFadeOut = false; + m_bRelScl = true; + m_fDefTarScl = 1.5f; + + // Area parameters (commented out) / 区域参数(已注释) + // m_bArea = false; + // m_Shape = (EmitShape)0; + // m_vSize = new Vector3(0.0f, 0.0f, 0.0f); + + // Param (commented out) / 参数(已注释) + // m_paramType = (GfxSkillValType)1; + // m_param = new GFX_SKILL_PARAM(); + // m_param.nVal = 0; restrict_weapons.Add(0); restrict_weapons.Add(292); range = new Range(); diff --git a/Assets/PerfectWorld/Scripts/Skills/SkillStubs2/skill150.cs b/Assets/PerfectWorld/Scripts/Skills/SkillStubs2/skill150.cs index 4f04ff911b..1ba1d105a0 100644 --- a/Assets/PerfectWorld/Scripts/Skills/SkillStubs2/skill150.cs +++ b/Assets/PerfectWorld/Scripts/Skills/SkillStubs2/skill150.cs @@ -86,9 +86,9 @@ namespace BrewMonster public Skill150Stub() : base(150) { cls = 4; - name = "˺ҧ"; - nativename = "˺ҧ"; - icon = "˺ҧ"; + name = "撕咬"; + nativename = "撕咬"; + icon = "撕咬"; max_level = 10; type = 1; apcost = 20; @@ -109,11 +109,40 @@ namespace BrewMonster long_range = 0; restrict_corpse = 0; allow_forms = 2; - effect = "˺ҧ"; + effect = "撕咬"; doenchant = 1; dobless = 0; commoncooldown = 0; commoncooldowntime = 0; + m_szFlyGfxPath = string.Empty; + m_szHitGrndGfxPath = string.Empty; + m_szHitGfxPath = "策划联入/人物技能/击中/撕咬击中.gfx"; + + // GFX Movement and Behavior Parameters / GFX移动和行为参数 + m_MoveMode = (GfxMoveMode)0; + m_TargetMode = (GfxTargetMode)0; + m_AttFlyMode = (GfxAttackMode)0; + m_AttHitMode = (GfxAttackMode)0; + m_dwFlyTime = 0; + m_bTraceTarget = false; + m_FlyClusterCount = 1; + m_FlyClusterInterval = 0; + m_HitClusterCount = 1; + m_HitClusterInterval = 0; + m_bOneHit = true; + m_bFadeOut = false; + m_bRelScl = true; + m_fDefTarScl = 1.5f; + + // Area parameters (commented out) / 区域参数(已注释) + // m_bArea = false; + // m_Shape = (EmitShape)0; + // m_vSize = new Vector3(0.0f, 0.0f, 0.0f); + + // Param (commented out) / 参数(已注释) + // m_paramType = (GfxSkillValType)1; + // m_param = new GFX_SKILL_PARAM(); + // m_param.nVal = 0; restrict_weapons.Add(9); restrict_weapons.Add(0); range = new Range(); diff --git a/Assets/PerfectWorld/Scripts/UI/Action/CDlgSkillSubAction.cs b/Assets/PerfectWorld/Scripts/UI/Action/CDlgSkillSubAction.cs index f8659fc4ee..80dfd55700 100644 --- a/Assets/PerfectWorld/Scripts/UI/Action/CDlgSkillSubAction.cs +++ b/Assets/PerfectWorld/Scripts/UI/Action/CDlgSkillSubAction.cs @@ -37,7 +37,7 @@ namespace BrewMonster OnShowDialog(); } - public void Init() + private void Init() { int[] objCount = { 8, 2, 2, 27 }; @@ -53,17 +53,17 @@ namespace BrewMonster image = orderTP, pLabel = orderTP.GetComponentInChildren() }); - + } } for (int j = 0; j < 27; j++) { var actionTP = Instantiate(actionTemplate, actionContain); actionTP.gameObject.SetActive(true); - + // Set up click handler for action items / 为动作项设置点击处理程序 SetupActionClickHandler(actionTP); - + m_aActionInfo.Add(new ActionInfo { image = actionTP, @@ -73,7 +73,7 @@ namespace BrewMonster //force refresh layout orderContain anc actionContain //then refresh layout of this gameobject } - public void OnShowDialog() + private void OnShowDialog() { AUIImagePicture pImage; TextMeshProUGUI pLabel; @@ -129,14 +129,14 @@ namespace BrewMonster Debug.Log($"CDlgSkillSubAction::SetupActionClickHandler():: Setting up click handler for action item: {actionImage.name}"); // Get the button component / 获取按钮组件 var button = actionImage.GetComponentInChildren(); - if (button == null) + if (button == null) return; - + // Remove existing listeners and add our custom handler / 移除现有监听器并添加我们的自定义处理程序 button.onClick.RemoveAllListeners(); button.onClick.AddListener(() => OnActionClicked(actionImage)); } - + /// /// Handle action icon click, similar to wave hand logic / 处理动作图标点击,类似于挥手逻辑 /// @@ -147,7 +147,7 @@ namespace BrewMonster // Get the shortcut from the action image / 从动作图像获取快捷方式 actionImage.Execute(); } - + [Serializable] public struct ActionInfo { diff --git a/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIImagePicture.cs b/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIImagePicture.cs index 8a8e1cb271..54e191f526 100644 --- a/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIImagePicture.cs +++ b/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIImagePicture.cs @@ -1,3 +1,4 @@ +using BrewMonster; using BrewMonster.UI; using System; using System.Collections; @@ -74,7 +75,7 @@ namespace BrewMonster.Assets.PerfectWorld.Scripts.UI.GamePlay { var rectTransform = GetComponent(); int skillID = int.Parse(this.name.Split('_')[1]); - uiManager.ShowSkillTooltip(m_hintText, rectTransform, () => EventBus.Publish(new OpenAssignSkillEvent(skillID))); + uiManager.ShowSkillTooltip(m_hintText, rectTransform, () => EventBus.Publish(new AssignSkillSelectionChangedEvent(skillID, true))); } } } diff --git a/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIToggle.cs b/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIToggle.cs index 3df0df3674..0f5d8e52c7 100644 --- a/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIToggle.cs +++ b/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIToggle.cs @@ -32,38 +32,33 @@ namespace BrewMonster } } - public struct OpenAssignSkillEvent + /// Merged open/close skill selection for assign UI (replaces OpenAssignSkillEvent + CloseAssignSkillEvent). + public struct AssignSkillSelectionChangedEvent { public int skillID; - public OpenAssignSkillEvent(int id) + public bool selected; + public AssignSkillSelectionChangedEvent(int skillId, bool selected) { - skillID = id; - } - } - public struct CloseAssignSkillEvent - { - public int skillID; - public CloseAssignSkillEvent(int id) - { - skillID = id; - } - } - public struct OpenAssignSlotEvent - { - public int slotIndex; - public OpenAssignSlotEvent(int index) - { - slotIndex = index; - } - } - public struct CloseAssignSlotEvent - { - public int slotIndex; - public CloseAssignSlotEvent(int index) - { - slotIndex = index; + skillID = skillId; + this.selected = selected; } } + // public struct OpenAssignSlotEvent + // { + // public int slotIndex; + // public OpenAssignSlotEvent(int index) + // { + // slotIndex = index; + // } + // } + // public struct CloseAssignSlotEvent + // { + // public int slotIndex; + // public CloseAssignSlotEvent(int index) + // { + // slotIndex = index; + // } + // } public struct OnAssignSkillEvent { public int skillID; @@ -74,4 +69,32 @@ namespace BrewMonster this.slotIndex = slotIndex; } } + + /// Action palette row selection for quickbar assign (same order as CDlgSkillSubAction shortcut sets). + public struct AssignActionSelectionChangedEvent + { + public int actionSetIndex; + public int shortcutIndexInSet; + public bool selected; + public AssignActionSelectionChangedEvent(int actionSetIndex, int shortcutIndexInSet, bool selected) + { + this.actionSetIndex = actionSetIndex; + this.shortcutIndexInSet = shortcutIndexInSet; + this.selected = selected; + } + } + + /// Published after an action shortcut is written to the assign cache; palette uses indices to UncheckAfterAssign. + public struct OnAssignActionEvent + { + public int actionSetIndex; + public int shortcutIndexInSet; + public int quickbarSlotIndex; + public OnAssignActionEvent(int actionSetIndex, int shortcutIndexInSet, int quickbarSlotIndex) + { + this.actionSetIndex = actionSetIndex; + this.shortcutIndexInSet = shortcutIndexInSet; + this.quickbarSlotIndex = quickbarSlotIndex; + } + } } diff --git a/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIToggleActionAssign.cs b/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIToggleActionAssign.cs new file mode 100644 index 0000000000..38986b8982 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIToggleActionAssign.cs @@ -0,0 +1,62 @@ +using System; +using UnityEngine; +using UnityEngine.UI; + +namespace BrewMonster +{ + /// Assign UI row for command/action shortcuts; toggle only — does not Execute(). + public class AUIToggleActionAssign : AUIToggle + { + [Header("ActionAssign")] + [SerializeField] private int actionSetIndex; + [SerializeField] private int shortcutIndexInSet; + + /// bool: isOn, int: actionSetIndex, int: shortcutIndexInSet + public event Action OnActionAssignToggleChanged; + + public override void Awake() + { + UnSubscribeEvents(); + SubscribeEvents(); + } + + public void OnDestroy() + { + UnSubscribeEvents(); + } + + private void UnSubscribeEvents() + { + if (uiToggle != null) + uiToggle.onValueChanged.RemoveAllListeners(); + } + + private void SubscribeEvents() + { + if (uiToggle != null) + uiToggle.onValueChanged.AddListener(OnToggleValueChanged); + } + + private void OnToggleValueChanged(bool isOn) + { + OnActionAssignToggleChanged?.Invoke(isOn, actionSetIndex, shortcutIndexInSet); + } + + public void SetActionSlotIndices(int setIndex, int indexInSet) + { + actionSetIndex = setIndex; + shortcutIndexInSet = indexInSet; + } + + public int GetActionSetIndexForAssign() => actionSetIndex; + public int GetShortcutIndexInSetForAssign() => shortcutIndexInSet; + + public Toggle GetUIToggle() => uiToggle; + + public void UncheckAfterAssign() + { + if (uiToggle != null) + uiToggle.isOn = false; + } + } +} diff --git a/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIToggleActionAssign.cs.meta b/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIToggleActionAssign.cs.meta new file mode 100644 index 0000000000..518a3808ec --- /dev/null +++ b/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIToggleActionAssign.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b8e4d32c9f5c56dab2e3f45678901bcd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIToggleAssignSlot.cs b/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIToggleAssignSlot.cs index b85c6f5b64..f595822757 100644 --- a/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIToggleAssignSlot.cs +++ b/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIToggleAssignSlot.cs @@ -1,13 +1,12 @@ -using BrewMonster.Assets.PerfectWorld.Scripts.UI.GamePlay; +using System; using UnityEngine; -using BrewMonster.UI; -using BrewMonster.Network; + namespace BrewMonster { public class AUIToggleAssignSlot : AUIToggle { - // [Header("AssignSlotToggleUI")] - // [SerializeField] int slotIndex; + public event Action OnSetSlot; + public override void Awake() { UnSubscribeEvents(); @@ -21,31 +20,21 @@ namespace BrewMonster private void UnSubscribeEvents() { uiToggle.onValueChanged.RemoveAllListeners(); - EventBus.Unsubscribe(OnAssignSlotEvent); } private void SubscribeEvents() { - Debug.Log($"HoangDev: SubscribeEvents: AssignSlots"); uiToggle.onValueChanged.AddListener(OnToggleValueChanged); - EventBus.Subscribe(OnAssignSlotEvent); } private void OnToggleValueChanged(bool isOn) { - if (isOn) - { - EventBus.Publish(new OpenAssignSlotEvent(slotIndex)); - }else{ - EventBus.Publish(new CloseAssignSlotEvent(slotIndex)); - } + OnSetSlot?.Invoke(isOn, slotIndex); } - private void OnAssignSlotEvent(OnAssignSkillEvent @event) + + public int GetSlotIndexForAssign() => slotIndex; + + public void UncheckAfterAssign() { - if(@event.slotIndex == slotIndex) - { - var processSkill = CECGameRun.Instance.GetHostPlayer().GetPositiveSkillByID(@event.skillID); - EC_Game.GetGameRun().GetUIManager().GetInGameUIMan().SetCover(this, processSkill.GetIconFile(), EC_GAMEUI_ICONS.ICONS_SKILL); - uiToggle.isOn = false; - } + uiToggle.isOn = false; } } } diff --git a/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIToggleSkillAssign.cs b/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIToggleSkillAssign.cs index 598255858a..d2f779a452 100644 --- a/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIToggleSkillAssign.cs +++ b/Assets/PerfectWorld/Scripts/UI/GamePlay/AUIToggleSkillAssign.cs @@ -1,11 +1,13 @@ -using BrewMonster.Assets.PerfectWorld.Scripts.UI.GamePlay; +using System; using UnityEngine; -using UnityEngine.UI; namespace BrewMonster { public class AUIToggleSkillAssign : AUIToggle { + /// bool: isOn, int: skillID + public event Action OnAssignToggleChanged; + public override void Awake() { UnSubscribeEvents(); @@ -19,29 +21,21 @@ namespace BrewMonster private void UnSubscribeEvents() { uiToggle.onValueChanged.RemoveAllListeners(); - EventBus.Unsubscribe(OnAssignSkillEvent); } private void SubscribeEvents() { - Debug.Log($"HoangDev: SubscribeEvents: Slot"); uiToggle.onValueChanged.AddListener(OnToggleValueChanged); - EventBus.Subscribe(OnAssignSkillEvent); } private void OnToggleValueChanged(bool isOn) { - if (isOn) - { - EventBus.Publish(new OpenAssignSkillEvent(skillID)); - }else{ - EventBus.Publish(new CloseAssignSkillEvent(skillID)); - } + OnAssignToggleChanged?.Invoke(isOn, skillID); } - private void OnAssignSkillEvent(OnAssignSkillEvent @event) + + public int GetSkillIdForAssign() => skillID; + + /// Used when assignment completes — unchecks row (fires AssignSkillSelectionChangedEvent via DlgAssignSub). + public void UncheckAfterAssign() { - if(@event.skillID != skillID) - { - return; - } uiToggle.isOn = false; } } diff --git a/Assets/PerfectWorld/Scripts/UI/GamePlay/CdlgQuickBar.cs b/Assets/PerfectWorld/Scripts/UI/GamePlay/CdlgQuickBar.cs index b29d19d512..0e76887c8c 100644 --- a/Assets/PerfectWorld/Scripts/UI/GamePlay/CdlgQuickBar.cs +++ b/Assets/PerfectWorld/Scripts/UI/GamePlay/CdlgQuickBar.cs @@ -260,7 +260,7 @@ namespace BrewMonster pClock.SetColor(new Color32(0, 0, 0, 128)); } } - + //if (pSCItem.GetInventory == InventoryConst.IVTRTYPE_EQUIPPACK) //{ // pCell.SetColor(new Color(128, 128, 255, 128)); @@ -271,6 +271,35 @@ namespace BrewMonster string itemIcon = pItem.GetIconFile(); GetGameUIMan().SetCover(pCell, itemIcon, EC_GAMEUI_ICONS.ICONS_INVENTORY); } + } + + else if (pSC.GetType() == (int)CECShortcut.ShortcutType.SCT_COMMAND) + { + iIconFile = (int)EC_GAMEUI_ICONS.ICONS_ACTION; + if (pSC.GetType() == (int)CECShortcut.ShortcutType.SCT_COMMAND) + { + CECSCCommand pCommandSC = (CECSCCommand)pSC; + if (pHost.IsInvisible()) + { + if (pCommandSC.GetCommandID() == (int)CECSCCommand.CommandID.CMD_STARTTRADE || + pCommandSC.GetCommandID() == (int)CECSCCommand.CommandID.CMD_SELLBOOTH || + pCommandSC.GetCommandID() == (int)CECSCCommand.CommandID.CMD_BINDBUDDY) + { + pCell.SetColor(new Color(128, 128, 128, 255)); + } + else + { + pCell.SetColor(new Color(255, 255, 255, 255)); + + } + } + else + { + pCell.SetColor(new Color(255, 255, 255, 255)); + } + + pCell.SetInteract(true); + } } //else if(pSC.GetType() == (int)CECShortcut.ShortcutType.SCT_PET) //{ @@ -374,6 +403,10 @@ namespace BrewMonster // fix later now haven't skill group icon yet GetGameUIMan().SetCover(pCell, "unknown", EC_GAMEUI_ICONS.ICONS_SKILL); } + else if (pSC.GetType() == (int)CECShortcut.ShortcutType.SCT_COMMAND) + { + GetGameUIMan().SetCover(pCell, ((CECSCCommand)pSC).GetIconFile(), EC_GAMEUI_ICONS.ICONS_ACTION); + } else { if (pSkill != null) diff --git a/Assets/PerfectWorld/Scripts/UI/HUDPlayer.cs b/Assets/PerfectWorld/Scripts/UI/HUDPlayer.cs index 473c4b17fe..060f487618 100644 --- a/Assets/PerfectWorld/Scripts/UI/HUDPlayer.cs +++ b/Assets/PerfectWorld/Scripts/UI/HUDPlayer.cs @@ -98,7 +98,6 @@ namespace BrewMonster if(hostPlayer == null) return; var iconStates = hostPlayer.m_aIconStates; - Debug.LogError($"UpdateBuffIcons: iconStates.Count = {iconStates.Count}"); if(buffIcons.Count < iconStates.Count) { for(int i = buffIcons.Count; i < iconStates.Count; i++) diff --git a/Assets/PerfectWorld/Scripts/UI/SkillUI/AssignSkill.cs b/Assets/PerfectWorld/Scripts/UI/SkillUI/AssignSkill.cs index d3579a1e81..3fbb173687 100644 --- a/Assets/PerfectWorld/Scripts/UI/SkillUI/AssignSkill.cs +++ b/Assets/PerfectWorld/Scripts/UI/SkillUI/AssignSkill.cs @@ -23,7 +23,6 @@ namespace BrewMonster actionButton.onClick.AddListener(OnActionButtonClicked); itemSkillButton.onClick.AddListener(OnItemButtonClicked); buttonClose.onClick.AddListener(OnCloseButtonClicked); - actionButton.interactable = false; itemSkillButton.interactable = false; } void OnEnable() diff --git a/Assets/PerfectWorld/Scripts/UI/SkillUI/DlgAssignSlots.cs b/Assets/PerfectWorld/Scripts/UI/SkillUI/DlgAssignSlots.cs index 3845fc9d0c..41894a66d7 100644 --- a/Assets/PerfectWorld/Scripts/UI/SkillUI/DlgAssignSlots.cs +++ b/Assets/PerfectWorld/Scripts/UI/SkillUI/DlgAssignSlots.cs @@ -10,6 +10,7 @@ using CSNetwork.GPDataType; using System.Collections.Generic; using System.Linq; using UnityEngine; +using UnityEngine.Serialization; using UnityEngine.UI; using static BrewMonster.PET_EGG_ESSENCE; @@ -20,7 +21,7 @@ namespace BrewMonster //[SerializeField] List m_aSkillImage = new List(); //[SerializeField] List