#include "stdafx.h" //#include <3DEngine/3DTerrain/WorldBase.h> #include "FieldInfo.h" //#include "WorldServer/WorldServer.h" //#include //#include //#include <3DEngine/IncludeAll_NewWorld.h> //#include //#include //#include "ViewPortManager.h" #include "WorldServer.h" //////////////////////////////////////////////////////////////////////////////////// // MapInfo class //////////////////////////////////////////////////////////////////////////////////// MapInfo::MapInfo(): m_pMapInfo ( NULL ) { m_FieldInfoHashTable.Initialize( _MAX_FIELD_IN_MAP_NUM ); } MapInfo::~MapInfo() { m_FieldInfoHashTable.RemoveAll(); } VOID MapInfo::AddFieldInfo( FieldInfo * pFieldInfo ) { m_FieldInfoHashTable.Add( pFieldInfo, pFieldInfo->GetFieldCode() ); } //////////////////////////////////////////////////////////////////////////////////// // FieldInfo class //////////////////////////////////////////////////////////////////////////////////// FieldInfo::FieldInfo(): m_pWorldBase ( NULL ), m_dwTotalSectorNum ( 0 ), m_ppSectorInfo( NULL ), m_pFieldInfo ( NULL ) //m_pViewPortManager(NULL) { m_pMapObjectInfoHashTable = new util::SolarHashTable; m_pMapObjectInfoHashTable->Initialize( _MAX_MAPOBJECT_INFO_NUM ); } FieldInfo::~FieldInfo() { for( DWORD i = 0 ; i < m_dwTotalSectorNum ; ++i ) { SAFE_DELETE( m_ppSectorInfo[i] ); } SAFE_DELETE_ARRAY( m_ppSectorInfo ); Destroy(); SAFE_DELETE( m_pMapObjectInfoHashTable ); } VOID FieldInfo::Create( const sFIELDINFO * pInfoIn ) //, ViewPortManager *pViewPortManager ) { SetFieldInfo( pInfoIn ); ASSERT(!m_pWorldBase); // m_pViewPortManager = pViewPortManager; // m_pWorldBase = (CWorldBase *)ViewPortManager::Instance()->m_fnContactTerrain( CT_NEW_WORLD, 0 ); m_pWorldBase = (CWorldBase *)WorldServer::Instance()->m_fnContactTerrain( CT_NEW_WORLD, 0 ); m_pWorldBase->Create(); } INT FieldInfo::Init() { return m_pWorldBase->x_pRoomManager->DuplicateRoomInfo(); } VOID FieldInfo::Release( INT Index ) { BOOL rt = m_pWorldBase->x_pRoomManager->DestroyRoomInfo(Index); ASSERT( rt ); } ///< FieldInfo¸¦ ÀÐÀº ´ÙÀ½, SectorSize¿¡ µû¸¥ SectorInfo¸¦ ¼ÂÆÃ VOID FieldInfo::EstablishSectorInfo( WORD wSectorSize, BOOL bViewport ) { if(wSectorSize == 0) ASSERT( !"¼½ÅÍ À妽º°¡ 0ÀÌ´Ù" ); m_dwSectorSize = wSectorSize; m_bViewport = bViewport; BvAABB bdv = m_pWorldBase->GetTerrainSize(); // ÃÖ´ë°ªÀÌ À½¼öÀϼöµµ ÀÖÀ¸¹Ç·Î Àý´ë°ªÀ¸·Î °è»ê DWORD XSize = 0, YSize = 0; XSize = (DWORD)abs(bdv.m_wvMax.x - bdv.m_wvMin.x); YSize = (DWORD)abs(bdv.m_wvMax.y - bdv.m_wvMin.y); // ¼½ÅÍ À妽º¸¦ °è»êÇϱâ À§ÇÑ º¯¼ö m_iShiftMinX = (int)(bdv.m_wvMin.x); m_iShiftMinY = (int)(bdv.m_wvMin.y); m_iShiftMaxX = (int)(bdv.m_wvMax.x); m_iShiftMaxY = (int)(bdv.m_wvMax.y); BYTE byMarginX = 0, byMarginY = 0; XSize % wSectorSize == 0 ? byMarginX = 0 : byMarginX = 1; YSize % wSectorSize == 0 ? byMarginY = 0 : byMarginY = 1; m_dwSectorXNum = XSize / wSectorSize + byMarginX; m_dwSectorYNum = YSize / wSectorSize + byMarginY; m_dwTotalSectorNum = m_dwSectorXNum * m_dwSectorYNum; m_ppSectorInfo = new SectorInfo*[ m_dwSectorXNum * m_dwSectorYNum ]; memset( m_ppSectorInfo, 0, sizeof(SectorInfo *) * m_dwSectorXNum * m_dwSectorYNum ); /// ÇöÀç, ¸ðµç Sector°¡ Á¸ÀçÇÑ´Ù°í °¡Á¤ DWORD dwSectorIndex = 0; for( dwSectorIndex = 0 ; dwSectorIndex < m_dwTotalSectorNum ; ++dwSectorIndex ) { m_ppSectorInfo[ dwSectorIndex ] = new SectorInfo( dwSectorIndex ); } /// ÀÌ¿ôÇÏ´Â sector¸¦ ¿¬°á for( dwSectorIndex = 0 ; dwSectorIndex < m_dwTotalSectorNum ; ++dwSectorIndex ) { // ÇØ´ç ¼½ÅÍÀÇ Çà°ú ¿­À» ±¸ÇÑ´Ù. DWORD dwRow = dwSectorIndex / m_dwSectorXNum; // Index_Y DWORD dwColumn = dwSectorIndex % m_dwSectorXNum; // Index_X for( int i = -1; i <= 1; ++i ) { int iNeighborColumn = dwColumn + i; if( iNeighborColumn < 0 || iNeighborColumn >= (int)m_dwSectorXNum ) continue; for( int j = -1; j <= 1; ++j ) { int iNeighborRow = dwRow + j; if( iNeighborRow < 0 || iNeighborRow >= (int)m_dwSectorYNum ) continue; int index = iNeighborRow * m_dwSectorXNum + iNeighborColumn; if( dwSectorIndex == index ) continue; if( !m_ppSectorInfo[index] ) continue; m_ppSectorInfo[dwSectorIndex]->AddNeighbor( m_ppSectorInfo[index] ); } } } } BOOL FieldInfo::IsValidCoordinates( WzVector* pwzVec ) { // X,YÁÂÇ¥»ó¿¡¼­ ÃÖ¼Ò°ªº¸´Ù ÀÛÀº °ªÀ» Ŭ¶óÀÌ¾ðÆ®¿¡¼­ º¸³½ °æ¿ì if( ( m_iShiftMinX > pwzVec->x ) || ( m_iShiftMinY > pwzVec->y ) ) { return FALSE; } if( ( m_iShiftMaxX < pwzVec->x ) || ( m_iShiftMaxY < pwzVec->y ) ) { return FALSE; } return TRUE; } // Client¿¡¼­ ³Ñ¾î¿Â ÁÂÇ¥¸¦ °¡Áö°í ÇØ´çÇÏ´Â À妽º¸¦ ¾ò¾î¿È DWORD FieldInfo::GetSectorIndexFor( WzVector * pwzVec ) { DWORD dwXIndex = 0; DWORD dwYIndex = 0; if( IsValidCoordinates( pwzVec ) ) { GetSectorIndexFor( pwzVec, dwXIndex, dwYIndex ); } ASSERT( dwXIndex + m_dwSectorXNum * dwYIndex < m_dwTotalSectorNum ); return ( dwXIndex + m_dwSectorXNum * dwYIndex ); } VOID FieldInfo::GetSectorIndexFor( WzVector * pwzVec, DWORD & dwXIndexOut, DWORD & dwYIndexOut ) { dwXIndexOut = (DWORD)( pwzVec->x - m_iShiftMinX ) / GetSectorSize(); dwYIndexOut = (DWORD)( pwzVec->y - m_iShiftMinY ) / GetSectorSize(); } VOID FieldInfo::Destroy() { _unloadMapObjectInfo(); if( m_pWorldBase ) { m_pWorldBase->Destroy( NULL ); // ViewPortManager::Instance()->m_fnContactTerrain( CT_DELETE_WORLD, m_pWorldBase ); WorldServer::Instance()->m_fnContactTerrain( CT_DELETE_WORLD, m_pWorldBase ); m_pWorldBase = NULL; } } #include BOOL FieldInfo::Load() { CWzArchive archive; CDiscAccess cda; cda.Create(); //m_pWorldBase->SetDiscAccess(&cda); ASSERT(_access(m_pFieldInfo->pszPath,0)!=-1); if( archive.LoadFile( const_cast(m_pFieldInfo->pszPath) ) == FALSE ) { DISPMSG( "Failed LoadFile() : From Fieldxx.map" ); archive.Close(); return FALSE; } if( m_pWorldBase->Serialize( &archive ) == FALSE ) { archive.Close(); return FALSE; } //_loadMapObjectInfo( archive ); //_loadAreaInfo( archive ); archive.Close(); SetStartingTileIndex(); return TRUE; } VOID FieldInfo::_loadMapObjectInfo( CWzArchive & archive ) { BOOL bAreaChunk = FALSE; while( TRUE ) { St_ChunkInfo ci = archive.ReadChunk(); if( ci.m_nID == 0x1781 ) { bAreaChunk = TRUE; break; } archive.SkipCurrentChunk(ci); } ASSERT( TRUE == bAreaChunk ); DWORD dwNumbers = 0; DWORD dwDummy = 0; // WZU°Ç³Ê¶ï archive >> dwNumbers; char pszUnitFileFullPath[0xff]; for( DWORD j = 0 ; j < dwNumbers ; ++j ) { archive.ReadName( pszUnitFileFullPath ); archive >> dwDummy; } // ÅØ½ºÃÄ °Ç³Ê¶ï archive >> dwNumbers; for (DWORD j = 0; j < dwNumbers; ++j ) { archive >> dwDummy; archive.ReadName( pszUnitFileFullPath ); } MAPOBJECT_INFO * pObject = NULL; // ½ÇÁ¦ ¸Ê¿ÀºêÁ§Æ® archive >> dwNumbers; for( DWORD i = 0 ; i < dwNumbers ; ++i ) { pObject = new MAPOBJECT_INFO; //pObject->dwMapObjectID = MAP_OBJECT_KEY+i; //< Ŭ¶óÀÌ¾ðÆ®¿Í ´ë¿ªÀ» ¸ÂÃçÁà¾ß ÇÑ´Ù. pObject->dwMapObjectID = i; archive >> pObject->wzId >> pObject->dwAttribute >> pObject->wvPos >> pObject->wzRot >> pObject->wzScale >> pObject->wzBV; if(archive.GetVersion() >= 138) { archive >> dwDummy; } ASSERT( NULL == m_pMapObjectInfoHashTable->GetData( pObject->dwMapObjectID ) ); m_pMapObjectInfoHashTable->Add( pObject, pObject->dwMapObjectID ); } } /* VOID FieldInfo::_loadAreaInfo( CWzArchive & archive ) { //------------------------------------------------------------------------------------ // if( archive.GetVersion() < 140 ) return; if( archive.GetVersion() > 143 ) return; BOOL bAreaChunk = FALSE; while( TRUE ) { St_ChunkInfo ci = archive.ReadChunk(); if( ci.m_nID == 0x1785 ) { bAreaChunk = TRUE; break; } archive.SkipCurrentChunk(ci); } if( TRUE != bAreaChunk ) return; // ¿µ¿ª °³¼ö WORD wNumberOfAreas = 0; BYTE byAreaType = 0; WzID wzAreaID = 0; archive >> wNumberOfAreas; ASSERT( wNumberOfAreas < 1000 ); DEBUG_CODE( if(wNumberOfAreas >= 1000) return; ); for( DWORD idx = 0 ; idx < wNumberOfAreas ; ++idx ) { archive >> byAreaType; archive >> wzAreaID; if( byAreaType == AREA_INFO::AREA_AABB ) { AABB_AREA_INFO * pAreaInfo = new AABB_AREA_INFO; pAreaInfo->dwKey = idx; pAreaInfo->byAreaType = byAreaType; pAreaInfo->wzAreaID = wzAreaID; archive >> pAreaInfo->bvAABB; //m_pAreaInfoHashTable->Add( pAreaInfo, pAreaInfo->wzAreaID ); m_pAreaInfoHashTable->Add( pAreaInfo, pAreaInfo->dwKey ); } else { TILE_AREA_INFO * pAreaInfo = new TILE_AREA_INFO; pAreaInfo->dwKey = idx; pAreaInfo->byAreaType = byAreaType; pAreaInfo->wzAreaID = wzAreaID; archive >> pAreaInfo->wNumberOfTiles; pAreaInfo->piTileIndex = new int[pAreaInfo->wNumberOfTiles]; memset( pAreaInfo->piTileIndex, 0, sizeof(int) * pAreaInfo->wNumberOfTiles ); WORD wTileAttr; int iTileIndex = 0; WORD wValidateTiles = 0; for( WORD i = 0 ; i < pAreaInfo->wNumberOfTiles ; ++i ) { if( !m_pWorldBase ) continue; archive >> iTileIndex; wTileAttr = m_pWorldBase->x_pPathFinder->GetAttribute( iTileIndex ); if( wTileAttr & PTA_NO_WALK ) { continue; } pAreaInfo->piTileIndex[wValidateTiles] = iTileIndex; ++wValidateTiles; } pAreaInfo->wNumberOfTiles = wValidateTiles; m_pAreaInfoHashTable->Add( pAreaInfo, pAreaInfo->dwKey ); } } } */ VOID FieldInfo::_unloadMapObjectInfo() { MAPOBJECT_INFO * pDelNode = NULL; m_pMapObjectInfoHashTable->SetFirst(); while( (pDelNode = m_pMapObjectInfoHashTable->GetNext()) != NULL ) { SAFE_DELETE( pDelNode ); } m_pMapObjectInfoHashTable->RemoveAll(); } /* VOID FieldInfo::_unloadAreaInfo() { AREA_INFO * pDelNode = NULL; m_pAreaInfoHashTable->SetFirst(); while( (pDelNode = m_pAreaInfoHashTable->GetNext()) != NULL ) { SAFE_DELETE( pDelNode ); } m_pAreaInfoHashTable->RemoveAll(); } */ VOID FieldInfo::SetStartingTileIndex() { m_StartTiles.clear(); for( int i = '0' ; i <= '9' ; ++i ) { WzSpecialArea * pArea = m_pWorldBase->GetSpecialArea( CharToWzID('S','T','R',i) ); if( !pArea ) continue; ASSERT( pArea->m_wbvRegion.m_eBvType == BVT_PATH_TILE_INDEX ); if( pArea->m_wbvRegion.m_eBvType != BVT_PATH_TILE_INDEX ) continue; ASSERT( pArea->m_wbvRegion.m_BvPathTileIndex.m_nCount != 0 ); for( DWORD j = 0 ; j < pArea->m_wbvRegion.m_BvPathTileIndex.m_nCount ; ++j ) m_StartTiles.push_back( pArea->m_wbvRegion.m_BvPathTileIndex.m_pdwData[j] ); } for( int i = 'A' ; i <= 'Z' ; ++i ) { WzSpecialArea * pArea = m_pWorldBase->GetSpecialArea( CharToWzID('S','T','R', i) ); if( !pArea ) continue; ASSERT( pArea->m_wbvRegion.m_eBvType == BVT_PATH_TILE_INDEX ); if( pArea->m_wbvRegion.m_eBvType != BVT_PATH_TILE_INDEX ) continue; ASSERT( pArea->m_wbvRegion.m_BvPathTileIndex.m_nCount != 0 ); for( DWORD j = 0 ; j < pArea->m_wbvRegion.m_BvPathTileIndex.m_nCount ; ++j ) m_StartTiles.push_back( pArea->m_wbvRegion.m_BvPathTileIndex.m_pdwData[j] ); } } //DWORD FieldInfo::GetRandomStartingTileIndex() //{ // // ·£´ý ¼ÅÇà // ASSERT( m_StartTiles.size() != 0 ); // random_shuffle( m_StartTiles.begin(), m_StartTiles.end() ); // return *(m_StartTiles.begin()); //} BOOL FieldInfo::CheckMapVersion( DWORD dwCheckSum ) { if( m_pWorldBase->GetCheckSum() != dwCheckSum ) { return FALSE; } else { if( 0 == dwCheckSum) { // 0ÀÎ °æ¿ì´Â ±¸¹öÀü ¸Ê!! return FALSE; } return TRUE; } } //////////////////////////////////////////////////////////////////////////////////// // SectorInfo class //////////////////////////////////////////////////////////////////////////////////// SectorInfo::SectorInfo( DWORD index ) : m_dwSectorIndex ( index ), m_NeighborSectorInfo ( MAX_NEIGHBOR_SECTOR_NUM ) { } SectorInfo::~SectorInfo() { } VOID SectorInfo::AddNeighbor( SectorInfo * pSectorInfo ) { m_NeighborSectorInfo.AddTail( pSectorInfo ); }