📄 gamemap.cpp
字号:
// GameMap.cpp: implementation of the CGameMap class.
//
//////////////////////////////////////////////////////////////////////
#pragma warning(disable: 4786)
#include "GameObj.h"
#include "GameMap.h"
#include <algorithm>
#include "AllMsg.h"
#include "GameData.h"
#include "I_MapData.h"
#include "MapGroup.h"
#include "BaseFunc.h"
#include "WeatherRegion.h"
#include "RoleManager.h"
#include "Array.h"
//////////////////////////////////////////////////////////////////////
#define MAPDATA_VERSION ((LPCTSTR)true) // DDVersion
const DWORD DEFAULT_LIGHTRGB = 0xFFFFFFFF;
//////////////////////////////////////////////////////////////////////
MYHEAP_IMPLEMENTATION(CGameMap,s_heap)
char szMapTable[] = _TBL_MAP;
char szRegionTable[] = _TBL_REGION;
char szPortalTable[] = _TBL_PORTAL;
char szPasswayTable[] = _TBL_PASSWAY;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CGameMap::CGameMap()
{
SetObjType(OBJ_MAP);
m_idProcess = PROCESS_NONE;
m_pData = NULL;
m_pMapData = NULL;
m_setRegion = NULL;
m_setWeather = NULL;
m_dwLightRGB = DEFAULT_LIGHTRGB;
m_nStatus = STATUS_NONE;
}
//////////////////////////////////////////////////////////////////////
CGameMap::~CGameMap()
{
if(m_pData)
{
if(IsDynaMap())
m_pData->Update();
m_pData->Release();
}
if(m_pMapData)
m_pMapData->Release();
if(m_setRegion)
m_setRegion->Release();
if(m_setWeather)
m_setWeather->Release();
}
//////////////////////////////////////////////////////////////////////
bool CGameMap::Create(PROCESS_ID idProcess, IRecordset* pRes)
{
m_idProcess = idProcess;
m_pData = CGameMapData::CreateNew();
if(!m_pData || !m_pData->Create(pRes))
return false;
//*
LOGMSG("加载地图文件[%d]...", m_pData->GetInt(GAMEMAPDATA_MAPDOC));
m_pMapData = IMapData::CreateNew(m_pData->GetInt(GAMEMAPDATA_MAPDOC), MAPDATA_VERSION);
if(!m_pMapData)
{
LOGERROR("地图文件[%d]加载失败!", m_pData->GetInt(GAMEMAPDATA_MAPDOC));
return false;
}
// 装载地图
m_setBlock.resize(GetWidthOfBlock());
for(int i = 0; i < m_setBlock.size(); i++)
{
m_setBlock[i].resize(GetHeightOfBlock());
for(int j = 0; j < m_setBlock[i].size(); j++)
m_setBlock[i][j].Create();
}
//*/
m_setRegion = CRegionSet::CreateNew(true);
CHECKF(m_setRegion);
SQLBUF szSQL;
sprintf(szSQL, "SELECT * FROM %s WHERE mapid=%u", szRegionTable, m_pData->GetID());
if(!m_setRegion->Create(szSQL, Database()))
return false;
m_setWeather = CWeatherSet::CreateNew(true);
CHECKF(m_setWeather);
for( i = 0; i < m_setRegion->GetAmount(); i++)
{
CRegionData* pData = m_setRegion->GetObjByIndex(i);
if(pData && pData->GetInt(REGIONDATA_TYPE) == REGION_WEATHER)
{
CWeatherRegion* pWeather = CWeatherRegion::CreateNew();
CHECKF(pWeather);
IF_OK(pWeather->Create(pData, idProcess))
m_setWeather->AddObj(pWeather);
else
pWeather->ReleaseByOwner();
}
}
return true;
}
//////////////////////////////////////////////////////////////////////
void CGameMap::OnTimer(DWORD tCurr)
{
for(int i = 0; i < m_setWeather->GetAmount(); i++)
{
CWeatherRegion* pWeather = m_setWeather->GetObjByIndex(i);
if(pWeather)
pWeather->QueryWeather()->OnTimer();
}
}
//////////////////////////////////////////////////////////////////////
bool CGameMap::QueryObjInPos(int nPosX, int nPosY, OBJID idObjType, void** ppObj)
{
*ppObj = NULL;
CHECKF(idObjType != ID_NONE);
IThingSet* pSet = QueryBlock(nPosX, nPosY).QuerySet();
for(int i = 0; i < pSet->GetAmount(); i++)
{
IMapThing* pTarget = pSet->GetObjByIndex(i);
void* pTemp;
if(pTarget && pTarget->QueryObj(idObjType, &pTemp) && pTarget->GetPosX() == nPosX && pTarget->GetPosY() == nPosY)
{
*ppObj = pTemp;
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////
bool CGameMap::QueryObj(int nCenterX, int nCenterY, OBJID idObjType, OBJID idObj, void** ppObj)
{
*ppObj = NULL;
CHECKF(idObjType != ID_NONE);
void* pTemp = NULL;
int x,y,z;
FOR_9_BLOCKTHINGS(this, nCenterX, nCenterY)
{
IMapThing* pTarget = QueryThingByIndex(x,y,z);
if(pTarget && pTarget->QueryObj(idObjType, &pTemp))
{
if (idObj != ID_NONE)
{
if (pTarget->GetID() == idObj)
{
*ppObj = pTemp;
return true;
}
}
else
{
*ppObj = pTemp;
return true;
}
}
}
return false;
}
//////////////////////////////////////////////////////////////////////
IRole* CGameMap::QueryRole(int nCenterX, int nCenterY, OBJID idObj)
{
//CHECKF(idObj != ID_NONE);
IRole* pRole = NULL;
int x,y,z;
FOR_9_BLOCKTHINGS(this, nCenterX, nCenterY)
{
IMapThing* pTarget = QueryThingByIndex(x,y,z);
if (pTarget && pTarget->QueryRole(IPP_OF(pRole)))
{
if (idObj == ID_NONE
&& pTarget->GetPosX() == nCenterX
&& pTarget->GetPosY() == nCenterY)
{
return pRole;
}
if (pTarget->GetID() == idObj)
return pRole;
}
}
return NULL;
}
//////////////////////////////////////////////////////////////////////
IRole* CGameMap::QueryRoleByPos(int nPosX, int nPosY)
{
if(!IsValidPoint(nPosX, nPosY))
return NULL;
IRole* pRole = NULL;
IThingSet* pSet = QueryBlock(nPosX, nPosY).QuerySet();
for(int i = 0; i < pSet->GetAmount(); i++)
{
IMapThing* pTarget = pSet->GetObjByIndex(i);
if (pTarget && pTarget->QueryRole(IPP_OF(pRole))
&& pTarget->GetPosX() == nPosX && pTarget->GetPosY() == nPosY)
{
return pRole;
}
}
return NULL;
}
//////////////////////////////////////////////////////////////////////
void CGameMap::SendBlockInfo(IRole* pRole)
{
CHECK(pRole);
// 优化
void* pTemp = NULL;
if(pRole->QueryObj(OBJ_USER, IPP_OF(pTemp)))
{
int x,y;
FOR_9_BLOCKS(this, pRole->GetPosX(), pRole->GetPosY())
{
IThingSet* pSet = BlockByIndex(x,y).QuerySet();
for(int i = 0; i < pSet->GetAmount(); i++)
{
IMapThing* pMapThing = pSet->GetObjByIndex(i);
if(pMapThing && !(pMapThing->GetObjType() == OBJ_USER && pMapThing->GetID() == pRole->GetID()) )
{
if(!( IsNewbieMap() && pMapThing->GetObjType() == OBJ_USER ))
pMapThing->SendShow(pRole);
}
}
}
}
else // if(pRole->QueryObj(OBJ_MONSTER, IPP_OF(pTemp)))
{
CUser* pUser = NULL;
int x,y;
FOR_9_BLOCKS(this, pRole->GetPosX(), pRole->GetPosY())
{
IThingSet* pSet = BlockByIndex(x,y).QuerySet();
for(int i = 0; i < pSet->GetAmount(); i++)
{
IMapThing* pMapThing = pSet->GetObjByIndex(i);
if(pMapThing && pMapThing->GetObjType() == OBJ_USER) //@ 只发USER的信息给NPC服务器
{
pMapThing->SendShow(pRole);
}
}
}
}
}
//////////////////////////////////////////////////////////////////////
void CGameMap::BroadcastBlockMsg(IMapThing* pThing, CNetMsg* pMsg, bool bSendSelf /*= false*/)
{
ASSERT(pMsg);
//? 这个函数的逻辑有点乱:(
void* pObj = NULL;
IRole* pRole = NULL;
CMonster* pMonster = NULL;
//@不发非玩家消息到NPC服务器 bool bSendToNpc = (!pThing->QueryObj(OBJ_MONSTER, IPP_OF(pObj)) || bSendSelf);
bool bSendToNpc = (pThing->QueryObj(OBJ_USER, IPP_OF(pObj))
|| (pThing->QueryObj(OBJ_MONSTER, IPP_OF(pMonster)) && (pMonster->IsCallPet() || pMonster->IsEudemon()))
|| bSendSelf);
// newbie map
if (IsNewbieMap() && bSendSelf)
{
if(pThing->QueryRole(IPP_OF(pRole)))
pRole->SendMsg(pMsg);
return ;
}
int x,y,z;
FOR_9_BLOCKTHINGS(this, pThing->GetPosX(), pThing->GetPosY())
{
DEBUG_TRY // VVVVVVVVVVVVVVVVVVVV
IMapThing* pTarget = QueryThingByIndex(x,y,z);
if(pTarget && pTarget->QueryRole(IPP_OF(pRole)) && pRole->GetDistance(pThing) <= CELLS_PER_VIEW)
{
if(bSendSelf || !(pTarget->GetObjType() == pThing->GetObjType() && pTarget->GetID() == pThing->GetID()))
{
// monster
if (pTarget->QueryObj(OBJ_MONSTER, IPP_OF(pMonster)) && bSendToNpc)
{
if (pMonster->IsCallPet() || pMonster->IsEudemon())
{
}
else
{
pRole->SendMsg(pMsg);
bSendToNpc = false;
}
}
// user
CUser* pUser;
if (pTarget->QueryObj(OBJ_USER, IPP_OF(pUser)))
{
if(!pUser->IsAgent())
{
// player
pRole->SendMsg(pMsg);
}
else if(bSendToNpc)
{
// agent
pRole->SendMsg(pMsg);
bSendToNpc = false;
}
}
}
}
DEBUG_CATCH("BroadcastBlockMsg") // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
}
}
//////////////////////////////////////////////////////////////////////
void CGameMap::BroadcastBlockMsg(int nPosX, int nPosY, CNetMsg* pMsg)
{
ASSERT(pMsg);
bool bSendNpcAlready = false;
void* pObj = NULL;
IRole* pRole = NULL;
int x,y,z;
FOR_9_BLOCKTHINGS(this, nPosX, nPosY)
{
DEBUG_TRY // VVVVVVVVVVVVVVVVVVVV
IMapThing* pTarget = QueryThingByIndex(x,y,z);
if(pTarget && pTarget->QueryRole(IPP_OF(pRole)) && pRole->GetDistance(nPosX, nPosY) <= CELLS_PER_VIEW)
{
// monster
CMonster* pMonster = NULL;
if (pTarget->QueryObj(OBJ_MONSTER, IPP_OF(pMonster)) && !bSendNpcAlready)
{
if (pMonster->IsCallPet() || pMonster->IsEudemon())
{
}
else
{
pRole->SendMsg(pMsg);
bSendNpcAlready = true;
}
}
// user
CUser* pUser;
if (pTarget->QueryObj(OBJ_USER, IPP_OF(pUser)))
{
if(!pUser->IsAgent())
{
// player
pRole->SendMsg(pMsg);
}
else if(!bSendNpcAlready)
{
// agent
pRole->SendMsg(pMsg);
bSendNpcAlready = true;
}
}
}
DEBUG_CATCH("BroadcastBlockMsg") // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
}
}
//////////////////////////////////////////////////////////////////////
// role
//////////////////////////////////////////////////////////////////////
void CGameMap::EnterRoom(IMapThing* pThing, BOOL bWithBlock/*=false*/)
{
CHECK(pThing);
QueryBlock(pThing->GetPosX(), pThing->GetPosY()).QuerySet()->AddObj(pThing);
if(bWithBlock)
m_pMapData->IncRole(pThing->GetPosX(), pThing->GetPosY());
}
//////////////////////////////////////////////////////////////////////
void CGameMap::LeaveRoom(IMapThing* pThing, BOOL bWithBlock/*=false*/)
{
CHECK(pThing);
QueryBlock(pThing->GetPosX(), pThing->GetPosY()).QuerySet()->DelObj(pThing->GetID(), pThing->GetObjType());
if(bWithBlock)
m_pMapData->DecRole(pThing->GetPosX(), pThing->GetPosY());
}
//////////////////////////////////////////////////////////////////////
void CGameMap::MoveTo(IRole* pRole, int nNewPosX, int nNewPosY, BOOL bLeaveBlock/*=false*/, BOOL bEnterBlock/*=false*/) // 移动到相邻的BLOCK
{
CHECK(pRole);
if(bLeaveBlock)
m_pMapData->DecRole(pRole->GetPosX(), pRole->GetPosY());
if(bEnterBlock)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -