Add trace to gather matter and gathering matter
This commit is contained in:
@@ -5,6 +5,7 @@ using BrewMonster.Scripts;
|
||||
using CSNetwork.GPDataType;
|
||||
using System;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using PerfectWorld.Scripts;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -132,6 +133,10 @@ namespace BrewMonster
|
||||
float fMaxCut = m_bMoreClose ? -1.0f : 1.0f;
|
||||
|
||||
CECObject pObject = EC_ManMessageMono.Instance.GetObject(m_iObjectId, 0);
|
||||
if (pObject == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
float fTouchRadius = 0.0f;
|
||||
if (GPDataTypeHelper.ISPLAYERID(m_iObjectId))
|
||||
@@ -142,7 +147,13 @@ namespace BrewMonster
|
||||
}
|
||||
else
|
||||
{
|
||||
CECPlayer pPlayer = pObject.GetComponent<CECHostPlayer>();
|
||||
// pObject is usually EC_ElsePlayer/CECPlayer, not CECHostPlayer.
|
||||
// Using GetComponent<CECHostPlayer>() returns null and breaks touch checks.
|
||||
CECPlayer pPlayer = pObject as CECPlayer;
|
||||
if (pPlayer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
fTouchRadius = pPlayer.GetTouchRadius();
|
||||
}
|
||||
return m_pHost.CanTouchTarget(vHostPos, vTargetPos, fTouchRadius, iTouchReason, fMaxCut);
|
||||
@@ -150,13 +161,25 @@ namespace BrewMonster
|
||||
else if (GPDataTypeHelper.ISNPCID(m_iObjectId))
|
||||
{
|
||||
CECNPC pNPC = pObject as CECNPC;
|
||||
if (pNPC == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
fTouchRadius = pNPC.GetTouchRadius();
|
||||
return m_pHost.CanTouchTarget(vHostPos, vTargetPos, fTouchRadius, iTouchReason, fMaxCut);
|
||||
}
|
||||
else if (GPDataTypeHelper.ISMATTERID(m_iObjectId))
|
||||
{
|
||||
//CECMatter pMatter = (pObject) as CECMatter;
|
||||
//return pMatter.CalcDist(vHostPos, true) < pMatter.GetGatherDist();
|
||||
CECMatter pMatter = (pObject) as CECMatter;
|
||||
if (pMatter == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// For matter, use horizontal distance (ignore Y).
|
||||
// Unity's touch check uses host position + capsule extent, which would otherwise
|
||||
// force the player to get much closer than intended.
|
||||
// C++ behavior expects a stand-off distance (default 3.0).
|
||||
return pMatter.CalcDist(vHostPos, false) < pMatter.GetGatherDist();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -207,7 +230,11 @@ namespace BrewMonster
|
||||
|
||||
public override A3DVECTOR3 GetTargetPos()
|
||||
{
|
||||
return (GetTargetObject() as CECNPC).GetServerPos();
|
||||
// 使用 Unity transform 的实时位置,而不是服务器缓存位置(可能滞后 / 未及时刷新),
|
||||
// 否则追踪目的地/触碰判定会偏离导致永远触不到。
|
||||
// Use live transform position (GetPos) instead of cached server position (GetServerPos),
|
||||
// otherwise tracing destination and touch checks can be wrong and never trigger.
|
||||
return (GetTargetObject() as CECNPC).GetPos();
|
||||
}
|
||||
|
||||
public override bool OnTouched()
|
||||
@@ -231,8 +258,16 @@ namespace BrewMonster
|
||||
}
|
||||
else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_ATTACK)
|
||||
{
|
||||
if (m_iObjectId == m_pHost.m_idSelTarget &&
|
||||
m_pHost.AttackableJudge(m_iObjectId, m_bForceAttack) == 1)
|
||||
// 服务器的选中目标同步可能比追踪触碰晚到,导致这里永远不触发攻击。
|
||||
// 为了保证追踪到目标后能正常攻击,这里在必要时主动选中目标。
|
||||
// Server select-target ack can arrive later than the trace touch moment, which would
|
||||
// make this block forever. Ensure we select the traced target before attacking.
|
||||
if (m_iObjectId != m_pHost.m_idSelTarget)
|
||||
{
|
||||
UnityGameSession.c2s_CmdSelectTarget(m_iObjectId);
|
||||
m_pHost.m_idSelTarget = m_iObjectId;
|
||||
}
|
||||
if (m_pHost.AttackableJudge(m_iObjectId, m_bForceAttack) == 1)
|
||||
{
|
||||
byte byPVPMask = EC_Utility.glb_BuildPVPMask(m_bForceAttack);
|
||||
UnityGameSession.c2s_CmdNormalAttack(byPVPMask);
|
||||
@@ -317,7 +352,9 @@ namespace BrewMonster
|
||||
}
|
||||
else
|
||||
{
|
||||
return (pObject as EC_ElsePlayer).GetServerPos();
|
||||
// 同上:用实时位置避免 server pos 滞后导致追踪/触碰失败。
|
||||
// Same rationale: use live position to avoid stale server pos breaking trace/touch.
|
||||
return (pObject as EC_ElsePlayer).GetPos();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,8 +379,14 @@ namespace BrewMonster
|
||||
}
|
||||
if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_ATTACK)
|
||||
{
|
||||
if (m_iObjectId == m_pHost.m_idSelTarget &&
|
||||
m_pHost.AttackableJudge(m_iObjectId, m_bForceAttack) == 1)
|
||||
// 同 NPC:追踪触碰可能早于服务器选中目标同步,需主动选中以避免攻击不触发。
|
||||
// Same as NPC: trace touch can happen before server selection ack; proactively select.
|
||||
if (m_iObjectId != m_pHost.m_idSelTarget)
|
||||
{
|
||||
UnityGameSession.c2s_CmdSelectTarget(m_iObjectId);
|
||||
m_pHost.m_idSelTarget = m_iObjectId;
|
||||
}
|
||||
if (m_pHost.AttackableJudge(m_iObjectId, m_bForceAttack) == 1)
|
||||
{
|
||||
byte byPVPMask = EC_Utility.glb_BuildPVPMask(m_bForceAttack);
|
||||
UnityGameSession.c2s_CmdNormalAttack(byPVPMask);
|
||||
@@ -431,70 +474,73 @@ namespace BrewMonster
|
||||
public override bool OnTouched()
|
||||
{
|
||||
bool bActionDone = false;
|
||||
//if (GPDataTypeHelper.ISMATTERID(m_iObjectId))
|
||||
//{
|
||||
// if (m_pHost.GetProfession() == PROF_GHOST && m_pHost.IsInvisible())
|
||||
// {
|
||||
// g_pGame.GetGameRun().AddFixedMessage(FIXMSG_CANNOT_USE_WHEN_INVISIBLE);
|
||||
// return bActionDone;
|
||||
// }
|
||||
// CECMatter* pMatter = (CECMatter*)GetTargetObject();
|
||||
if (GPDataTypeHelper.ISMATTERID(m_iObjectId))
|
||||
{
|
||||
// if (m_pHost.GetProfession() == BrewMonster.RoleTypes.PROF_GHOST && m_pHost.IsInvisible())
|
||||
// {
|
||||
// EC_Game.GetGameRun().AddFixedMessage(FIXMSG_CANNOT_USE_WHEN_INVISIBLE);
|
||||
// return bActionDone;
|
||||
// }
|
||||
CECMatter pMatter = (CECMatter)GetTargetObject();
|
||||
|
||||
// if (m_iReason == CECHPWorkTrace::TRACE_PICKUP)
|
||||
// {
|
||||
// // Check whether we have enougth place to hold this item or money
|
||||
// a_LogOutput(1, "[NormalATK]- CECTracedMatter- OnTouched- TRACE_PICKUP");
|
||||
// if (m_pHost.CanTakeItem(pMatter.GetTemplateID(), 1))
|
||||
// {
|
||||
// // Send pickup asking and wait response command
|
||||
// g_pGame.GetGameSession().c2s_CmdPickup(m_iObjectId, pMatter.GetTemplateID());
|
||||
// bActionDone = true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // Print a notify message
|
||||
// g_pGame.GetGameRun().AddFixedMessage(FIXMSG_PACKISFULL);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// { // m_iReason == TRACE_GATHER
|
||||
// int tidMatter = pMatter.GetTemplateID();
|
||||
// a_LogOutput(1, "[NormalATK]- CECTracedMatter- OnTouched- TRACE_GATHER");
|
||||
// // Check mine level requirement
|
||||
// if (m_pHost.GetBasicProps().iLevel < pMatter.GetLevelReq())
|
||||
// {
|
||||
// g_pGame.GetGameRun().AddFixedMessage(FIXMSG_LEVELTOOLOW);
|
||||
// return bActionDone;
|
||||
// }
|
||||
if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_PICKUP)
|
||||
{
|
||||
// Check whether we have enougth place to hold this item or money
|
||||
if (m_pHost.CanTakeItem(pMatter.GetTemplateID(), 1))
|
||||
{
|
||||
// Send pickup asking and wait response command
|
||||
UnityGameSession.RequestPickupItem(m_iObjectId, pMatter.GetTemplateID());
|
||||
bActionDone = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Print a notify message
|
||||
//g_pGame.GetGameRun().AddFixedMessage(FIXMSG_PACKISFULL);
|
||||
Debug.Log("Khong du cho trong de nhat item");
|
||||
}
|
||||
}
|
||||
else if (m_iReason == CECHPWorkTrace.Trace_reason.TRACE_GATHER)
|
||||
{ // m_iReason == TRACE_GATHER
|
||||
int tidMatter = pMatter.GetTemplateID();
|
||||
// Check mine level requirement
|
||||
if (m_pHost.GetBasicProps().iLevel < pMatter.GetLevelReq())
|
||||
{
|
||||
//g_pGame.GetGameRun().AddFixedMessage(FIXMSG_LEVELTOOLOW);
|
||||
Debug.Log("Cap do cua ban khong du de khai thac tai nguyen nay");
|
||||
return bActionDone;
|
||||
}
|
||||
|
||||
// // Check whether we have a mine tool
|
||||
// int iPack, iIndex, idTool;
|
||||
// if (m_pHost.FindMineTool(tidMatter, &iPack, &iIndex, &idTool))
|
||||
// {
|
||||
// DATA_TYPE DataType;
|
||||
// const MINE_ESSENCE* pData = (const MINE_ESSENCE*)g_pGame.GetElementDataMan().get_data_ptr(pMatter.GetTemplateID(), ID_SPACE_ESSENCE, DataType);
|
||||
// if (DataType != DT_MINE_ESSENCE)
|
||||
// {
|
||||
// ASSERT(DataType == DT_MINE_ESSENCE);
|
||||
// return bActionDone;
|
||||
// }
|
||||
// Check whether we have a mine tool
|
||||
int iPack = 0;
|
||||
int iIndex = 0;
|
||||
int idTool = 0;
|
||||
if (m_pHost.FindMineTool(tidMatter, ref iPack, ref iIndex, ref idTool))
|
||||
{
|
||||
DATA_TYPE DataType = DATA_TYPE.DT_INVALID;
|
||||
MINE_ESSENCE pData = (MINE_ESSENCE)ElementDataManProvider.GetElementDataMan().get_data_ptr((uint)pMatter.GetTemplateID(), ID_SPACE.ID_SPACE_ESSENCE, ref DataType);
|
||||
if (DataType != DATA_TYPE.DT_MINE_ESSENCE)
|
||||
{
|
||||
//ASSERT(DataType == DT_MINE_ESSENCE);
|
||||
return bActionDone;
|
||||
}
|
||||
|
||||
// if (m_pHost.GetCoolTime(GP_CT_PLAYER_GATHER))
|
||||
// {
|
||||
// g_pGame.GetGameRun().AddFixedMessage(FIXMSG_CMD_INCOOLTIME);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // Send gather asking and wait response command
|
||||
// g_pGame.GetGameSession().c2s_CmdGatherMaterial(m_iObjectId, iPack, iIndex, idTool, pData.task_in);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// g_pGame.GetGameRun().AddFixedMessage(FIXMSG_NEEDTOOL);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
// if (m_pHost.GetCoolTime(GP_CT_PLAYER_GATHER))
|
||||
// {
|
||||
// g_pGame.GetGameRun().AddFixedMessage(FIXMSG_CMD_INCOOLTIME);
|
||||
// }
|
||||
else
|
||||
{
|
||||
// Send gather asking and wait response command
|
||||
UnityGameSession.c2s_CmdGatherMaterial(m_iObjectId, iPack, iIndex, idTool, (int)pData.task_in);
|
||||
bActionDone = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//g_pGame.GetGameRun().AddFixedMessage(FIXMSG_NEEDTOOL);
|
||||
}
|
||||
}
|
||||
}
|
||||
return bActionDone;
|
||||
}
|
||||
|
||||
@@ -531,6 +577,10 @@ namespace BrewMonster
|
||||
public void SetTraceTarget(CECTracedObject pTraceObj, bool bUseAutoPF = false)
|
||||
{
|
||||
ResetUseAutoPF(bUseAutoPF);
|
||||
if (pTraceObj == null)
|
||||
{
|
||||
return; // Invalid trace object / Invalid trace object
|
||||
}
|
||||
if (!pTraceObj.GetTargetObject() || pTraceObj.GetObjectID() == m_pHost.GetCharacterID())
|
||||
{
|
||||
// This is special case
|
||||
@@ -568,10 +618,10 @@ namespace BrewMonster
|
||||
{
|
||||
return new CECTracedNPC(TraceObjectType.TRACE_NPC, iTraceObjId, m_pHost, iReason, bForceAttack);
|
||||
}
|
||||
//else if (GPDataTypeHelper.ISMATTERID(iTraceObjId))
|
||||
//{
|
||||
// return new CECTracedMatter(TraceObjectType.TRACE_MATTER, iTraceObjId, m_pHost, iReason);
|
||||
//}
|
||||
else if (GPDataTypeHelper.ISMATTERID(iTraceObjId))
|
||||
{
|
||||
return new CECTracedMatter(TraceObjectType.TRACE_MATTER, iTraceObjId, m_pHost, iReason);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -596,17 +646,20 @@ namespace BrewMonster
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_bCheckTouch)
|
||||
// 重要:不要用 m_bCheckTouch 在这里抑制 Touch 检测。
|
||||
// 之前的移植里 m_bCheckTouch 会在 GroundMove 后被置为 false,导致下一帧永远不进入 OnTouchTarget。
|
||||
// Important: do not suppress touch checks with m_bCheckTouch here.
|
||||
// In this port, m_bCheckTouch can be forced false after GroundMove, making OnTouchTarget never fire.
|
||||
if (IsGoodTimeToTouch())
|
||||
{
|
||||
if (IsGoodTimeToTouch())
|
||||
// 注意:这里不能加 vExtent.y(胶囊半高),否则会把主角位置抬高导致 3D 距离变大,
|
||||
// 进而 CanTouchTarget 永远不满足(OnTouchTarget 永远不会触发)。
|
||||
// Note: Do NOT add vExtent.y (capsule half-height) here; touch uses 3D distance and this
|
||||
// artificially increases the distance, preventing OnTouchTarget() from ever triggering.
|
||||
if (m_pTraceObject.CanTouchFrom(m_pHost.GetPos()))
|
||||
{
|
||||
//OnTouchTarget();
|
||||
//return true;
|
||||
if (m_pTraceObject.CanTouchFrom(m_pHost.GetPos() + new A3DVECTOR3(0f, m_pHost.m_CDRInfo.vExtent.y, 0f)))
|
||||
{
|
||||
OnTouchTarget();
|
||||
return true;
|
||||
}
|
||||
OnTouchTarget();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
m_bCheckTouch = true;
|
||||
@@ -797,7 +850,7 @@ namespace BrewMonster
|
||||
// Operations
|
||||
|
||||
// On first tick
|
||||
protected virtual void OnFirstTick()
|
||||
protected override void OnFirstTick()
|
||||
{
|
||||
m_pHost.m_iMoveMode = (int)MoveMode.MOVE_MOVE;
|
||||
m_bHaveMoved = false;
|
||||
@@ -851,7 +904,7 @@ namespace BrewMonster
|
||||
else if (!m_pHost.m_GndInfo.bOnGround)
|
||||
iMoveMode = (int)GPMoveMode.GP_MOVE_FALL;
|
||||
|
||||
RaycastHit lastGroundHit;
|
||||
//RaycastHit lastGroundHit;
|
||||
//m_pHost.m_GndInfo.bOnGround = m_pHost.GroundCheck(out lastGroundHit);
|
||||
if (m_pHost.m_GndInfo.bOnGround)
|
||||
{
|
||||
@@ -886,10 +939,9 @@ namespace BrewMonster
|
||||
// CECIntelligentRoute::Instance().OnPlayerPosChange(vCurPos);
|
||||
//}
|
||||
|
||||
if (cdr.vTPNormal.IsZero())
|
||||
{
|
||||
m_bCheckTouch = false;
|
||||
}
|
||||
// 不要在这里关闭 touch 检测:Tick() 的 touch 检测发生在移动之前,
|
||||
// 如果这里把 m_bCheckTouch 置 false,会导致下一帧永远跳过触发逻辑。
|
||||
// Do not disable touch checking here; touch checking happens before movement in Tick().
|
||||
|
||||
//if (!m_vCurDirH.IsZero())
|
||||
//{
|
||||
@@ -972,6 +1024,33 @@ namespace BrewMonster
|
||||
}
|
||||
public A3DVECTOR3 GetCurMovingDest()
|
||||
{
|
||||
// 对于采集/拾取物体:保持一定距离,避免角色模型顶住碰撞体抖动
|
||||
// For gather/pickup matters: keep a stand-off distance to avoid jittering against colliders.
|
||||
if (m_pTraceObject != null && m_pTraceObject.GetTraceType() == TraceObjectType.TRACE_MATTER)
|
||||
{
|
||||
CECMatter matter = m_pTraceObject.GetTargetObject() as CECMatter;
|
||||
if (matter != null)
|
||||
{
|
||||
float keepDist = matter.GetGatherDist();
|
||||
if (keepDist > 0.01f)
|
||||
{
|
||||
A3DVECTOR3 hostPos = m_pHost.GetPos();
|
||||
A3DVECTOR3 targetPos = matter.GetPos();
|
||||
|
||||
A3DVECTOR3 deltaH = targetPos - hostPos;
|
||||
deltaH.y = 0.0f;
|
||||
float distH = deltaH.MagnitudeH();
|
||||
if (distH > keepDist + 0.05f && distH > 1e-4f)
|
||||
{
|
||||
deltaH.Normalize();
|
||||
A3DVECTOR3 dest = targetPos - deltaH * keepDist;
|
||||
// keep Y stable; GroundMove will resolve final Y anyway
|
||||
dest.y = hostPos.y;
|
||||
return dest;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return m_pTraceObject.GetTargetPos();
|
||||
}
|
||||
public void UpdateUseAutoPF()
|
||||
|
||||
Reference in New Issue
Block a user