diff --git a/Assets/PerfectWorld/Scripts/Common/EC_Configs.cs b/Assets/PerfectWorld/Scripts/Common/EC_Configs.cs index 51a94a36d9..e39c5b680a 100644 --- a/Assets/PerfectWorld/Scripts/Common/EC_Configs.cs +++ b/Assets/PerfectWorld/Scripts/Common/EC_Configs.cs @@ -1071,11 +1071,12 @@ namespace BrewMonster { try { + BMLogger.LogError("LoadUserConfigData: Start loading user config data"); using (MemoryStream ms = new MemoryStream(pDataBuf, 0, iDataSize)) using (BinaryReader reader = new BinaryReader(ms)) { uint dwVer = reader.ReadUInt32(); - + if (dwVer < 15) { DefaultUserConfigData(); @@ -1115,9 +1116,9 @@ namespace BrewMonster // Note: Would need EC_Game reference // g_pGame->GetA3DGFXExMan()->SetPriority(m_vs.nEffect); // Send force attack to server - /* byte forceAttack = glb_BuildPVPMask(false); - byte refuseBless = glb_BuildRefuseBLSMask(); - UnityGameSession.Instance.c2s_CmdNotifyForceAttack(forceAttack, refuseBless);*/ + byte forceAttack = EC_Utility.glb_BuildPVPMask(false); + byte refuseBless = EC_Utility.glb_BuildRefuseBLSMask(); + UnityGameSession.c2s_SendCmdNotifyForceAttack(forceAttack, refuseBless); } public void SetSceneLoadRadius(float fRadius) diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_IvtrItem/EC_IvtrItem.cs b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrItem/EC_IvtrItem.cs index 67ab258250..4c13ccd138 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_IvtrItem/EC_IvtrItem.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_IvtrItem/EC_IvtrItem.cs @@ -807,7 +807,7 @@ namespace BrewMonster.Scripts.Managers var pItem = new EC_IvtrItem(tid, expire_date); DATA_TYPE DataType = DATA_TYPE.DT_INVALID; object data = ElementDataManProvider.GetElementDataMan().get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType); - Debug.Log("Create item data: DataType: " + DataType); + //Debug.Log("Create item data: DataType: " + DataType); switch(DataType) { case DATA_TYPE.DT_WEAPON_ESSENCE: diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/C2SCommand/C2SCommandFactory.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/C2SCommand/C2SCommandFactory.cs index de485044dd..6355e2b309 100644 --- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/C2SCommand/C2SCommandFactory.cs +++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/C2SCommand/C2SCommandFactory.cs @@ -331,6 +331,16 @@ namespace CSNetwork.C2SCommand var cmdBuf = SerializeCommand(CommandID.CAST_POS_SKILL, cmd); return cmdBuf; } + public static Octets CreateNotifyForceAttack(int iForceAttack, byte refuseBless) + { + var cmd = new cmd_notify_force_attack + { + force_attack = (byte)iForceAttack, + refuse_bless = refuseBless + }; + var cmdBuf = SerializeCommand(CommandID.NOTIFY_FORCE_ATTACK, cmd); + return cmdBuf; + } public static short FloatToFix8(float x) { diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs index 11b015098a..f6a097f84a 100644 --- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs +++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs @@ -2194,19 +2194,20 @@ namespace CSNetwork.GPDataType public int exp; }; public _entry[] records; - public bool CheckValid(int buf_size, out int sz) - { sz = 0; - if (count < 0) - return false; - sz = Marshal.SizeOf() - Marshal.SizeOf<_entry[]>(); - sz += count * Marshal.SizeOf<_entry>(); - return buf_size >= sz; - } - }; + public bool CheckValid(int buf_size, out int sz) + { + sz = 0; + if (count < 0) + return false; + sz = Marshal.SizeOf() - Marshal.SizeOf<_entry[]>(); + sz += count * Marshal.SizeOf<_entry>(); + return buf_size >= sz; + } + }; // Pet type public enum GP_PET_TYPE - { + { GP_PET_CLASS_INVALID = -1, GP_PET_CLASS_MOUNT = 0, // ��� GP_PET_CLASS_COMBAT, // ս������ @@ -2216,13 +2217,13 @@ namespace CSNetwork.GPDataType GP_PET_CLASS_EVOLUTION, // ������ GP_PET_CLASS_MAX, }; - + public struct PetSkill { public int skill; public int level; - } + } public struct _evo_prop { public int r_attack; @@ -2234,29 +2235,29 @@ namespace CSNetwork.GPDataType } public enum GP_PET_SKILL_NUM { - GP_PET_SKILL_NUM = 8 + GP_PET_SKILL_NUM = 8 }; public struct info_pet - { - public int honor_point; // �øж� - public int hunger; // ������ - public int feed_time; // �ϴ�ι�������ڵ�ʱ�� - public int pet_tid; // �����ģ��ID - public int pet_vis_tid; // ����Ŀɼ�ID�����Ϊ0�����ʾ������ɼ�ID�� - public int pet_egg_tid; // ���ﵰ��ID - public int pet_class; // �������� ս�裬��裬���ͳ� - public float hp_factor; // Ѫ��������������ջ�ʱʹ�ã� 0��Ϊ���� - public short level; // ���V�� - public ushort color; // ������ɫ�����λΪ1��ʾ��Ч��Ŀǰ���������Ч - public int exp; // ���ﵱǰ���� - public int skill_point; // ʣ�༼�ܵ� - public char is_bind; // �Ƿ����˺�һ��������һ��Mask��0x01 ���˺�һ��0x02 Ѱ�����ɽ��� - public char unused; // Ŀǰ������Ч - public ushort name_len; // ���ֳ��� Ŀǰ������Ч����Ϊ�߻������������� - public char[] name; // �������� - public PetSkill[] skills; + { + public int honor_point; // �øж� + public int hunger; // ������ + public int feed_time; // �ϴ�ι�������ڵ�ʱ�� + public int pet_tid; // �����ģ��ID + public int pet_vis_tid; // ����Ŀɼ�ID�����Ϊ0�����ʾ������ɼ�ID�� + public int pet_egg_tid; // ���ﵰ��ID + public int pet_class; // �������� ս�裬��裬���ͳ� + public float hp_factor; // Ѫ��������������ջ�ʱʹ�ã� 0��Ϊ���� + public short level; // ���V�� + public ushort color; // ������ɫ�����λΪ1��ʾ��Ч��Ŀǰ���������Ч + public int exp; // ���ﵱǰ���� + public int skill_point; // ʣ�༼�ܵ� + public char is_bind; // �Ƿ����˺�һ��������һ��Mask��0x01 ���˺�һ��0x02 Ѱ�����ɽ��� + public char unused; // Ŀǰ������Ч + public ushort name_len; // ���ֳ��� Ŀǰ������Ч����Ϊ�߻������������� + public char[] name; // �������� + public PetSkill[] skills; public _evo_prop evo_prop; - public int[] reserved; // δ�� + public int[] reserved; // δ�� public info_pet(bool isDefault = true) { honor_point = 0; @@ -2276,7 +2277,8 @@ namespace CSNetwork.GPDataType name_len = 0; name = new char[16]; skills = new PetSkill[(int)GP_PET_SKILL_NUM.GP_PET_SKILL_NUM]; - evo_prop = new _evo_prop{ + evo_prop = new _evo_prop + { r_attack = 0, r_defense = 0, r_hp = 0, @@ -2286,6 +2288,17 @@ namespace CSNetwork.GPDataType }; reserved = new int[10]; } - }; + }; + public enum REFUSE_BLESS_MASK : byte + { + REFUSE_NEUTRAL_BLESS = 0x0001, // ²»½ÓÊÜÖÐÐÔ×£¸£ + REFUSE_NON_TEAMMATE_BLESS = 0x0002, // ²»½ÓÊܷǶÓÓÑ×£¸£ + }; + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct cmd_notify_force_attack + { + public byte force_attack; + public byte refuse_bless; + }; } diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs index 60cf427d0c..ba3261ad16 100644 --- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs +++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs @@ -364,11 +364,11 @@ namespace CSNetwork case ProtocolType.PROTOCOL_GETUICONFIG_RE: OnPrtcGetConfigRe(protocol); break; case ProtocolType.PROTOCOL_AUTOTEAMSETGOAL_RE: - { - // CECAutoTeam pAutoTeam = CECGameRun.Instance.GetHostPlayer().GetAutoTeam(); - // if( pAutoTeam !=null) - // pAutoTeam.OnPrtcAutoTeamSetGoalRe((AutoTeamSetGoal_Re)protocol); - } + { + // CECAutoTeam pAutoTeam = CECGameRun.Instance.GetHostPlayer().GetAutoTeam(); + // if( pAutoTeam !=null) + // pAutoTeam.OnPrtcAutoTeamSetGoalRe((AutoTeamSetGoal_Re)protocol); + } break; default: @@ -593,64 +593,64 @@ namespace CSNetwork #if UNITY_EDITOR BMLogger.LogError($"### GameDataSend: ERROR_MESSAGE: {errRaw}"); #endif - cmd_error_msg pCmd = GPDataTypeHelper.FromBytes(pDataBuf); + cmd_error_msg pCmd = GPDataTypeHelper.FromBytes(pDataBuf); #if UNITY_EDITOR BMLogger.LogError($"### GameDataSend: ERROR_MESSAGE parsed iMessage={pCmd.iMessage}"); #endif - if (pCmd.iMessage != 0) - { - // string szMsg = m_ErrorMsgs.GetWideString(pCmd.iMessage); - // if (string.IsNullOrEmpty(szMsg)) - // BMLogger.LogError("SERVER - unknown error !"); - //else if (pCmd.iMessage != 2) - //g_pGame.GetGameRun().AddChatMessage(szMsg, GP_CHAT_MISC); - } + if (pCmd.iMessage != 0) + { + // string szMsg = m_ErrorMsgs.GetWideString(pCmd.iMessage); + // if (string.IsNullOrEmpty(szMsg)) + // BMLogger.LogError("SERVER - unknown error !"); + //else if (pCmd.iMessage != 2) + //g_pGame.GetGameRun().AddChatMessage(szMsg, GP_CHAT_MISC); + } - if (pCmd.iMessage == 2) - { - // Attack target is too far - EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_TARGETISFAR, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader); - } - else if (pCmd.iMessage == 20) - { - // Failed to cast skill - //pGameRun.PostMessage(MSG_PM_CASTSKILL, MAN_PLAYER, 0, (DWORD)pDataBuf, pCmdHeader.cmd); - } - else if (pCmd.iMessage == 133 || pCmd.iMessage == 134) - { - // deal failed - //pGameRun.PostMessage(MSG_HST_BUY_SELL_FAIL, MAN_PLAYER, 0, (DWORD)pDataBuf, pCmdHeader.cmd); - } - else if (pCmd.iMessage == 158) - { - // µ±Ç°»ãÂʲ»¶Ô£¬ÖØÐÂÈ¡»ãÂÊ - //c2s_CmdGetCashMoneyRate(); - } - else if (pCmd.iMessage == 108 /*&& pGameRun.GetHostPlayer().IsInKingService()*/) - { - /* CECGameUIMan* pGameUI = pGameRun.GetUIManager().GetInGameUIMan(); - if (pGameUI) - pGameUI.EndNPCService();*/ - } - else if - (pCmd.iMessage == 108 /*&& pGameRun.GetHostPlayer().GetOfflineShopCtrl().GetNPCSevFlag() != COfflineShopCtrl::NPCSEV_NULL*/ - ) - { - /* CECGameUIMan* pGameUI = pGameRun.GetUIManager().GetInGameUIMan(); - if (pGameUI) - pGameUI.EndNPCService();*/ - } - else if (pCmd.iMessage == 175) - { - //c2s_CmdQueryParallelWorld(); - } - else if (pCmd.iMessage == 6) - { - //AP_ActionEvent(AP_EVENT_CANNOTPICKUP); - } + if (pCmd.iMessage == 2) + { + // Attack target is too far + EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_TARGETISFAR, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader); + } + else if (pCmd.iMessage == 20) + { + // Failed to cast skill + //pGameRun.PostMessage(MSG_PM_CASTSKILL, MAN_PLAYER, 0, (DWORD)pDataBuf, pCmdHeader.cmd); + } + else if (pCmd.iMessage == 133 || pCmd.iMessage == 134) + { + // deal failed + //pGameRun.PostMessage(MSG_HST_BUY_SELL_FAIL, MAN_PLAYER, 0, (DWORD)pDataBuf, pCmdHeader.cmd); + } + else if (pCmd.iMessage == 158) + { + // µ±Ç°»ãÂʲ»¶Ô£¬ÖØÐÂÈ¡»ãÂÊ + //c2s_CmdGetCashMoneyRate(); + } + else if (pCmd.iMessage == 108 /*&& pGameRun.GetHostPlayer().IsInKingService()*/) + { + /* CECGameUIMan* pGameUI = pGameRun.GetUIManager().GetInGameUIMan(); + if (pGameUI) + pGameUI.EndNPCService();*/ + } + else if + (pCmd.iMessage == 108 /*&& pGameRun.GetHostPlayer().GetOfflineShopCtrl().GetNPCSevFlag() != COfflineShopCtrl::NPCSEV_NULL*/ + ) + { + /* CECGameUIMan* pGameUI = pGameRun.GetUIManager().GetInGameUIMan(); + if (pGameUI) + pGameUI.EndNPCService();*/ + } + else if (pCmd.iMessage == 175) + { + //c2s_CmdQueryParallelWorld(); + } + else if (pCmd.iMessage == 6) + { + //AP_ActionEvent(AP_EVENT_CANNOTPICKUP); + } - break; + break; } case CommandID.SELECT_TARGET: case CommandID.UNSELECT: @@ -719,7 +719,7 @@ namespace CSNetwork case CommandID.OBJECT_CAST_INSTANT_SKILL: case CommandID.OBJECT_CAST_POS_SKILL: { - cmd_object_cast_skill pCmd2 = GPDataTypeHelper.FromBytes(pDataBuf,true); + cmd_object_cast_skill pCmd2 = GPDataTypeHelper.FromBytes(pDataBuf, true); if (ISPLAYERID(pCmd2.caster)) EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_CASTSKILL, MANAGER_INDEX.MAN_PLAYER, -1, pDataBuf, pCmdHeader); else if (ISNPCID(pCmd2.caster)) @@ -1121,6 +1121,12 @@ namespace CSNetwork SendProtocol(gamedatasend); } + public void c2s_SendCmdNotifyForceAttack(int iForceAttack, byte refuseBless) + { + gamedatasend gamedatasend = new gamedatasend(); + gamedatasend.Data = C2SCommandFactory.CreateNotifyForceAttack(iForceAttack, refuseBless); + SendProtocol(gamedatasend); + } public void c2s_SendCmdContinueAction() { gamedatasend gamedatasend = new gamedatasend(); @@ -1210,24 +1216,24 @@ namespace CSNetwork // Get referral name for adding friend or other display //TODO: a Hung lam phan select role info di - /* RoleInfo info = EC_Game.GetGameRun().GetSelectedRoleInfo(); - if (info.referrer_role > 0) - GetPlayerBriefInfo(1, info.referrer_role, 2);*/ + /* RoleInfo info = EC_Game.GetGameRun().GetSelectedRoleInfo(); + if (info.referrer_role > 0) + GetPlayerBriefInfo(1, info.referrer_role, 2);*/ } CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer(); pHost.OnAllInitDataReady(); - /* if (pHost.IsGM()) - { - CDlgCountryMap pDlgCountryMap = (CDlgCountryMap)pGameUI.GetDialog("Win_CountryMap"); - pDlgCountryMap.GetConfig(); - } + /* if (pHost.IsGM()) + { + CDlgCountryMap pDlgCountryMap = (CDlgCountryMap)pGameUI.GetDialog("Win_CountryMap"); + pDlgCountryMap.GetConfig(); + } - g_pGame.GetConfigs().ApplyOptimizeSetting(); + g_pGame.GetConfigs().ApplyOptimizeSetting(); - if (g_pGame.GetConfigs().IsMiniClient()) - CECMCDownload::GetInstance().SendGetDownloadOK();*/ + if (g_pGame.GetConfigs().IsMiniClient()) + CECMCDownload::GetInstance().SendGetDownloadOK();*/ } } private void OnPrtcPlayerBaseInfoRe(Protocol pProtocol) @@ -1434,7 +1440,7 @@ namespace CSNetwork public void c2s_SendCmdTaskNotify(byte[] pData, uint dwDataSize) { gamedatasend gamedatasend = new gamedatasend(); - gamedatasend.Data = C2SCommandFactory.CreateTaskNotifyCmd( pData, dwDataSize); + gamedatasend.Data = C2SCommandFactory.CreateTaskNotifyCmd(pData, dwDataSize); BMLogger.Log($"[MH Task] c2s_SendCmdTaskNotify Command ID : {pData[0]} Size: {dwDataSize}"); SendProtocol(gamedatasend); } @@ -1445,24 +1451,24 @@ namespace CSNetwork gamedatasend.Data = C2SCommandFactory.CreateNakeCmd(C2SCommand.CommandID.STAND_UP); SendProtocol(gamedatasend); } - + public void c2s_SendCmdAutoTeamSetGoal(int type, int goal_id, int op) { gamedatasend gamedatasend = new gamedatasend(); - gamedatasend.Data = C2SCommandFactory.CreateAutoTeamSetGoalCommand(type,goal_id, op); + gamedatasend.Data = C2SCommandFactory.CreateAutoTeamSetGoalCommand(type, goal_id, op); SendProtocol(gamedatasend); } public void c2s_CmdGoto(float x, float y, float z) { - c2s_SendCmdGoto(x, y, z); + c2s_SendCmdGoto(x, y, z); } - + // Send C2S::GOTO command data void c2s_SendCmdGoto(float x, float y, float z) { gamedatasend gamedatasend = new gamedatasend(); - gamedatasend.Data = C2SCommandFactory.CreateGoToCommed( x, y, z); + gamedatasend.Data = C2SCommandFactory.CreateGoToCommed(x, y, z); SendProtocol(gamedatasend); } diff --git a/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs b/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs index 4db362886e..63af6537f0 100644 --- a/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs +++ b/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs @@ -316,6 +316,10 @@ namespace BrewMonster.Network public static void c2s_CmdNPCSevHeal() { + } + public static void c2s_SendCmdNotifyForceAttack(int iForceAttack, byte refuseBless) + { + Instance._gameSession.c2s_SendCmdNotifyForceAttack(iForceAttack, refuseBless); } public static void c2s_CmdNPCSevAcceptTask(int idTask,int idStorage,int idRefreshItem) { diff --git a/Assets/PerfectWorld/Scripts/Objet/Shortcut/CECShortcutSet.cs b/Assets/PerfectWorld/Scripts/Objet/Shortcut/CECShortcutSet.cs index 6029803c8b..b1341287f6 100644 --- a/Assets/PerfectWorld/Scripts/Objet/Shortcut/CECShortcutSet.cs +++ b/Assets/PerfectWorld/Scripts/Objet/Shortcut/CECShortcutSet.cs @@ -636,100 +636,100 @@ namespace BrewMonster break; } - /* case CECShortcut.ShortcutType.SCT_ITEM: - { - int iPack = BitConverter.ToInt32(pDataBuf, offset); - offset += sizeof(int); - int iIvtrSlot = BitConverter.ToInt32(pDataBuf, offset); - offset += sizeof(int); - int idItem = BitConverter.ToInt32(pDataBuf, offset); - offset += sizeof(int); +/* case CECShortcut.ShortcutType.SCT_ITEM: + { + int iPack = BitConverter.ToInt32(pDataBuf, offset); + offset += sizeof(int); + int iIvtrSlot = BitConverter.ToInt32(pDataBuf, offset); + offset += sizeof(int); + int idItem = BitConverter.ToInt32(pDataBuf, offset); + offset += sizeof(int); - CECInventory pPack = pHost.GetPack(iPack); - if (pPack == null) - { - Debug.LogError("CECShortcutSet::LoadConfigData - Invalid inventory"); - return false; - } + CECInventory pPack = pHost.GetPack(iPack); + if (pPack == null) + { + Debug.LogError("CECShortcutSet::LoadConfigData - Invalid inventory"); + return false; + } - CECIvtrItem pItem = pPack.GetItem(iIvtrSlot); - if (pItem != null) - CreateItemShortcut(iSlot, iPack, iIvtrSlot, pItem); + CECIvtrItem pItem = pPack.GetItem(iIvtrSlot); + if (pItem != null) + CreateItemShortcut(iSlot, iPack, iIvtrSlot, pItem); - break; - } + break; + }*/ - case CECShortcut.ShortcutType.SCT_SKILLGRP: - { - if (dwVer >= 3) - { - int iGroupIdx = BitConverter.ToInt32(pDataBuf, offset); - offset += sizeof(int); + case CECShortcut.ShortcutType.SCT_SKILLGRP: + { + if (dwVer >= 3) + { + int iGroupIdx = BitConverter.ToInt32(pDataBuf, offset); + offset += sizeof(int); - if (iGroupIdx >= 0) - CreateSkillGroupShortcut(iSlot, iGroupIdx); - } - else - { - Debug.LogError("CECShortcutSet::LoadConfigData - Invalid version for skill group"); - return false; - } - break; - } + if (iGroupIdx >= 0) + CreateSkillGroupShortcut(iSlot, iGroupIdx); + } + else + { + Debug.LogError("CECShortcutSet::LoadConfigData - Invalid version for skill group"); + return false; + } + break; + } - case CECShortcut.ShortcutType.SCT_PET: - { - if (dwVer >= 4) - { - int iPetIndex = BitConverter.ToInt32(pDataBuf, offset); - offset += sizeof(int); + /*case CECShortcut.ShortcutType.SCT_PET: + { + if (dwVer >= 4) + { + int iPetIndex = BitConverter.ToInt32(pDataBuf, offset); + offset += sizeof(int); - if (iPetIndex >= 0) - CreatePetShortcut(iSlot, iPetIndex); - } - else - { - Debug.LogError("CECShortcutSet::LoadConfigData - Invalid version for pet"); - return false; - } - break; - } + if (iPetIndex >= 0) + CreatePetShortcut(iSlot, iPetIndex); + } + else + { + Debug.LogError("CECShortcutSet::LoadConfigData - Invalid version for pet"); + return false; + } + break; + } - case CECShortcut.ShortcutType.SCT_AUTOFASHION: - { - if (dwVer >= 5) - { - int iAutoFashionIndex = BitConverter.ToInt32(pDataBuf, offset); - offset += sizeof(int); + case CECShortcut.ShortcutType.SCT_AUTOFASHION: + { + if (dwVer >= 5) + { + int iAutoFashionIndex = BitConverter.ToInt32(pDataBuf, offset); + offset += sizeof(int); - if (iAutoFashionIndex >= 0) - CreateAutoFashionShortcut(iSlot, iAutoFashionIndex); - } - else - { - Debug.LogError("CECShortcutSet::LoadConfigData - Invalid version for auto fashion"); - return false; - } - break; - } + if (iAutoFashionIndex >= 0) + CreateAutoFashionShortcut(iSlot, iAutoFashionIndex); + } + else + { + Debug.LogError("CECShortcutSet::LoadConfigData - Invalid version for auto fashion"); + return false; + } + break; + } - case CECShortcut.ShortcutType.SCT_SYSMODULE: - { - if (dwVer > 10) - { - int iSys = BitConverter.ToInt32(pDataBuf, offset); - offset += sizeof(int); + case CECShortcut.ShortcutType.SCT_SYSMODULE: + { + if (dwVer > 10) + { + int iSys = BitConverter.ToInt32(pDataBuf, offset); + offset += sizeof(int); - if (iSys >= 0) - CreateSystemModuleShortcut(iSlot, iSys); - } - else - { - Debug.LogError("CECShortcutSet::LoadConfigData - Invalid version for system module"); - return false; - } - break; - }*/ + if (iSys >= 0) + CreateSystemModuleShortcut(iSlot, iSys); + } + else + { + Debug.LogError("CECShortcutSet::LoadConfigData - Invalid version for system module"); + return false; + } + break; + }*/ /* default: //TODO: uncomment diff --git a/Assets/PerfectWorld/Scripts/Skills/FLOW_COMBO_SKILL_CLICK.md b/Assets/PerfectWorld/Scripts/Skills/FLOW_COMBO_SKILL_CLICK.md new file mode 100644 index 0000000000..74a32e2df7 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Skills/FLOW_COMBO_SKILL_CLICK.md @@ -0,0 +1,631 @@ +# Flow: Player Clicks Shortcut to Use Combo Skill + +## Overview + +This document describes the complete flow from when a player clicks on a combo skill shortcut in the UI until the combo skill sequence is executed. + +--- + +## Complete Flow Diagram + +``` +┌─────────────────────────────────────────────────────────────┐ +│ 1. PLAYER CLICKS COMBO SKILL SHORTCUT │ +│ (Mouse click on shortcut bar OR keyboard hotkey) │ +└─────────────────┬───────────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────────────────────────────┐ +│ 2. UI EVENT HANDLER │ +│ File: EC_GameUIEvent.cpp (line 173) │ +│ OR EC_GameUIMan.cpp (line 1320, 1344) │ +│ │ +│ CECShortcut* pSC = GetShortcutFromUI(); │ +│ pSC->Execute(); // ← Calls Execute() on shortcut │ +└─────────────────┬───────────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────────────────────────────┐ +│ 3. CECSCSkillGrp::Execute() │ +│ File: EC_Shortcut.cpp (line 712-716) │ +│ │ +│ bool CECSCSkillGrp::Execute() │ +│ { │ +│ CECHostPlayer* pHost = GetHostPlayer(); │ +│ pHost->ApplyComboSkill(m_iGroupIdx); // ← Group ID │ +│ return true; │ +│ } │ +└─────────────────┬───────────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────────────────────────────┐ +│ 4. CECHostPlayer::ApplyComboSkill() │ +│ File: EC_HostPlayer.cpp (line 7696-7721) │ +│ │ +│ bool ApplyComboSkill(int iGroup, ...) │ +│ { │ +│ ClearComboSkill(); // Clear any existing combo │ +│ │ +│ m_pComboSkill = new CECComboSkill; │ +│ │ +│ // Initialize combo skill with group index │ +│ m_pComboSkill->Init(this, iGroup, │ +│ m_idSelTarget, │ +│ bForceAttack, │ +│ bIgnoreAtkLoop); │ +│ │ +│ // Start first skill in combo │ +│ m_pComboSkill->Continue(m_bMelee); │ +│ │ +│ return true; │ +│ } │ +└─────────────────┬───────────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────────────────────────────┐ +│ 5. CECComboSkill::Init() │ +│ File: EC_ComboSkill.cpp (line 74-123) │ +│ │ +│ bool Init(CECHostPlayer* pHost, int iGroup, ...) │ +│ { │ +│ // Load combo skill data from configs │ +│ CECConfigs* pCfg = GetConfigs(); │ +│ m_cs = pCfg->GetVideoSettings() │ +│ .comboSkill[iGroup]; // ← Load combo │ +│ │ +│ // Find loop start flag (if any) │ +│ // Move cursor to first valid skill │ +│ StepCursor(true); │ +│ │ +│ return true; │ +│ } │ +└─────────────────┬───────────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────────────────────────────┐ +│ 6. CECComboSkill::Continue() - FIRST SKILL │ +│ File: EC_ComboSkill.cpp (line 128-217) │ +│ │ +│ bool Continue(bool bMeleeing) │ +│ { │ +│ int idSkill = GetNextSkill(); // Get skill ID │ +│ │ +│ if (idSkill > 0) // Regular skill │ +│ { │ +│ // Execute skill │ +│ bool bRet = m_pHost->ApplySkillShortcut( │ +│ idSkill, true, m_idTarget, ...); │ +│ │ +│ if (bRet) │ +│ { │ +│ StepCursor(false); // Move to next skill │ +│ return true; // Continue combo │ +│ } │ +│ } │ +│ else if (idSkill == SID_ATTACK) // Normal attack │ +│ { │ +│ m_pHost->CmdNormalAttack(...); │ +│ StepCursor(false); │ +│ return true; │ +│ } │ +│ │ +│ return false; // Combo stopped │ +│ } │ +└─────────────────┬───────────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────────────────────────────┐ +│ 7. SKILL EXECUTION │ +│ File: EC_HostPlayer.cpp │ +│ │ +│ ApplySkillShortcut() executes the skill: │ +│ - Checks if skill is ready │ +│ - Sends command to server │ +│ - Starts skill animation │ +│ - Updates cooldown timers │ +└─────────────────┬───────────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────────────────────────────┐ +│ 8. CONTINUE COMBO (After Skill Finishes) │ +│ File: EC_HostPlayer.cpp (line 4129-4135, 6244-6252) │ +│ │ +│ When skill finishes or melee state changes: │ +│ │ +│ if (m_pComboSkill && !m_pComboSkill->IsStop()) │ +│ { │ +│ // Post message to continue combo │ +│ PostMessage(MSG_HST_CONTINUECOMBOSKILL, │ +│ MAN_PLAYER, 0, │ +│ bMeleeing ? 1 : 0, │ +│ m_pComboSkill->GetGroupIndex()); │ +│ } │ +└─────────────────┬───────────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────────────────────────────┐ +│ 9. OnMsgContinueComboSkill() │ +│ File: EC_HostPlayer.cpp (line 6261-6268) │ +│ │ +│ void OnMsgContinueComboSkill(const ECMSG &Msg) │ +│ { │ +│ bool bMeleeing = (Msg.dwParam1 == 1); │ +│ int iGroupID = (int)Msg.dwParam2; │ +│ │ +│ if (m_pComboSkill && │ +│ m_pComboSkill->GetGroupIndex() == iGroupID && │ +│ !m_pComboSkill->IsStop()) │ +│ { │ +│ m_pComboSkill->Continue(bMeleeing); // ← Loop │ +│ } │ +│ } │ +└─────────────────┬───────────────────────────────────────────┘ + ↓ +┌─────────────────────────────────────────────────────────────┐ +│ 10. REPEAT STEPS 6-9 │ +│ Until combo skill sequence completes or stops │ +│ │ +│ - Continue() executes next skill in sequence │ +│ - StepCursor() moves to next position │ +│ - If loop flag found, cursor jumps back │ +│ - If end reached, combo stops │ +└─────────────────────────────────────────────────────────────┘ +``` + +--- + +## Detailed Step-by-Step Flow + +### **STEP 1: Player Clicks Shortcut** +**Trigger**: +- Mouse click on shortcut bar UI element +- OR Keyboard hotkey (1-9, Q, E, R, etc.) + +**UI Elements**: +- `DlgQuickBar` - Main shortcut bar dialog +- `Item_01`, `Item_02`, ... - Shortcut slot UI controls + +--- + +### **STEP 2: UI Event Handler** +**File**: `EC_GameUIEvent.cpp` (line 163-174) + +```cpp +// Mouse click handler +if (abs(x - m_ptLButtonDown.x) < 3 && abs(y - m_ptLButtonDown.y) < 3) +{ + if (strstr(pDlgSrc->GetName(), "Win_Quickbar") || + 0 == stricmp(pDlgSrc->GetName(), "Win_Action")) + { + CECShortcut* pSC = (CECShortcut*)pDlg->GetDataPtr(); + if (pSC) + pSC->Execute(); // ← Execute shortcut + } +} +``` + +**OR Keyboard Handler**: +**File**: `EC_GameUIMan.cpp` (line 1316-1321) + +```cpp +// Keyboard shortcut handler +int nCurPanel1 = CDlgQuickBar::GetCurPanel1(); +CECShortcutSet* pSCS = pHost->GetShortcutSet1(nCurPanel1 - 1); +CECShortcut* pSC = pSCS->GetShortcut(iUsage - LKEY_UI_QUICK9_SC1); +if (pSC) + pSC->Execute(); // ← Execute shortcut +``` + +--- + +### **STEP 3: CECSCSkillGrp::Execute()** +**File**: `EC_Shortcut.cpp` (line 712-716) + +```cpp +bool CECSCSkillGrp::Execute() +{ + CECHostPlayer* pHost = g_pGame->GetGameRun()->GetHostPlayer(); + pHost->ApplyComboSkill(m_iGroupIdx); // ← Group index (0-EC_COMBOSKILL_NUM-1) + return true; +} +``` + +**Key Points**: +- `m_iGroupIdx` is the combo skill group index (0, 1, 2, ...) +- This was set when the shortcut was created from config data + +--- + +### **STEP 4: CECHostPlayer::ApplyComboSkill()** +**File**: `EC_HostPlayer.cpp` (line 7696-7721) + +```cpp +bool CECHostPlayer::ApplyComboSkill(int iGroup, bool bIgnoreAtkLoop, int iForceAtk) +{ + // Clear any existing combo skill + ClearComboSkill(); + + // Create new combo skill object + if (!(m_pComboSkill = new CECComboSkill)) + return false; + + // Determine force attack flag + bool bForceAttack; + if (iForceAtk < 0) + bForceAttack = glb_GetForceAttackFlag(NULL); + else + bForceAttack = iForceAtk > 0 ? true : false; + + // Initialize combo skill + if (!(m_pComboSkill->Init(this, iGroup, m_idSelTarget, bForceAttack, bIgnoreAtkLoop))) + { + delete m_pComboSkill; + m_pComboSkill = NULL; + return false; + } + + // Start the combo skill sequence + m_pComboSkill->Continue(m_bMelee); + + return true; +} +``` + +**Key Points**: +- Clears any existing combo skill first +- Creates new `CECComboSkill` object +- Initializes with group index, target, force attack flag +- Immediately calls `Continue()` to start first skill + +--- + +### **STEP 5: CECComboSkill::Init()** +**File**: `EC_ComboSkill.cpp` (line 74-123) + +```cpp +bool CECComboSkill::Init(CECHostPlayer* pHost, int iGroup, int idTarget, + bool bForceAttack, bool bIgnoreAtkLoop) +{ + if (iGroup < 0 || iGroup >= EC_COMBOSKILL_NUM) + return false; + + m_pHost = pHost; + m_iGroup = iGroup; + m_iCursor = 0; + m_bStop = false; + m_idTarget = idTarget; + m_bForceAtk = bForceAttack; + m_bIgnoreAtkLoop = bIgnoreAtkLoop; + + // ★ KEY: Load combo skill data from configs + CECConfigs* pCfg = g_pGame->GetConfigs(); + m_cs = pCfg->GetVideoSettings().comboSkill[iGroup]; + // m_cs contains: + // - m_cs.nIcon: Icon index + // - m_cs.idSkill[]: Array of skill IDs in sequence + + // Find the last loop start flag (SID_LOOPSTART = -2) + m_iLoopStart = -1; + for (int i = 0; i < EC_COMBOSKILL_LEN; i++) + { + if (m_cs.idSkill[i] == SID_LOOPSTART) + m_iLoopStart = i; + } + + // Validate loop start flag + if (m_iLoopStart >= 0) + { + // Check if there's a valid skill after loop start + // ... validation code ... + } + + // Move cursor to first valid skill position + StepCursor(true); + + return true; +} +``` + +**Key Points**: +- Loads combo skill data from `EC_Configs::m_vs.comboSkill[iGroup]` +- Finds loop start flag if present +- Moves cursor to first valid skill + +--- + +### **STEP 6: CECComboSkill::Continue() - Execute Skills** +**File**: `EC_ComboSkill.cpp` (line 128-217) + +```cpp +bool CECComboSkill::Continue(bool bMeleeing) +{ + // Check if combo should stop + if (m_bStop || !m_cs.nIcon || !m_pHost || + m_iCursor < 0 || m_iCursor >= EC_COMBOSKILL_LEN || + (m_idTarget != m_pHost->GetSelectedTarget() && !m_bIgnoreAtkLoop)) + return false; + + int idSkill = GetNextSkill(); // Get skill ID at current cursor position + + if (idSkill > 0) // Regular skill + { + // Execute the skill + bool bRet = m_pHost->ApplySkillShortcut(idSkill, true, m_idTarget, + m_bForceAtk ? 1 : 0); + + if (!bRet) + { + // Skill failed, try next skill + StepCursor(false); + if (!IsStop()) + { + // Post message to continue combo + g_pGame->GetGameRun()->PostMessage(MSG_HST_CONTINUECOMBOSKILL, + MAN_PLAYER, 0, + bMeleeing ? 1 : 0, + m_iGroup); + } + else + { + // Combo finished + AP_ActionEvent(AP_EVENT_COMBOFINISH); + } + return false; + } + else + { + // Skill executed successfully + AP_ActionEvent(AP_EVENT_COMBOCONTINUE); + } + } + else if (idSkill == SID_ATTACK) // Normal attack (-1) + { + if (!bMeleeing && !m_bIgnoreAtkLoop) + { + bool bRet = m_pHost->CmdNormalAttack(false, true, m_idTarget, + m_bForceAtk ? 1 : 0); + if (!bRet) + { + StepCursor(false); + if (!IsStop()) + { + g_pGame->GetGameRun()->PostMessage(MSG_HST_CONTINUECOMBOSKILL, + MAN_PLAYER, 0, + bMeleeing ? 1 : 0, + m_iGroup); + } + return false; + } + } + } + + // Move cursor to next skill + StepCursor(false); + + return true; +} +``` + +**Key Points**: +- Gets next skill ID from `m_cs.idSkill[m_iCursor]` +- Executes skill via `ApplySkillShortcut()` +- Moves cursor forward with `StepCursor(false)` +- If skill fails, posts message to try next skill + +--- + +### **STEP 7: StepCursor() - Move Through Sequence** +**File**: `EC_ComboSkill.cpp` (line 220-247) + +```cpp +void CECComboSkill::StepCursor(bool bFirst) +{ + if (bFirst) + m_iCursor = -1; // Start before first position + + while (1) + { + m_iCursor++; + + if (m_iCursor >= EC_COMBOSKILL_LEN) // Reached end + { + // If loop flag exists, jump back to loop start + if (m_iLoopStart >= 0 && !m_bIgnoreAtkLoop) + m_iCursor = m_iLoopStart; + else + { + m_bStop = true; // Combo finished + return; + } + } + else + { + int id = m_cs.idSkill[m_iCursor]; + // Find next valid skill (id > 0) or attack (id == SID_ATTACK) + if (id > 0 || (id == SID_ATTACK && !m_bIgnoreAtkLoop)) + break; // Found valid skill + } + } +} +``` + +**Key Points**: +- Moves cursor forward through skill array +- Skips empty slots (id == 0) +- If loop flag exists, jumps back to loop start +- Sets `m_bStop = true` when combo ends + +--- + +### **STEP 8: Continue Combo After Skill Finishes** +**File**: `EC_HostPlayer.cpp` (line 4129-4135, 6244-6252) + +When a skill finishes or melee state changes: + +```cpp +// After melee attack finishes +if (m_bMelee && m_pComboSkill && !m_pComboSkill->IsStop()) +{ + if (CECAutoPolicy::GetInstance().IsAutoPolicyEnabled()) + g_pGame->GetGameRun()->PostMessage(MSG_HST_CONTINUECOMBOSKILL, + MAN_PLAYER, 0, 1, + m_pComboSkill->GetGroupIndex()); + else + m_pComboSkill->Continue(true); +} + +// After other actions finish +if (bDoOtherThing) +{ + if (m_pComboSkill && !m_pComboSkill->IsStop()) + { + if (CECAutoPolicy::GetInstance().IsAutoPolicyEnabled()) + g_pGame->GetGameRun()->PostMessage(MSG_HST_CONTINUECOMBOSKILL, + MAN_PLAYER, 0, 0, + m_pComboSkill->GetGroupIndex()); + else + m_pComboSkill->Continue(false); + } +} +``` + +**Key Points**: +- Posts `MSG_HST_CONTINUECOMBOSKILL` message to continue combo +- Message includes melee state and group index +- Allows combo to continue asynchronously + +--- + +### **STEP 9: OnMsgContinueComboSkill()** +**File**: `EC_HostPlayer.cpp` (line 6261-6268) + +```cpp +void CECHostPlayer::OnMsgContinueComboSkill(const ECMSG &Msg) +{ + bool bMeleeing = (Msg.dwParam1 == 1); + if (bMeleeing != m_bMelee) + bMeleeing = m_bMelee; // Use current melee state + + int iGroupID = (int)Msg.dwParam2; + + // Verify combo is still active and matches group + if (m_pComboSkill && + m_pComboSkill->GetGroupIndex() == iGroupID && + !m_pComboSkill->IsStop()) + { + m_pComboSkill->Continue(bMeleeing); // Continue to next skill + } +} +``` + +**Key Points**: +- Handles message to continue combo +- Verifies combo is still active +- Calls `Continue()` again to execute next skill + +--- + +### **STEP 10: Loop Until Complete** + +Steps 6-9 repeat until: +- All skills in sequence are executed +- Combo reaches end (no loop flag) +- Combo is stopped (`m_bStop = true`) +- Target changes (unless `bIgnoreAtkLoop` is true) + +--- + +## Key Data Structures + +### **EC_COMBOSKILL** +```cpp +struct EC_COMBOSKILL +{ + BYTE nIcon; // Icon index (0-N) + short idSkill[EC_COMBOSKILL_LEN]; // Array of skill IDs +}; +``` + +**Special Skill IDs**: +- `SID_ATTACK = -1`: Normal attack +- `SID_LOOPSTART = -2`: Loop start flag +- `0`: Empty slot (skipped) +- `> 0`: Regular skill ID + +### **CECComboSkill Member Variables** +```cpp +CECHostPlayer* m_pHost; // Host player +EC_COMBOSKILL m_cs; // Combo skill data +int m_iGroup; // Group index (0-EC_COMBOSKILL_NUM-1) +int m_iCursor; // Current position in sequence +bool m_bStop; // Stop flag +int m_iLoopStart; // Loop start index (-1 if no loop) +int m_idTarget; // Attack target +bool m_bForceAtk; // Force attack flag +bool m_bIgnoreAtkLoop; // Ignore attack loop flag +``` + +--- + +## Important Files + +| File | Purpose | +|------|---------| +| `EC_GameUIEvent.cpp` | Handles mouse clicks on shortcuts | +| `EC_GameUIMan.cpp` | Handles keyboard shortcuts | +| `EC_Shortcut.cpp` | `CECSCSkillGrp::Execute()` - Entry point | +| `EC_HostPlayer.cpp` | `ApplyComboSkill()` - Creates and starts combo | +| `EC_ComboSkill.cpp` | `CECComboSkill` class - Manages combo sequence | +| `EC_Configs.cpp` | Stores combo skill data in `m_vs.comboSkill[]` | + +--- + +## For Unity Port + +To implement this in Unity: + +1. **Shortcut Click Handler**: + ```csharp + public void OnShortcutClicked(int slotIndex) + { + CECShortcut shortcut = GetShortcut(slotIndex); + if (shortcut != null && shortcut.GetType() == SCT_SKILLGRP) + { + CECSCSkillGrp skillGrp = (CECSCSkillGrp)shortcut; + GetHostPlayer().ApplyComboSkill(skillGrp.GetGroupIndex()); + } + } + ``` + +2. **ApplyComboSkill**: + ```csharp + public bool ApplyComboSkill(int groupIndex) + { + ClearComboSkill(); + + m_comboSkill = new CECComboSkill(); + if (!m_comboSkill.Init(this, groupIndex, m_selectedTarget, + forceAttack, ignoreAtkLoop)) + return false; + + m_comboSkill.Continue(m_isMeleeing); + return true; + } + ``` + +3. **Continue Combo**: + ```csharp + // After skill finishes + if (m_comboSkill != null && !m_comboSkill.IsStop()) + { + StartCoroutine(ContinueComboAfterDelay()); + } + ``` + +--- + +## Summary + +**Complete Flow**: +1. Player clicks shortcut → `pSC->Execute()` +2. `CECSCSkillGrp::Execute()` → `ApplyComboSkill(groupIndex)` +3. `ApplyComboSkill()` → Creates `CECComboSkill` and calls `Init()` +4. `Init()` → Loads combo data from configs +5. `Continue()` → Executes first skill +6. After skill finishes → Posts `MSG_HST_CONTINUECOMBOSKILL` +7. `OnMsgContinueComboSkill()` → Calls `Continue()` again +8. Repeat until combo completes + +**Key**: The combo skill data (`EC_COMBOSKILL`) is loaded from `EC_Configs::m_vs.comboSkill[groupIndex]`, which was loaded from server in `LoadUserConfigData()`. diff --git a/Assets/PerfectWorld/Scripts/Skills/FLOW_COMBO_SKILL_CLICK.md.meta b/Assets/PerfectWorld/Scripts/Skills/FLOW_COMBO_SKILL_CLICK.md.meta new file mode 100644 index 0000000000..d52ee8bad0 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Skills/FLOW_COMBO_SKILL_CLICK.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 09b07dfdbdd8c094d9ded2ba81316847 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PerfectWorld/Scripts/UI/GamePlay/CdlgQuickBar.cs b/Assets/PerfectWorld/Scripts/UI/GamePlay/CdlgQuickBar.cs index 72b49c472a..d37631cb45 100644 --- a/Assets/PerfectWorld/Scripts/UI/GamePlay/CdlgQuickBar.cs +++ b/Assets/PerfectWorld/Scripts/UI/GamePlay/CdlgQuickBar.cs @@ -23,6 +23,213 @@ namespace BrewMonster /// Apply for a license remove later /// /// + //public bool UpdateShortcuts() + //{ + // CECShortcut pSC; + // Image skillImage; + // CECSCSkill pSCSkill; + // int iIconFile, nMax; + // AUIImagePicture pCell; + // CECSkill pSkill = new CECSkill(-1, -1); + // AUIClockIcon pClock; + + + // int nCurPanel9 = GetCurPanel1(); + // int nCurPanel8 = GetCurPanel2(); + + // CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer(); + // if (pHost == null) return false; + // var a_pSCS = new List(); + // var a_pszPanel = new List(); + // GetQuickBarNameAndSC(pHost, a_pszPanel, a_pSCS, nCurPanel9, nCurPanel8); + + // for (int i = 0; i <= 1(int)a_pSCS.Count; i++) + // { + // if (a_pSCS[i] == null) + // continue; + + // CDlgQuickBar* pQuickBar = dynamic_cast(GetGameUIMan()->GetDialog(a_pszPanel[i])); + // if (!pQuickBar || !pQuickBar->IsShow()) continue; + // int slotIndex = 0; + // for (int j = 0; j < a_pSCS.Count; j++) + // { + // pCell = AUIImagePictureList[slotIndex]; + // pSC = a_pSCS[i].GetShortcut(j); + // pClock = pCell.GetClockIcon(); + // pClock.SetProgressRange(0, 1); + // pClock.SetProgressPos(1); + // if (pSC != null) + // { + // if (pSC.GetType() == (int)CECShortcut.ShortcutType.SCT_SKILL) + // { + // iIconFile = (int)EC_GAMEUI_ICONS.ICONS_SKILL; + // pSCSkill = (CECSCSkill)pSC; + // pSkill = pSCSkill.GetSkill(); + // if (falsem_bDelGoblinSkillSC && GNET::ElementSkill::IsGoblinSkill(pSkill->GetSkillID())) + // { + // a_pSCS[i]->SetShortcut(j, NULL); + // pSC = NULL; + // } + // else + // { + // if (pSkill != null && pSkill.ReadyToCast() && pHost.GetPrepSkill() != pSkill) + // { + // if (ElementSkill.IsGoblinSkill((uint)pSkill.GetSkillID())) + // { + // if (pHostGoblin && !pHostGoblin->CheckSkillCastCondition(pSkill)) + // { + // pCell->SetColor(A3DCOLORRGB(255, 255, 255)); + // } + // else + // { + // pCell->SetColor(A3DCOLORRGB(128, 128, 128)); + // } + // } + // else + // { + // if (pHost.CheckSkillCastCondition(pSkill) == 0) + // { + // //pCell.SetColor(A3DCOLORRGB(255, 255, 255)); + // } + // else + // { + // //pCell.SetColor(A3DCOLORRGB(128, 128, 128)); + // } + // } + // } + // else + // pClock.SetColor(A3DCOLORRGBA(0, 0, 0, 128)); + // if (pSkill != null && (pSkill.GetCoolingTime() > 0 || + // pHost.GetPrepSkill() == pSkill)) + // { + // pClock.SetProgressRange(0, pSkill.GetCoolingTime()); + // if (pHost.GetPrepSkill() == pSkill) + // { + // pClock.SetProgressPos(0); + // } + // else + // { + // pClock.SetProgressPos(pSkill.GetCoolingTime() - pSkill.GetCoolingCnt()); + // } + // } + // } + // } + // else if (pSC->GetType() == CECShortcut::SCT_ITEM) + // { + // iIconFile = CECGameUIMan::ICONS_INVENTORY; + // pCell->SetColor(A3DCOLORRGB(255, 255, 255)); + // pSCItem = (CECSCItem*)pSC; + // pIvtr = GetHostPlayer()->GetPack(pSCItem->GetInventory()); + // pItem = pIvtr->GetItem(pSCItem->GetIvtrSlot()); + // if (pItem && pItem->GetCoolTime(&nMax) > 0) + // { + // pClock->SetProgressRange(0, nMax); + // pClock->SetProgressPos(nMax - pItem->GetCoolTime()); + // pClock->SetColor(A3DCOLORRGBA(0, 0, 0, 128)); + // } + // if (pSCItem->GetInventory() == IVTRTYPE_EQUIPPACK) + // pCell->SetColor(A3DCOLORRGBA(128, 128, 255, 128)); + // } + // else if (pSC->GetType() == CECShortcut::SCT_PET) + // { + // pSCPet = (CECSCPet*)pSC; + // CECPetData* pPet = pPetCorral->GetPetData(pSCPet->GetPetIndex()); + // iIconFile = CECGameUIMan::ICONS_INVENTORY; + // pCell->SetColor(A3DCOLORRGB(255, 255, 255)); + // if (pPet) + // { + // // dead combat pet + // if ((pPet->GetClass() == GP_PET_CLASS_COMBAT || pPet->GetClass() == GP_PET_CLASS_EVOLUTION) && pPet->GetHPFactor() == 0.0f) + // { + // pCell->SetColor(A3DCOLORRGB(128, 128, 128)); + // } + // // current active pet + // else if (pSCPet->IsActivePet()) + // { + // pCell->SetColor(A3DCOLORRGB(255, 255, 0)); + // } + // } + // } + // else if (pSC->GetType() == CECShortcut::SCT_AUTOFASHION) + // { + // iIconFile = CECGameUIMan::ICONS_SUITE; + // fashionCoolTime = pHost->GetCoolTime(GP_CT_EQUIP_FASHION_ITEM, &fashionCoolTimeMax); + // pCell->SetColor(A3DCOLORRGB(255, 255, 255)); + // if (fashionCoolTimeMax > 0) + // { + // pClock->SetProgressRange(0, fashionCoolTimeMax); + // pClock->SetProgressPos(fashionCoolTimeMax - fashionCoolTime); + // pClock->SetColor(A3DCOLORRGBA(0, 0, 0, 175)); + // } + // } + // else + // { + // iIconFile = CECGameUIMan::ICONS_ACTION; + // if (pSC->GetType() == CECShortcut::SCT_COMMAND) + // { + // CECSCCommand* pCommandSC = (CECSCCommand*)pSC; + // if (GetHostPlayer()->IsInvisible()) + // { + // if (pCommandSC->GetCommandID() == CECSCCommand::CMD_STARTTRADE || + // pCommandSC->GetCommandID() == CECSCCommand::CMD_SELLBOOTH || + // pCommandSC->GetCommandID() == CECSCCommand::CMD_BINDBUDDY) + // { + // pCell->SetColor(A3DCOLORRGB(128, 128, 128)); + // } + // else + // { + // pCell->SetColor(A3DCOLORRGB(255, 255, 255)); + // } + // } + // else + // { + // pCell->SetColor(A3DCOLORRGB(255, 255, 255)); + // } + // } + + // if (pSC->GetCoolTime(&nMax) > 0) + // { + // pClock->SetProgressRange(0, nMax); + // pClock->SetProgressPos(nMax - pSC->GetCoolTime()); + // pClock->SetColor(A3DCOLORRGBA(0, 0, 0, 128)); + // } + // } + // if (pSC != null) + // { + // pCell.SetDataPtr(pSC, "ptr_CECShortcut"); + // if (pSC.GetType() == (int)CECShortcut.ShortcutType.SCT_SKILLGRP) + // { + // EC_VIDEO_SETTING setting = GetGame()->GetConfigs()->GetVideoSettings(); + // pCell->SetCover(GetGameUIMan()->m_pA2DSpriteIcons[CECGameUIMan::ICONS_SKILLGRP], + // setting.comboSkill[((CECSCSkillGrp*)pSC)->GetGroupIndex()].nIcon + 1); + // } + // else + // { + // if (pSkill != null) + // { + // slotIndex++; + // //BMLogger.Log("HoangDev: QuickBar Set Skill Icon: " + (uint)pSkill.GetSkillID() + " : " + ElementSkill.GetIcon((uint)pSkill.GetSkillID())); + // var nameskill = ElementSkill.GetIcon((uint)pSkill.GetSkillID()); + // GetGameUIMan().SetCover(pCell, nameskill, EC_GAMEUI_ICONS.ICONS_SKILL); + // } + // af_GetFileTitle(pSC->GetIconFile(), strFile); + // strFile.MakeLower(); + // pCell->SetCover(GetGameUIMan()->m_pA2DSpriteIcons[iIconFile], + // GetGameUIMan()->m_IconMap[iIconFile][strFile]); + // } + // } + // } + // else + // { + // pCell->SetCover(NULL, -1); + // pCell->SetText(_AL("")); + // pCell->SetDataPtr(NULL); + // pCell->SetColor(A3DCOLORRGB(255, 255, 255)); + // } + // } + // } + // return true; + //} public bool UpdateShortcuts() { CECShortcut pSC; @@ -48,12 +255,12 @@ namespace BrewMonster if (a_pSCS[i] == null) continue; - /*CDlgQuickBar* pQuickBar = dynamic_cast(GetGameUIMan()->GetDialog(a_pszPanel[i])); - if (!pQuickBar || !pQuickBar->IsShow()) continue;*/ - int slotIndex = 0; - for (int j = 0; j < a_pSCS.Count; j++) + //*//*CDlgQuickBar* pQuickBar = dynamic_cast(GetGameUIMan()->GetDialog(a_pszPanel[i])); + //if (!pQuickBar || !pQuickBar->IsShow()) continue;*//* + + for (int j = 0; j < AUIImagePictureList.Count; j++) { - pCell = AUIImagePictureList[slotIndex]; + pCell = AUIImagePictureList[j]; pSC = a_pSCS[i].GetShortcut(j); pClock = pCell.GetClockIcon(); pClock.SetProgressRange(0, 1); @@ -67,8 +274,8 @@ namespace BrewMonster pSkill = pSCSkill.GetSkill(); if (false/*m_bDelGoblinSkillSC && GNET::ElementSkill::IsGoblinSkill(pSkill->GetSkillID())*/) { - /* a_pSCS[i]->SetShortcut(j, NULL); - pSC = NULL;*/ + /* a_pSCS[i]->SetShortcut(j, NULL); + pSC = NULL;*/ } else { @@ -76,14 +283,14 @@ namespace BrewMonster { if (ElementSkill.IsGoblinSkill((uint)pSkill.GetSkillID())) { - /* if (pHostGoblin && !pHostGoblin->CheckSkillCastCondition(pSkill)) - { - pCell->SetColor(A3DCOLORRGB(255, 255, 255)); - } - else - { - pCell->SetColor(A3DCOLORRGB(128, 128, 128)); - }*/ + /* if (pHostGoblin && !pHostGoblin->CheckSkillCastCondition(pSkill)) + { + pCell->SetColor(A3DCOLORRGB(255, 255, 255)); + } + else + { + pCell->SetColor(A3DCOLORRGB(128, 128, 128)); + }*/ } else { @@ -97,8 +304,8 @@ namespace BrewMonster } } } - /* else - pClock.SetColor(A3DCOLORRGBA(0, 0, 0, 128));*/ + /*else + pClock.SetColor(A3DCOLORRGBA(0, 0, 0, 128));*/ if (pSkill != null && (pSkill.GetCoolingTime() > 0 || pHost.GetPrepSkill() == pSkill)) { @@ -193,222 +400,20 @@ namespace BrewMonster pClock->SetProgressPos(nMax - pSC->GetCoolTime()); pClock->SetColor(A3DCOLORRGBA(0, 0, 0, 128)); } - }*/ + }*//**/ if (pSC != null) { + BMLogger.LogError("HoangDev: QuickBar Set Skil"); + pCell.SetDataPtr(pSC, "ptr_CECShortcut"); if (pSC.GetType() == (int)CECShortcut.ShortcutType.SCT_SKILLGRP) { - /* EC_VIDEO_SETTING setting = GetGame()->GetConfigs()->GetVideoSettings(); - pCell->SetCover(GetGameUIMan()->m_pA2DSpriteIcons[CECGameUIMan::ICONS_SKILLGRP], - setting.comboSkill[((CECSCSkillGrp*)pSC)->GetGroupIndex()].nIcon + 1);*/ - } - else - { - if (pSkill != null) - { - slotIndex++; - //BMLogger.Log("HoangDev: QuickBar Set Skill Icon: " + (uint)pSkill.GetSkillID() + " : " + ElementSkill.GetIcon((uint)pSkill.GetSkillID())); - var nameskill = ElementSkill.GetIcon((uint)pSkill.GetSkillID()); - GetGameUIMan().SetCover(pCell, nameskill, EC_GAMEUI_ICONS.ICONS_SKILL); - } - /*af_GetFileTitle(pSC->GetIconFile(), strFile); - strFile.MakeLower(); - pCell->SetCover(GetGameUIMan()->m_pA2DSpriteIcons[iIconFile], - GetGameUIMan()->m_IconMap[iIconFile][strFile]);*/ - } - } - } - else - { - /* pCell->SetCover(NULL, -1); - pCell->SetText(_AL("")); - pCell->SetDataPtr(NULL); - pCell->SetColor(A3DCOLORRGB(255, 255, 255));*/ - } - } - } - return true; - } - /* public bool UpdateShortcuts() - { - CECShortcut pSC; - Image skillImage; - CECSCSkill pSCSkill; - int iIconFile, nMax; - AUIImagePicture pCell; - CECSkill pSkill = new CECSkill(-1, -1); - AUIClockIcon pClock; - - - int nCurPanel9 = GetCurPanel1(); - int nCurPanel8 = GetCurPanel2(); - - CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer(); - if (pHost == null) return false; - var a_pSCS = new List(); - var a_pszPanel = new List(); - GetQuickBarNameAndSC(pHost, a_pszPanel, a_pSCS, nCurPanel9, nCurPanel8); - - for (int i = 0; i <= 1*//*(int)a_pSCS.Count*//*; i++) - { - if (a_pSCS[i] == null) - continue; - - *//*CDlgQuickBar* pQuickBar = dynamic_cast(GetGameUIMan()->GetDialog(a_pszPanel[i])); - if (!pQuickBar || !pQuickBar->IsShow()) continue;*//* - - for (int j = 0; j < AUIImagePictureList.Count; j++) - { - pCell = AUIImagePictureList[j]; - pSC = a_pSCS[i].GetShortcut(j); - pClock = pCell.GetClockIcon(); - pClock.SetProgressRange(0, 1); - pClock.SetProgressPos(1); - if (pSC != null) - { - if (pSC.GetType() == (int)CECShortcut.ShortcutType.SCT_SKILL) - { - iIconFile = (int)EC_GAMEUI_ICONS.ICONS_SKILL; - pSCSkill = (CECSCSkill)pSC; - pSkill = pSCSkill.GetSkill(); - if (false*//*m_bDelGoblinSkillSC && GNET::ElementSkill::IsGoblinSkill(pSkill->GetSkillID())*//*) - { - *//* a_pSCS[i]->SetShortcut(j, NULL); - pSC = NULL;*//* - } - else - { - if (pSkill != null && pSkill.ReadyToCast() && pHost.GetPrepSkill() != pSkill) - { - if (ElementSkill.IsGoblinSkill((uint)pSkill.GetSkillID())) - { - *//* if (pHostGoblin && !pHostGoblin->CheckSkillCastCondition(pSkill)) - { - pCell->SetColor(A3DCOLORRGB(255, 255, 255)); - } - else - { - pCell->SetColor(A3DCOLORRGB(128, 128, 128)); - }*//* - } - else - { - if (pHost.CheckSkillCastCondition(pSkill) == 0) - { - //pCell.SetColor(A3DCOLORRGB(255, 255, 255)); - } - else - { - //pCell.SetColor(A3DCOLORRGB(128, 128, 128)); - } - } - } - *//* else - pClock.SetColor(A3DCOLORRGBA(0, 0, 0, 128));*//* - if (pSkill != null && (pSkill.GetCoolingTime() > 0 || - pHost.GetPrepSkill() == pSkill)) - { - pClock.SetProgressRange(0, pSkill.GetCoolingTime()); - if (pHost.GetPrepSkill() == pSkill) - { - pClock.SetProgressPos(0); - } - else - { - pClock.SetProgressPos(pSkill.GetCoolingTime() - pSkill.GetCoolingCnt()); - } - } - } - } - *//*else if (pSC->GetType() == CECShortcut::SCT_ITEM) - { - iIconFile = CECGameUIMan::ICONS_INVENTORY; - pCell->SetColor(A3DCOLORRGB(255, 255, 255)); - pSCItem = (CECSCItem*)pSC; - pIvtr = GetHostPlayer()->GetPack(pSCItem->GetInventory()); - pItem = pIvtr->GetItem(pSCItem->GetIvtrSlot()); - if (pItem && pItem->GetCoolTime(&nMax) > 0) - { - pClock->SetProgressRange(0, nMax); - pClock->SetProgressPos(nMax - pItem->GetCoolTime()); - pClock->SetColor(A3DCOLORRGBA(0, 0, 0, 128)); - } - if (pSCItem->GetInventory() == IVTRTYPE_EQUIPPACK) - pCell->SetColor(A3DCOLORRGBA(128, 128, 255, 128)); - } - else if (pSC->GetType() == CECShortcut::SCT_PET) - { - pSCPet = (CECSCPet*)pSC; - CECPetData* pPet = pPetCorral->GetPetData(pSCPet->GetPetIndex()); - iIconFile = CECGameUIMan::ICONS_INVENTORY; - pCell->SetColor(A3DCOLORRGB(255, 255, 255)); - if (pPet) - { - // dead combat pet - if ((pPet->GetClass() == GP_PET_CLASS_COMBAT || pPet->GetClass() == GP_PET_CLASS_EVOLUTION) && pPet->GetHPFactor() == 0.0f) - { - pCell->SetColor(A3DCOLORRGB(128, 128, 128)); - } - // current active pet - else if (pSCPet->IsActivePet()) - { - pCell->SetColor(A3DCOLORRGB(255, 255, 0)); - } - } - } - else if (pSC->GetType() == CECShortcut::SCT_AUTOFASHION) - { - iIconFile = CECGameUIMan::ICONS_SUITE; - fashionCoolTime = pHost->GetCoolTime(GP_CT_EQUIP_FASHION_ITEM, &fashionCoolTimeMax); - pCell->SetColor(A3DCOLORRGB(255, 255, 255)); - if (fashionCoolTimeMax > 0) - { - pClock->SetProgressRange(0, fashionCoolTimeMax); - pClock->SetProgressPos(fashionCoolTimeMax - fashionCoolTime); - pClock->SetColor(A3DCOLORRGBA(0, 0, 0, 175)); - } - } - else - { - iIconFile = CECGameUIMan::ICONS_ACTION; - if (pSC->GetType() == CECShortcut::SCT_COMMAND) - { - CECSCCommand* pCommandSC = (CECSCCommand*)pSC; - if (GetHostPlayer()->IsInvisible()) - { - if (pCommandSC->GetCommandID() == CECSCCommand::CMD_STARTTRADE || - pCommandSC->GetCommandID() == CECSCCommand::CMD_SELLBOOTH || - pCommandSC->GetCommandID() == CECSCCommand::CMD_BINDBUDDY) - { - pCell->SetColor(A3DCOLORRGB(128, 128, 128)); - } - else - { - pCell->SetColor(A3DCOLORRGB(255, 255, 255)); - } - } - else - { - pCell->SetColor(A3DCOLORRGB(255, 255, 255)); - } - } - - if (pSC->GetCoolTime(&nMax) > 0) - { - pClock->SetProgressRange(0, nMax); - pClock->SetProgressPos(nMax - pSC->GetCoolTime()); - pClock->SetColor(A3DCOLORRGBA(0, 0, 0, 128)); - } - }*//* - if (pSC != null) - { - pCell.SetDataPtr(pSC, "ptr_CECShortcut"); - if (pSC.GetType() == (int)CECShortcut.ShortcutType.SCT_SKILLGRP) - { - *//* EC_VIDEO_SETTING setting = GetGame()->GetConfigs()->GetVideoSettings(); - pCell->SetCover(GetGameUIMan()->m_pA2DSpriteIcons[CECGameUIMan::ICONS_SKILLGRP], - setting.comboSkill[((CECSCSkillGrp*)pSC)->GetGroupIndex()].nIcon + 1);*//* + BMLogger.LogError("HoangDev: QuickBar Set Skill Group Icon SCT_SKILLGRP"); + EC_VIDEO_SETTING setting = EC_Game.GetConfigs().GetVideoSettings(); + /* pCell.SetCover(GetGameUIMan()->m_pA2DSpriteIcons[CECGameUIMan::ICONS_SKILLGRP], + setting.comboSkill[((CECSCSkillGrp)pSC).GetGroupIndex()].nIcon + 1); + setting.comboSkill[((CECSCSkillGrp)pSC).GetGroupIndex()].nIcon + 1;*/ + GetGameUIMan().SetCover(pCell, "unknown", EC_GAMEUI_ICONS.ICONS_SKILLGRP); } else { @@ -419,24 +424,24 @@ namespace BrewMonster var nameskill = ElementSkill.GetIcon((uint)pSkill.GetSkillID()); GetGameUIMan().SetCover(pCell, nameskill, EC_GAMEUI_ICONS.ICONS_SKILL); } - *//*af_GetFileTitle(pSC->GetIconFile(), strFile); - strFile.MakeLower(); - pCell->SetCover(GetGameUIMan()->m_pA2DSpriteIcons[iIconFile], - GetGameUIMan()->m_IconMap[iIconFile][strFile]);*//* + /* af_GetFileTitle(pSC->GetIconFile(), strFile); + strFile.MakeLower(); + pCell->SetCover(GetGameUIMan()->m_pA2DSpriteIcons[iIconFile], + GetGameUIMan()->m_IconMap[iIconFile][strFile]); */ } } } else { - *//* pCell->SetCover(NULL, -1); - pCell->SetText(_AL("")); + /* pCell->SetCover(NULL, -1); + pCell->SetText(_AL("")); pCell->SetDataPtr(NULL); - pCell->SetColor(A3DCOLORRGB(255, 255, 255));*//* + pCell->SetColor(A3DCOLORRGB(255, 255, 255)); */ } } } return true; - }*/ + } private void GetQuickBarNameAndSC(CECHostPlayer pHost, List pszPanel, List pSCS, int panel9, int panel8) { string dlgName; diff --git a/Assets/Scripts/CECGameRun.cs b/Assets/Scripts/CECGameRun.cs index 3f30b2b31c..10f1a5d242 100644 --- a/Assets/Scripts/CECGameRun.cs +++ b/Assets/Scripts/CECGameRun.cs @@ -6,8 +6,10 @@ using BrewMonster.UI; using CSNetwork; using CSNetwork.GPDataType; using CSNetwork.Protocols.RPCData; +using System; using System.Collections.Generic; using System.Data; +using System.Linq; using System.Threading.Tasks; using Unity.Cinemachine; using UnityEngine; @@ -300,7 +302,6 @@ public partial class CECGameRun dwRealLen = 0; } byte[] pData = pDataBuf; - int dataOffset = offset; if (dwVer >= 3) { @@ -343,7 +344,7 @@ public partial class CECGameRun } } //TODO: flow in update fix later - Task.Run(() => + /* Task.Run(() => { GameSession.Context.Post(_ => { @@ -353,22 +354,21 @@ public partial class CECGameRun } m_pUIManager.GetCDlgQuickBar().UpdateShortcuts(); }, null); - }); - + });*/ // TODO: Uncomment when UI manager is available // Load UI configs / 加载UI配置 CECGameUIMan pGameUI = m_pUIManager.GetInGameUIMan(); - /* if (pGameUI != null) - { - int iSize = dr.ReadInt(); - byte[] uiConfigData = dr.ReadData(iSize); - if (!pGameUI.SetUserLayout(uiConfigData, iSize)) - { - BMLogger.LogError("CECGameRun::LoadConfigsFromServer, Failed to set user layout"); - return false; - } - }*/ + if (pGameUI != null) + { + int iSize = dr.ReadInt(); + byte[] uiConfigData = dr.ReadData(iSize); + /*if (!pGameUI.SetUserLayout(uiConfigData, iSize)) + { + BMLogger.LogError("CECGameRun::LoadConfigsFromServer, Failed to set user layout"); + return false; + }*/ + } // Load user settings / 加载用户设置 if (dwVer >= 2) @@ -376,11 +376,11 @@ public partial class CECGameRun // TODO: Uncomment when game configs are available int iSize = dr.ReadInt(); byte[] settingsData = dr.ReadData(iSize); - /* if (!EC_Game.GetConfigs().LoadUserConfigData(settingsData, iSize)) - { - BMLogger.LogError("CECGameRun::LoadConfigsFromServer, Failed to load user config data"); - return false; - }*/ + if (!EC_Game.GetConfigs().LoadUserConfigData(settingsData, iSize)) + { + BMLogger.LogError("CECGameRun::LoadConfigsFromServer, Failed to load user config data"); + return false; + } } } catch (System.Exception e) diff --git a/Assets/Scripts/EC_Utility.cs b/Assets/Scripts/EC_Utility.cs index 652a661e93..91a2a40600 100644 --- a/Assets/Scripts/EC_Utility.cs +++ b/Assets/Scripts/EC_Utility.cs @@ -85,6 +85,21 @@ public static class EC_Utility { return new System.Numerics.Vector3(v.x, v.y, v.z); } + public static byte glb_BuildRefuseBLSMask() + { + byte byMask = 0; + + // const EC_GAME_SETTING &gs = g_pGame->GetConfigs()->GetGameSettings(); + var gs = EC_Game.GetConfigs().GetGameSettings(); + + if (gs.bBlsRefuse_Neutral) + byMask |= (byte)REFUSE_BLESS_MASK.REFUSE_NEUTRAL_BLESS; + + if (gs.bBlsRefuse_NonTeammate) + byMask |= (byte)REFUSE_BLESS_MASK.REFUSE_NON_TEAMMATE_BLESS; + + return byMask; + } public static void Swap(List arr, int a, int b) { T tmp = arr[a];