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