diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_HostInputFilter.cs b/Assets/PerfectWorld/Scripts/Managers/EC_HostInputFilter.cs index 121617c34c..4daee7ebcf 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_HostInputFilter.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_HostInputFilter.cs @@ -2,6 +2,7 @@ using BrewMonster.Managers; using BrewMonster.Network; using BrewMonster.Scripts; using CSNetwork.GPDataType; +using PerfectWorld.Scripts; using System; using UnityEngine; @@ -25,23 +26,107 @@ namespace BrewMonster public void OnMsgLBtnClick() { + // 停止自动策略 / Stop auto policy + // Note: Auto policy check would go here if implemented + int idTraceTarget = 0, idSelTarget = 0; bool bForceAttack = false; int iTraceReason = CECHPWorkTrace.Trace_reason.TRACE_NONE; bool bWikiMonster = false; ray = mainCam.ScreenPointToRay(Input.mousePosition); + Vector3 vStart = mainCam.transform.position; + Vector3 vDest = ray.GetPoint(1.0f); + Vector3 vDelta = vDest - vStart; + + // Check for NPC with pate text (hover text) first + // Note: This would require GetMouseOnPateTextNPC implementation + // For now, we'll proceed with raycast if (Physics.Raycast(ray, out hit)) { - if (hit.collider.gameObject.TryGetComponent(out CECObject clickedObject)) + // Check if hit terrain, building, or forest (no CECObject component) + if (!hit.collider.gameObject.TryGetComponent(out CECObject clickedObject)) { - int idObject = CECObject.GetObjectID(clickedObject); - if (idObject != 0) + //ENABLE LATER - CURRENT WORKING FINE + // Hit terrain / building / forest / Hit terrain + // if (m_pWorkMan.IsSitting()) + // { + // UnityGameSession.c2s_CmdStandUp(); + // return; + // } + // if (!CanDo(ActionCanDo.CANDO_MOVETO)) + // return; + // + // // Calculate move destination / Hit terrain + // Vector3 vMoveDest = hit.point; + // A3DVECTOR3 a3dMoveDest = EC_Utility.ToA3DVECTOR3(vMoveDest); + // + // if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) + // { + // // Ctrl pressed - direct goto / Ctrl pressed + // // Note: c2s_CmdGoto not implemented, using work system instead + // // UnityGameSession.c2s_CmdGoto(a3dMoveDest.x, a3dMoveDest.y, a3dMoveDest.z); + // // For now, use work system even with Ctrl + // } + // // else removed - always use work system + // { + // CECHPWork pWork = m_pWorkMan.GetWork(CECHPWork.Host_work_ID.WORK_MOVETOPOS); + // if (pWork != null) + // { + // CECHPWorkMove pWorkMove = pWork as CECHPWorkMove; + // if (pWorkMove != null) + // { + // pWorkMove.SetDestination(CECHPWorkMove.DestTypes.DEST_2D, a3dMoveDest); + // pWorkMove.SetUseAutoMoveDialog(false); + // // Note: PlayMoveTargetGFX would go here if implemented + // } + // } + // else if (m_pWorkMan.CanStartWork(CECHPWork.Host_work_ID.WORK_MOVETOPOS)) + // { + // // If destination is too near, ignore it. / If destination is too near, ignore it. + // A3DVECTOR3 vDist = a3dMoveDest - GetPos(); + // float fDistH = (float)Math.Sqrt(vDist.x * vDist.x + vDist.z * vDist.z); + // if (fDistH > 0.5f) + // { + // CECHPWorkMove pWorkMove = (CECHPWorkMove)m_pWorkMan.CreateWork(CECHPWork.Host_work_ID.WORK_MOVETOPOS); + // pWorkMove.SetDestination(CECHPWorkMove.DestTypes.DEST_2D, a3dMoveDest); + // // Note: PlayMoveTargetGFX would go here if implemented + // m_pWorkMan.StartWork_p1(pWorkMove); + // } + // } + // } + return; + } + + // Hit an object / Hit a object + int idObject = CECObject.GetObjectID(clickedObject); + if (idObject != 0) + { + // Check if it's a matter object / Check if it's a matter object + if (clickedObject.IsMatter()) { + CECMatter pMatter = clickedObject as CECMatter; + if (pMatter != null) + { + idTraceTarget = pMatter.GetMatterID(); + // Check if it's a mine (gather) or item (pickup) / Check if it's a mine (gather) or item (pickup) + bool bIsMine = pMatter.IsMine(); + iTraceReason = bIsMine ? CECHPWorkTrace.Trace_reason.TRACE_GATHER : CECHPWorkTrace.Trace_reason.TRACE_PICKUP; + } + } + // Check if it's a dynamic object / Check if it's a dynamic object + // else if (clickedObject.gameObject.CompareTag("DynamicObject")) // ECENT_DYN_OBJ + // { + // return; // Dynamic objects are not clickable + // } + else + { + // NPC or Player / NPC or Player CECNPC pNPC = EC_ManMessageMono.Instance.CECNPCMan.GetNPC(idObject); if (pNPC != null) { + // Msg.dwParam4 is double click flag / Msg.dwParam4 is double click flag if (!pNPC.IsDead() && m_idSelTarget == idObject) { idTraceTarget = idObject; @@ -53,6 +138,7 @@ namespace BrewMonster if (idTraceTarget != 0) { + // bForceAttack = glb_GetForceAttackFlag(&Msg.dwParam3); if (AttackableJudge(idObject, bForceAttack) == 1) iTraceReason = CECHPWorkTrace.Trace_reason.TRACE_ATTACK; else if (pNPC.IsServerNPC()) @@ -64,12 +150,12 @@ namespace BrewMonster } else { - // pCDS.m_RayTraceRt.iEntity == ECENT_PLAYER + // pCDS.m_RayTraceRt.iEntity == ECENT_PLAYER / pCDS.m_RayTraceRt.iEntity == ECENT_PLAYER CECPlayer pPlayer = EC_ManMessageMono.Instance.EC_ManPlayer.GetPlayer(idObject); - // 1. Msg.dwParam4 is double click flag. - // 2. Buddy player counld't be traced - if (!pPlayer.IsDead() /*&& pPlayer.GetCharacterID() != m_iBuddyId*/ && + // 1. Msg.dwParam4 is double click flag. / 1. Msg.dwParam4 is double click flag. + // 2. Buddy player counld't be traced / 2. Buddy player counld't be traced + if (pPlayer != null && !pPlayer.IsDead() /*&& pPlayer.GetCharacterID() != m_iBuddyId*/ && (m_idSelTarget == idObject /*|| (Msg.dwParam4 && m_idUCSelTarget == idObject)*/)) { idTraceTarget = idObject; @@ -80,31 +166,73 @@ namespace BrewMonster else if (pPlayer.GetBoothState() != 0) iTraceReason = CECHPWorkTrace.Trace_reason.TRACE_TALK; } - else + else if (pPlayer != null) { idSelTarget = idObject; } } - // cancel this action if not selectable + // cancel this action if not selectable / cancel this action if not selectable if (!CanSelectTarget(idTraceTarget)) { - idTraceTarget = 0; - //return; + return; } + + // Check for wiki monster / Check for wiki monster + // Note: CDlgAutoHelp::IsAutoHelp() check would go here if implemented + // if (CDlgAutoHelp.IsAutoHelp() && pNPC != null && pNPC.IsMonsterNPC()) + // bWikiMonster = true; } } } - - // Tell server we select a target - if (idSelTarget != 0 && m_idSelTarget != idSelTarget) + else { - m_idUCSelTarget = idSelTarget; - SelectTarget(m_idUCSelTarget); + // Nothing is clicked / Nothing is clicked + if (m_pWorkMan.IsSitting()) + { + UnityGameSession.c2s_CmdStandUp(); + return; + } + + if (!CanDo(ActionCanDo.CANDO_MOVETO)) + return; + + // Move on the clicked direction / Move on the clicked direction + Vector3 vMoveDir = vDelta; + vMoveDir.y = 0.0f; + if (vMoveDir.sqrMagnitude < 0.0001f) + return; + + vMoveDir.Normalize(); + A3DVECTOR3 a3dMoveDir = EC_Utility.ToA3DVECTOR3(vMoveDir); + + CECHPWork pWork = m_pWorkMan.GetWork(CECHPWork.Host_work_ID.WORK_MOVETOPOS); + if (pWork != null) + { + CECHPWorkMove pWorkMove = pWork as CECHPWorkMove; + if (pWorkMove != null) + { + pWorkMove.SetDestination(CECHPWorkMove.DestTypes.DEST_DIR, a3dMoveDir); + } + } + else if (m_pWorkMan.CanStartWork(CECHPWork.Host_work_ID.WORK_MOVETOPOS)) + { + CECHPWorkMove pWorkMove = (CECHPWorkMove)m_pWorkMan.CreateWork(CECHPWork.Host_work_ID.WORK_MOVETOPOS); + pWorkMove.SetDestination(CECHPWorkMove.DestTypes.DEST_DIR, a3dMoveDir); + m_pWorkMan.StartWork_p1(pWorkMove); + } + return; } + // Handle trace target / Handle trace target if (idTraceTarget != 0) { + if (m_pWorkMan.IsSitting()) + { + UnityGameSession.c2s_CmdStandUp(); + return; + } + // Trace a object / Trace a object if (iTraceReason == CECHPWorkTrace.Trace_reason.TRACE_ATTACK) { if (!CanDo(ActionCanDo.CANDO_MELEE)) @@ -115,14 +243,15 @@ namespace BrewMonster { if (!CanDo(ActionCanDo.CANDO_MOVETO)) return; + CECHPWork pWork; if (iTraceReason == CECHPWorkTrace.Trace_reason.TRACE_PICKUP) { - //PickupObject(idTraceTarget, false); + PickupObject(idTraceTarget, false); } else if (iTraceReason == CECHPWorkTrace.Trace_reason.TRACE_GATHER) { - //PickupObject(idTraceTarget, true); + PickupObject(idTraceTarget, true); } else if ((pWork = m_pWorkMan.GetWork(CECHPWork.Host_work_ID.WORK_TRACEOBJECT)) != null) { @@ -137,6 +266,13 @@ namespace BrewMonster } } } + + // Tell server we select a target / Tell server we select a target + if (idSelTarget != 0 && m_idSelTarget != idSelTarget) + { + m_idUCSelTarget = idSelTarget; + SelectTarget(m_idUCSelTarget); + } } public void OnMsgHstJump() @@ -226,5 +362,78 @@ namespace BrewMonster //m_GndInfo.bOnGround = GroundCheck(out lastGroundHit); OnMsgHstJump(); } + + // Pickup an object / Pickup an object + public bool PickupObject(int idTarget, bool bGather) + { + if (IsDead() || IsSpellingMagic() || idTarget == 0 || !GPDataTypeHelper.ISMATTERID(idTarget)) + return false; + + // Check matter type / Check matter type + CECMatter pMatter = EC_ManMessageMono.Instance.EC_ManMatter.GetMatter(idTarget); + if (pMatter == null) + { +#if UNITY_EDITOR || DEVELOPMENT_BUILD + Debug.LogWarning( + $"PickupObject: GetMatter returned null. idTarget={idTarget} (0x{idTarget:X8}) bGather={bGather}"); +#endif + return false; + } + + if (bGather != pMatter.IsMine()) + return false; + + if (bGather && !CanGatherMatter(pMatter)) + return false; + + bool bOK = true; + + // Trace a object / Trace a object + CECHPWork pWork = m_pWorkMan.GetWork(CECHPWork.Host_work_ID.WORK_TRACEOBJECT); + if (pWork != null) + { + CECHPWorkTrace pWorkTrace = pWork as CECHPWorkTrace; + if (pWorkTrace != null) + { + CECTracedObject traceTarget = pWorkTrace.CreatTraceTarget(idTarget, + bGather ? CECHPWorkTrace.Trace_reason.TRACE_GATHER : CECHPWorkTrace.Trace_reason.TRACE_PICKUP, + false); + if (traceTarget != null) + { + pWorkTrace.SetTraceTarget(traceTarget); + bOK = true; + } + } + } + else if (m_pWorkMan.CanStartWork(CECHPWork.Host_work_ID.WORK_TRACEOBJECT)) + { + CECHPWorkTrace pWorkTrace = (CECHPWorkTrace)m_pWorkMan.CreateWork(CECHPWork.Host_work_ID.WORK_TRACEOBJECT); + if (pWorkTrace != null) + { + CECTracedObject traceTarget = pWorkTrace.CreatTraceTarget(idTarget, + bGather ? CECHPWorkTrace.Trace_reason.TRACE_GATHER : CECHPWorkTrace.Trace_reason.TRACE_PICKUP, + false); + if (traceTarget != null) + { + pWorkTrace.SetTraceTarget(traceTarget); + m_pWorkMan.StartWork_p1(pWorkTrace); + bOK = true; + } + } + } + + return bOK; + } + + // Check whether host can gather specified matter / Check whether host can gather specified matter + public bool CanGatherMatter(CECMatter pMatter) + { + if (pMatter == null || !pMatter.IsMine()) + return false; + + // TODO: Add level requirement check and other gather validations / TODO: Add level requirement check and other gather validations + // For now, return true if it's a mine / For now, return true if it's a mine + return true; + } } }