#include "StdAfx.h" #include "TagStream.h" #include "Tile.h" #include "Map.h" #include "SceneManager.h" #include "SceneProperty.h" #include "LightManager.h" #include "Collision.h" #include "Utils/ClientUtils.h" #include "ResourceManager.h" #include "ModelInstance.h" #include "TaskManager.h" NiImplementRTTI(CTile, NiNode); #pragma warning(disable : 4355) CTile::CTile(int x, int y, Festival_Flag Festival) :m_iX(x) ,m_iY(y) ,m_pkModels(256, 32) ,m_pkTextures(16, 4) ,m_kTileLoader(this) ,m_bNeedDelete(false) ,m_Festival(Festival) { // 构造模型节点 m_spModelNode = NiNew NiNode; } CTile::~CTile() { //释放贴图 for( unsigned int i = 0; i < m_pkTextures.GetSize(); i++ ) { g_ResMgr->FreeTexture(m_pkTextures.GetAt(i)->spTexture); NiDelete m_pkTextures.GetAt(i); } //释放模型 for( unsigned int i = 0; i < m_spModelNode->GetArrayCount(); ++i) { g_ResMgr->FreeNif(m_spModelNode->GetAt(i)); } for(unsigned int i = 0; i < m_pkModels.GetSize(); ++i) { NiDelete m_pkModels.GetAt(i); } } NiFile* CTile::GetFile(const char* Filestr) { NiFile* pkFile = NULL; pkFile = NiFile::GetFile(Filestr, NiFile::READ_ONLY); if( !pkFile || !(*pkFile) ) { NiDelete pkFile; return NULL; } return pkFile ; } bool CTile::Load() { const NiFixedString& kMapName = CMap::Get()->GetMapName(); NiFile* pkFile = NULL; char acFilename[NI_MAX_PATH]; if (m_Festival > Festival_None && m_Festival < Festival_Max) { NiSprintf(acFilename, NI_MAX_PATH, "Data\\World\\Maps\\%s\\%s\\%s_%d_%d.tle", (const char*)kMapName,Festival_File[m_Festival],(const char*)kMapName, m_iX, m_iY); pkFile = GetFile(acFilename); if (pkFile == NULL) { NiSprintf(acFilename, NI_MAX_PATH, "Data\\World\\Maps\\%s\\%s_%d_%d.tle", (const char*)kMapName, (const char*)kMapName, m_iX, m_iY); pkFile = GetFile(acFilename); } }else { NiSprintf(acFilename, NI_MAX_PATH, "Data\\World\\Maps\\%s\\%s_%d_%d.tle", (const char*)kMapName, (const char*)kMapName, m_iX, m_iY); pkFile = GetFile(acFilename); } if( pkFile == NULL ) { return false; } CTagStream kTagStream; while( kTagStream.ReadFromStream( pkFile ) ) { switch( kTagStream.GetTag() ) { case 'VERS': kTagStream.Read(&m_uiVersion, sizeof(int)); kTagStream.SetVersion(m_uiVersion); break; case 'TEXS'://贴图列表 { NiFixedString kTextureName; while( kTagStream.ReadFixedString( kTextureName ) ) { CTileTexture* pkTileTexture = NiNew CTileTexture; kTagStream.Read(&pkTileTexture->fUScale, sizeof(float)); kTagStream.Read(&pkTileTexture->fVScale, sizeof(float)); pkTileTexture->spTexture = g_ResMgr->LoadTexture(kTextureName); m_pkTextures.Add(pkTileTexture); } } break; case 'MODL': //物件模型 { CModelInstance* pkModelInstance; bool bHasCollision; bool bShouldUpdate; kTagStream.SetBase(float(m_iX*TILE_SIZE), float(m_iY*TILE_SIZE)); while( (pkModelInstance = kTagStream.ReadModelInstance()) != NULL ) { pkModelInstance->GetSceneRoot()->Update(0.f); bHasCollision = CreateCollisionData(pkModelInstance->GetSceneRoot()); pkModelInstance->SetCollision(bHasCollision); bShouldUpdate = RecursiveFindAnimation(pkModelInstance->GetSceneRoot()); pkModelInstance->SetShouldUpdate(bShouldUpdate); m_spModelNode->AttachChild(pkModelInstance->GetSceneRoot()); m_pkModels.Add(pkModelInstance); } } break; case 'CHNK'://chunks { int x, y; kTagStream.Read(&x, sizeof(int)); kTagStream.Read(&y, sizeof(int)); NIASSERT( x >= 0 && x < CHUNK_COUNT ); NIASSERT( y >= 0 && y < CHUNK_COUNT ); m_kChunks[x][y].Set(x, y, this); m_kChunks[x][y].Load( &kTagStream ); } break; default: { NIASSERT( false ); } break; } } NiDelete pkFile; return true; } void CTile::BeginBackLoad() { g_pkTaskManager->PushTask(&m_kTileLoader); } void CTile::OnLoaded() { m_spModelNode->AttachProperty(SceneMgr->GetSceneProperty()->GetFogProperty()); SceneMgr->GetLightMgr()->ApplyDirLight(m_spModelNode); m_spModelNode->UpdateProperties(); m_spModelNode->UpdateEffects(); m_spModelNode->UpdateNodeBound(); m_spModelNode->Update(0.0f); } CChunk* CTile::GetChunk(float x, float y) { if( !IsLoaded() ) return NULL; int iX = int(x / CHUNK_SIZE) - m_iX*CHUNK_COUNT; int iY = int(y / CHUNK_SIZE) - m_iY*CHUNK_COUNT; if( iX < 0 || iX >= CHUNK_COUNT || iY < 0 || iY >= CHUNK_COUNT) { return NULL; } return &m_kChunks[iX][iY]; }