📄 role.cpp
字号:
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 + -