//////////////////////////////////////////////////////////////////////
// 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;
}
Exemplo n.º 3
0
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);
                }
            }
        }
    }
}