277 lines
8.1 KiB
C++
277 lines
8.1 KiB
C++
|
|
#include "StdAfx.h"
|
|||
|
|
#include "DNFieldData.h"
|
|||
|
|
#include "EtResourceMng.h"
|
|||
|
|
#include "EtWorldGrid.h"
|
|||
|
|
#include "EtWorldSector.h"
|
|||
|
|
#include "EtWorldEventControl.h"
|
|||
|
|
#include "EtWorldEventArea.h"
|
|||
|
|
#include "EtWorldProp.h"
|
|||
|
|
#include "DNField.h"
|
|||
|
|
#include "DNNpcObject.h"
|
|||
|
|
#include "DNPropNpcObject.h"
|
|||
|
|
#include "DNGameDataManager.h"
|
|||
|
|
#include "Util.h"
|
|||
|
|
#include "Log.h"
|
|||
|
|
#include "PropHeader.h"
|
|||
|
|
#include "DnWorldGateStruct.h"
|
|||
|
|
|
|||
|
|
CDNFieldData::CDNFieldData(void)
|
|||
|
|
{
|
|||
|
|
m_nMapIndex = 0;
|
|||
|
|
m_VecGateList.clear();
|
|||
|
|
m_VecStartPositionList.clear();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CDNFieldData::~CDNFieldData(void)
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool CDNFieldData::Init(char *pszMapName, int nMapIndex)
|
|||
|
|
{
|
|||
|
|
DNTableFileFormat *pSox = GetDNTable( CDnTableDB::TMAP );
|
|||
|
|
EWorldEnum::MapTypeEnum MapType = (EWorldEnum::MapTypeEnum)pSox->GetFieldFromLablePtr( nMapIndex, "_MapType" )->GetInteger();
|
|||
|
|
|
|||
|
|
m_szMapName = pszMapName;
|
|||
|
|
m_nMapIndex = nMapIndex;
|
|||
|
|
|
|||
|
|
if (!m_World.Initialize(CEtResourceMng::GetInstance().GetFullPath("MapData").c_str(), pszMapName)) return false;
|
|||
|
|
|
|||
|
|
int nLoadSectorEnum = CEtWorldSector::LSE_Terrain | CEtWorldSector::LSE_Control | CEtWorldSector::LSE_Prop;
|
|||
|
|
if( MapType == EWorldEnum::MapTypeVillage ) nLoadSectorEnum |= CEtWorldSector::LSE_GenCollisionHeight;
|
|||
|
|
|
|||
|
|
m_World.ForceInitialize( nLoadSectorEnum );
|
|||
|
|
|
|||
|
|
CalcGatePosition();
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CDNFieldData::GetWidthHeight(UINT &nWidth, UINT &nHeight)
|
|||
|
|
{
|
|||
|
|
nWidth = m_World.GetGridWidth() * 100;
|
|||
|
|
nHeight = m_World.GetGridHeight() * 100;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CDNFieldData::CalcGatePosition()
|
|||
|
|
{
|
|||
|
|
DWORD dwCount = m_World.GetGrid()->GetActiveSectorCount();
|
|||
|
|
CEtWorldEventControl *pControl = NULL;
|
|||
|
|
CEtWorldSector *pSector = NULL;
|
|||
|
|
CEtWorldEventArea *pArea = NULL;
|
|||
|
|
EventAreaStruct *pStruct = NULL;
|
|||
|
|
|
|||
|
|
char szStr[32];
|
|||
|
|
AreaInfo Info;
|
|||
|
|
|
|||
|
|
SAFE_DELETE_VEC( m_VecGateList );
|
|||
|
|
SAFE_DELETE_VEC( m_VecStartPositionList );
|
|||
|
|
|
|||
|
|
for( DWORD i=0; i<dwCount; i++ ) {
|
|||
|
|
pSector = m_World.GetGrid()->GetActiveSector(i);
|
|||
|
|
pControl = pSector->GetControlFromUniqueID( ETE_EventArea );
|
|||
|
|
if( !pControl ) continue;
|
|||
|
|
|
|||
|
|
for( int j=0; j<DNWORLD_GATE_COUNT; j++ ) {
|
|||
|
|
sprintf_s( szStr, "Gate %d", j + 1 );
|
|||
|
|
pArea = pControl->GetAreaFromName( szStr );
|
|||
|
|
if( pArea ) {
|
|||
|
|
Info.nIndex = j + 1;
|
|||
|
|
Info.Min.nX = (int)(pArea->GetMin()->x * 1000.f) - 100000;
|
|||
|
|
Info.Min.nY = (int)(pArea->GetMin()->y * 1000.f) - 100000;
|
|||
|
|
Info.Min.nZ = (int)(pArea->GetMin()->z * 1000.f) - 100000;
|
|||
|
|
Info.Max.nX = (int)(pArea->GetMax()->x * 1000.f) + 100000;
|
|||
|
|
Info.Max.nY = (int)(pArea->GetMax()->y * 1000.f) + 100000;
|
|||
|
|
Info.Max.nZ = (int)(pArea->GetMax()->z * 1000.f) + 100000;
|
|||
|
|
Info.fAngle = pArea->GetRotate();
|
|||
|
|
|
|||
|
|
pStruct = (EventAreaStruct *)pArea->GetData();
|
|||
|
|
if (pStruct) Info.nType = pStruct->GateType;
|
|||
|
|
|
|||
|
|
m_VecGateList.push_back( Info );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
sprintf_s( szStr, "StartPosition %d", j + 1 );
|
|||
|
|
pArea = pControl->GetAreaFromName( szStr );
|
|||
|
|
if( pArea ) {
|
|||
|
|
Info.nIndex = j + 1;
|
|||
|
|
Info.Min.nX = (int)(pArea->GetMin()->x * 1000.f) ;
|
|||
|
|
Info.Min.nY = (int)(pArea->GetMin()->y * 1000.f) ;
|
|||
|
|
Info.Min.nZ = (int)(pArea->GetMin()->z * 1000.f) ;
|
|||
|
|
Info.Max.nX = (int)(pArea->GetMax()->x * 1000.f) ;
|
|||
|
|
Info.Max.nY = (int)(pArea->GetMax()->y * 1000.f) ;
|
|||
|
|
Info.Max.nZ = (int)(pArea->GetMax()->z * 1000.f) ;
|
|||
|
|
Info.fAngle = pArea->GetRotate();
|
|||
|
|
m_VecStartPositionList.push_back( Info );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CDNFieldData::CheckGateArea(TPosition &Position)
|
|||
|
|
{
|
|||
|
|
for (int i = 0; i < (int)m_VecGateList.size(); i++){
|
|||
|
|
if (Position.nX < m_VecGateList[i].Min.nX || Position.nX > m_VecGateList[i].Max.nX ||
|
|||
|
|
Position.nZ < m_VecGateList[i].Min.nZ || Position.nZ > m_VecGateList[i].Max.nZ) continue;
|
|||
|
|
return m_VecGateList[i].nIndex;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool CDNFieldData::GetStartPosition(char cGateNo, TPosition &Pos)
|
|||
|
|
{
|
|||
|
|
for( DWORD i=0; i<m_VecStartPositionList.size(); i++ ) {
|
|||
|
|
if( m_VecStartPositionList[i].nIndex == cGateNo ) {
|
|||
|
|
Pos = m_VecStartPositionList[i].Min;
|
|||
|
|
|
|||
|
|
int nValue = ( m_VecStartPositionList[i].Max.nX - m_VecStartPositionList[i].Min.nX ) / 1000;
|
|||
|
|
if( nValue <= 0 ) nValue = 1;
|
|||
|
|
Pos.nX += ( _rand()%nValue ) * 1000;
|
|||
|
|
|
|||
|
|
nValue = ( m_VecStartPositionList[i].Max.nY - m_VecStartPositionList[i].Min.nY ) / 1000;
|
|||
|
|
if( nValue <= 0 ) nValue = 1;
|
|||
|
|
Pos.nY += ( _rand()%nValue ) * 1000;
|
|||
|
|
|
|||
|
|
nValue = ( m_VecStartPositionList[i].Max.nZ - m_VecStartPositionList[i].Min.nZ ) / 1000;
|
|||
|
|
if( nValue <= 0 ) nValue = 1;
|
|||
|
|
Pos.nZ += ( _rand()%nValue ) * 1000;
|
|||
|
|
|
|||
|
|
Pos.nY += (int)m_World.GetHeight( Pos.nX / 1000.f, Pos.nZ / 1000.f ) * 1000;
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CDNFieldData::GetRandomStartPosition(TPosition &Pos)
|
|||
|
|
{
|
|||
|
|
if( m_VecGateList.empty() )
|
|||
|
|
return;
|
|||
|
|
int nGateNo = _rand() % (int)m_VecGateList.size();
|
|||
|
|
GetStartPosition(m_VecGateList[nGateNo].nIndex, Pos);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CDNFieldData::GetStartPositionAngle( char cGateNo, float &fAngle )
|
|||
|
|
{
|
|||
|
|
for( DWORD i=0; i<m_VecStartPositionList.size(); i++ ) {
|
|||
|
|
if( m_VecStartPositionList[i].nIndex == cGateNo ) {
|
|||
|
|
fAngle = m_VecStartPositionList[i].fAngle;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
char CDNFieldData::GetRandomGateNo()
|
|||
|
|
{
|
|||
|
|
if ( m_VecGateList.empty() )
|
|||
|
|
return -1;
|
|||
|
|
|
|||
|
|
int nGateNo = _rand() % (int)m_VecGateList.size();
|
|||
|
|
return m_VecGateList[nGateNo].nIndex;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CDNFieldData::LoadCreateNpc(CDNField *pField)
|
|||
|
|
{
|
|||
|
|
DWORD dwCount = m_World.GetGrid()->GetActiveSectorCount();
|
|||
|
|
CEtWorldEventControl *pControl = NULL;
|
|||
|
|
CEtWorldSector *pSector = NULL;
|
|||
|
|
CEtWorldEventArea *pArea = NULL;
|
|||
|
|
|
|||
|
|
TNpcData *pNpcData = NULL;
|
|||
|
|
EtVector3 vPos;
|
|||
|
|
TPosition Pos;
|
|||
|
|
int nNpcIndex;
|
|||
|
|
char szAreaName[256] = { 0, };
|
|||
|
|
|
|||
|
|
DNTableFileFormat *pSox = GetDNTable( CDnTableDB::TPROP );
|
|||
|
|
|
|||
|
|
|
|||
|
|
for (DWORD i = 0; i < dwCount; i++){
|
|||
|
|
pSector = m_World.GetGrid()->GetActiveSector(i);
|
|||
|
|
|
|||
|
|
// EventArea <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Npc <20><>.
|
|||
|
|
pControl = pSector->GetControlFromUniqueID(ETE_UnitArea);
|
|||
|
|
if( pControl ) {
|
|||
|
|
char szFirstName[256];
|
|||
|
|
|
|||
|
|
for (DWORD j = 0; j < pControl->GetAreaCount(); j++){
|
|||
|
|
pArea = pControl->GetAreaFromIndex(j);
|
|||
|
|
|
|||
|
|
sprintf_s(szAreaName, pArea->GetName());
|
|||
|
|
_strlwr_s(szAreaName);
|
|||
|
|
sscanf_s( szAreaName, "%s %d", szFirstName, sizeof(szFirstName), &nNpcIndex );
|
|||
|
|
if( strcmp( szFirstName, "npc" ) ) continue;
|
|||
|
|
|
|||
|
|
pNpcData = g_pDataManager->GetNpcData(nNpcIndex);
|
|||
|
|
if (!pNpcData){
|
|||
|
|
g_Log.Log(LogType::_ERROR, L"(NpcName:%S) NpcData not found\r\n", szAreaName);
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CDNNpcObject *pNpcObj = new CDNNpcObject;
|
|||
|
|
if (!pNpcObj) continue;
|
|||
|
|
|
|||
|
|
vPos.x = pArea->GetMin()->x + ((int)(pArea->GetMax()->x - pArea->GetMin()->x) / 2);
|
|||
|
|
vPos.z = pArea->GetMin()->z + ((int)(pArea->GetMax()->z - pArea->GetMin()->z) / 2);
|
|||
|
|
vPos.y = m_World.GetHeight(vPos) + pArea->GetMin()->y;
|
|||
|
|
|
|||
|
|
memset(&Pos, 0, sizeof(TPosition));
|
|||
|
|
Pos.nX = (int)(vPos.x * 1000.f);
|
|||
|
|
Pos.nZ = (int)(vPos.z * 1000.f);
|
|||
|
|
Pos.nY = (int)(vPos.y * 1000.f);
|
|||
|
|
|
|||
|
|
pNpcObj->CreateNpc(pNpcData, szAreaName, g_IDGenerator.GetNpcID(), pField->GetChnnelID(), pField->GetMapIndex(), &Pos, pArea->GetRotate());
|
|||
|
|
pField->AddNpcObject(pNpcObj);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Npc Prop <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|||
|
|
for( DWORD j=0; j<pSector->GetPropCount(); j++ ) {
|
|||
|
|
CEtWorldProp *pProp = pSector->GetPropFromIndex(j);
|
|||
|
|
if( !pProp ) continue;
|
|||
|
|
int nItemID = pSox->GetItemIDFromField( "_Name", pProp->GetPropName() );
|
|||
|
|
if( nItemID == -1 ) continue;
|
|||
|
|
if( pSox->GetFieldFromLablePtr( nItemID, "_ClassID" )->GetInteger() != PTE_Npc ) continue;
|
|||
|
|
|
|||
|
|
NpcStruct *pStruct = (NpcStruct *)pProp->GetData();
|
|||
|
|
|
|||
|
|
if( pStruct->nNpcID <= 0 ) continue;
|
|||
|
|
|
|||
|
|
pNpcData = g_pDataManager->GetNpcData(pStruct->nNpcID);
|
|||
|
|
if (!pNpcData){
|
|||
|
|
g_Log.Log(LogType::_ERROR, L"(NpcName:%S) NpcData not found\r\n", szAreaName);
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CDNPropNpcObject *pNpcObj = new CDNPropNpcObject;
|
|||
|
|
if (!pNpcObj) continue;
|
|||
|
|
|
|||
|
|
pNpcObj->CreateNpc( pNpcData, g_IDGenerator.GetNpcID(), pField->GetChnnelID(), pField->GetMapIndex(), pProp );
|
|||
|
|
pField->AddNpcObject(pNpcObj);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
float CDNFieldData::GetCollisionHeight(float fX, float fZ)
|
|||
|
|
{
|
|||
|
|
return m_World.GetCollisionHeight(fX, fZ);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
DWORD CDNFieldData::GetCurrentTileSize()
|
|||
|
|
{
|
|||
|
|
return m_World.GetCurrentTileSize();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int CDNFieldData::GetGateType(TPosition &Position)
|
|||
|
|
{
|
|||
|
|
for (int i = 0; i < (int)m_VecGateList.size(); i++){
|
|||
|
|
if (Position.nX < m_VecGateList[i].Min.nX || Position.nX > m_VecGateList[i].Max.nX ||
|
|||
|
|
Position.nZ < m_VecGateList[i].Min.nZ || Position.nZ > m_VecGateList[i].Max.nZ) continue;
|
|||
|
|
return m_VecGateList[i].nType;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return -1;
|
|||
|
|
}
|