////////////////////////////////////////////////////////////////////// // feature_Factory::AddFeatureType() // \author Logan Jones ////////////////////////////////////// \date 2/13/2002 // //==================================================================== // Parameters: // LPCTSTR strName - // FeatureFileInfo_t* pFeatureFileInfo - // // Return: BOOL - // BOOL feature_Factory::AddFeatureType( LPCTSTR strName, FeatureFileInfo_t* pFeatureFileInfo ) { #define StringIsValid( STRING_TO_CHECK ) ( (STRING_TO_CHECK)[0]!=0 && stricmp((STRING_TO_CHECK),"empty")!=0 ) DWORD NameKey = std_NameHash( strName ); FeatureType_t Feature; char FilePath[ MAX_PATH ]; // Make sure that there isn't already an entry for this key FeatureTypeMap_t::iterator it = m_FeatureTypes.find( NameKey ); if( it!=m_FeatureTypes.end() ) { theApp.Console.Comment( CT_LOAD, "ERROR: Key for \'%s\'(%d) already used by \'%s\'(%d).", strName, std_NameHash(strName), (*it).second.Name.c_str(), std_NameHash((*it).second.Name.c_str()) ); return FALSE; } // Copy some stuff from the info Feature.Name = strName; Feature.Description = pFeatureFileInfo->Description; Feature.Footprint.Set( pFeatureFileInfo->FootPrintX, pFeatureFileInfo->FootPrintZ ); Feature.Height = pFeatureFileInfo->Height; Feature.Flags = (pFeatureFileInfo->Animating ? FTF_Animating : 0) | (pFeatureFileInfo->Flamable ? FTF_Flamable : 0) | (pFeatureFileInfo->Reclaimable ? FTF_Reclaimable : 0) | (pFeatureFileInfo->Blocking ? FTF_Blocking : 0) | (pFeatureFileInfo->Geothermal ? FTF_Geothermal : 0) | (pFeatureFileInfo->Indestructible ? FTF_Indestructible : 0) | (pFeatureFileInfo->Permanent ? FTF_Permanent : 0) | (pFeatureFileInfo->NoDisplayInfo ? FTF_NoDisplayInfo : 0); // Check if the feature is to use sprites if( StringIsValid(pFeatureFileInfo->FileName) ) { // Check if this anim file is not already loaded if( stricmp(pFeatureFileInfo->FileName,m_CurrentAnimFileName)!=0 ) { // Not loaded, do so sprintf( FilePath, "anims/%s.gaf", pFeatureFileInfo->FileName ); if( !theFileTree.DumpFileToBuffer(FilePath,&m_CurrentAnimFile) ) { theApp.Console.Comment( CT_LOAD, "ERROR: Unable to retrieve \'%s\'", FilePath ); return FALSE; } strcpy( m_CurrentAnimFileName, pFeatureFileInfo->FileName ); } // Create the sprites used to render the feature if( bFAILED(CreateFeatureImages(pFeatureFileInfo,&Feature)) ) return FALSE; } // No sprites, but maybe a model else if( StringIsValid(pFeatureFileInfo->Object) ) { assertEx( 0, "Feature models not yet implemented." ); return FALSE; } else // Error { theApp.Console.Comment( CT_LOAD, "ERROR: Unable to load images or a model for %s.", strName ); return FALSE; } // Add this feature type to the list m_FeatureTypes[ NameKey ] = Feature; // Add some more features to the to-load list if( StringIsValid( pFeatureFileInfo->FeatureDead ) ) { AddToLoadList( pFeatureFileInfo->FeatureDead, m_LoadPass + 1 ); m_FeatureTypes[ NameKey ].FeatureDead = std_NameHash( pFeatureFileInfo->FeatureDead ); } if( StringIsValid( pFeatureFileInfo->FeatureBurnt ) ) { AddToLoadList( pFeatureFileInfo->FeatureBurnt, m_LoadPass + 1 ); m_FeatureTypes[ NameKey ].FeatureBurnt = std_NameHash( pFeatureFileInfo->FeatureBurnt ); } if( StringIsValid( pFeatureFileInfo->FeatureReclamate ) ) { AddToLoadList( pFeatureFileInfo->FeatureReclamate, m_LoadPass + 1 ); m_FeatureTypes[ NameKey ].FeatureReclaimed = std_NameHash( pFeatureFileInfo->FeatureReclamate ); } return TRUE; }
////////////////////////////////////////////////////////////////////// // feature_Factory::Create() // \author Logan Jones ////////////////////////////// \date 2/12/2002 // //==================================================================== // Parameters: // BYTE* pTntFileBuffer - // LPTSTR strWorld - // game_Main::LoadGameStruct Load - // // Return: BOOL - // BOOL feature_Factory::Create( BYTE* pTntFileBuffer, LPTSTR strWorld, game_LoadFacilitator Load ) { app_FileTree::HFIND hList; app_FileTree::FindData_t ListInfo; app_FileTree::HFIND hFind; app_FileTree::FindData_t FindInfo; BOOL bWorkingFeatureFolders; BOOL bWorkingFeatureFiles; char SubDirectoryToSearch[128]; LPTA_TNT_HEADER pHeader; LPTA_TNT_EXT_HEADER pMapHeader; DWORD count; TA_TNT_FEATURE_ENTRY* pFeatureToLoad; int CurrentProgress; if( bFAILED( AddHardcodedFeatureTypes() ) ) { return FALSE; } // Initialize some loading members m_LoadPass = -1; m_CurrentAnimFile = NULL; m_CurrentAnimFileName[0] = '\0'; // TODO: Add unit feature stuff (corpses, etc...) to the list pHeader = (LPTA_TNT_HEADER)pTntFileBuffer; pMapHeader = (LPTA_TNT_EXT_HEADER)(pTntFileBuffer + sizeof(TA_TNT_HEADER)); // Add the features from the map to the list pFeatureToLoad = (TA_TNT_FEATURE_ENTRY*)(pTntFileBuffer + pMapHeader->OffsetToFeatureEntryArray); for( count=pMapHeader->NumberOfFeatures; count>0; --count, ++pFeatureToLoad) AddToLoadList( pFeatureToLoad->Name, 0 ); // Precheck features in the all worlds folder to speed loading theApp.Console.Comment( CT_LOAD, "Processing features/all worlds" ); for( m_NewFeatureAdded=TRUE; m_NewFeatureAdded; ) { m_NewFeatureAdded = FALSE; ProcessDirectory( "all worlds", Load ); } Load.Progress( 10 ); // Precheck features in the specific world folder to speed loading if( strWorld[0]!='\0' ) { theApp.Console.Comment( CT_LOAD, "Processing features/%s", strWorld ); for( m_NewFeatureAdded=TRUE; m_NewFeatureAdded; ) { m_NewFeatureAdded = FALSE; ProcessDirectory( strWorld, Load ); } } Load.Progress( 20 ); // If there are any features left to load, look through all the other subdirectories for( m_LoadPass=0,CurrentProgress=20; !m_FeaturesToLoad.empty(); ++m_LoadPass ) { // Check if we need to check for unfound features if( m_LoadPass>0 ) { FeatureToLoadList_t::iterator e,it = m_FeaturesToLoad.begin(); FeatureToLoadList_t::const_iterator end= m_FeaturesToLoad.end(); for( ; it!=end; ) { if( (*it).second.SearchAdded<m_LoadPass ) { theApp.Console.Comment( CT_LOAD, "Could not find feature \"%s\"", (*it).second.Name ); m_FeaturesToLoad.erase( e=it++ ); } else ++it; } if( m_FeaturesToLoad.empty() ) break; } // end if( m_LoadPass > 0 ) // Search all subdirectories ind 'features' hList = theFileTree.Find( app_FileTree::DIRECTORIES, NULL, "features", &ListInfo ); bWorkingFeatureFolders = hList!=NULL; while( bWorkingFeatureFolders ) { // Make sure this is a directory if( ListInfo.bIsFile==FALSE ) { theApp.Console.Comment( CT_LOAD, "Processing features/%s", ListInfo.Name ); // Search all tdf files in this subdirectory sprintf( SubDirectoryToSearch, "features/%s", ListInfo.Name ); hFind = theFileTree.Find( app_FileTree::FILES_WITH_EXTENSIONS, "tdf", SubDirectoryToSearch, &FindInfo ); bWorkingFeatureFiles = hFind!=NULL; while( bWorkingFeatureFiles ) { //theApp.Console.Comment( CT_LOAD, "Processing features/%s/%s", ListInfo.ItemName, FindInfo.Name ); ProcessTDF( FindInfo.hFile, ListInfo.Name, FindInfo.Name, Load ); // Check if there is anything else to load if( m_FeaturesToLoad.empty() ) break; // Find next file bWorkingFeatureFiles = theFileTree.ContinueFind( hFind, &FindInfo ); } // end while( tdf files ) theFileTree.CloseFind( hFind ); } // end if( IsDirectory ) // Check if there is anything else to load if( m_FeaturesToLoad.empty() ) break; // Find next subdirectory bWorkingFeatureFolders = theFileTree.ContinueFind( hList, &ListInfo ); } // end while( subdirectories ) theFileTree.CloseFind( hList ); } // end while( there are still features to load ) // Clean up some loading members SAFE_DELETE_ARRAY( m_CurrentAnimFile ); theApp.Console.Comment( CT_LOAD, "Placing features on the terrain..." ); Load.Progress( 90 ); // Spawn all the features on the map pFeatureToLoad = (TA_TNT_FEATURE_ENTRY*)(pTntFileBuffer + pMapHeader->OffsetToFeatureEntryArray); LPTA_TNT_MAP_ENTRY pMapStuff = (LPTA_TNT_MAP_ENTRY)(pTntFileBuffer + pMapHeader->OffsetToMapInfoArray); for( DWORD y=0; y<pHeader->Height-1; ++y,pMapStuff+=pHeader->Width) for( DWORD x=0; x<pHeader->Width-1; ++x) if( pMapStuff[x].Special>=0 ) SpawnFeature( pFeatureToLoad[pMapStuff[x].Special].Name, x * 16, y * 16, pMapStuff[x].Elevation ); Load.Progress( 100 ); return TRUE; }
void trpgPageManager::LodPageInfo::AddChildrenToLoadList(std::vector<trpgManagedTile*>& parentList) { if(parentList.size() == 0) return; // Area coverage, in cell unit trpg2iPoint sw,ne; sw.x = cell.x - aoiSize.x; sw.y = cell.y - aoiSize.y; ne.x = cell.x + aoiSize.x; ne.y = cell.y + aoiSize.y; sw.x = MAX(0,sw.x); sw.y = MAX(0,sw.y); ne.x = MIN(lodSize.x-1,ne.x); ne.y = MIN(lodSize.y-1,ne.y); int dx = ne.x - sw.x +1; int dy = ne.y - sw.y +1; // Mark the one that are already there tmpCurrent.resize(dx*dy); std::fill(tmpCurrent.begin(), tmpCurrent.end(), false); for (unsigned int i = 0; i<current.size(); i++) { trpgManagedTile *tile = current[i]; if (tile) { int tileX,tileY,tileLod; tile->GetTileLoc(tileX,tileY,tileLod); tmpCurrent[(tileY-sw.y)*dx + (tileX-sw.x)] = true; } } for (unsigned int i=0;i<load.size();i++) { trpgManagedTile *tile = load[i]; if (tile) { int tileX,tileY,tileLod; tile->GetTileLoc(tileX,tileY,tileLod); tmpCurrent[(tileY-sw.y)*dx + (tileX-sw.x)] = true; } } for(unsigned int parentIdx = 0; parentIdx < parentList.size(); ++parentIdx) { trpgManagedTile* parentTile = parentList[parentIdx]; unsigned int nbChildren = parentTile->GetNbChildren(); for(unsigned int childIdx = 0; childIdx < nbChildren; ++childIdx) { const TileLocationInfo& childLoc = parentTile->GetChildLocationInfo(childIdx); // a sanity check: if the lod is not the same then this // parent is not at the right place if(childLoc.lod != lod) break; // Make sure it is within if (childLoc.x >= sw.x && childLoc.x <= ne.x && childLoc.y >= sw.y && childLoc.y <= ne.y) { // Is it alread there ? if(!tmpCurrent[(childLoc.y - sw.y)*dx + (childLoc.x - sw.x)]) { // Not there, add it AddToLoadList(childLoc.x, childLoc.y, childLoc.addr); } } } } }