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

📄 role.cpp

📁 魔域的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		int	nDeltaY	= abs(nPosY - m_nPosY);
		
		// 检查外挂
		if(nDeltaX > CELLS_PER_BLOCK || nDeltaY > CELLS_PER_BLOCK)
		{
			//		::GmLogSave("玩家[%s]跳的距离非法[%d][%d]。", GetName(), nDeltaX, nDeltaY);
			return ;
		}
		if(GetMap() && !GetMap()->IsStandEnable(nPosX, nPosY))
		{
			SendSysMsg(STR_INVALID_COORDINATE);
//			MSGBUF	szMsg;
//			sprintf(szMsg, "玩家[%s]跳到非法坐标[%d,%d,%d]。", GetName(), GetMapID(), nPosX, nPosY);
//			::GmLogSave(szMsg);
			pUser->KickBack();
			//UserManager()->KickOutSocket(GetSocketID(), szMsg);
			return ;
		}
	}

	CRole::DetachStatus(this, STATUS_HIDDEN);

	pMap->MoveTo(this, nPosX, nPosY, WITH_BLOCK, WITH_BLOCK);
	if (pUser)
	{
		pUser->StandRestart();
		pMap->ChangeRegion(pUser, nPosX, nPosY);
	}
	int	nOldX	= m_nPosX;
	int	nOldY	= m_nPosY;
	m_nPosX = nPosX;
	m_nPosY = nPosY;
	
	// 其它玩家
/*
	int x,y,z;
	IRole*	pRole = NULL;
	FOR_9_BLOCKTHINGS(pMap, GetPosX(), GetPosY())
	{
		IMapThing* pTarget = pMap->QueryThingByIndex(x,y,z);
		CUser* pTargetUser = NULL;
		if(pTarget && 
			(pUser													// 玩家,一定要发
			|| pTarget->QueryObj(OBJ_USER, IPP_OF(pTargetUser))))	// 非玩家,仅在看到玩家才发
		{
			if(abs(pTarget->GetPosX() - nOldX) > CELLS_PER_VIEW  
				&& abs(pTarget->GetPosX() - this->GetPosX()) <= CELLS_PER_VIEW
				|| abs(pTarget->GetPosY() - nOldY) > CELLS_PER_VIEW 
				&& abs(pTarget->GetPosY() - this->GetPosY()) <= CELLS_PER_VIEW )
			{
				pTarget->SendShow(this);
				//				this->SendSysMsg("跳了");//@

				if(pTarget->QueryRole(IPP_OF(pRole)))
					this->SendShow(pRole);
			}
		}
	}
*/

	ClrBroadcastSet();
	UpdateBroadcastSet();
	
	ProcessAfterMove();
}

//////////////////////////////////////////////////////////////////////
bool CRole::SyncTrackTo(int nPosX, int nPosY, int nDir, DWORD dwAction)
{
	m_nDir	= nDir%8;
	
	if (GetPosX() != nPosX || GetPosY() != nPosY)
	{
		CMapPtr pMap = this->GetMap();
		IF_NOT(pMap && pMap->IsValidPoint(nPosX, nPosY))
			return false;
		
		if(GetMap() && !GetMap()->IsStandEnable(nPosX, nPosY))
		{
			//SendSysMsg(STR_INVALID_COORDINATE);
			//::LogSave("Invalid coordinate (%d, %d)", nPosX, nPosY);
			return false;
		}
		
		CRole::DetachStatus(this, STATUS_HIDDEN);
		
		pMap->MoveTo(this, nPosX, nPosY, WITH_BLOCK, WITH_BLOCK);
		CUser* pUser = NULL;
		if (this->QueryObj(OBJ_USER, IPP_OF(pUser)))
		{
			pUser->StandRestart();
			pMap->ChangeRegion(pUser, nPosX, nPosY);
		}

//		int	nOldX	= m_nPosX;
//		int	nOldY	= m_nPosY;
		m_nPosX	= nPosX;
		m_nPosY	= nPosY;

/*
		int x,y,z;
		IRole*	pRole = NULL;
		FOR_9_BLOCKTHINGS(pMap, GetPosX(), GetPosY())
		{
			IMapThing* pTarget = pMap->QueryThingByIndex(x,y,z);
			CUser* pTargetUser = NULL;
			if(pTarget && 
				(pUser													// 玩家,一定要发
				|| pTarget->QueryObj(OBJ_USER, IPP_OF(pTargetUser))))	// 非玩家,仅在看到玩家才发
			{
				if(abs(pTarget->GetPosX() - nOldX) > CELLS_PER_VIEW  
					&& abs(pTarget->GetPosX() - this->GetPosX()) <= CELLS_PER_VIEW
					|| abs(pTarget->GetPosY() - nOldY) > CELLS_PER_VIEW 
					&& abs(pTarget->GetPosY() - this->GetPosY()) <= CELLS_PER_VIEW )
				{
					pTarget->SendShow(this);

					if(pTarget->QueryRole(IPP_OF(pRole)))		// 遇见的是角色
						this->SendShow(pRole);
				}
			}
		}
*/
	}

	UpdateBroadcastSet();

	//	ProcessAfterMove();
	
	// 同步轨迹
	CMsgAction	msg;
	IF_OK (msg.Create(GetID(), GetPosX(), GetPosY(), GetDir(), actionMagicTrack, dwAction))
		BroadcastRoomMsg(&msg, true);
	
	return true;
}


//////////////////////////////////////////////////////////////////////
bool CRole::UpdateBroadcastSet(bool bClearSet/*=false*/)
{
	CHECKF (GetMap());
	CUser* pUser = NULL;
	QueryObj(OBJ_USER, IPP_OF(pUser));

	bool	bIsCallPet = false;
	CMonster* pMonster;
	if (QueryObj(OBJ_MONSTER, IPP_OF(pMonster)))
	{
		if (pMonster->IsCallPet() || pMonster->IsEudemon())
			bIsCallPet = true;
	}

	// 寻找新的目标集
	typedef std::vector<IRole*>		ROLE_SET;
	ROLE_SET		setNewRole;
	BROADCAST_SET	setNewMapItem;
	int x,y,z;
	IRole*	pRole = NULL;
	FOR_9_BLOCKTHINGS(GetMap(), GetPosX(), GetPosY())
	{
		IMapThing* pTarget = GetMap()->QueryThingByIndex(x,y,z);
		if(!pTarget)
			continue;
			
		if (abs(pTarget->GetPosX() - GetPosX()) <= CELLS_PER_VIEW
			&& abs(pTarget->GetPosY() - GetPosY()) <= CELLS_PER_VIEW)
		{
			if (pTarget->QueryRole(IPP_OF(pRole)))
			{
				CUser* pTargetUser = NULL;
				if (pRole->GetID() != this->GetID()
					&& (bIsCallPet || pUser || pTarget->QueryObj(OBJ_USER, IPP_OF(pTargetUser))
						|| (pTarget->QueryObj(OBJ_MONSTER, IPP_OF(pMonster)) 
								&& (pMonster->IsCallPet() || pMonster->IsEudemon()))))
				{
					// 自己是玩家、幻兽,或者目标是玩家、幻兽
					setNewRole.push_back(pRole);
				}
			}
			else if (pUser)	// 地图上的物品不需要发给NPC服务器
			{
				setNewMapItem.push_back(pTarget->GetID());
			}
		}
	}

	// 清除原有目标集 —— 重新搜索所有目标
//	if (bClearSet)
//	{
//		m_setBCRole.clear();
//		m_setBCMapItem.clear();
//	}
//	else
	{
		// 遍历原目标集,删除不在新目标集中的id,压入已删除队列
		// 同时也删除新目标集中原来已经存在的id
		BROADCAST_SET::iterator it = m_setBCRole.begin();
		for (; it!=m_setBCRole.end(); )
		{
			OBJID id = *it;
			bool  bMatch = false;
			ROLE_SET::iterator iter = setNewRole.begin();
			for (; iter!=setNewRole.end(); iter++)
			{
				IRole* pRole = *iter;
				if (pRole && pRole->GetID() == id)
				{
					bMatch = true;
					setNewRole.erase(iter);
					break;
				}
			}
			BROADCAST_SET::iterator itErase = it;
			++it;
			if (!bMatch)
			{
				m_setBCRole.erase(itErase);

				// 通知自己对方消失
				RemoveFromBCRoleSet(id);

				// 通知对方自己消失
				IRole* pRole = RoleManager()->QueryRole(id);
				if (pRole)
					pRole->RemoveFromBCRoleSet(this->GetID());
			}
		}
		for (it=m_setBCMapItem.begin(); it!=m_setBCMapItem.end(); )
		{
			OBJID id = *it;
			bool bMatch = false;
			BROADCAST_SET::iterator iter = setNewMapItem.begin();
			for (; iter!=setNewMapItem.end(); iter++)
			{
				if (id == *iter)
				{
					bMatch = true;
					setNewMapItem.erase(iter);
					break;
				}
			}
			BROADCAST_SET::iterator itErase = it;
			++it;
			if (!bMatch)
			{
				m_setBCMapItem.erase(itErase);

				RemoveFromBCMapItemSet(id);
			}
		}
	}

	// 将整理后的新旧目标集合并
	CUser* pTargetUser = NULL;
	if (!setNewRole.empty())
	{
		ROLE_SET::iterator it=setNewRole.begin();
		for (; it!=setNewRole.end(); it++)
		{
			IRole* pRole = *it;
			if (pRole)
			{
				// 将对方加入自己的目标集,同时也将自己加入对方目标集
				// 自己是玩家,或者自己是NPC且对方是玩家或幻兽的时候才需要发送
				bool bSendSelf = (pUser || 
									(!bIsCallPet && (pRole->QueryObj(OBJ_USER, IPP_OF(pTargetUser))
													|| (pRole->QueryObj(OBJ_MONSTER, IPP_OF(pMonster))
															&& (pMonster->IsCallPet() || pMonster->IsEudemon())))));
				AddToBCRoleSet(pRole->GetID(), bSendSelf);

				// 对方不是幻兽,且,自己是玩家或幻兽或者对方是玩家的时候才需要发送
				pRole->QueryObj(OBJ_MONSTER, IPP_OF(pMonster));
				bool bSendTarget = ((!pMonster || (!pMonster->IsCallPet() && !pMonster->IsEudemon()))
										&& (pUser || bIsCallPet || pRole->QueryObj(OBJ_USER, IPP_OF(pTargetUser))));
				pRole->AddToBCRoleSet(GetID(), bSendTarget);
			}
		}
	}
	if (!setNewMapItem.empty())
	{
		BROADCAST_SET::iterator it=setNewMapItem.begin();
		for (; it!=setNewMapItem.end(); it++)
		{
			AddToBCMapItemSet(*it);
		}
	}

	return true;
}

//////////////////////////////////////////////////////////////////////
void CRole::ClrBroadcastSet()
{
	BROADCAST_SET::iterator it = m_setBCRole.begin();
	for (; it!=m_setBCRole.end(); it++)
	{
		OBJID id = *it;
		// 通知对方自己消失
		IRole* pRole = RoleManager()->QueryRole(id);
		if (pRole)
			pRole->RemoveFromBCRoleSet(this->GetID());		
	}
	m_setBCRole.clear();

	m_setBCMapItem.clear();
}

//////////////////////////////////////////////////////////////////////
void CRole::AddToBCRoleSet(OBJID idRole, bool bSendMsg)
{
	BROADCAST_SET::iterator it=m_setBCRole.begin();
	for (; it!=m_setBCRole.end(); it++)
	{
		if (idRole == *it)
			return;
	}
	m_setBCRole.push_back(idRole);
	if (bSendMsg)
	{
		IRole* pRole =  RoleManager()->QueryRole(idRole);
		if (pRole)
		{
			pRole->QueryMapThing()->SendShow((IRole*)this);
		}
	}
}

//////////////////////////////////////////////////////////////////////
void CRole::RemoveFromBCRoleSet(OBJID idRole)
{
	//NPC服务器机制暂时不改,这里只需通知客户端玩家
	CUser* pUser = NULL;
	if (QueryObj(OBJ_USER, IPP_OF(pUser)))
	{
		// 通知自己对方消失
		CMsgAction msg;
		if (msg.Create(idRole, 0, 0, 0, actionDisappear, 0))
			SendMsg(&msg);
	}

	BROADCAST_SET::iterator it=m_setBCRole.begin();
	for (; it!=m_setBCRole.end(); it++)
	{
		if (idRole == *it)
		{
			m_setBCRole.erase(it);
			break;
		}
	}
}

//////////////////////////////////////////////////////////////////////
void CRole::AddToBCMapItemSet(OBJID idMapItem)
{
	BROADCAST_SET::iterator it=m_setBCMapItem.begin();
	for (; it!=m_setBCMapItem.end(); it++)
	{
		if (idMapItem == *it)
			return;
	}
	m_setBCMapItem.push_back(idMapItem);
	CMapItem* pMapItem = MapManager()->QueryMapItem(idMapItem);
	if (pMapItem)
	{
		pMapItem->QueryMapThing()->SendShow(this);
	}
}

//////////////////////////////////////////////////////////////////////
void CRole::RemoveFromBCMapItemSet(OBJID idMapItem)
{
	//NPC服务器机制暂时不改,这里只需通知客户端
	CUser* pUser = NULL;
	if (QueryObj(OBJ_USER, IPP_OF(pUser)))
	{
		CMsgAction msg;
		if (msg.Create(idMapItem, 0, 0, 0, actionDisappear, 1))
			SendMsg(&msg);
	}

	BROADCAST_SET::iterator it=m_setBCMapItem.begin();
	for (; it!=m_setBCMapItem.end(); it++)
	{
		if (idMapItem == *it)
		{
			m_setBCMapItem.erase(it);
			break;
		}
	}
}

//////////////////////////////////////////////////////////////////////
void CRole::BroadcastRoomMsg(CNetMsg* pMsg, bool bSendSelf)
{
	CHECK(pMsg);
	CGameMap* pMap = GetMap();
	CHECK (pMap);

	CUser*	pUser		= NULL;
	IRole*	pRole		= NULL;
	CMonster* pMonster	= NULL;
	bool bSendToNpc	= (QueryObj(OBJ_USER, IPP_OF(pUser))
						|| (QueryObj(OBJ_MONSTER, IPP_OF(pMonster)) && (pMonster->IsCallPet() || pMonster->IsEudemon()))
						|| bSendSelf);

	if (pMap->IsNewbieMap() && bSendSelf)
	{
		SendMsg(pMsg);
		return;
	}

	if (bSendSelf)
		m_setBCRole.push_back(this->GetID());
	DEBUG_TRY
	BROADCAST_SET::iterator it=m_setBCRole.begin();
	for (; it!=m_setBCRole.end(); it++)
	{
		OBJID idRole = *it;
		IRole* pRole = RoleManager()->QueryRole(idRole);
		if (pRole)
		{
			if (pRole->QueryObj(OBJ_MONSTER, IPP_OF(pMonster)) && bSendToNpc)
			{
				if (!pMonster->IsCallPet() && !pMonster->IsEudemon())
				{
					pRole->SendMsg(pMsg);
					bSendToNpc = false;
				}
			}
			if (pRole->QueryObj(OBJ_USER, IPP_OF(pUser)))
			{
				pRole->SendMsg(pMsg);
				if (pUser->IsAgent() && bSendToNpc)
					bSendToNpc = false;
			}
		}
	}
	DEBUG_CATCH("CRole::BroadcastRoomMsg")
	if (bSendSelf)
		m_setBCRole.pop_back();
}

⌨️ 快捷键说明

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