diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_HPWork.cs b/Assets/PerfectWorld/Scripts/Managers/EC_HPWork.cs index 56541b4296..ef2107e0ca 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_HPWork.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_HPWork.cs @@ -837,6 +837,11 @@ namespace BrewMonster.Scripts } return result; } + + public bool IsFreeFalling() + { + return IsWorkRunning(Host_work_ID.WORK_FREEFALL); + } } public abstract class CECHPWorkPostTickCommand { diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs b/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs index 9a31801cbe..eb87632482 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs @@ -64,6 +64,7 @@ namespace PerfectWorld.Scripts.Managers case int value5 when value5 == EC_MsgDef.MSG_PM_ENCHANTRESULT: case int value6 when value6 == EC_MsgDef.MSG_PM_PLAYERDOEMOTE: case int value7 when value7 == EC_MsgDef.MSG_PM_PLAYERGATHER: + case int value8 when value8 == EC_MsgDef.MSG_PM_PLAYERFLY: TransmitMessage(Msg); break; case int value when value == EC_MsgDef.MSG_PM_PLAYERDIED: @@ -658,6 +659,14 @@ namespace PerfectWorld.Scripts.Managers cid = cmdMineGathered.player_id; } + break; + case long value when value == EC_MsgDef.MSG_PM_PLAYERFLY: + + if (Convert.ToInt32(Msg.dwParam2) == CommandID.OBJECT_TAKEOFF) + cid = (GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1)).object_id; + else // OBJECT_LANDING + cid = (GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1)).object_id; + break; // ⚠️ Các case khác cũng tương tự, chỉ việc lấy ra đúng trường id / caster / user ... // Do quá dài nên bạn có thể copy dần từng case từ C++ sang. diff --git a/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs b/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs index 43f8f903d1..92fc1ab68b 100644 --- a/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs +++ b/Assets/PerfectWorld/Scripts/Move/CECPlayer.cs @@ -89,6 +89,7 @@ namespace BrewMonster protected bool m_bHangerOn = false; protected int m_iCurAction; bool m_bAboutToDie = false; + public bool m_bCandHangerOn = false; public MOVECONST m_MoveConst; // Const used when moving control public Move_Mode m_MoveMode; @@ -1607,6 +1608,21 @@ namespace BrewMonster public bool IsAboutToDie() { return m_bAboutToDie; } public void SetAboutToDie(bool bFlag) { m_bAboutToDie = bFlag; } + + public bool IsHangerOn() { return m_bHangerOn; } + + // Show / hide wing + public void ShowWing(bool bShow) + { + //if (m_pPlayerModel) + //{ + // CECModel* pWing = m_pPlayerModel->GetChildModel(_wing); + // if (pWing) pWing->Show(bShow); + + // CECModel* pWing2 = m_pPlayerModel->GetChildModel(_wing2); + // if (pWing2) pWing2->Show(bShow); + //} + } } public struct PlayActionEvent diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs index 88403766c2..693d78415a 100644 --- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs +++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs @@ -2119,5 +2119,23 @@ namespace CSNetwork.GPDataType public int player_id; public int item_type; }; + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct cmd_object_takeoff + { + public int object_id; + }; + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct cmd_object_landing + { + public int object_id; + }; + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct cmd_host_rush_fly + { + public byte is_active; + }; } diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs index 769af55162..3f0e0d4fbb 100644 --- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs +++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs @@ -592,7 +592,7 @@ namespace CSNetwork // if (string.IsNullOrEmpty(szMsg)) // BMLogger.LogError("SERVER - unknown error !"); //else if (pCmd.iMessage != 2) - //g_pGame->GetGameRun()->AddChatMessage(szMsg, GP_CHAT_MISC); + //g_pGame.GetGameRun().AddChatMessage(szMsg, GP_CHAT_MISC); } if (pCmd.iMessage == 2) @@ -603,31 +603,31 @@ namespace CSNetwork else if (pCmd.iMessage == 20) { // Failed to cast skill - //pGameRun->PostMessage(MSG_PM_CASTSKILL, MAN_PLAYER, 0, (DWORD)pDataBuf, pCmdHeader->cmd); + //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); + //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()*/) + else if (pCmd.iMessage == 108 /*&& pGameRun.GetHostPlayer().IsInKingService()*/) { - /* CECGameUIMan* pGameUI = pGameRun->GetUIManager()->GetInGameUIMan(); + /* CECGameUIMan* pGameUI = pGameRun.GetUIManager().GetInGameUIMan(); if (pGameUI) - pGameUI->EndNPCService();*/ + pGameUI.EndNPCService();*/ } else if - (pCmd.iMessage == 108 /*&& pGameRun->GetHostPlayer()->GetOfflineShopCtrl()->GetNPCSevFlag() != COfflineShopCtrl::NPCSEV_NULL*/ + (pCmd.iMessage == 108 /*&& pGameRun.GetHostPlayer().GetOfflineShopCtrl().GetNPCSevFlag() != COfflineShopCtrl::NPCSEV_NULL*/ ) { - /* CECGameUIMan* pGameUI = pGameRun->GetUIManager()->GetInGameUIMan(); + /* CECGameUIMan* pGameUI = pGameRun.GetUIManager().GetInGameUIMan(); if (pGameUI) - pGameUI->EndNPCService();*/ + pGameUI.EndNPCService();*/ } else if (pCmd.iMessage == 175) { @@ -787,6 +787,27 @@ namespace CSNetwork case CommandID.COOLTIME_DATA: EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_COOLTIMEDATA, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader); break; + case CommandID.OBJECT_TAKEOFF: + { + cmd_object_takeoff pCmdTakeOff = GPDataTypeHelper.FromBytes((byte[])pDataBuf); + if (ISPLAYERID(pCmdTakeOff.object_id)) + EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_PLAYERFLY, MANAGER_INDEX.MAN_PLAYER, -1, pDataBuf, pCmdHeader); + break; + } + case CommandID.OBJECT_LANDING: + { + cmd_object_landing pCmdLanding = GPDataTypeHelper.FromBytes((byte[])pDataBuf); + if (ISPLAYERID(pCmdLanding.object_id)) + EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_PLAYERFLY, MANAGER_INDEX.MAN_PLAYER, -1, pDataBuf, pCmdHeader); + break; + } + case CommandID.HOST_RUSH_FLY: + EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_PLAYERFLY, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader); + break; + case CommandID.FLYSWORD_TIME: + EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_FLYSWORDTIME, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader); + break; + } } diff --git a/Assets/Scripts/CECHostPlayer.cs b/Assets/Scripts/CECHostPlayer.cs index bcb244cda4..1ab400b6d1 100644 --- a/Assets/Scripts/CECHostPlayer.cs +++ b/Assets/Scripts/CECHostPlayer.cs @@ -21,10 +21,7 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using UnityEngine; -using UnityEngine.PlayerLoop; -using UnityEngine.SceneManagement; using UnityEngine.UI; -using static System.Net.Mime.MediaTypeNames; using Host_work_ID = BrewMonster.Scripts.CECHPWork.Host_work_ID; using Trace_reason = BrewMonster.CECHPWorkTrace.Trace_reason; @@ -90,6 +87,7 @@ namespace BrewMonster private CECSkill m_pTargetItemSkill; // Target item skill public CECComboSkill m_pComboSkill; // Combo skill public A3DVECTOR3 m_vAccel; // Accelerate\ + public bool m_bRushFly = false; // true, in rush fly mode private CECCounter m_IncantCnt; private bool m_bMelee; @@ -119,7 +117,7 @@ namespace BrewMonster // ID of summon player skill const int ID_SUMMONPLAYER_SKILL = 1824; - private CECAutoTeam m_pAutoTeam; + private CECAutoTeam m_pAutoTeam; // ====== Ground cast config ====== [Header("Ground Cast")] @@ -547,6 +545,7 @@ namespace BrewMonster case int value when value == EC_MsgDef.MSG_HST_COOLTIMEDATA: OnMsgHstCoolTimeData(Msg); break; case int value when value == EC_MsgDef.MSG_HST_SETCOOLTIME: OnMsgHstSetCoolTime(Msg); break; case int value when value == EC_MsgDef.MSG_HST_PRESSCANCEL: OnMsgHstPressCancel(Msg); break; + case int value when value == EC_MsgDef.MSG_PM_PLAYERFLY: OnMsgPlayerFly(Msg); break; } @@ -593,30 +592,30 @@ namespace BrewMonster { int i; // other goblin skills should be set public cool down, 1 second - /* for (i = 0; i < m_aGoblinSkills.GetSize(); i++) - { - if (m_aGoblinSkills[i] && m_aGoblinSkills[i].GetCoolingCnt() == 0) - m_aGoblinSkills[i].StartCooling(GetCoolTime(GP_CT_CAST_ELF_SKILL), GetCoolTime(GP_CT_CAST_ELF_SKILL)); - }*/ + /* for (i = 0; i < m_aGoblinSkills.GetSize(); i++) + { + if (m_aGoblinSkills[i] && m_aGoblinSkills[i].GetCoolingCnt() == 0) + m_aGoblinSkills[i].StartCooling(GetCoolTime(GP_CT_CAST_ELF_SKILL), GetCoolTime(GP_CT_CAST_ELF_SKILL)); + }*/ - /* for (i = 0; i < m_aPsSkills.Count; i++) - { - CECSkill pSkill = GetPassiveSkillByIndex(i); - if (pSkill && (pSkill.GetCommonCoolDown() & (1 << (pCmd.cooldown_index - GP_CT_SKILLCOMMONCOOLDOWN0)))) - pSkill.StartCooling(GetCoolTime(pCmd.cooldown_index), GetCoolTime(pCmd.cooldown_index)); - }*/ + /* for (i = 0; i < m_aPsSkills.Count; i++) + { + CECSkill pSkill = GetPassiveSkillByIndex(i); + if (pSkill && (pSkill.GetCommonCoolDown() & (1 << (pCmd.cooldown_index - GP_CT_SKILLCOMMONCOOLDOWN0)))) + pSkill.StartCooling(GetCoolTime(pCmd.cooldown_index), GetCoolTime(pCmd.cooldown_index)); + }*/ } if (pCmd.cooldown_index >= (int)CoolTimeIndex.GP_CT_SKILLCOMMONCOOLDOWN0 && pCmd.cooldown_index <= (int)CoolTimeIndex.GP_CT_SKILLCOMMONCOOLDOWN4) { // other player skills should be set public cool down too. - uint mask = (uint)( 1 << (pCmd.cooldown_index - (int)CoolTimeIndex.GP_CT_SKILLCOMMONCOOLDOWN0)); + uint mask = (uint)(1 << (pCmd.cooldown_index - (int)CoolTimeIndex.GP_CT_SKILLCOMMONCOOLDOWN0)); for (int i = 0; i < GetPositiveSkillNum(); i++) { CECSkill pSkill = GetPositiveSkillByIndex(i); int fakeRef = 0; if (pSkill != null && (pSkill.GetCommonCoolDown() & mask) != 0) - pSkill.StartCooling(GetCoolTime(pCmd.cooldown_index,ref fakeRef), GetCoolTime(pCmd.cooldown_index, ref fakeRef)); + pSkill.StartCooling(GetCoolTime(pCmd.cooldown_index, ref fakeRef), GetCoolTime(pCmd.cooldown_index, ref fakeRef)); } /*const std::map&inherentSkillMap = CECComboSkillState::Instance().GetInherentSkillMap(); std::map < unsigned int, CECSkill*>::const_iterator it; @@ -646,13 +645,13 @@ namespace BrewMonster { pSkill.StartCooling(pCmd.cooldown_time, pCmd.cooldown_time); } - /* else if (pSkill = CECComboSkillState::Instance().GetInherentSkillByID(idSkill)) - { - pSkill.StartCooling(pCmd.cooldown_time, pCmd.cooldown_time); - }*/ + /* else if (pSkill = CECComboSkillState::Instance().GetInherentSkillByID(idSkill)) + { + pSkill.StartCooling(pCmd.cooldown_time, pCmd.cooldown_time); + }*/ else if (GetEquipSkillByID(idSkill) == null) { - BMLogger.LogError ("HoangDev: pSkill " + pSkill); + BMLogger.LogError("HoangDev: pSkill " + pSkill); } } else @@ -4466,10 +4465,7 @@ namespace BrewMonster return false; } - if (m_iMoveEnv == Move_environment.MOVEENV_AIR) - { - } - else if (m_iMoveEnv == Move_environment.MOVEENV_WATER) + if (m_iMoveEnv == Move_environment.MOVEENV_WATER || m_iMoveEnv == Move_environment.MOVEENV_AIR) { float angle = Vector2.Angle(new Vector2(joystick.Horizontal, joystick.Vertical), Vector2.up); angle *= joystick.Horizontal < 0 ? 1 : -1; @@ -4520,7 +4516,7 @@ namespace BrewMonster { h0 = hits[0].point.y; } - if(vPos.y < h0 - m_MoveConst.fShoreDepth) + if (vPos.y < h0 - m_MoveConst.fShoreDepth) { return false; } @@ -5552,13 +5548,13 @@ namespace BrewMonster vHitNormal = EC_Utility.ToA3DVECTOR3(Vector3.up); } else - { + { if (Math.Abs(hits[0].distance - 0f) <= float.Epsilon) { // halfBox with y = 0.05f? I need Y box check too small. count = Physics.BoxCastNonAlloc(vCenter, new Vector3(vExt.x, 0.05f, vExt.z), (Vector3.down).normalized, hits, transform.rotation, DeltaY, layerMask); - if(count == 0) + if (count == 0) { vHitPos = vCenter; vHitNormal = EC_Utility.ToA3DVECTOR3(Vector3.up); @@ -6044,7 +6040,7 @@ namespace BrewMonster { // Get real time tick of this frame var iRealTime = EC_Game.GetRealTickTime(); - + // Update flysword time /*if (IsFlying() && GetRushFlyFlag()) { @@ -6279,7 +6275,7 @@ namespace BrewMonster } // Cancel current selection - if (m_idSelTarget >0) + if (m_idSelTarget > 0) { SelectTarget(0); return; @@ -6293,13 +6289,15 @@ namespace BrewMonster return; } } - + // Is doing session pose ? private bool DoingSessionPose() { var pCurWork = m_pWorkMan.GetRunningWork(Host_work_ID.WORK_STAND); - if (pCurWork !=null){ - if (((CECHPWorkStand)pCurWork).DoingSessionPose()){ + if (pCurWork != null) + { + if (((CECHPWorkStand)pCurWork).DoingSessionPose()) + { return true; } } @@ -6313,7 +6311,7 @@ namespace BrewMonster // m_pActionSwitcher.PostMessge(CECActionSwitcherBase::MSG_FLY); // first of all see if we need to cancel sitdown work. - + if (!CanDo(ActionCanDo.CANDO_FLY)) return false; @@ -6322,8 +6320,11 @@ namespace BrewMonster if (pItem == null) return false; - if (((EC_IvtrEquip)pItem).IsDestroying()) - return false; + if(pItem is EC_IvtrEquip) + { + if ((pItem as EC_IvtrEquip).IsDestroying()) + return false; + } if (!IsFlying()) { @@ -6342,5 +6343,54 @@ namespace BrewMonster UnityGameSession.c2s_CmdUseItem(InventoryConst.IVTRTYPE_EQUIPPACK, InventoryConst.EQUIPIVTR_FLYSWORD, pItem.GetTemplateID(), 1); return true; } + + void OnMsgPlayerFly(ECMSG Msg) + { + if (Convert.ToInt32(Msg.dwParam2) == CommandID.OBJECT_TAKEOFF) + { + if ((m_dwStates & PlayerNPCState.GP_STATE_FLY) == 0) + { + m_dwStates |= PlayerNPCState.GP_STATE_FLY; + m_bRushFly = false; + + CECHPWorkFly pWork = (CECHPWorkFly)m_pWorkMan.CreateWork(CECHPWork.Host_work_ID.WORK_FLYOFF); + if (m_pWorkMan.IsFreeFalling()) + { + pWork.m_bContinueFly = true; + m_pWorkMan.StartWork_p1(pWork); + } + else + { + pWork.m_bContinueFly = false; + m_pWorkMan.StartWork_p2(pWork); + } + } + } + else if (Convert.ToInt32(Msg.dwParam2) == CommandID.OBJECT_LANDING) + { + if ((m_dwStates & PlayerNPCState.GP_STATE_FLY) != 0) + { + m_dwStates &= ~(uint)PlayerNPCState.GP_STATE_FLY; + + if (IsDead() || m_bCandHangerOn || IsHangerOn()) + ShowWing(false); + else + { + CECHPWorkFall pWork = (CECHPWorkFall)m_pWorkMan.CreateWork(CECHPWork.Host_work_ID.WORK_FREEFALL); + pWork.SetFallType(CECHPWorkFall.Fall_type.TYPE_FLYFALL); + m_pWorkMan.StartWork_p1(pWork); + } + + // Below two lines will fix the "host stand in air" bug. + m_iMoveEnv = Move_environment.MOVEENV_GROUND; + m_CDRInfo.vTPNormal.Clear(); + } + } + else // HOST_RUSH_FLY + { + cmd_host_rush_fly pCmd = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1); + m_bRushFly = pCmd.is_active != 0 ? true : false; + } + } } }