From 8e52589c07297feef39183e647fdf5a9253c473d Mon Sep 17 00:00:00 2001 From: HungDK <> Date: Mon, 29 Dec 2025 16:56:21 +0700 Subject: [PATCH] Add interact with npc, attack btn --- .../Scripts/Managers/EC_HostInputFilter.cs | 92 +++++++++++++++++-- 1 file changed, 83 insertions(+), 9 deletions(-) diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_HostInputFilter.cs b/Assets/PerfectWorld/Scripts/Managers/EC_HostInputFilter.cs index 26602b8a5e..58efffce4d 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_HostInputFilter.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_HostInputFilter.cs @@ -24,7 +24,11 @@ namespace BrewMonster } } - public void OnMsgLBtnClick() + /// + /// Handle left button click / 处理左键点击 + /// + /// Optional target ID to use instead of raycast (for second-click behavior) / 可选的目标ID,用于替代射线检测(用于第二次点击行为) + public void OnMsgLBtnClick(int idTargetOverride = 0) { // 停止自动策略 / Stop auto policy // Note: Auto policy check would go here if implemented @@ -34,16 +38,85 @@ namespace BrewMonster 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; + // If target override is provided, treat it as second click on selected target / 如果提供了目标覆盖,将其视为对已选中目标的第二次点击 + if (idTargetOverride != 0) + { + int idObject = idTargetOverride; + + // Check if it's a matter object / 检查是否是物品对象 + CECMatter pMatter = EC_ManMessageMono.Instance.EC_ManMatter.GetMatter(idObject); + if (pMatter != null) + { + idTraceTarget = pMatter.GetMatterID(); + bool bIsMine = pMatter.IsMine(); + iTraceReason = bIsMine ? CECHPWorkTrace.Trace_reason.TRACE_GATHER : CECHPWorkTrace.Trace_reason.TRACE_PICKUP; + } + else + { + // NPC or Player / NPC或玩家 + CECNPC pNPC = EC_ManMessageMono.Instance.CECNPCMan.GetNPC(idObject); + if (pNPC != null) + { + // Treat as second click (already selected) / 视为第二次点击(已选中) + if (!pNPC.IsDead() && m_idSelTarget == idObject) + { + idTraceTarget = idObject; + } + else + { + idSelTarget = idObject; + } - // Check for NPC with pate text (hover text) first - // Note: This would require GetMouseOnPateTextNPC implementation - // For now, we'll proceed with raycast + if (idTraceTarget != 0) + { + if (AttackableJudge(idObject, bForceAttack) == 1) + iTraceReason = CECHPWorkTrace.Trace_reason.TRACE_ATTACK; + else if (pNPC.IsServerNPC()) + { + if (!IsInBattle() || InSameBattleCamp(pNPC)) + iTraceReason = CECHPWorkTrace.Trace_reason.TRACE_TALK; + } + } + } + else + { + // Player / 玩家 + CECPlayer pPlayer = EC_ManMessageMono.Instance.EC_ManPlayer.GetPlayer(idObject); + if (pPlayer != null && !pPlayer.IsDead() && + (m_idSelTarget == idObject)) + { + idTraceTarget = idObject; + if (AttackableJudge(idObject, bForceAttack) == 1) + iTraceReason = CECHPWorkTrace.Trace_reason.TRACE_ATTACK; + else if (pPlayer.GetBoothState() != 0) + iTraceReason = CECHPWorkTrace.Trace_reason.TRACE_TALK; + } + else if (pPlayer != null) + { + idSelTarget = idObject; + } + } - if (Physics.Raycast(ray, out hit)) + // cancel this action if not selectable / 如果不可选择则取消此操作 + if (!CanSelectTarget(idTraceTarget)) + { + return; + } + } + } + else + { + // Normal raycast-based click / 正常的基于射线检测的点击 + 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)) { // Check if hit terrain, building, or forest (no CECObject component) if (!hit.collider.gameObject.TryGetComponent(out CECObject clickedObject)) @@ -185,6 +258,7 @@ namespace BrewMonster } } } + } /*else { // Nothing is clicked / Nothing is clicked