#include "StdAfx.h" #include ".\sharedfieldinfo.h" #include #include #include #include <3DEngine/Common/IncludeAll_NewWorld.h> #include <3DEngine/3DTerrain/WorldBase.h> #include #include "GameServerEx.h" #include #include "AppliedNpcDependencyChain.h" SharedFieldInfo::SharedFieldInfo(void) : m_pWorldBase(NULL) , m_LastUsedRoomIndex(0) { // (f100623.1L) cache for checksums ZeroMemory(&checksums_, sizeof(checksums_)); } SharedFieldInfo::~SharedFieldInfo(void) { Destroy(); } BOOL SharedFieldInfo::Create( FIELDCODE fieldcode, const char * field_path, FIELDCODE wmocode, BOOL bNewPathEngine, BOOL bWarCastle ) { if (field_path == NULL || field_path[0] == '\0') { SUNLOG(eCRITICAL_LOG, "[SharedFieldInfo::Create] empty path, FieldCode=%u WMO=%u", (unsigned)fieldcode, (unsigned)wmocode); return FALSE; } if (g_pGameServer == NULL || g_pGameServer->m_fnContactTerrain == NULL) { SUNLOG(eCRITICAL_LOG, "[SharedFieldInfo::Create] terrain DLL is not ready"); return FALSE; } m_Code = fieldcode; m_WMOCode = wmocode; m_bNewPathEngine = bNewPathEngine; m_bWarCastle = bWarCastle; _tcsncpy( m_tszMapPath, field_path, MAX_PATH ); m_tszMapPath[MAX_PATH] = '\0'; m_MapObjectInfoHash.clear(); ASSERT(!m_pWorldBase); m_pWorldBase = (CWorldBase *)g_pGameServer->m_fnContactTerrain( CT_NEW_WORLD, 0 ); if (m_pWorldBase == NULL) { SUNLOG(eCRITICAL_LOG, "[SharedFieldInfo::Create] CT_NEW_WORLD failed, FieldCode=%u", (unsigned)fieldcode); return FALSE; } if( m_bNewPathEngine ) m_pWorldBase->Create(); else m_pWorldBase->Create( FALSE ); // (CHANGES) (f100501.2L) (WAVERIX) add the debugging facility SUNLOG(eDEV_LOG, _T("|Start Read|FieldCode=%d|WMOCode=%d|Path=%s|"), fieldcode, wmocode, field_path); if (_Load(field_path) == false) { SUNLOG(eCRITICAL_LOG, _T("|Reading failed!|Path=%s|"), field_path); Destroy(); return false; } SUNLOG(eDEV_LOG, _T("|End Read|Path=%s|"), field_path); _SetStartingTileIndex(); _SetCRStartingTileIndex(); if( m_StartTiles.size() == 0 && m_CR1StartTiles.size() == 0 && m_CR2StartTiles.size() == 0 ) { SUNLOG( eDEV_LOG, "[SharedFieldInfo::Create] StartTiles not found, FieldCode = %u, FieldPath = %s", fieldcode, field_path ); } #ifdef _DEV_TAIYO_PATHENGINE_CODE //LARGE_INTEGER firstcounter,nextcounter; //QueryPerformanceCounter(&firstcounter); //if( m_bNewPathEngine ) //{ // char pszFilePath[_MAX_PATH]={0,}; // char pszFileName[_MAX_FNAME]={0,}; // char pszDir[_MAX_PATH]={0,}; // _splitpath( field_path, NULL, pszDir, pszFileName, NULL ); // _snprintf( pszFilePath, _MAX_PATH, "%s\\%s.pfc", pszDir, pszFileName ); // m_pWorldBase->x_pPathFinder->GenerateCollisionPreprocess( m_pWorldBase->GetDiscAccess(), pszFilePath ); //} //else // m_pWorldBase->x_pPathFinder->GenerateCollisionPreprocess( NULL, NULL ); //QueryPerformanceCounter(&nextcounter); //__int64 elapsedclock = nextcounter.QuadPart - firstcounter.QuadPart; //__int64 elapsedmillsecond = elapsedclock / g_pGameServer->m_freq.QuadPart; //printf( "[GenerateCollisionPreprocess] FieldCode[%d] Tick[%I64d]\n", m_Code, elapsedmillsecond ); #endif return TRUE; } VOID SharedFieldInfo::Destroy() { _UnloadMapObjectInfo(); m_TriggerInfoManager.Release(); if( m_pWorldBase ) { m_pWorldBase->Destroy( NULL ); g_pGameServer->m_fnContactTerrain( CT_DELETE_WORLD, m_pWorldBase ); m_pWorldBase = NULL; } m_MapObjectInfoHash.clear(); } VOID SharedFieldInfo::_UnloadMapObjectInfo() { MAPOBJECT_INFO * pDelNode = NULL; MAPOBJECT_INFO_HASH_IT itend = m_MapObjectInfoHash.end(); for( MAPOBJECT_INFO_HASH_IT it = m_MapObjectInfoHash.begin(); it != itend ; ++it ) { pDelNode = it->second; SAFE_DELETE( pDelNode ); } m_MapObjectInfoHash.clear(); } VOID SharedFieldInfo::_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] ); } } VOID SharedFieldInfo::_SetCRStartingTileIndex() { m_CR1StartTiles.clear(); m_CR2StartTiles.clear(); for( int i = '0' ; i <= '9' ; ++i ) { WzSpecialArea * pArea = m_pWorldBase->GetSpecialArea( CharToWzID('C','R','1',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_CR1StartTiles.push_back( pArea->m_wbvRegion.m_BvPathTileIndex.m_pdwData[j] ); pArea = m_pWorldBase->GetSpecialArea( CharToWzID('C','R','2',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_CR2StartTiles.push_back( pArea->m_wbvRegion.m_BvPathTileIndex.m_pdwData[j] ); } } BOOL SharedFieldInfo::_Load( const char * field_path ) { CWzArchive archive; CDiscAccess cda; cda.Create(); // (WAVERIX) (090718) (CHANGES) Sun3DEngine_090717 version???? ?ュ?? DiscAccess ???? ??? ?リ? ????. m_pWorldBase->SetDiscAccess(&cda); if( _access(field_path,0) == -1 ) { SUNLOG( eCRITICAL_LOG, "[FieldInfo::Load] Failed : %s file is not Exist", field_path ); return FALSE; } if( archive.LoadFile( const_cast(field_path) ) == FALSE ) { SUNLOG( eCRITICAL_LOG, "[FieldInfo::Load] Failed LoadFile() : From Fieldxx.map[%s]", field_path ); archive.Close(); return FALSE; } // (f100623.1L) ZeroMemory(&checksums_, sizeof(checksums_)); archive.Seek( 4, SO_CURRENT ); archive >> m_Version; archive.Seek( -6, SO_CURRENT ); if( m_pWorldBase->Serialize( &archive ) == FALSE ) { SUNLOG( eCRITICAL_LOG, "[FieldInfo::Load] Failed WorldBase_Serialize() : From Fieldxx.map[%s]", field_path ); archive.Close(); return FALSE; } // ???????? + ????? ???? if( !_Serialize_WMO( archive ) ) { SUNLOG( eCRITICAL_LOG, "[FieldInfo::Load] Failed _Serialize_WMO() : From Fieldxx.map[%s]", field_path ); archive.Close(); return FALSE; } // release resources archive.Close(); return true; } BOOL SharedFieldInfo::_Serialize_WMO( CWzArchive & archive ) { BOOL bAreaChunk = FALSE; while( TRUE ) { St_ChunkInfo ci = archive.ReadChunk(); if( ci.m_nID == 0x1792 ) { bAreaChunk = TRUE; break; } archive.SkipCurrentChunk(ci); } ASSERT( TRUE == bAreaChunk ); char pszFilePath[_MAX_PATH]={0,}; char pszFileName[_MAX_FNAME]={0,}; char pszDir[_MAX_PATH]={0,}; const sWMOINFO * pInfo = MapInfoParser::Instance()->FindWMOInfo(GetWMOCode()); if( !pInfo ) return FALSE; #ifdef _HARDMODE_TRIGGER_PRINT_ ;{ std::ofstream out_trigger("TRIGGER.txt", std::ios::app); CHAR buffer[512] = { 0, }; sprintf(buffer, "mapcode : [%d] filename : [%s]\n", pInfo->Code, pInfo->pszPath); out_trigger << buffer; }; #endif //_HARDMODE_TRIGGER_PRINT_ return _LoadMapObjectInfo(pInfo->pszPath); } BOOL SharedFieldInfo::_LoadMapObjectInfo( const char * pszFilePath ) { _tcsncpy( m_tszWmoPath, pszFilePath, MAX_PATH ); m_tszWmoPath[MAX_PATH-1] = '\0'; CWzArchive l_archive; l_archive.SetDiscAccess(GetWorldBase()->GetDiscAccess()); if( _access(pszFilePath,0) == -1 ) { SUNLOG( eCRITICAL_LOG, "[_LoadMapObjectInfo] Failed : %s file is not Exist", pszFilePath ); return FALSE; } if(!l_archive.LoadFile( const_cast(pszFilePath) )) { return FALSE; } WORD wVersion = 0; l_archive.Seek( 4, SO_CURRENT ); l_archive >> wVersion; l_archive.SetVersion( wVersion ); St_LHFileHeader fhInfo = { 0, }; if( 170 < l_archive.GetVersion() ) { l_archive.Read(&fhInfo.wSecondVersion, sizeof(WORD)); l_archive.Read(&fhInfo.dwCheckSum, sizeof(DWORD)); SUNLOG( eDEV_LOG, "Second Ver[%u] and CheckSum[%u]", fhInfo.wSecondVersion, fhInfo.dwCheckSum ); } // (f100623.1L) checksums_.checksum_map = m_pWorldBase->GetCheckSum(); checksums_.checksum_wmo = fhInfo.dwCheckSum; GetWorldBase()->SerializeExtraAreaInfo(&l_archive, TRUE); _SerializeMapObjectAll(l_archive); // Map?? Wmo ?????? Version ???? ??! _CheckVersionBetweenMapWmo( GetVersion(), l_archive.GetVersion() ); l_archive.Close(); return TRUE; } VOID SharedFieldInfo::_SerializeMapObjectAll( CWzArchive & archive ) { CLoadHelper * pLoadHelper = GetWorldBase()->x_pLoadHelper; pLoadHelper->LoadObj(&archive); //???? ??? ????? ?ュ? int count = pLoadHelper->GetObjectCount(); St_LHObject * pLHObject = pLoadHelper->GetObject(); //ASSERT( count < (ITEM_OBJECT_KEY - MAP_OBJECT_KEY) ); //< ??? 5???? ??????? ???. for( int i = 0 ; i < count ; ++i ) { MAPOBJECT_INFO * pObject = new MAPOBJECT_INFO; //__NA001283_20090303_COLLECTION_MAPOBJECTID pObject->dwMapObjectID = i + MAP_OBJECT_KEY; pObject->wzId = pLHObject[i].m_WzID; pObject->wvPos = pLHObject[i].m_wvPos; pObject->wzRot = pLHObject[i].m_wvRot; pObject->wzScale = pLHObject[i].m_wvScale; pObject->wzBV = pLHObject[i].m_wzBV; pObject->dwAttribute = pLHObject[i].m_dwAttribute; pObject->CollectionID = pLHObject[i].m_wiUser; // ???? ????? -> user == ????? (????? ?ュ???) // ??? ?????? ???? pObject->dwExtraInfos[eMAPOBJECT_TYPE] = pLHObject[i].m_dwParam[eMAPOBJECT_TYPE]; pObject->dwExtraInfos[eMAPOBJECT_MONSTER] = pLHObject[i].m_dwParam[eMAPOBJECT_MONSTER]; pObject->dwExtraInfos[eMAPOBJECT_USE_ALPHA] = pLHObject[i].m_dwParam[eMAPOBJECT_USE_ALPHA]; pObject->dwExtraInfos[eMAPOBJECT_LINKED_MONSTER_REGEN_TYPE] = pLHObject[i].m_dwParam[eMAPOBJECT_LINKED_MONSTER_REGEN_TYPE]; ASSERT( NULL == FindMapObjectInfo( pObject->dwMapObjectID ) ); m_MapObjectInfoHash.insert( MAPOBJECT_INFO_PAIR(pObject->dwMapObjectID, pObject) ); } pLoadHelper->DeleteObject(); // ????? ???? ?ュ? m_TriggerInfoManager.LoadGroupInfos( archive, AppliedNpcDependencyChain::Instance()->GetIEventRegisterForNpcKillByTrigger() ); } BOOL SharedFieldInfo::_LoadPathEngineCollision( char * pszFileName ) { CWzArchive l_archive; l_archive.SetDiscAccess(GetWorldBase()->GetDiscAccess()); if( _access(pszFileName,0) == -1 ) { SUNLOG( eCRITICAL_LOG, "[_LoadPathEngineCollision] Failed : %s file is not Exist", pszFileName ); return FALSE; } if( !l_archive.LoadFile( pszFileName ) ) return FALSE; l_archive.Seek( 4, SO_CURRENT ); WORD wVersion = 0; l_archive >> wVersion; wVersion = VERSION_WEBZEN_MAP; l_archive.SetVersion(wVersion); CWzArray wzArrayVect; int iObjCnt = 0; int iBvCnt = 0; int iVCnt = 0; int iID = 0; WzVector wvPos; //. Object ?????? ????? ??? l_archive >> iObjCnt; for(int iCnt=0;iCnt> iBvCnt; if( iBvCnt ) { l_archive >> iVCnt; l_archive >> iID; l_archive >> wvPos; l_archive.Read(wzArrayVect.GetBufferPtr(),iVCnt*sizeof(WzVector)); GetWorldBase()->x_pPathFinder->EntryCollisionTerritoryUnderLine(ECO_OBJECT,iID,wvPos,iVCnt,wzArrayVect.GetBufferPtr()); } } //. SpeedTree ?????? ????? ??? l_archive >> iObjCnt; for(int iCnt=0;iCnt> iVCnt; if( iVCnt ) { l_archive >> iID; l_archive >> wvPos; l_archive.Read(wzArrayVect.GetBufferPtr(),iVCnt*sizeof(WzVector)); GetWorldBase()->x_pPathFinder->EntryCollisionTerritoryUnderLine(ECO_SPEEDTREE,iID,wvPos,iVCnt,wzArrayVect.GetBufferPtr()); } } l_archive.Close(); return TRUE; } VOID SharedFieldInfo::_CheckVersionBetweenMapWmo( DWORD MapVersion, DWORD WmoVersion ) { // 167 ???? ?????? Map?? ???? ?????? ???? ?ュ??? ????? ????. if( MapVersion <= 167 ) { SUNLOG( eCRITICAL_LOG, "[_CheckVersionBetweenMapWmo] Warning! %s Version[%u] is Low!!", m_tszMapPath, MapVersion ); } // 162, 166, 167?? ???? Wmo ???? Map?? ?????? ?? ?????? ????. if( MapVersion > 162 && WmoVersion <= 162 || MapVersion > 166 && WmoVersion <= 166 || MapVersion > 167 && WmoVersion <= 167 || MapVersion > 170 && WmoVersion <= 170 ) { SUNLOG( eCRITICAL_LOG, "[_CheckVersionBetweenMapWmo] Critical! %s Version[%u] is Low!!", m_tszMapPath, WmoVersion ); } }