#include "StdAfx.h" #include "EtWorld.h" #include "EtWorldGrid.h" #include "EtWorldSector.h" #include "EtWorldEventControl.h" #include "EtWorldEventArea.h" #ifdef _DEBUG #define new new(_NORMAL_BLOCK,__FILE__,__LINE__) #endif CEtWorldGrid::CEtWorldGrid( CEtWorld *pWorld ) { m_dwGridX = m_dwGridY = 1; m_dwGridWidth = m_dwGridHeight = 2000; m_pParent = NULL; m_pWorld = pWorld; m_pProcessSector = NULL; m_dwTileSize = 0; m_fSectorCalcValueX = m_fSectorCalcValueY = 0.f; } CEtWorldGrid::~CEtWorldGrid() { SAFE_DELETE_PVEC( m_pVecChild ); FreeSector(); } bool CEtWorldGrid::Initialize( const char *szName, DWORD dwX, DWORD dwY, DWORD dwWidth, DWORD dwHeight, DWORD dwTileSize ) { if( szName ) SetName( szName ); m_dwGridX = dwX; m_dwGridY = dwY; m_dwGridWidth = dwWidth; m_dwGridHeight = dwHeight; m_dwTileSize = dwTileSize; m_fSectorCalcValueX = ( ( GetGridWidth() * 100 ) * GetGridX() ) / 2.f; m_fSectorCalcValueY = ( ( GetGridHeight() * 100 ) * GetGridY() ) / 2.f; // ·çÆ®ÀÏ °æ¿ì¿£ -1 ³Ñ¾î¿Â´Ù. if( dwX == 0 && dwY == 0 && dwWidth == 0 && dwHeight == 0 ) return true; // Alloc Sector CEtWorldSector *pSector; std::vector< CEtWorldSector * > pVecList; for( DWORD j=0; jInitialize( this, SectorIndex( j, i ) ); pSector->SetTileSize( (float)dwTileSize ); pVecList.push_back( pSector ); } m_ppSector.push_back( pVecList ); } return true; } bool CEtWorldGrid::LoadGrid( const char *szName ) { CResMngStream Stream( szName ); if( !Stream.IsValid() ) return false; InfoFile_Header Header; _ASSERT( sizeof(InfoFile_Header) == Stream.Size() ); if( Stream.Read( &Header, sizeof(InfoFile_Header) ) < 0 ) return false; return Initialize( NULL, Header.dwGridX, Header.dwGridY, Header.dwGridWidth, Header.dwGridHeight, Header.dwTileSize ); } bool CEtWorldGrid::LoadSector( SectorIndex Index, bool bThreadLoad, int nLoadSectorEnum ) { CEtWorldSector *pSector = GetSector( Index ); if( !pSector ) return false; if( pSector->IsLoaded() ) return false; if( pSector->Load( -1, bThreadLoad, nLoadSectorEnum ) == false ) { pSector->SetLoadFailed( true ); return false; } m_VecActiveSector.push_back( Index ); return true; } void CEtWorldGrid::FreeSector( SectorIndex Index ) { for( DWORD i=0; iFree(); m_VecActiveSector.erase( m_VecActiveSector.begin() + i ); break; } } } CEtWorldSector *CEtWorldGrid::AllocSector() { return new CEtWorldSector; } void CEtWorldGrid::FreeSector() { for( DWORD i=0; i= m_VecActiveSector.size() ) return NULL; return m_ppSector[ m_VecActiveSector[dwIndex].nX ][ m_VecActiveSector[dwIndex].nY ]; } CEtWorldSector *CEtWorldGrid::GetSector( float fX, float fZ, float *fResultX, float *fResultZ ) { int nWidth = GetGridWidth() * 100; int nHeight = GetGridHeight() * 100; fX += m_fSectorCalcValueX; fZ += m_fSectorCalcValueY; int nX = (int)( fX / nWidth ); int nY = (int)( fZ / nHeight ); if( fResultX ) *fResultX = fX - ( nX * nWidth ); if( fResultZ ) *fResultZ = fZ - ( nY * nHeight ); if( nX < 0 || nX >= (int)m_dwGridX ) return NULL; if( nY < 0 || nY >= (int)m_dwGridY ) return NULL; return m_ppSector[nX][nY]; } float CEtWorldGrid::GetHeight( float fX, float fZ, EtVector3 *pNormal, int nTileScale ) { float fResultX, fResultZ; CEtWorldSector *pSector = GetSector( fX, fZ, &fResultX, &fResultZ ); if( pSector == NULL ) return 0.f; if( !pSector->IsLoaded() ) return 0.f; return pSector->GetHeight( fResultX, fResultZ, pNormal, nTileScale ); } float CEtWorldGrid::GetCollisionHeight( float fX, float fZ, EtVector3 *pNormal, int nTileScale ) { float fResultX, fResultZ; CEtWorldSector *pSector = GetSector( fX, fZ, &fResultX, &fResultZ ); if( pSector == NULL ) return 0.f; if( !pSector->IsLoaded() ) return 0.f; return pSector->GetCollisionHeight( fResultX, fResultZ, pNormal, nTileScale ); } bool CEtWorldGrid::GetWaterHeight( float fX, float fZ, float *pfHeight ) { float fResultX, fResultZ; CEtWorldSector *pSector = GetSector( fX, fZ, &fResultX, &fResultZ ); if( pSector == NULL ) return false; if( !pSector->IsLoaded() ) return false; return pSector->GetWaterHeight( fResultX, fResultZ, pfHeight ); } char CEtWorldGrid::GetAttribute( float fX, float fZ ) { float fResultX, fResultZ; CEtWorldSector *pSector = GetSector( fX, fZ, &fResultX, &fResultZ ); if( pSector == NULL ) return 0; if( !pSector->IsLoaded() ) return 0; return pSector->GetAttribute( fResultX, fResultZ ); } int CEtWorldGrid::GetAttributeBlockSize( float fX, float fZ ) { CEtWorldSector *pSector = GetSector( fX, fZ ); if( pSector == NULL ) return 0; if( !pSector->IsLoaded() ) return 0; return pSector->GetAttributeBlockSize(); } NavigationMesh *CEtWorldGrid::GetNavMesh( EtVector3 &vPos ) { CEtWorldSector *pSector = GetSector( vPos.x, vPos.z ); if( pSector == NULL ) return 0; if( !pSector->IsLoaded() ) return 0; return pSector->GetNavMesh(); } bool CEtWorldGrid::Pick( EtVector3 &vOrig, EtVector3 &vDir, EtVector3 &vPickPos ) { CEtWorldSector *pSector = GetSector( vOrig.x, vOrig.z ); if( pSector == NULL ) return false; if( !pSector->IsLoaded() ) return false; return pSector->Pick( vOrig, vDir, vPickPos ); } bool CEtWorldGrid::PickWater( EtVector3 &vOrig, EtVector3 &vDir, EtVector3 &vPickPos ) { CEtWorldSector *pSector = GetSector( vOrig.x, vOrig.z ); if( pSector == NULL ) return false; if( !pSector->IsLoaded() ) return false; return pSector->PickWater( vOrig, vDir, vPickPos ); } void CEtWorldGrid::SetName( const char *szName ) { if( szName == NULL ) m_szName.clear(); else m_szName = szName; } const char *CEtWorldGrid::GetName() { return m_szName.c_str(); } void CEtWorldGrid::SetParent( CEtWorldGrid *pGrid ) { m_pParent = pGrid; } DWORD CEtWorldGrid::GetChildCount() { return (DWORD)m_pVecChild.size(); } CEtWorldGrid *CEtWorldGrid::GetChildFromIndex( DWORD dwIndex ) { if( dwIndex >= m_pVecChild.size() ) return NULL; return m_pVecChild[dwIndex]; } void CEtWorldGrid::InsertChild( CEtWorldGrid *pGrid ) { m_pVecChild.push_back( pGrid ); } void CEtWorldGrid::RemoveChild( CEtWorldGrid *pGrid ) { for( DWORD i=0; iGetOffset() - *m_pWorld->GetUpdatePosition(); float fLength = EtVec3Length( &vOffset ); if( fLength < m_pWorld->GetUpdateDirectionLength() || fLength < max( m_pWorld->GetGridWidth() * 100.f, m_pWorld->GetGridHeight() * 100.f ) / 2.f ) { if( !m_ppSector[i][j]->IsLoaded() ) LoadSector( SectorIndex( i, j ), false ); } else { if( m_ppSector[i][j]->IsLoaded() ) FreeSector( SectorIndex( i, j ) ); } } } if( LocalTime == -1 ) return; for( DWORD i=0; iProcess( LocalTime, fDelta ); } m_pProcessSector = NULL; } CEtWorldProp *CEtWorldGrid::AddProp( const char *szPropName, EtVector3 &vPos, EtVector3 &vRotate, EtVector3 &vScale, void *pCustomParam ) { CEtWorldSector *pSector = GetSector( vPos.x, vPos.z ); if( pSector == NULL ) return NULL; if( !pSector->IsLoaded() ) return NULL; return pSector->AddProp( szPropName, vPos, vRotate, vScale, pCustomParam ); } void CEtWorldGrid::ScanProp( EtVector3 &vPos, float fRadius, DNVector(CEtWorldProp*) *pVecResult ) { for( DWORD i=0; iScanProp( vPos, fRadius, pVecResult ); } } void CEtWorldGrid::ScanDecal( EtVector2 &vPos, float fRadius, std::vector *pVecResult ) { for( DWORD i=0; iScanDecal( vPos, fRadius, pVecResult ); } } void CEtWorldGrid::ScanEventArea( EtVector2 &vPos, float fRadius, std::vector *pVecResult ) { for( DWORD i=0; iScanEventArea( vPos, fRadius, pVecResult ); } } void CEtWorldGrid::ScanEventArea( SAABox &Box, std::vector *pVecResult ) { for( DWORD i=0; iScanEventArea( Box, pVecResult ); } } void CEtWorldGrid::ScanEventArea( SOBB &Box, std::vector *pVecResult ) { for( DWORD i=0; iScanEventArea( Box, pVecResult ); } } int CEtWorldGrid::FindPropFromCreateUniqueID( DWORD dwUniqueID, std::vector *pVecResult ) { int nCount = 0; for( DWORD i=0; iGetPropFromCreateUniqueID( dwUniqueID ); if( pProp ) { if( pVecResult ) pVecResult->push_back( pProp ); nCount++; } } return nCount; } int CEtWorldGrid::FindEventControlFromUniqueID( int nUniqueID, std::vector *pVecList ) { int nCount = 0; for( DWORD i=0; iGetControlFromUniqueID( nUniqueID ); if( pControl ) { if( pVecList ) pVecList->push_back( pControl ); nCount++; } } return nCount; } int CEtWorldGrid::FindEventAreaFromName( int nUniqueID, const char *szAreaName, std::vector *pVecList ) { int nCount = 0; for( DWORD i=0; iGetControlFromUniqueID( nUniqueID ); if( !pControl ) continue; std::vector pVecAreaList; nCount += pControl->FindAreaFromName( szAreaName, pVecList ); } return nCount; } int CEtWorldGrid::FindEventAreaFromSubStr( int nUniqueID, const char *szStr, std::vector *pVecList ) { int nCount = 0; for( DWORD i=0; iGetControlFromUniqueID( nUniqueID ); if( !pControl ) continue; for( DWORD j=0; jGetAreaCount(); j++ ) { CEtWorldEventArea *pArea = pControl->GetAreaFromIndex(j); if( strstr( pArea->GetName(), szStr ) ) { if( pVecList ) pVecList->push_back( pArea ); nCount++; } } } return nCount; } int CEtWorldGrid::FindEventAreaFromCreateUniqueID( int nCreateUniqueID, std::vector *pVecList ) { int nCount = 0; for( DWORD i=0; iGetControlCount(); j++ ) { CEtWorldEventControl *pControl = pSector->GetControlFromIndex(j); if( !pControl ) continue; CEtWorldEventArea *pArea = pControl->GetAreaFromCreateUniqueID( nCreateUniqueID ); if( pArea ) { if( pVecList ) pVecList->push_back( pArea ); nCount++; } } } return nCount; } CEtWorldSector *CEtWorldGrid::GetProcessSector() { return m_pProcessSector; } void CEtWorldGrid::CalcWorldBasePos( float fX, float fZ, float &fResultX, float &fResultZ ) { GetSector( fX, fZ, &fResultX, &fResultZ ); }