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

📄 gamemap.cpp

📁 网络游戏魔域的服务端与客户端完整源代码 包括详细的说明文档与开发日志
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		m_pMapData->IncRole(nNewPosX, nNewPosY);

	if(Block(pRole->GetPosX()) == Block(nNewPosX) && Block(pRole->GetPosY()) == Block(nNewPosY))
		return;

	IMapThing* pThing = pRole->QueryMapThing();
	CHECK(pThing);

	QueryBlock(pThing->GetPosX(), pThing->GetPosY()).QuerySet()->DelObj(pThing->GetID(), pThing->GetObjType());
	QueryBlock(nNewPosX, nNewPosY).QuerySet()->AddObj(pThing);
}

//////////////////////////////////////////////////////////////////////
// region info
//////////////////////////////////////////////////////////////////////
void CGameMap::SendRegionInfo(CUser* pUser)
{
	for(int i = 0; i < m_setWeather->GetAmount(); i++)
	{
		CWeatherRegion* pRegion = m_setWeather->GetObjByIndex(i);
		if(pRegion && IsInRegion(pRegion->QueryRegion(), pUser->GetMapID(), pUser->GetPosX(), pUser->GetPosY()))
		{
			pRegion->QueryWeather()->SendWeather(pUser);
			pUser->SetWeatherID(pRegion->GetID());
			return;
		}
	}
}

//////////////////////////////////////////////////////////////////////
void CGameMap::ClearRegionInfo(CUser* pUser)
{
	if(pUser->GetWeatherID() != ID_NONE)
	{
		CWeather::SendNoWeather(pUser);
		pUser->SetWeatherID(ID_NONE);
	}
}

//////////////////////////////////////////////////////////////////////
void CGameMap::ChangeRegion(CUser* pUser, int nNewPosX, int nNewPosY)
{
	for(int i = 0; i < m_setWeather->GetAmount(); i++)
	{
		CWeatherRegion* pRegion = m_setWeather->GetObjByIndex(i);
		if(pRegion && IsInRegion(pRegion->QueryRegion(), pUser->GetMapID(), nNewPosX, nNewPosY))
		{
			// found weather region
			if(pUser->GetWeatherID() != pRegion->GetID())
			{
				pRegion->QueryWeather()->SendWeather(pUser);
				pUser->SetWeatherID(pRegion->GetID());
			}
			return;
		}
	}

	// not in any weather region
	if(pUser->GetWeatherID() != ID_NONE)
	{
		CWeather::SendNoWeather(pUser);
		pUser->SetWeatherID(ID_NONE);
	}
}

//////////////////////////////////////////////////////////////////////
// const
//////////////////////////////////////////////////////////////////////
bool CGameMap::IsStandEnable(int nPosX, int nPosY)
{
	if(!IsValidPoint(nPosX, nPosY))
		return false;
	return (m_pMapData->GetFloorMask(nPosX, nPosY) == 0);
}

//////////////////////////////////////////////////////////////////////
bool CGameMap::IsMoveEnable(int x, int y)
{
	if(!IsValidPoint(x, y))
		return false;
	if(m_pMapData->GetFloorMask(x, y) != 0)
		return false;
	if(m_pMapData->GetRoleAmount(x, y) > 0)
		return false;

	return true;
}

//////////////////////////////////////////////////////////////////////
bool CGameMap::IsMoveEnable(int xSour, int ySour, int x, int y, int nClimbCap)
{
	if(!IsValidPoint(x, y))
		return false;
	if(m_pMapData->GetFloorMask(x, y) != 0)
		return false;
	if(m_pMapData->GetRoleAmount(x, y) > 0)
		return false;
	if(m_pMapData->GetFloorAlt(x, y) - m_pMapData->GetFloorAlt(xSour, ySour) > nClimbCap)
		return false;

	return true;
}

//////////////////////////////////////////////////////////////////////
bool CGameMap::IsAltEnable(const POINT& posSour, const POINT& pos, int nAltDiff)
{
	if(!IsValidPoint(pos))
		return false;
	if(abs(m_pMapData->GetFloorAlt(pos.x, pos.y) - m_pMapData->GetFloorAlt(posSour.x, posSour.y)) >= nAltDiff)
		return false;

	return true;
}

//////////////////////////////////////////////////////////////////////
bool CGameMap::IsAltOver(const POINT& pos, int nAlt)
{
	if(!IsValidPoint(pos))
		return false;

	if(m_pMapData->GetFloorAlt(pos.x, pos.y) > nAlt)
		return true;

	return false;
}

//////////////////////////////////////////////////////////////////////
CRegionData* CGameMap::QueryRegion(int nRegionType, int x, int y)
{
	for(int i = 0; i < QueryRegionSet()->GetAmount(); i++)
	{
		CRegionData* pData = QueryRegionSet()->GetObjByIndex(i);
		if(pData && pData->GetInt(REGIONDATA_TYPE) == nRegionType && IsInRegion(pData, GetID(), x, y))
		{
			return pData;
		}
	}

	return NULL;
}

//////////////////////////////////////////////////////////////////////
bool CGameMap::IsInRegionType(int nRegionType, int x, int y)
{
	for(int i = 0; i < QueryRegionSet()->GetAmount(); i++)
	{
		CRegionData* pData = QueryRegionSet()->GetObjByIndex(i);
		if(pData && pData->GetInt(REGIONDATA_TYPE) == nRegionType && IsInRegion(pData, GetID(), x, y))
		{
			return true;
		}
	}

	return false;
}

//////////////////////////////////////////////////////////////////////
bool CGameMap::IsInRegion(CRegionData* pData, OBJID idMap, int x, int y)
{
	if(idMap == pData->GetInt(REGIONDATA_MAPID)
			&& x >= pData->GetInt(REGIONDATA_BOUND_X) && x < pData->GetInt(REGIONDATA_BOUND_X) + pData->GetInt(REGIONDATA_BOUND_CX)
			&& y >= pData->GetInt(REGIONDATA_BOUND_Y) && y < pData->GetInt(REGIONDATA_BOUND_Y) + pData->GetInt(REGIONDATA_BOUND_CY))
		return true;

	return false;
}

//////////////////////////////////////////////////////////////////////
bool CGameMap::BroadcastDance(CUser* pUser, OBJID idEmotion)
{
	CRegionData* pData = QueryRegion(REGION_DANCE, pUser->GetPosX(), pUser->GetPosY());
	if(pData && pData->GetInt(REGIONDATA_DATA0) == pData->GetID() && idEmotion > 1)	// leader
	{
		CMsgAction	msg;
		IF_OK(msg.Create(pUser->GetID(), pUser->GetPosX(), pUser->GetPosY(), pUser->GetDir(), actionEmotion, idEmotion))
			pUser->BroadcastRoomMsg(&msg, INCLUDE_SELF);

		CRegionData* pFollow = QueryRegionSet()->GetObj(pData->GetInt(REGIONDATA_DATA1));
		CUserManager::Iterator pTarget = UserManager()->NewEnum();
		while(pTarget.Next())
		{
			if(IsInRegion(pFollow, pTarget->GetMapID(), pTarget->GetPosX(), pTarget->GetPosY()) && pTarget->GetSex() == pUser->GetSex())
			{
				pTarget->SetPose(idEmotion);

				CMsgAction	msg;
				IF_OK(msg.Create(pTarget->GetID(), pTarget->GetPosX(), pTarget->GetPosY(), pTarget->GetDir(), actionEmotion, idEmotion))
					pTarget->BroadcastRoomMsg(&msg, INCLUDE_SELF);
#ifdef _DEBUG
				pTarget->SendSysMsg("群舞:%d", idEmotion);
#endif
			}
		}
/*
		CMsgAction	msg;
		IF_OK(msg.Create(pUser->GetID(), pUser->GetPosX(), pUser->GetPosY(), pUser->GetDir(), actionMusic, pData->GetInt(REGIONDATA_DATA2)))
			pUser->BroadcastRoomMsg(&msg, INCLUDE_SELF);
*/
		return true;
	}

	if(pData && pData->GetInt(REGIONDATA_DATA0) != pData->GetID())	// follow
	{
		CRegionData* pLeaderData = QueryRegionSet()->GetObj(pData->GetInt(REGIONDATA_DATA0));
		IF_OK(pLeaderData)
		{
			CUser* pLeader;
			if(QueryObjInPos(pLeaderData->GetInt(REGIONDATA_BOUND_X), pLeaderData->GetInt(REGIONDATA_BOUND_Y), OBJ_USER, IPP_OF(pLeader))
						&& pLeader->GetSex() == pUser->GetSex() && pLeader->GetPose() > 1 && pLeader->GetPose() < 10)
			{
				idEmotion = pLeader->GetPose();
#ifdef _DEBUG
				pUser->SendSysMsg("跟舞:%d", idEmotion);
#endif
			}
		}
	}

	pUser->SetPose(idEmotion);

	CMsgAction	msg;
	IF_OK(msg.Create(pUser->GetID(), pUser->GetPosX(), pUser->GetPosY(), pUser->GetDir(), actionEmotion, idEmotion))
		pUser->BroadcastRoomMsg(&msg, INCLUDE_SELF);
	return true;
}

//////////////////////////////////////////////////////////////////////
// application
//////////////////////////////////////////////////////////////////////
void CGameMap::CollectMapThing(MAPTHING_SET& setMapThing, const POINT pos, int nRange, OBJID idObjTypeUnion)
{
//	CHECK(psetMapThing);

	int	nSize		= nRange*2 + 1;
	int	nBufSize	= nSize * nSize;
	setMapThing.resize(nBufSize);

	int x,y,z;
	FOR_9_BLOCKTHINGS(this, pos.x, pos.y)
	{
		IMapThing* pThing = QueryThingByIndex(x,y,z);
		if(pThing && ::IsObjType(pThing->GetObjType(), idObjTypeUnion)
				&& Distance(pThing->GetPosX(), pThing->GetPosY(), pos.x, pos.y) <= nRange)
		{
			int idx = POS2INDEX(pThing->GetPosX() - (pos.x - nRange), pThing->GetPosY() - (pos.y - nRange), nSize, nSize);
			IF_OK(idx >= 0 && idx < nBufSize)
				setMapThing[idx]	= pThing;
		}
	}
}

//////////////////////////////////////////////////////////////////////
bool CGameMap::FindDropItemCell(int nRange, POINT* pPos)		// pos: in/out
{
	int	nSize		= nRange*2 + 1;
	int	nBufSize	= nSize * nSize;
	MAPTHING_SET	setItem;

	CollectMapThing(setItem, *pPos, nRange, OBJ_MAPITEM);

	// 先随机
	int		nIndex = ::RandGet(nBufSize);
	if(!setItem[nIndex])
	{
		POINT	posTest;
		int		nLeft	= pPos->x - nRange;
		int		nTop	= pPos->y - nRange;
		posTest.x	= nLeft + INDEX2X(nIndex, nSize, nSize);
		posTest.y	= nTop + INDEX2Y(nIndex, nSize, nSize);
		if(IsLayItemEnable(posTest.x, posTest.y))
		{
			*pPos = posTest;
			return true;
		}
	}

	// 顺序找
	int		nMinRange = nRange + 1;
	int		ret	= false;
	POINT	posFree;
	for(int i = __max(pPos->x-nRange, 0); i <= pPos->x+nRange && i < GetWidth(); i++)
	{
		for(int j = __max(pPos->y-nRange, 0); j <= pPos->y+nRange && j < GetHeight(); j++)
		{
			int idx = POS2INDEX(i - (pPos->x - nRange), j - (pPos->y - nRange), nSize, nSize);
			IF_OK(idx >= 0 && idx < nBufSize)
				if(setItem[idx])
					continue;

			if(IsLayItemEnable(i, j))
			{
				int	nDistance = Distance(i, j, pPos->x, pPos->y);
				if(nDistance < nMinRange)
				{
					// 找到了!
					nMinRange = nDistance;
					posFree.x	= i;
					posFree.y	= j;
					ret = true;
				}
			}
		}
	}

	if(ret)
	{
		*pPos = posFree;
		return true;
	}
	else
	{
		return false;
	}
}

//////////////////////////////////////////////////////////////////////
bool CGameMap::GetPassageMap(OBJID* pidMap, POINT* pposTarget, const POINT& pos)
{
	CHECKF(pos.x >= 0 && pos.x < GetWidth() && pos.y >=0 && pos.y < GetHeight());

	int	idxPassage = m_pMapData->GetPassage(pos.x, pos.y);
	if(idxPassage == PASSAGE_NONE)
		return false;

	if(IsDynaMap())
	{
		*pidMap				= m_pData->GetInt(GAMEMAPDATA_LINKMAP);
		pposTarget->x		= m_pData->GetInt(GAMEMAPDATA_LINK_X);
		pposTarget->y		= m_pData->GetInt(GAMEMAPDATA_LINK_Y);
		return true;
	}

	OBJID	idTargetMap	= ID_NONE;
	int		idxPortal	= 0;
	if(!MapManager()->FindPassway(&idTargetMap, &idxPortal, GetID(), idxPassage))
	{
		LOGWARNING("没有找到[%d]地图的[%d]号出口点! %s 数据错误。", GetID(), idxPassage, _TBL_PASSWAY);
		return false;
	}

	POINT	posNew;
	if(!MapManager()->FindPortal(&posNew, idTargetMap, idxPortal))
	{
		LOGWARNING("没有找到地图入口点[%u][%d], 使用缺省入口点! %s 数据错误。", idTargetMap, idxPortal, _TBL_PORTAL);
		CGameMapData* pTargetMap = MapManager()->QuerySystemMapSet()->GetObj(idTargetMap);
		IF_NOT(pTargetMap)
		{
			LOGERROR("没有找到切屏地图[%u]! %s 数据错误。", idTargetMap, _TBL_PORTAL);
			return false;
		}
		posNew.x	= pTargetMap->GetInt(GAMEMAPDATA(GAMEMAPDATA_PORTAL0_X));
		posNew.y	= pTargetMap->GetInt(GAMEMAPDATA(GAMEMAPDATA_PORTAL0_Y));
	}

	*pidMap	= idTargetMap;
	*pposTarget	= posNew;

	return true;
}

//////////////////////////////////////////////////////////////////////
bool CGameMap::SetStatus(int nStatus, bool flag)
{
	int	nOldStatus = m_nStatus;
	if(flag)
		m_nStatus	|= nStatus;
	else
		m_nStatus	&= ~nStatus;

	if(nOldStatus != m_nStatus)
	{
		// synchro npc server
		CMsgAction	msg;
		IF_OK(msg.Create(GetID(),1,1,1,actionMapStatus, m_nStatus))
			MapGroup(PID)->QueryIntraMsg()->SendNpcMsg(ID_NONE, &msg);

		return true;
	}

	return false;
}

//////////////////////////////////////////////////////////////////////
bool CGameMap::GetRebornMap(OBJID* pidMap, POINT* pposTarget)
{
	OBJID	idTargetMap	= m_pData->GetInt(GAMEMAPDATA_REBORN_MAPID);
	int		idxPortal	= m_pData->GetInt(GAMEMAPDATA_REBORN_PORTAL);
	CHECKF(idTargetMap != ID_NONE);

	/*
	if(!MapManager()->FindPortal(&posNew, idTargetMap, idxPortal))
	{
		LOGWARNING("没有找到地图入口点[%u][%d], 使用缺省入口点.", idTargetMap, idxPortal);
	}
	*/
	
	CGameMapData* pTargetMap = MapManager()->QuerySystemMapSet()->GetObj(idTargetMap);
	IF_NOT(pTargetMap)
	{
		LOGERROR("没有找到切屏地图[%u] !", idTargetMap);
		return false;
	}

	POINT	posNew;
	posNew.x	= pTargetMap->GetInt(GAMEMAPDATA(GAMEMAPDATA_PORTAL0_X));
	posNew.y	= pTargetMap->GetInt(GAMEMAPDATA(GAMEMAPDATA_PORTAL0_Y));

	IF_NOT (posNew.x != 0 || posNew.y != 0)
		return false;

	*pidMap	= idTargetMap;
	*pposTarget	= posNew;

⌨️ 快捷键说明

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