369 lines
9.7 KiB
C++
369 lines
9.7 KiB
C++
|
|
#include "StdAfx.h"
|
|||
|
|
#include "DNField.h"
|
|||
|
|
#include "DNFieldBlock.h"
|
|||
|
|
#include "DNFieldData.h"
|
|||
|
|
#include "DNNpcObject.h"
|
|||
|
|
#include "DNNpcObjectManager.h"
|
|||
|
|
#include "DNGameDataManager.h"
|
|||
|
|
#include "Log.h"
|
|||
|
|
|
|||
|
|
CDNField::CDNField(void): m_pMapInfo(NULL), m_pFieldData(NULL), m_pNpcObjectManager(NULL)
|
|||
|
|
{
|
|||
|
|
m_nChannelID = m_nMapIndex= m_nChannelAtt = m_nWidth = m_nHeight = m_nWidthNo = m_nHeightNo = 0;
|
|||
|
|
// m_nMapArrayIndex = 0;
|
|||
|
|
m_nMinX = m_nMinZ = m_nMaxX = m_nMaxZ = 0;
|
|||
|
|
|
|||
|
|
m_FieldBlocks.clear();
|
|||
|
|
|
|||
|
|
m_pNpcObjectManager = new CDNNpcObjectManager;
|
|||
|
|
m_nPermitLevel = -1;
|
|||
|
|
m_nChannelMaxUser = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CDNField::~CDNField(void)
|
|||
|
|
{
|
|||
|
|
SAFE_DELETE(m_pNpcObjectManager);
|
|||
|
|
Final();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool CDNField::Init(int nChannelID, int nChannelAtt, int nChannelMaxUser, int nMapIndex, const TMapInfo *pMapInfo, CDNFieldData *pFieldData, int nPermitLevel)
|
|||
|
|
{
|
|||
|
|
if ((!pMapInfo) || (nChannelID <= 0) || (nMapIndex <= 0)) return false;
|
|||
|
|
Final();
|
|||
|
|
|
|||
|
|
m_nChannelID = nChannelID;
|
|||
|
|
m_nChannelAtt = nChannelAtt;
|
|||
|
|
m_nChannelMaxUser = nChannelMaxUser;
|
|||
|
|
m_nMapIndex = nMapIndex;
|
|||
|
|
m_nPermitLevel = nPermitLevel;
|
|||
|
|
|
|||
|
|
// m_nMapArrayIndex = 0;
|
|||
|
|
m_pMapInfo = const_cast<TMapInfo*>(pMapInfo);
|
|||
|
|
m_pFieldData = pFieldData;
|
|||
|
|
|
|||
|
|
m_pFieldData->GetWidthHeight(m_nWidth, m_nHeight);
|
|||
|
|
|
|||
|
|
int Width = m_pFieldData->GetGridX() * m_nWidth / 2; // <20><><EFBFBD>Ͷ<EFBFBD> 100<30><30> <20><><EFBFBD>ؾ<EFBFBD><D8BE>Ѵ<EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2<><32> <20>Ͽ<EFBFBD> <20>Ȱ<EFBFBD><C8B0><EFBFBD> -, + <20><> <20>Ѵ<EFBFBD>.
|
|||
|
|
int Height = m_pFieldData->GetGridY() * m_nHeight / 2;
|
|||
|
|
|
|||
|
|
m_nMinX = -Width;
|
|||
|
|
m_nMinZ = -Height;
|
|||
|
|
m_nMaxX = Width;
|
|||
|
|
m_nMaxZ = Height;
|
|||
|
|
|
|||
|
|
m_nWidthNo = (UINT)(m_nWidth / FIELDBLOCKRANGE);
|
|||
|
|
if (m_nWidth % FIELDBLOCKRANGE > 0)
|
|||
|
|
m_nWidthNo++;
|
|||
|
|
|
|||
|
|
m_nHeightNo = (UINT)(m_nHeight / FIELDBLOCKRANGE);
|
|||
|
|
if (m_nHeight % FIELDBLOCKRANGE > 0)
|
|||
|
|
m_nHeightNo++;
|
|||
|
|
|
|||
|
|
CDNFieldBlock *pBlock = NULL;
|
|||
|
|
for (UINT i = 0; i < m_nHeightNo; i++){
|
|||
|
|
for (UINT j = 0; j < m_nWidthNo; j++){
|
|||
|
|
pBlock = new CDNFieldBlock;
|
|||
|
|
if (!pBlock) return false;
|
|||
|
|
|
|||
|
|
pBlock->Init(j, i, m_nMinX + (j * FIELDBLOCKRANGE), m_nMinZ + (i * FIELDBLOCKRANGE));
|
|||
|
|
m_FieldBlocks.push_back(pBlock);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool CDNField::Final()
|
|||
|
|
{
|
|||
|
|
if (m_FieldBlocks.empty()) return false;
|
|||
|
|
|
|||
|
|
CDNFieldBlock *pBlock = NULL;
|
|||
|
|
for (int i = 0; i < (int)m_FieldBlocks.size(); i++){
|
|||
|
|
pBlock = m_FieldBlocks[i];
|
|||
|
|
SAFE_DELETE(pBlock);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
m_FieldBlocks.clear();
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
#ifdef PRE_ADD_COLOSSEUM_BEGINNER
|
|||
|
|
void CDNField::GetWaitUserList( std::list<CDNUserSession*>& UserList, int iLimitLevel/*=-1*/, BYTE cPvPChannelType/* = static_cast<BYTE>(PvPCommon::RoomType::max)*/ )
|
|||
|
|
#else //#ifdef PRE_ADD_COLOSSEUM_BEGINNER
|
|||
|
|
void CDNField::GetWaitUserList( std::list<CDNUserSession*>& UserList, int iLimitLevel/*=-1*/ )
|
|||
|
|
#endif //#ifdef PRE_ADD_COLOSSEUM_BEGINNER
|
|||
|
|
{
|
|||
|
|
for( UINT i=0; i <m_FieldBlocks.size() ; ++i)
|
|||
|
|
{
|
|||
|
|
if( !m_FieldBlocks[i] )
|
|||
|
|
continue;
|
|||
|
|
#ifdef PRE_ADD_COLOSSEUM_BEGINNER
|
|||
|
|
m_FieldBlocks[i]->GetWaitUserList( UserList, iLimitLevel, cPvPChannelType );
|
|||
|
|
#else //#ifdef PRE_ADD_COLOSSEUM_BEGINNER
|
|||
|
|
m_FieldBlocks[i]->GetWaitUserList( UserList, iLimitLevel );
|
|||
|
|
#endif //#ifdef PRE_ADD_COLOSSEUM_BEGINNER
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool CDNField::EnterObject(CDNBaseObject *pObj)
|
|||
|
|
{
|
|||
|
|
CDNFieldBlock *pBlock = GetFieldBlock(&pObj->GetCurrentPos());
|
|||
|
|
if (!pBlock){
|
|||
|
|
if( !bIsPvPLobby() )
|
|||
|
|
g_Log.Log(LogType::_ERROR, L"[ObjUID:%u] FieldBlock NULL!! (%d,%d,%d)\r\n", pObj->GetObjectID(), pObj->GetCurrentPos().nX, pObj->GetCurrentPos().nY, pObj->GetCurrentPos().nZ);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return pBlock->AddBaseObject(pObj);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool CDNField::LeaveObject(CDNBaseObject *pObj)
|
|||
|
|
{
|
|||
|
|
CDNFieldBlock *pBlock = GetFieldBlock(&pObj->GetCurrentPos());
|
|||
|
|
if (!pBlock){
|
|||
|
|
if( !bIsPvPLobby() )
|
|||
|
|
g_Log.Log(LogType::_ERROR, L"[ObjUID:%u] FieldBlock NULL!! (%d,%d,%d)\r\n", pObj->GetObjectID(), pObj->GetCurrentPos().nX, pObj->GetCurrentPos().nY, pObj->GetCurrentPos().nZ);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return pBlock->DelBaseObject(pObj);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CDNField::FinalUser( CDNBaseObject* pObj )
|
|||
|
|
{
|
|||
|
|
for( UINT i=0 ; i<m_FieldBlocks.size() ; ++i )
|
|||
|
|
{
|
|||
|
|
m_FieldBlocks[i]->DelBaseObject( pObj );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CDNField::SendFieldMessage(CDNBaseObject *pSender, USHORT wMsg, TBaseData *pSenderData, TParamData *pParamData)
|
|||
|
|
{
|
|||
|
|
int cursxp, curszp, curexp, curezp;
|
|||
|
|
int targetsxp, targetszp, targetexp, targetezp;
|
|||
|
|
int i, j;
|
|||
|
|
|
|||
|
|
switch(wMsg)
|
|||
|
|
{
|
|||
|
|
case FM_CREATE:
|
|||
|
|
if (!EnterObject(pSender)){
|
|||
|
|
g_Log.Log(LogType::_ERROR, L"[CDNField::SendMessage] EnterObject Fail!!\r\n");
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
pSender->FieldProcess(pSender, FM_SHOW, pSenderData, pParamData);
|
|||
|
|
|
|||
|
|
GetViewRange(&pSender->GetCurrentPos(), cursxp, curszp, curexp, curezp);
|
|||
|
|
for (i = curszp; i <= curezp; i++){
|
|||
|
|
for (j = cursxp; j <= curexp; j++){
|
|||
|
|
m_FieldBlocks[(i * m_nWidthNo) + j]->SendFieldMessage(pSender, wMsg, pSenderData, pParamData);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case FM_DESTROY:
|
|||
|
|
GetViewRange(&pSender->GetCurrentPos(), cursxp, curszp, curexp, curezp);
|
|||
|
|
for (i = curszp; i <= curezp; i++){
|
|||
|
|
for (j = cursxp; j <= curexp; j++){
|
|||
|
|
m_FieldBlocks[(i * m_nWidthNo) + j]->SendFieldMessage(pSender, wMsg, pSenderData, pParamData);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
pSender->FieldProcess(pSender, FM_HIDE, pSenderData, pParamData);
|
|||
|
|
if (!LeaveObject(pSender)){
|
|||
|
|
g_Log.Log(LogType::_ERROR, L"[CDNField::SendMessage] LeaveObject Fail!!\r\n");
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case FM_MOVE:
|
|||
|
|
CDNFieldBlock *pCurBlock, *pTargetBlock;
|
|||
|
|
|
|||
|
|
pCurBlock = GetFieldBlock(&pSender->GetCurrentPos());
|
|||
|
|
pTargetBlock = GetFieldBlock(&pSender->GetTargetPos());
|
|||
|
|
|
|||
|
|
if (pCurBlock && pTargetBlock){
|
|||
|
|
GetViewRange(&pSender->GetCurrentPos(), cursxp, curszp, curexp, curezp);
|
|||
|
|
GetViewRange(&pSender->GetTargetPos(), targetsxp, targetszp, targetexp, targetezp);
|
|||
|
|
|
|||
|
|
if (cursxp > targetsxp) cursxp = targetsxp;
|
|||
|
|
if (curszp > targetszp) curszp = targetszp;
|
|||
|
|
if (curexp < targetexp) curexp = targetexp;
|
|||
|
|
if (curezp < targetezp) curezp = targetezp;
|
|||
|
|
|
|||
|
|
for (i = curszp; i <= curezp; i++){
|
|||
|
|
for (j = cursxp; j <= curexp; j++){
|
|||
|
|
m_FieldBlocks[(i * m_nWidthNo) + j]->SendFieldMessage(pSender, wMsg, pSenderData, pParamData);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
pSender->SwapPosition();
|
|||
|
|
|
|||
|
|
if (pCurBlock != pTargetBlock){
|
|||
|
|
if (pCurBlock->DelBaseObject(pSender) == false)
|
|||
|
|
_DANGER_POINT(); //<2F>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʿ<EFBFBD><CABF><EFBFBD> <20>հ<EFBFBD> <20>ڲ<EFBFBD> <20> <20><><EFBFBD>ܺ<EFBFBD><DCBA><EFBFBD>
|
|||
|
|
pTargetBlock->AddBaseObject(pSender);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case FM_GUILDWARWINSKILL :
|
|||
|
|
{
|
|||
|
|
// <20>þ<EFBFBD> 2<><32> ¥<><C2A5><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|||
|
|
GetDoubleViewRange(&pSender->GetCurrentPos(), cursxp, curszp, curexp, curezp);
|
|||
|
|
for (i = curszp; i <= curezp; i++)
|
|||
|
|
{
|
|||
|
|
for (j = cursxp; j <= curexp; j++)
|
|||
|
|
{
|
|||
|
|
m_FieldBlocks[(i * m_nWidthNo) + j]->SendFieldMessage(pSender, wMsg, pSenderData, pParamData);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CDNField::DoUpdate(DWORD CurTick)
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CDNFieldBlock* CDNField::GetFieldBlock(TPosition *pPos)
|
|||
|
|
{
|
|||
|
|
if (!pPos) return NULL;
|
|||
|
|
|
|||
|
|
int CurPosX, CurPosZ;
|
|||
|
|
UINT X, Z, XPoint, ZPoint, Index;
|
|||
|
|
|
|||
|
|
CurPosX = (int)(pPos->nX / 1000);
|
|||
|
|
CurPosZ = (int)(pPos->nZ / 1000);
|
|||
|
|
if (CurPosX < m_nMinX || CurPosX > m_nMaxX || CurPosZ < m_nMinZ || CurPosZ > m_nMaxZ)
|
|||
|
|
{
|
|||
|
|
if( bIsPvPLobby() )
|
|||
|
|
{
|
|||
|
|
if( m_FieldBlocks.size() > 0 )
|
|||
|
|
return m_FieldBlocks[0];
|
|||
|
|
}
|
|||
|
|
return NULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
X = (UINT)(CurPosX - m_nMinX);
|
|||
|
|
Z = (UINT)(CurPosZ - m_nMinZ);
|
|||
|
|
|
|||
|
|
XPoint = (UINT)(X / FIELDBLOCKRANGE);
|
|||
|
|
ZPoint = (UINT)(Z / FIELDBLOCKRANGE);
|
|||
|
|
|
|||
|
|
Index = (ZPoint * m_nWidthNo) + XPoint;
|
|||
|
|
if (Index >= m_FieldBlocks.size())
|
|||
|
|
{
|
|||
|
|
if( bIsPvPLobby() )
|
|||
|
|
{
|
|||
|
|
if( m_FieldBlocks.size() > 0 )
|
|||
|
|
return m_FieldBlocks[0];
|
|||
|
|
}
|
|||
|
|
return NULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return m_FieldBlocks[Index];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CDNField::GetViewRange(TPosition *pCurPos, int &sxp, int &szp, int &exp, int &ezp)
|
|||
|
|
{
|
|||
|
|
UINT x, z, sx, sz, ex, ez;
|
|||
|
|
|
|||
|
|
x = (UINT)((pCurPos->nX / 1000) - m_nMinX);
|
|||
|
|
z = (UINT)((pCurPos->nZ / 1000) - m_nMinZ);
|
|||
|
|
|
|||
|
|
if (x >= VIEWRANGE) sx = x - VIEWRANGE;
|
|||
|
|
else sx = 0;
|
|||
|
|
|
|||
|
|
if (z >= VIEWRANGE) sz = z - VIEWRANGE;
|
|||
|
|
else sz = 0;
|
|||
|
|
|
|||
|
|
if (x + VIEWRANGE < m_nWidth) ex = x + VIEWRANGE;
|
|||
|
|
else ex = m_nWidth - 1;
|
|||
|
|
|
|||
|
|
if (z + VIEWRANGE < m_nHeight) ez = z + VIEWRANGE;
|
|||
|
|
else ez = m_nHeight - 1;
|
|||
|
|
|
|||
|
|
sxp = (int)(sx / FIELDBLOCKRANGE);
|
|||
|
|
szp = (int)(sz / FIELDBLOCKRANGE);
|
|||
|
|
exp = (int)(ex / FIELDBLOCKRANGE);
|
|||
|
|
ezp = (int)(ez / FIELDBLOCKRANGE);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CDNField::GetDoubleViewRange(TPosition *pCurPos, int &sxp, int &szp, int &exp, int &ezp)
|
|||
|
|
{
|
|||
|
|
UINT x, z, sx, sz, ex, ez;
|
|||
|
|
|
|||
|
|
x = (UINT)((pCurPos->nX / 1000) - m_nMinX);
|
|||
|
|
z = (UINT)((pCurPos->nZ / 1000) - m_nMinZ);
|
|||
|
|
|
|||
|
|
if (x >= (VIEWRANGE*2)) sx = x - (VIEWRANGE*2);
|
|||
|
|
else sx = 0;
|
|||
|
|
|
|||
|
|
if (z >= (VIEWRANGE*2)) sz = z - (VIEWRANGE*2);
|
|||
|
|
else sz = 0;
|
|||
|
|
|
|||
|
|
if (x + (VIEWRANGE*2) < m_nWidth) ex = x + (VIEWRANGE*2);
|
|||
|
|
else ex = m_nWidth - 1;
|
|||
|
|
|
|||
|
|
if (z + (VIEWRANGE*2) < m_nHeight) ez = z + (VIEWRANGE*2);
|
|||
|
|
else ez = m_nHeight - 1;
|
|||
|
|
|
|||
|
|
sxp = (int)(sx / FIELDBLOCKRANGE);
|
|||
|
|
szp = (int)(sz / FIELDBLOCKRANGE);
|
|||
|
|
exp = (int)(ex / FIELDBLOCKRANGE);
|
|||
|
|
ezp = (int)(ez / FIELDBLOCKRANGE);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CDNField::RequestGenerationNpc(int nNpcID, TPosition *pCurPos, float fRotate)
|
|||
|
|
{
|
|||
|
|
TNpcData *pNpcData = g_pDataManager->GetNpcData(nNpcID);
|
|||
|
|
if (!pNpcData) return;
|
|||
|
|
|
|||
|
|
CDNNpcObject *pNpcObj = new CDNNpcObject;
|
|||
|
|
if (!pNpcObj) return;
|
|||
|
|
|
|||
|
|
pNpcObj->CreateNpc(pNpcData, "", g_IDGenerator.GetNpcID(), GetChnnelID(), GetMapIndex(), pCurPos, 0);
|
|||
|
|
AddNpcObject(pNpcObj);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool CDNField::AddNpcObject(CDNNpcObject *pNpcObj)
|
|||
|
|
{
|
|||
|
|
return m_pNpcObjectManager->AddObject(pNpcObj);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CDNNpcObject* CDNField::GetNpcObjectByNpcObjID(UINT nNpcObjID)
|
|||
|
|
{
|
|||
|
|
return (CDNNpcObject*)m_pNpcObjectManager->FindObject(nNpcObjID);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CDNField::SendFieldNotice(int cLen, const WCHAR *pwszChatMsg, int nShowSec)
|
|||
|
|
{
|
|||
|
|
if (m_FieldBlocks.empty()) return;
|
|||
|
|
|
|||
|
|
for (int i = 0; i < (int)m_FieldBlocks.size(); i++){
|
|||
|
|
m_FieldBlocks[i]->SendFieldNotice(cLen, pwszChatMsg, nShowSec);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CDNField::SendChannelChat(int cLen, const WCHAR *pwszCharacterName, const WCHAR *pwszChatMsg, int nRet)
|
|||
|
|
{
|
|||
|
|
if (m_FieldBlocks.empty()) return;
|
|||
|
|
|
|||
|
|
for (int i = 0; i < (int)m_FieldBlocks.size(); i++){
|
|||
|
|
m_FieldBlocks[i]->SendChannelChat(cLen, pwszCharacterName, pwszChatMsg);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CDNField::SendDebugChat(const WCHAR* szMsg)
|
|||
|
|
{
|
|||
|
|
if (m_FieldBlocks.empty()) return;
|
|||
|
|
|
|||
|
|
for (int i = 0; i < (int)m_FieldBlocks.size(); i++){
|
|||
|
|
m_FieldBlocks[i]->SendDebugChat(szMsg);
|
|||
|
|
}
|
|||
|
|
}
|