Add pickup item, gather logic of movement, anim

This commit is contained in:
HungDK
2025-12-23 10:31:20 +07:00
parent eb8980943c
commit ffb88a57ea
@@ -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<CECObject>(out CECObject clickedObject))
// Check if hit terrain, building, or forest (no CECObject component)
if (!hit.collider.gameObject.TryGetComponent<CECObject>(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;
}
}
}