⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mapdatapath.cpp

📁 魔域的服务端源代码。Visual C++编译的版本
💻 CPP
字号:
//----------------------------------------------------//
// InterActiveLayer.cpp
//----------------------------------------------------//
#include "typedef.h"
#include "MapData.h"
#include "TerrainObj.h"
#include "common.h"


///////////////////////////////////////////////////////////////////////////////////////
// posSource(in), pposTarget(in/out), pPathBuf(out), pBufSize(in/out)
bool CMapData::FindPath(PASSPATH0* pPathBuf, int nBufSize, POINT posSource, POINT posTarget, IRoleAttr* pAttr, int nEscapeSteps /*= 0*/)
{
	m_nLeaveDisc = nEscapeSteps;
	m_nPathMode = (nEscapeSteps == 0 ? _ASTAR_CLOSE : _ASTAR_LEAVE);
	this->FindPath(posSource, posTarget);

	memset(pPathBuf, 0, nBufSize);
	char*	pStep	= pPathBuf->pPath;

	int nAmount = this->GetPathAmount();
	if(nAmount == 0 || m_nPathMode == _ASTAR_LEAVE)
	{
		if(m_nPathMode == _ASTAR_LEAVE)
		{
			m_nPathMode = _ASTAR_CLOSE;
			this->FindPath(posSource, m_posRealTarget);
			m_nPathMode = _ASTAR_LEAVE;
		}
		else
		{
			this->FindPath(posSource, m_posRealTarget);
		}
	}
	nAmount = this->GetPathAmount();
	if(nAmount > nBufSize - sizeof(PASSPATH0))
		nAmount =  nBufSize - sizeof(PASSPATH0);
	for(int i = 0; i < nAmount; i++)
	{
		NodeInfo* pInfo = GetNodeByIndex(i);
        if(pInfo)
        {
			*(pStep++)	= pInfo->nDir;
        }
	}

	pPathBuf->nSize	= pStep - pPathBuf->pPath;
	pPathBuf->posStart	= posSource;
	pPathBuf->posStop	= m_posRealTarget;

	return true;
}

//----------------------------------------------------//
void CMapData::FindPath(POINT posStart, POINT posTarget)
{
	m_posRealTarget = posStart;
	m_posStart =posStart;
	m_posTarget =posTarget;
	if((posStart.x ==  posTarget.x) && (posStart.y ==  posTarget.y))
		return;
	this->InitAStar();
	while(true)
	{
		if(m_nCloseNodeAmount >= _MAX_PATHSTEP)
			return;
		if(m_setOpen.size() == 0)
			return;
		NodeInfo* pBestNode = this->CheckOpenList();
		if(!pBestNode)
			continue;
		if(this->AddSucNode(pBestNode))
			return;
	}
}
//----------------------------------------------------//
void CMapData::InitAStar()
{
	//把s压入open
	this->ClearNodeSet();
	this->ClearPathSet();
	this->ClearOpenSet();
	this->ClearCloseSet();
	m_nNodeIndex = 0;
	int nAmount = m_setCellAStar.size();
	for(int i = 0; i < nAmount; i++)
	{
		CCell* pCell = m_setCellAStar[i];
		if(pCell)
			pCell->SetSearchFlag(false);
	}
	m_setCellAStar.clear();
	NodeInfo* pNode = this->CreateNewNode();
	if(pNode)
	{
		pNode->nX = m_posStart.x;
		pNode->nY = m_posStart.y;
		pNode->nG = 0;
		pNode->nH = pNode->nG+this->GetHValue(m_posStart);
		pNode->nStep = 0;
		pNode->pNode = NULL;
		pNode->pChildNode = NULL;
		m_setOpen.push_back(pNode);
	}
	CCell* pCell =  this->GetCell(m_posStart.x, m_posStart.y);
	if(pCell)
	{
		pCell->SetSearchFlag(true);
		m_setCellAStar.push_back(pCell);
	}
}
//----------------------------------------------------//
int CMapData::GetHValue(POINT pos)
{
	int nDx = abs(m_posTarget.x-pos.x);
	int nDy = abs(m_posTarget.y-pos.y);
	if(nDx > nDy)
		return 10*nDx+6*nDy;
	return 10*nDy+6*nDx;
}
//----------------------------------------------------//
NodeInfo* CMapData::CheckOpenList()
{
	NodeInfo* pNode = this->CheckBestNode();
	if(pNode->nStep >= _MAX_PATHSTEP)
		return NULL;
	return pNode;
}
//----------------------------------------------------//
NodeInfo* CMapData::CheckBestNode()
{
	int nAmount = m_setOpen.size();
	NodeInfo* pBestNode = m_setOpen[0];
	int nBestNodeIndex = 0;
	for(int i = 1; i < nAmount; i++)
	{
		NodeInfo* pNode =  m_setOpen[i];
		if(pNode)
		{
			if(m_nPathMode == _ASTAR_CLOSE)
			{
				if((pNode->nH) < (pBestNode->nH))
				{
					pBestNode = pNode;
					nBestNodeIndex = i;
				}
			}
			else
			{
				if((pNode->nH) > (pBestNode->nH))
				{
					pBestNode = pNode;
					nBestNodeIndex = i;
				}
			}
		}
	}
	//::LogMsg("最佳节点:%d_%d", pBestNode->nX, pBestNode->nY);
	// 从Open表最佳节点
	//pBestNode->nG = 65535555;
	m_setOpen.erase(m_setOpen.begin()+nBestNodeIndex);
	// 添加到Close表
	//m_setClose.push_back(pBestNode);
	m_nCloseNodeAmount ++;
	return pBestNode;
}
//----------------------------------------------------//
BOOL CMapData::AddSucNode(NodeInfo* pNode)
{
	if(!pNode)
		return false;
	POINT posNode;
	posNode.x = pNode->nX;
	posNode.y = pNode->nY;
	POINT posNewNode;
	
	int nArrayX[8] = {0, -1, -1, -1,  0,  1, 1, 1};
	int nArrayY[8] = {1,  1,  0, -1, -1, -1, 0, 1};
	
	for(int i = 0; i < 8; i++)
	{
		posNewNode.x = posNode.x+nArrayX[i];
		posNewNode.y = posNode.y+nArrayY[i];
		if(posNewNode.x < 0)
			continue;
		if(posNewNode.y < 0)
			continue;
		if(posNewNode.x >= m_sizeMap.cx)
			continue;
		if(posNewNode.y >= m_sizeMap.cy)
			continue;
		
		int nHeight = 0;
		
		CCell* pCell = this->GetCell(pNode->nX, pNode->nY);
		if(pCell)
		{
			nHeight = pCell->GetFloorAlt(m_set2Layer);
		}
		
		if(!this->CheckNode(posNewNode, nHeight))
			continue;
		NodeInfo* pNewNode =  this->CreateNewNode();
		if(!pNewNode)
			continue;
		pNewNode->nX = posNewNode.x;
		pNewNode->nY = posNewNode.y;
		//#####代价#####
		pNewNode->nG = pNode->nG;// + 8;
		pNewNode->nH = pNode->nG+this->GetHValue(posNewNode);
		pNewNode->nStep = pNode->nStep + 1;
		pNewNode->pNode = pNode;
		pNewNode->nDir  = i;
		pNode->pChildNode = pNewNode;
		m_setOpen.push_back(pNewNode);

		// 算最近点...
		if(_ASTAR_CLOSE == m_nPathMode)
		{
			DWORD dwOldV =(m_posRealTarget.x-m_posTarget.x) *
				(m_posRealTarget.x-m_posTarget.x) +
				(m_posRealTarget.y-m_posTarget.y) *
				(m_posRealTarget.y-m_posTarget.y);
			DWORD dwNewV =(pNewNode->nX-m_posTarget.x) *
				(pNewNode->nX-m_posTarget.x) +
				(pNewNode->nY-m_posTarget.y) *
				(pNewNode->nY-m_posTarget.y);
			if(dwNewV < dwOldV)
			{
				m_posRealTarget.x = pNewNode->nX;
				m_posRealTarget.y = pNewNode->nY;
			}
		}
		else
		{
			DWORD dwOldV =(m_posRealTarget.x-m_posTarget.x) *
				(m_posRealTarget.x-m_posTarget.x) +
				(m_posRealTarget.y-m_posTarget.y) *
				(m_posRealTarget.y-m_posTarget.y);
			DWORD dwNewV =(pNewNode->nX-m_posTarget.x) *
				(pNewNode->nX-m_posTarget.x) +
				(pNewNode->nY-m_posTarget.y) *
				(pNewNode->nY-m_posTarget.y);
			if(dwNewV > dwOldV)
			{
				m_posRealTarget.x = pNewNode->nX;
				m_posRealTarget.y = pNewNode->nY;
				if(dwNewV >= m_nLeaveDisc*m_nLeaveDisc)
				{
					this->GetPath(pNewNode);
					return true;
				}
			}
		}
		
		//::LogMsg("添加节点:%d_%d", pNewNode->nX, pNewNode->nY);
		if(_ASTAR_CLOSE == m_nPathMode && (pNewNode->nX == m_posTarget.x) && (pNewNode->nY == m_posTarget.y))
		{
			this->GetPath(pNewNode);
			return true;
		}
	}
	return false;
}
//----------------------------------------------------//
void CMapData::GetPath(NodeInfo* pNode)
{
	NodeInfo* pMyNode = pNode;
	while(true)
	{
		if(pMyNode->pNode)
		{
			m_setPath.push_front(pMyNode);
			pMyNode = pMyNode->pNode;
		}
		else
		{
			break;
		}
	}
}

//----------------------------------------------------//
BOOL CMapData::CheckNode(POINT posNode, int nHeight)
{
	// 可达 ...?
	CCell* pCell = GetCell(posNode.x, posNode.y);
	if(!pCell)
		return false;
	if(pCell->BeSearched())
		return false;
	if((pCell->GetFloorMask(m_set2Layer) == 0)&& abs(nHeight - pCell->GetFloorAlt(m_set2Layer)) <= 25)
	{
		pCell->SetSearchFlag(true);
		m_setCellAStar.push_back(pCell);
		return true;
	}
	return false;
}
//----------------------------------------------------//
int  CMapData::GetPathAmount()
{
	return m_setPath.size();
}
//----------------------------------------------------//
NodeInfo* CMapData::GetNodeByIndex(int nIndex)
{
	int nAmount = m_setPath.size();
	if(nIndex < 0)
		return NULL;
	if(nIndex >= nAmount)
		return NULL;
	return m_setPath[nIndex];
}
//----------------------------------------------------//
int  CMapData::GetStep(POINT posCell)
{
	int nAmount =  m_setPath.size();
	for(int i = 0; i < nAmount; i++)
	{
		NodeInfo* pNod = this->GetNodeByIndex(i);
		if(!pNod)
			return -1;
		if((pNod->nX == posCell.x) && (pNod->nY == posCell.y))
			return pNod->nStep;
	}
	return -1;
}
//----------------------------------------------------//
void CMapData::ClearNodeSet()
{
	int nAmount = m_setNode.size();
	for(int i = 0; i < nAmount; i++)
	{
		NodeInfo* pNod = m_setNode[i];
		SAFE_DELETE(pNod);
	}
	m_setNode.clear();
	m_nNodeIndex=0;
}

//----------------------------------------------------//
NodeInfo* CMapData::CreateNewNode()
{
	int nAmount =  m_setNode.size();
	NodeInfo* pNode = NULL;
	m_nNodeIndex ++;
	if(m_nNodeIndex >= nAmount)
	{
		pNode = new NodeInfo;
		m_setNode.push_back(pNode);
	}
	else
	{
		pNode = m_setNode[m_nNodeIndex];
	}
	return pNode;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -