📄 movement.cpp
字号:
IQuery.m_FilterFn = DNULL;
//get the farthest left we could travel
VEC_COPY(IQuery.m_From,vCurPos);
VEC_COPY(IQuery.m_Direction,vLeft);
if(pServerDE->CastRay(&IQuery,&ii))
{
fMaxDist = fLeftDist = VEC_DIST(vCurPos,ii.m_Point);
}
//now get the farthest right
VEC_COPY(IQuery.m_Direction,vRight);
if(pServerDE->CastRay(&IQuery,&ii))
{
fRightDist = VEC_DIST(vCurPos,ii.m_Point);
if(fRightDist > fMaxDist)
fMaxDist = fRightDist;
}
//travel the obstacle in both directions looking for a clearing
VEC_INIT(vDir);
VEC_MULSCALAR(vEnd,vForward,fMoveLen + 5.0f);
for(float fWidth = fMoveLen; !(fWidth >= fRightDist && fWidth >= fLeftDist); fWidth += fMoveLen)
{
//Check the right side
if(fWidth < fRightDist)
{
VEC_ADDSCALED(IQuery.m_From,vCurPos,vRight,fWidth);
VEC_ADD(IQuery.m_To,IQuery.m_From,vEnd);
if(!pServerDE->IntersectSegment(&IQuery,&ii))
{
VEC_ADDSCALED(IQuery.m_From,IQuery.m_From,vRight,fWidth/2);
pServerDE->AlignRotation(prRot, &vLeft, &m_vUp);
return IQuery.m_From;
}
}
//Check the left side
if(fWidth < fLeftDist)
{
VEC_ADDSCALED(IQuery.m_From,vCurPos,vLeft,fWidth);
VEC_ADD(IQuery.m_To,IQuery.m_From,vEnd);
if(!pServerDE->IntersectSegment(&IQuery,&ii))
{
VEC_ADDSCALED(IQuery.m_From,IQuery.m_From,vLeft,fWidth/2);
pServerDE->AlignRotation(prRot, &vRight, &m_vUp);
return IQuery.m_From;
}
}
}
return vStart;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CMovement::FindTurn
//
// PURPOSE: find pos to turn around
//
// ----------------------------------------------------------------------- //
DVector CMovement::FindTurn(DVector vStart, DVector vTestDir, DVector vMoveDir, DFLOAT fMoveLen,
DFLOAT fTestLen)
{
DVector vFinal,vCurPos;
DBOOL bStop = DTRUE;
DFLOAT fMaxDist = 0.0f;
VEC_INIT(vFinal);
VEC_COPY(vCurPos, vStart);
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return vFinal;
IntersectQuery IQuery;
IntersectInfo IInfo;
IQuery.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID;
IQuery.m_FilterFn = DNULL;
VEC_COPY(IQuery.m_From,vStart);
VEC_COPY(IQuery.m_Direction,vMoveDir);
//find maximum searchable distance in vMoveDir
if(pServerDE->CastRay(&IQuery,&IInfo))
{
fMaxDist = VEC_DIST(vStart,IInfo.m_Point);
}
//loop til we find a spot to turn
for(float fDist = 0.0f; !((fDist + fMoveLen) >= fMaxDist); fDist += fMoveLen)
{
VEC_ADDSCALED(vCurPos, vCurPos, vMoveDir, fMoveLen);
VEC_COPY(IQuery.m_From,vCurPos);
VEC_ADDSCALED(IQuery.m_To,vCurPos, vTestDir, fTestLen);
if(!pServerDE->IntersectSegment(&IQuery, &IInfo))
{
VEC_ADDSCALED(vFinal, vCurPos, vMoveDir, fMoveLen);
return vFinal;
}
}
if(m_nNumPoints >= 10 || (VEC_DIST(vCurPos,vStart) <= 0.0))
return vCurPos;
//we can't turn here so we add to list and keep searching in new direction
AddPosToPathList(vCurPos);
DVector vNewMoveDir;
VEC_MULSCALAR(vNewMoveDir, vTestDir, -1.0f);
return FindTurn(vCurPos, vMoveDir, vNewMoveDir, fMoveLen, (fMaxDist - fDist) + 1.0f);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CMovement::AddPosToPathList
//
// PURPOSE: add point to path list
//
// ----------------------------------------------------------------------- //
void CMovement::AddPosToPathList(DVector vPathpoint)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
DVector* vPoint = new DVector;
VEC_COPY(*vPoint, vPathpoint);
DLink* pLink = new DLink;
dl_AddTail(&m_PathList, pLink, (void*)vPoint);
m_nNumPoints++;
return;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CMovement::ConsolidatePath
//
// PURPOSE: add point to path list
//
// ----------------------------------------------------------------------- //
void CMovement::ConsolidatePath()
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
IntersectQuery IQuery;
IntersectInfo IInfo;
IQuery.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID;
IQuery.m_FilterFn = DNULL;
//check first from our pos to second path point
DLink* pLink1 = m_PathList.m_Head.m_pNext;
// add a little sanity checking (gk 9/2)
if (pLink1->m_pData && pLink1->m_pNext->m_pData)
{
VEC_COPY(IQuery.m_From, m_vPos);
VEC_COPY(IQuery.m_To, *((DVector*)pLink1->m_pNext->m_pData));
if(!pServerDE->IntersectSegment(&IQuery, &IInfo))
{
dl_RemoveAt(&m_PathList,pLink1);
delete pLink1;
}
}
//loop through pathpoint and pathpoint + 2
pLink1 = m_PathList.m_Head.m_pNext;
if (pLink1->m_pData && pLink1->m_pNext->m_pData)
{
DLink* pLink2 = pLink1->m_pNext->m_pNext;
while(pLink1->m_pData && pLink2->m_pData)
{
VEC_COPY(IQuery.m_From, *((DVector*)pLink1->m_pData));
VEC_COPY(IQuery.m_To, *((DVector*)pLink2->m_pData));
if(!pServerDE->IntersectSegment(&IQuery, &IInfo))
{
DLink *pObLink = pLink1->m_pNext;
dl_RemoveAt(&m_PathList,pObLink);
delete pObLink;
pLink2 = pLink2->m_pNext;
}
else
{
pLink1 = pLink1->m_pNext;
pLink2 = pLink2->m_pNext;
}
}
}
return;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CMovement::DebugDrawPath
//
// PURPOSE: debug draw path
//
// ----------------------------------------------------------------------- //
void CMovement::DebugDrawPath()
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE) return;
HCLASS hClass = pServerDE->GetClass( "CClientDebugLine" );
if( !hClass ) return;
ObjectCreateStruct ocStruct;
INIT_OBJECTCREATESTRUCT(ocStruct);
VEC_COPY(ocStruct.m_Pos, m_vPos);
ROT_COPY(ocStruct.m_Rotation, m_rRot);
DLink* pLink1 = m_PathList.m_Head.m_pNext;
DLink* pLink2 = pLink1->m_pNext;
while(pLink1->m_pData && pLink2->m_pData)
{
CClientDebugLine* pDebugline = (CClientDebugLine*)pServerDE->CreateObject(hClass, &ocStruct);
pDebugline->Setup((DVector*)pLink1->m_pData, (DVector*)pLink2->m_pData);
pLink1 = pLink1->m_pNext;
pLink2 = pLink2->m_pNext;
}
return;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CMovement::Save
//
// PURPOSE: Save the object
//
// ----------------------------------------------------------------------- //
void CMovement::Save(HMESSAGEWRITE hWrite, DDWORD dwSaveFlags)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE || !hWrite) return;
pServerDE->WriteToLoadSaveMessageObject(hWrite, m_hObject);
pServerDE->WriteToMessageRotation(hWrite, &m_rRot);
pServerDE->WriteToMessageVector(hWrite, &m_vRight);
pServerDE->WriteToMessageVector(hWrite, &m_vUp);
pServerDE->WriteToMessageVector(hWrite, &m_vForward);
pServerDE->WriteToMessageVector(hWrite, &m_vPos);
pServerDE->WriteToMessageVector(hWrite, &m_vLastPos);
pServerDE->WriteToMessageDWord(hWrite, m_PathList.m_nElements);
DLink *pLink = m_PathList.m_Head.m_pNext;
for (unsigned long i=0; i < m_PathList.m_nElements; i++)
{
pServerDE->WriteToMessageVector(hWrite, (DVector*)pLink->m_pData);
pLink = pLink->m_pNext;
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CMovement::Load
//
// PURPOSE: Load the object
//
// ----------------------------------------------------------------------- //
void CMovement::Load(HMESSAGEREAD hRead, DDWORD dwLoadFlags)
{
CServerDE* pServerDE = BaseClass::GetServerDE();
if (!pServerDE || !hRead) return;
pServerDE->ReadFromLoadSaveMessageObject(hRead, &m_hObject);
pServerDE->ReadFromMessageRotation(hRead, &m_rRot);
pServerDE->ReadFromMessageVector(hRead, &m_vRight);
pServerDE->ReadFromMessageVector(hRead, &m_vUp);
pServerDE->ReadFromMessageVector(hRead, &m_vForward);
pServerDE->ReadFromMessageVector(hRead, &m_vPos);
pServerDE->ReadFromMessageVector(hRead, &m_vLastPos);
int nNumPoints = pServerDE->ReadFromMessageDWord(hRead);
for (int i=0; i < nNumPoints; i++)
{
DVector vPos;
pServerDE->ReadFromMessageVector(hRead, &vPos);
AddPosToPathList(vPos);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -