Ejemplo n.º 1
0
// ***************************************************************************
void			CSkills::load(std::string configFileName)
{

    _Updated=false;
    CIFile f;
    try
    {
        if (f.open(configFileName+".skills"))
        {
            printf("reading skills for %s\n", configFileName.c_str());
            serial(f);
            f.close();
            _MyName=configFileName;
        }
        else
        {
            printf("Serialized file not found: %s.skills\n", configFileName.c_str());
            printf("Entering skills createFromConfigFile file.");
            createFromConfigFile(configFileName);
            printf("I have saved the file\n");
            printf("Serialized file is done and written");
            f.close();
            _MyName=configFileName;
        }
    }
    catch(exception &e)
    {
        printf ("My T3 Error %s\n", e.what ());
    }


}
Ejemplo n.º 2
0
void CSoundAnimation::load()
{
	CIFile file;

	// Open the file
	if (!file.open(_Filename.c_str()))
	{
		throw NLMISC::Exception("Can't open the file for reading");
	}

	// Create the XML stream
	CIXml input;

	// Init
	if (input.init (file))
	{
		xmlNodePtr animNode = input.getRootNode ();
		xmlNodePtr markerNode = input.getFirstChildNode(animNode, "MARKER");

		while (markerNode != 0)
		{
			CSoundAnimMarker* marker = new CSoundAnimMarker();

			const char *time = (const char*) xmlGetProp(markerNode, (xmlChar*) "time");
			if (time == 0)
			{
				throw NLMISC::Exception("Invalid sound animation marker");
			}

			marker->setTime((float) atof(time));
			xmlFree ((void*)time);


			xmlNodePtr soundNode = input.getFirstChildNode(markerNode, "SOUND");

			while (soundNode != 0)
			{
				char *name = (char*) xmlGetProp(soundNode, (xmlChar*) "name");
				if (name == 0)
				{
					throw NLMISC::Exception("Invalid sound animation marker");
				}

				marker->addSound(NLMISC::CSheetId(string(name), "sound"));

				xmlFree ((void*)name);

				soundNode = input.getNextChildNode(soundNode, "SOUND");
			}

			addMarker(marker);

			markerNode = input.getNextChildNode(markerNode, "MARKER");
		}
	}

	// Close the file
	file.close ();
	_Dirty = false;
}
Ejemplo n.º 3
0
//-----------------------------------------------
// loadDump :
// Create a file with the current state of the client (good to report a bug).
//-----------------------------------------------
void loadDump(const std::string &name)
{
	CVectorD currentPos;

	// Load information to start as the version
	CIFile fStart;
	if(fStart.open(name + "_start.rec", false))
	{
		fStart.serialVersion(RecordVersion);
		fStart.serial(currentPos);
		// Close the File.
		fStart.close();
	}
	else
		nlwarning("loadDump: cannot open the file '%s_start.rec'.", name.c_str());

	// Update the position for the vision.
	NetMngr.setReferencePosition(currentPos);

	// Select the closest continent from the new position.
	class CDummyProgress : public IProgressCallback
	{
		void progress (float /* value */) {}
	};
	CDummyProgress dummy;
	ContinentMngr.select(currentPos, dummy);

	// Load the DB
	IngameDbMngr.read(name + "_db.rec");

	// Open the file.
	CIFile f;
	if(f.open(name + ".rec", false))
	{
		// Dump entities.
		EntitiesMngr.dump(f);

		// Close the File.
		f.close();
	}
	else
		nlwarning("loadDump: cannot open '%s.rec'.", name.c_str());
}// loadDump //
Ejemplo n.º 4
0
//-----------------------------------------------------------------------------
CGmTpPendingCommand::CGmTpPendingCommand()
{
	CIFile f;
	string fileName = Bsi.getLocalPath() + toString("gm_pending_tp.bin");
	bool open = f.open(fileName);
	if( open )
	{
		f.serialCont( _CharacterTpPending );
	}
	f.close();
}
Ejemplo n.º 5
0
int main(int argc, char *argv[])
{
	if(argc != 4)
	{
		usage();
		return -1;
	}
	else
	{
		CBitmap		btmp;
		CIFile		inFile;
		COFile		outFile;

		uint	divideRatio;
		NLMISC::fromString(argv[3], divideRatio);
		if(divideRatio==0 || !isPowerOf2(divideRatio))
		{
			printf("divideRatio must be a powerOf2 (1, 2, 4, 8 ...) \n");
			return 0;
		}

		try
		{
			// read.
			if (!inFile.open(argv[1]))
			{
				printf("Can't open input file %s \n", argv[1]);
				return -1;
			}
			uint8	depth= btmp.load(inFile);
			if(depth==0)
				throw Exception("Bad File Format");
			inFile.close();

			// resize.
			btmp.resample(btmp.getWidth() / divideRatio, btmp.getHeight() / divideRatio);

			// output.
			if (!outFile.open(argv[2]))
			{
				printf("Can't open output file %s \n", argv[2]);
				return -1;
			}
			btmp.writeTGA(outFile, depth);
		}
		catch (const Exception &e)
		{
			printf("Error: %s\n", e.what());
				return -1;
		}

		return 0;
	}
}
/** Load the given zone (name without extension)
  * return a pointer to the zone, or NULL if not found
  * Throw an exception if a read error occured
  */
static CZone *LoadZone(uint16 xPos, uint16 yPos, std::string zoneExt)
{
	std::string zoneName;
	::getZoneNameByCoord(xPos, yPos, zoneName);
	std::auto_ptr<CZone> zone(new CZone);		
	std::string lookedUpZoneName = CPath::lookup(zoneName + zoneExt, false, false, false);
	if (lookedUpZoneName.empty()) return NULL;
	CIFile iF;
	if (!iF.open(lookedUpZoneName))
	{
		throw EFileNotOpened(lookedUpZoneName);
	}
	zone->serial(iF);
	iF.close();
	return zone.release();
}
Ejemplo n.º 7
0
void	CMailForumService::checkFile(const std::string& file)
{
	uint	fsz = CFile::getFileSize(file);

	if (fsz == 0)
		return;

	vector<uint8>	buffer(fsz);

	CIFile	fi;
	if (!fi.open(file))
		return;

	fi.serialBuffer(&(buffer[0]), fsz);
	fi.close();

	char*	pb = (char*)(&(buffer[0]));
	char*	pt = pb;

	while (*pt != '\0' && strncmp(pt, "$$$$", 4))
		++pt;

	// file contents "$$$$" -> end of file marker, file is complete, can be deleted
	if (pt != '\0')
	{
		CFile::deleteFile(file);

		int		shard_id;
		char	to_username[256];
		char	from_username[256];

		int		scanned = sscanf(pb, "shard=%d to=%s from=%s", &shard_id, to_username, from_username);

		CMessage	msgout("MAIL_NOTIF");

		uint32	shardId = (uint32)shard_id;
		string	toUserName = to_username;
		string	fromUserName = from_username;

		nldebug("MAIL: sent notification for user '%s' on shard '%d'", toUserName.c_str(), shardId);

		msgout.serial(shardId, toUserName, fromUserName);

		CUnifiedNetwork::getInstance()->send("EGS", msgout);
	}
}
Ejemplo n.º 8
0
/*
 * Load the ranges from a data file
 */
void				CRangeMirrorManager::loadRanges()
{
	try
	{
		CIFile file;
		if ( file.open( RANGE_MANAGER_BACKUP_FILE ) )
		{
			CIXml input;
			if ( input.init( file ) )
			{
				input.serialCont( _RangeListByDataSet );
			}
			file.close();
		}
		else
			throw EFileNotOpened( RANGE_MANAGER_BACKUP_FILE );
		nlinfo( "RangeMirrorManager: successfully loaded ranges" );
	}
	catch ( Exception& e )
	{
		nlinfo( "Can't load ranges: %s", e.what() ); // Info because not a problem
	}
}
Ejemplo n.º 9
0
bool CIconWnd::loadIcon(const std::string &filename, NLMISC::CBitmap &bmp)
{
    // Try to get the file path
    string filepath = CPath::lookup(filename, false, false);
    if (filepath == "")
    {
        bmp.makeDummy();
        bmp.convertToType(NLMISC::CBitmap::RGBA);
        bmp.resample(40, 40);
        return false;
    }

    // load icon
    CIFile f;
    f.open(filepath);

    bmp.load(f);
    bmp.convertToType(NLMISC::CBitmap::RGBA);
    bmp.resample(40, 40);

    f.close();

    return true;
}
int	main(int argc, char *argv[])
{
	uint	i;

	// Avoid warnings.
	NLMISC::createDebug();
	DebugLog->addNegativeFilter("Exception will be launched");
	WarningLog->addNegativeFilter("Exception will be launched");
	InfoLog->addNegativeFilter("FEHTIMER>");
	InfoLog->addNegativeFilter("adding the path");

	// Init serial
	registerSerial3d();

	if(argc<4)
	{
		puts("Usage:    build_clod_bank  path_file.cfg  config_file.cfg  destfile.clodbank  [bakeFrameRate=20] ");
		return 0;
	}


	try
	{
		// The bank to fill
		CLodCharacterShapeBank	lodShapeBank;


		// Read the frameRate to process bake of anims
		float	bakeFrameRate= 20;
		if(argc>=5)
		{
			bakeFrameRate= (float)atof(argv[4]);
			if(bakeFrameRate<=1)
			{
				nlwarning("bad bakeFrameRate value, use a default of 20");
				bakeFrameRate= 20;
			}
		}


		// parse the path file.
		//==================

		// try to load the config file.
		CConfigFile pathConfig;
		pathConfig.load (argv[1]);

		// Get the search pathes
		CConfigFile::CVar &search_pathes = pathConfig.getVar ("search_pathes");
		for (i = 0; i < (uint)search_pathes.size(); i++)
		{
			// Add to search path
			CPath::addSearchPath (search_pathes.asString(i));
		}

		// parse the config file.
		//==================

		// try to load the config file.
		CConfigFile config;
		config.load (argv[2]);

		// For all .clod to process
		//==================
		CConfigFile::CVar &clod_list = config.getVar ("clod_list");
		uint	lodId;
		for (lodId = 0; lodId < (uint)clod_list.size(); lodId++)
		{
			string	lodName= clod_list.asString(lodId);

			printf("Process LOD: %s\n", lodName.c_str());

			// Search the variable with this name.
			try
			{
				CIFile		iFile;

				// get the anim list.
				CConfigFile::CVar &clod_anim_list = config.getVar (lodName);

				// Correct format?
				if(clod_anim_list.size()<3)
				{
					nlwarning("%s skipped. Must have at least the skeleton file name, the lod file name, and one animation", lodName.c_str());
					// go to next.
					continue;
				}

				// Init lod shape process
				//===========================

				// The first variable is the name of the skeleton.
				string	skeletonName= clod_anim_list.asString(0);
				CSmartPtr<CSkeletonShape>	skeletonShape;

				// Load it.
				iFile.open(CPath::lookup(skeletonName));
				CShapeStream		strShape;
				strShape.serial(iFile);
				iFile.close();

				// Get the pointer, check it's a skeleton
				if(dynamic_cast<CSkeletonShape*>(strShape.getShapePointer()) == NULL)
					throw Exception("%s is not a Skeleton", skeletonName.c_str());
				skeletonShape= (CSkeletonShape*)strShape.getShapePointer();

				// The second var is the filename of the lod.
				string	lodFileName= clod_anim_list.asString(1);

				// Load the shape.
				CLodCharacterShapeBuild		lodShapeBuild;
				iFile.open( CPath::lookup(lodFileName) );
				iFile.serial(lodShapeBuild);
				iFile.close();

				// Prepare to build the lod.
				CLodCharacterBuilder		lodBuilder;
				lodBuilder.setShape(lodName, skeletonShape, &lodShapeBuild);


				// Traverse all anim in the list.
				//===========================
				uint	animId;
				for (animId = 2; animId < (uint)clod_anim_list.size(); animId++)
				{
					string	animFileName= clod_anim_list.asString(animId);

					// display.
					printf("Process Anim: %d/%d\r", animId-1, clod_anim_list.size()-2);

					// Try to load the animation
					CAnimation			*anim= new CAnimation;
					// NB: continue, to list all ANIM if anim not found
					try
					{
						iFile.open( CPath::lookup(animFileName) );
						iFile.serial(*anim);
						iFile.close();
						// Add to the builder. NB: animation will be delete in this method.
						// NB: the key name here is the entire file, with the .anim, for easier georges editing.
						lodBuilder.addAnim(animFileName.c_str(), anim, bakeFrameRate);
					}
					catch(EPathNotFound &)
					{
						printf("ERROR anim not found %s\n", animFileName.c_str());
						delete	anim;
					}
				}
				printf("\n");

				// Add to the bank.
				//===========================
				uint32	shapeId= lodShapeBank.addShape();
				*lodShapeBank.getShapeFullAcces(shapeId)= lodBuilder.getLodShape();
			}
			catch(EUnknownVar &evar)
			{
				nlwarning(evar.what());
				// Any other exception will make the program quit.
			}

		}

		// Save bank.
		//===========================

		// compile
		lodShapeBank.compile();

		// Save
		COFile	oFile(argv[3]);
		oFile.serial(lodShapeBank);
		oFile.close();
	}
	catch (Exception& except)
	{
		// Error message
		printf ("ERROR %s.\n Aborting.\n", except.what());
	}


	return 0;
}
// ***************************************************************************
int main(int argc, char* argv[])
{
	// Filter addSearchPath
	NLMISC::createDebug();
	InfoLog->addNegativeFilter ("adding the path");

	// Register 3d
	registerSerial3d ();

	// Good number of args ?
	if (argc<4)
	{
		// Help message
		printf ("ig_lighter [directoryIn] [pathOut] [parameter_file] \n");
	}
	else
	{
		try
		{
			string	directoryIn= argv[1];
			string	pathOut= argv[2];
			string	paramFile= argv[3];
			CInstanceLighter::CLightDesc	lighterDesc;
			string	grFile, rbankFile;

			// Verify directoryIn.
			directoryIn= CPath::standardizePath(directoryIn);
			if( !CFile::isDirectory(directoryIn) )
			{
				printf("DirectoryIn %s is not a directory", directoryIn.c_str());
				return -1;
			}
			// Verify pathOut.
			pathOut= CPath::standardizePath(pathOut);
			if( !CFile::isDirectory(pathOut) )
			{
				printf("PathOut %s is not a directory", pathOut.c_str());
				return -1;
			}

			// Load and setup configFile.
			//=================
			CConfigFile parameter;
			// Load and parse the param file
			parameter.load (paramFile);

			// Get the search pathes
			CConfigFile::CVar &search_pathes = parameter.getVar ("search_pathes");
			uint path;
			for (path = 0; path < (uint)search_pathes.size(); path++)
			{
				// Add to search path
				CPath::addSearchPath (search_pathes.asString(path));
			}

			// Light direction
			CConfigFile::CVar &sun_direction = parameter.getVar ("sun_direction");
			lighterDesc.LightDirection.x=sun_direction.asFloat(0);
			lighterDesc.LightDirection.y=sun_direction.asFloat(1);
			lighterDesc.LightDirection.z=sun_direction.asFloat(2);
			lighterDesc.LightDirection.normalize ();

			// Grid size
			CConfigFile::CVar &quad_grid_size = parameter.getVar ("quad_grid_size");
			lighterDesc.GridSize=quad_grid_size.asInt();

			// Grid size
			CConfigFile::CVar &quad_grid_cell_size = parameter.getVar ("quad_grid_cell_size");
			lighterDesc.GridCellSize=quad_grid_cell_size.asFloat();

			// Shadows enabled ?
			CConfigFile::CVar &shadow = parameter.getVar ("shadow");
			lighterDesc.Shadow=shadow.asInt ()!=0;

			// OverSampling
				CConfigFile::CVar &ig_oversampling = parameter.getVar ("ig_oversampling");
				lighterDesc.OverSampling= ig_oversampling.asInt ();
			// validate value: 0, 2, 4, 8, 16
			lighterDesc.OverSampling= raiseToNextPowerOf2(lighterDesc.OverSampling);
			clamp(lighterDesc.OverSampling, 0U, 16U);
			if(lighterDesc.OverSampling<2)
				lighterDesc.OverSampling= 0;

			// gr
			CConfigFile::CVar &grbank = parameter.getVar ("grbank");
			grFile= grbank.asString ();

			// rbank
			CConfigFile::CVar &rbank = parameter.getVar ("rbank");
			rbankFile= rbank.asString ();

			// CellSurfaceLightSize;
			CConfigFile::CVar &cell_surface_light_size = parameter.getVar ("cell_surface_light_size");
			float cellSurfaceLightSize= cell_surface_light_size.asFloat ();
			if(cellSurfaceLightSize<=0)
				throw Exception("cell_surface_light_size must be > 0");

			// CellRaytraceDeltaZ
			CConfigFile::CVar &cell_raytrace_delta_z = parameter.getVar ("cell_raytrace_delta_z");
			float cellRaytraceDeltaZ= cell_raytrace_delta_z.asFloat ();


			// colIdentifierPrefix
			CConfigFile::CVar &col_identifier_prefix = parameter.getVar ("col_identifier_prefix");
			string colIdentifierPrefix= col_identifier_prefix.asString ();

			// colIdentifierSuffix
			CConfigFile::CVar &col_identifier_suffix = parameter.getVar ("col_identifier_suffix");
			string colIdentifierSuffix= col_identifier_suffix.asString ();

			// colIdentifierSuffix
			CConfigFile::CVar &build_debug_surface_shape = parameter.getVar ("build_debug_surface_shape");
			bool	buildDebugSurfaceShape= build_debug_surface_shape.asInt()!=0;
			

			// try to open gr and rbank
			CRetrieverBank		*retrieverBank= NULL;
			CGlobalRetriever	*globalRetriever= NULL;
			uint32		grFileDate= 0;
			uint32		rbankFileDate= 0;
			if( grFile!="" && rbankFile!="" )
			{
				CIFile	fin;
				// serial the retrieverBank. Exception if not found.
				fin.open(CPath::lookup(rbankFile));
				retrieverBank= new CRetrieverBank;
				retrieverBank->setNamePrefix(CFile::getFilenameWithoutExtension(rbankFile).c_str ());

				// Add the search path for LR files
				CPath::addSearchPath (CFile::getPath(rbankFile));

				fin.serial(*retrieverBank);
				fin.close();

				// serial the globalRetriever. Exception if not found.
				fin.open(CPath::lookup(grFile));
				globalRetriever= new CGlobalRetriever;

				// set the RetrieverBank before loading
				globalRetriever->setRetrieverBank(retrieverBank);
				fin.serial(*globalRetriever);
				fin.close();

				// Get File Dates
				rbankFileDate= CFile::getFileModificationDate(CPath::lookup(rbankFile));
				grFileDate= CFile::getFileModificationDate(CPath::lookup(grFile));

				// And init them.
				globalRetriever->initAll();
			}


			// Scan and load all files .ig in directories
			//=================
			vector<string>				listFile;
			vector<CInstanceGroup*>		listIg;
			vector<string>				listIgFileName;
			vector<string>				listIgPathName;
			CPath::getPathContent(directoryIn, false, false, true, listFile);
			for(uint iFile=0; iFile<listFile.size(); iFile++)
			{
				string	&igFile= listFile[iFile];
				// verify it is a .ig.
				if( CFile::getExtension(igFile) == "ig" )
				{
					// Read the InstanceGroup.
					CInstanceGroup	*ig= new CInstanceGroup;
					CIFile	fin;
					fin.open(CPath::lookup(igFile));
					fin.serial(*ig);

					// add to list.
					listIg.push_back(ig);
					listIgPathName.push_back(igFile);
					listIgFileName.push_back(CFile::getFilename(igFile));
				}
			}


			// For all ig, light them, and save.
			//=================
			for(uint iIg= 0; iIg<listIg.size(); iIg++)
			{
				string	fileNameIn= listIgFileName[iIg];
				string	fileNameOut= pathOut + fileNameIn;

				// If File Out exist 
				if(CFile::fileExists(fileNameOut))
				{
					// If newer than file In (and also newer than retrieverInfos), skip
					uint32		fileOutDate= CFile::getFileModificationDate(fileNameOut);
					if(	fileOutDate > CFile::getFileModificationDate(listIgPathName[iIg]) &&
						fileOutDate > rbankFileDate && 
						fileOutDate > grFileDate 
						)
					{
						printf("Skiping %s\n", fileNameIn.c_str());
						continue;
					}
				}

				// progress
				printf("Processing %s\n", fileNameIn.c_str());

				CInstanceGroup	igOut;

				// Export a debugSun Name.
				string	debugSunName;
				debugSunName= pathOut + "/" + CFile::getFilenameWithoutExtension(fileNameIn) + "_debug_sun_.shape";
				string	debugPLName;
				debugPLName= pathOut + "/" + CFile::getFilenameWithoutExtension(fileNameIn) + "_debug_pl_.shape";

				// light the ig.
				CIgLighterLib::CSurfaceLightingInfo	slInfo;
				slInfo.CellSurfaceLightSize= cellSurfaceLightSize;
				slInfo.CellRaytraceDeltaZ= cellRaytraceDeltaZ;
				slInfo.RetrieverBank= retrieverBank;
				slInfo.GlobalRetriever= globalRetriever;
				slInfo.IgFileName= CFile::getFilenameWithoutExtension(fileNameIn);
				slInfo.ColIdentifierPrefix= colIdentifierPrefix;
				slInfo.ColIdentifierSuffix= colIdentifierSuffix;
				slInfo.BuildDebugSurfaceShape= buildDebugSurfaceShape;
				slInfo.DebugSunName= debugSunName;
				slInfo.DebugPLName= debugPLName;
				lightIg(*listIg[iIg], igOut, lighterDesc, slInfo, fileNameIn.c_str ());

				// Save this ig.
				COFile	fout;
				fout.open(fileNameOut);
				fout.serial(igOut);
				fout.close();

				// skip a line
				printf("\n");
			}

		}
		catch (Exception& except)
		{
			// Error message
			nlwarning ("ERROR %s\n", except.what());
		}
	}


	// Landscape is not deleted, nor the instanceGroups, for faster quit.
	// Must disalbe BlockMemory checks (for pointLights).
	NL3D_BlockMemoryAssertOnPurge= false;


	// exit.
	return 0;
}
//=======================================================================================
// ryzom specific build bbox of a village in a zone
static void computeBBoxFromVillage(const NLGEORGES::UFormElm *villageItem, 
								   const std::string &continentName,
								   uint villageIndex,
								   TShapeMap &shapeMap,
								   CLightingBBox &result
								  )
{	
	result = CLightingBBox();
	const NLGEORGES::UFormElm *igNamesItem;
	if (! (villageItem->getNodeByName (&igNamesItem, "IgList") && igNamesItem) )
	{
		nlwarning("No list of IGs was found in the continent form %s, village #%d", continentName.c_str(), villageIndex);
		return;
	}	
	// Get number of village
	uint numIgs;
	nlverify (igNamesItem->getArraySize (numIgs));
	const NLGEORGES::UFormElm *currIg;
	for(uint l = 0; l < numIgs; ++l)
	{														
		if (!(igNamesItem->getArrayNode (&currIg, l) && currIg))
		{
			nlwarning("Couldn't get ig #%d in the continent form %s, in village #%d", l, continentName.c_str(), villageIndex);
			continue;
		}			
		const NLGEORGES::UFormElm *igNameItem;
		currIg->getNodeByName (&igNameItem, "IgName");
		std::string igName;
		if (!igNameItem->getValue (igName))
		{
			nlwarning("Couldn't get ig name of ig #%d in the continent form %s, in village #%d", l, continentName.c_str(), villageIndex);
			continue;
		}
		if (igName.empty())
		{
			nlwarning("Ig name of ig #%d in the continent form %s, in village #%d is an empty string", l, continentName.c_str(), villageIndex);
			continue;
		}

		igName = CFile::getFilenameWithoutExtension(igName) + ".ig";
		string nameLookup = CPath::lookup (igName, false, true);
		if (!nameLookup.empty())
		{		
			CIFile inputFile;
			// Try to open the file
			if (inputFile.open (nameLookup))
			{				
				CInstanceGroup group;
				try
				{
					CLightingBBox currBBox;
					group.serial (inputFile);
					computeIGBBox(group, currBBox, shapeMap);											
					result.makeUnion(currBBox);					
				}
				catch(NLMISC::Exception &)
				{
					nlwarning ("Error while loading instance group %s\n", igName.c_str());	
					continue;
				}								
				inputFile.close();				
			}
			else
			{
				// Error
				nlwarning ("Can't open instance group %s\n", igName.c_str());
			}
		}								
	}	
}
Ejemplo n.º 13
0
int main(int argc, char* argv[])
{
	// Filter addSearchPath
	NLMISC::createDebug();
	InfoLog->addNegativeFilter ("adding the path");

	// Register 3d
	registerSerial3d ();

	// Good number of args ?
	if (argc<5)
	{
		// Help message
		printf ("%s [zonein.zonel] [igout.ig] [parameter_file] [dependancy_file]\n", argv[0]);
	}
	else
	{
		// Ok, read the zone
		CIFile inputFile;

		// Get extension
		string ext=getExt (argv[1]);
		string dir=getDir (argv[1]);

		// Open it for reading
		if (inputFile.open (argv[1]))
		{
			// Zone name
			string zoneName=toLower (string ("zone_"+getName (argv[1])));

			// Load the zone
			try
			{
				// Read the config file
				CConfigFile parameter;

				// Load and parse the parameter file
				parameter.load (argv[3]);

				// **********
				// *** Build the lighter descriptor
				// **********

				CInstanceLighter::CLightDesc lighterDesc;

				// Light direction
				CConfigFile::CVar &sun_direction = parameter.getVar ("sun_direction");
				lighterDesc.LightDirection.x=sun_direction.asFloat(0);
				lighterDesc.LightDirection.y=sun_direction.asFloat(1);
				lighterDesc.LightDirection.z=sun_direction.asFloat(2);
				lighterDesc.LightDirection.normalize ();

				// Grid size
				CConfigFile::CVar &quad_grid_size = parameter.getVar ("quad_grid_size");
				lighterDesc.GridSize=quad_grid_size.asInt();

				// Grid size
				CConfigFile::CVar &quad_grid_cell_size = parameter.getVar ("quad_grid_cell_size");
				lighterDesc.GridCellSize=quad_grid_cell_size.asFloat();

				// Shadows enabled ?
				CConfigFile::CVar &shadow = parameter.getVar ("shadow");
				lighterDesc.Shadow=shadow.asInt ()!=0;

				// OverSampling
				CConfigFile::CVar &ig_oversampling = parameter.getVar ("ig_oversampling");
				lighterDesc.OverSampling= ig_oversampling.asInt ();
				// validate value: 0, 2, 4, 8, 16
				lighterDesc.OverSampling= raiseToNextPowerOf2(lighterDesc.OverSampling);
				clamp(lighterDesc.OverSampling, 0U, 16U);
				if(lighterDesc.OverSampling<2)
					lighterDesc.OverSampling= 0;

				// For ig of Zones, never disable Sun contrib !!!
				lighterDesc.DisableSunContribution= false;

				// Get the search pathes
				CConfigFile::CVar &search_pathes = parameter.getVar ("search_pathes");
				uint path;
				for (path = 0; path < (uint)search_pathes.size(); path++)
				{
					// Add to search path
					CPath::addSearchPath (search_pathes.asString(path));
				}

				// A landscape allocated with new: it is not delete because destruction take 3 secondes more!
				CLandscape *landscape=new CLandscape;
				landscape->init();

				// A zone lighter
				CMyIgZoneLighter lighter;
				lighter.init ();

				// A vector of zone id
				vector<uint> listZoneId;

				// The zone
				CZone zone;

				// List of ig
				std::list<CInstanceGroup*> instanceGroup;

				// Load
				zone.serial (inputFile);
				inputFile.close();

				// Load ig of the zone
				string igName = getName (argv[1])+".ig";
				string igNameLookup = CPath::lookup (igName, false, false);
				if (!igNameLookup.empty())
					igName = igNameLookup;

				bool zoneIgLoaded;

				// Try to open the file
				CInstanceGroup *centerInstanceGroup= NULL;
				if (inputFile.open (igName))
				{
					// load the center ig
					centerInstanceGroup=new CInstanceGroup;

					// Serial it
					centerInstanceGroup->serial (inputFile);
					inputFile.close();

					// Add to the list
					instanceGroup.push_back (centerInstanceGroup);
					zoneIgLoaded = true;
				}
				else
				{
					// Warning
					fprintf (stderr, "Warning: can't load instance group %s\n", igName.c_str());
					zoneIgLoaded = false;
				}

				// If can't load the center instanceGroup, skip it.
				if(!zoneIgLoaded)
					return 0;

				// Get bank path
				CConfigFile::CVar &bank_name_var = parameter.getVar ("bank_name");
				string bank_name = bank_name_var.asString ();
				string bank_name_lookup = CPath::lookup (bank_name);
				if (!bank_name_lookup.empty())
					bank_name = bank_name_lookup;

				// Load the bank
				if (inputFile.open (bank_name))
				{
					try
					{
						// Load
						landscape->TileBank.serial (inputFile);
						landscape->initTileBanks();
					}
					catch (const Exception &e)
					{
						// Error
						nlwarning ("ERROR error loading tile bank %s\n%s\n", bank_name.c_str(), e.what());
					}
				}
				else
				{
					// Error
					nlwarning ("ERROR can't load tile bank %s\n", bank_name.c_str());
				}

				// Add the zone
				landscape->addZone (zone);
				listZoneId.push_back (zone.getZoneId());

				// Load instance group ?
				CConfigFile::CVar &load_ig= parameter.getVar ("load_ig");
				bool loadInstanceGroup = load_ig.asInt ()!=0;

				// Continue to build ?
				bool continu=true;

				// Try to load additionnal instance group.
				if (loadInstanceGroup)
				{
					// Additionnal instance group
					try
					{
						CConfigFile::CVar &additionnal_ig = parameter.getVar ("additionnal_ig");									
						for (uint add=0; add<(uint)additionnal_ig.size(); add++)
						{
							// Input file
							CIFile inputFile;

							// Name of the instance group
							string name = additionnal_ig.asString(add);
							string nameLookup = CPath::lookup (name, false, false);
							if (!nameLookup.empty())
								name = nameLookup;

							// Try to open the file
							if (inputFile.open (name))
							{
								// New ig
								CInstanceGroup *group=new CInstanceGroup;

								// Serial it
								group->serial (inputFile);
								inputFile.close();

								// Add to the list
								instanceGroup.push_back (group);
							}
							else
							{
								// Error
								nlwarning ("ERROR can't load instance group %s\n", name.c_str());

								// Stop before build
								continu=false;
							}
						}
					}
					catch (const NLMISC::EUnknownVar &)
					{
						nlinfo("No additionnal ig's to load");
					}
				}
				
				// Shadow ?
				if (lighterDesc.Shadow)
				{
					// Load and parse the dependency file
					CConfigFile dependency;
					dependency.load (argv[4]);

					// *** Scan dependency file
					CConfigFile::CVar &dependant_zones = dependency.getVar ("dependencies");
					for (uint i=0; i<(uint)dependant_zones.size(); i++)
					{
						// Get zone name
						string zoneName=dependant_zones.asString(i);

						// Load the zone
						CZone zoneBis;

						// Open it for reading
						if (inputFile.open (dir+zoneName+ext))
						{
							// Read it
							zoneBis.serial (inputFile);
							inputFile.close();

							// Add the zone
							landscape->addZone (zoneBis);
							listZoneId.push_back (zoneBis.getZoneId());
						}
						else
						{
							// Error message and continue
							nlwarning ("ERROR can't load zone %s\n", (dir+zoneName+ext).c_str());
						}

						// Try to load an instance group.
						if (loadInstanceGroup)
						{
							string name = zoneName+".ig";
							string nameLookup = CPath::lookup (name, false, false);
							if (!nameLookup.empty())
								name = nameLookup;

							// Name of the instance group
							if (inputFile.open (name))
							{
								// New ig
								CInstanceGroup *group=new CInstanceGroup;

								// Serial it
								group->serial (inputFile);
								inputFile.close();

								// Add to the list
								instanceGroup.push_back (group);
							}
							else
							{
								// Error message and continue
								nlwarning ("WARNING can't load instance group %s\n", name.c_str());
							}
						}
					}
				}

				// A vector of CInstanceLighter::CTriangle
				vector<CInstanceLighter::CTriangle> vectorTriangle;

				// **********
				// *** Build triangle array
				// **********

				landscape->checkBinds ();

				// Add triangles from landscape, for pointLight lighting.
				landscape->enableAutomaticLighting (false);
				lighter.addTriangles (*landscape, listZoneId, 0, vectorTriangle);

				// Load and add shapes

				// Map of shape
				std::map<string, IShape*> shapeMap;

				// For each instance group
				std::list<CInstanceGroup*>::iterator ite=instanceGroup.begin();
				while (ite!=instanceGroup.end())
				{
					// Instance group
					CInstanceGroup *group=*ite;

					// For each instance
					for (uint instance=0; instance<group->getNumInstance(); instance++)
					{
						// Get the instance shape name
						string name=group->getShapeName (instance);

						// Skip it?? use the DontCastShadowForExterior flag. See doc of this flag
						if(group->getInstance(instance).DontCastShadow || group->getInstance(instance).DontCastShadowForExterior)
							continue;

						// Add a .shape at the end ?
						if (!name.empty())
						{
							if (name.find('.') == std::string::npos)
								name += ".shape";

							// Find the file
							string nameLookup = CPath::lookup (name, false, false);
							if (!nameLookup.empty())
								name = nameLookup;

							// Find the shape in the bank
							std::map<string, IShape*>::iterator iteMap=shapeMap.find (name);
							if (iteMap==shapeMap.end())
							{
								// Input file
								CIFile inputFile;

								if (inputFile.open (name))
								{
									// Load it
									CShapeStream stream;
									stream.serial (inputFile);

									// Get the pointer
									iteMap=shapeMap.insert (std::map<string, IShape*>::value_type (name, stream.getShapePointer ())).first;
								}
								else
								{
									// Error
									nlwarning ("WARNING can't load shape %s\n", name.c_str());
								}
							}
							
							// Loaded ?
							if (iteMap!=shapeMap.end())
							{
								// Build the matrix
								CMatrix scale;
								scale.identity ();
								scale.scale (group->getInstanceScale (instance));
								CMatrix rot;
								rot.identity ();
								rot.setRot (group->getInstanceRot (instance));
								CMatrix pos;
								pos.identity ();
								pos.setPos (group->getInstancePos (instance));
								CMatrix mt=pos*rot*scale;

								// If centerInstanceGroup, take good instanceId, to avoid selfShadowing
								sint	instanceId;
								if(group == centerInstanceGroup)
									instanceId= instance;
								else
									instanceId= -1;

								// Add triangles
								lighter.addTriangles (*iteMap->second, mt, vectorTriangle, instanceId);
							}
						}
					}

					// For each point light of the ig
					const std::vector<CPointLightNamed>	&pointLightList= group->getPointLightList();
					for (uint plId=0; plId<pointLightList.size(); plId++)
					{
						// Add it to the Ig.
						lighter.addStaticPointLight(pointLightList[plId], igName.c_str ());
					}

					// Next instance group
					ite++;
				}

				// Continue ?
				if (continu)
				{
					// **********
					// *** Light!
					// **********

					// Start time
					TTime time=CTime::getLocalTime ();

					// Output ig
					CInstanceGroup	output;

					// Light the zone
					lighter.light (*centerInstanceGroup, output, lighterDesc, vectorTriangle, landscape);

					// Compute time
					printf ("\rCompute time: %d ms                                                      \r", 
						(uint)(CTime::getLocalTime ()-time));

					// Save the zone
					COFile outputFile;

					// Open it
					if (outputFile.open (argv[2]))
					{
						try
						{
							// Save the new ig
							outputFile.serial(output);
						}
						catch (const Exception& except)
						{
							// Error message
							nlwarning ("ERROR writing %s: %s\n", argv[2], except.what());
						}
					}
					else
					{
						// Error can't open the file
						nlwarning ("ERROR Can't open %s for writing\n", argv[2]);
					}
				}
				else
				{
					// Error
					nlwarning ("ERROR Abort: files are missing.\n");
				}
			}
			catch (const Exception& except)
			{
				// Error message
				nlwarning ("ERROR %s\n", except.what());
			}
		}
		else
		{
			// Error can't open the file
			nlwarning ("ERROR Can't open %s for reading\n", argv[1]);
		}

	}
	

	// Landscape is not deleted, nor the instanceGroups, for faster quit.
	// Must disalbe BlockMemory checks (for pointLights).
	NL3D_BlockMemoryAssertOnPurge= false;

	// exit.
	return 0;
}
void CRingAccess::init()
{



	if (_Initialised ) { return; } // no double initialisation
	_CustomNpcSheetId.clear();
	//CSheetId::init() must be called first
	_CustomNpcSheetId.insert(CSheetId("basic_matis_male.creature"));
	_CustomNpcSheetId.insert(CSheetId("basic_fyros_male.creature"));
	_CustomNpcSheetId.insert(CSheetId("basic_tryker_male.creature"));
	_CustomNpcSheetId.insert(CSheetId("basic_zorai_male.creature"));

	_CustomNpcSheetId.insert(CSheetId("basic_matis_female.creature"));
	_CustomNpcSheetId.insert(CSheetId("basic_fyros_female.creature"));
	_CustomNpcSheetId.insert(CSheetId("basic_tryker_female.creature"));
	_CustomNpcSheetId.insert(CSheetId("basic_zorai_female.creature"));


	for (uint32 i = 0 ; i <= 184 ; ++i)
	{
		_R2PlotItemSheetId.insert( CSheetId( NLMISC::toString("r2_plot_item_%d.sitem", i)));
	}

	_SheetIdToAccess.clear();//only usefull when manualy re init file
	// File stream
	CIFile file;


	std::string pathFileName = CPath::lookup(RingAccessFilename, false, false, false);
	// Open the file
	if (pathFileName.empty() || !file.open(pathFileName.c_str()))
	{
		nlinfo("Can't open the file for reading : %s", RingAccessFilename.c_str());
		return;
	}



	// Create the XML stream
	CIXml input;

	// Init
	if(input.init(file))
	{
		xmlNodePtr entitiesAccess = input.getRootNode();
		xmlNodePtr entityAccess = input.getFirstChildNode(entitiesAccess, "entityAccess");

		while (entityAccess != 0)
		{

			// island name
			CXMLAutoPtr namePtr( (const char*) xmlGetProp(entityAccess, (xmlChar*) "name") );
			CXMLAutoPtr packagePtr( (const char*) xmlGetProp(entityAccess, (xmlChar*) "package") );
			CXMLAutoPtr sheetClientPtr( (const char*) xmlGetProp(entityAccess, (xmlChar*) "sheetClient") );
			CXMLAutoPtr sheetPtr( (const char*) xmlGetProp(entityAccess, (xmlChar*) "sheetServer") );

			if (!namePtr.getDatas()|| !packagePtr.getDatas() || !sheetPtr.getDatas() || !sheetPtr.getDatas())
			{
				nlerror( "Syntax error in %s", pathFileName.c_str());
				return;
			}

			std::string sheet( sheetPtr.getDatas() );
			std::string package( packagePtr.getDatas() );
			std::string sheetClient(sheetClientPtr.getDatas());


			CSheetId sheetClientId(sheetClient);
			CSheetId sheetId; // no sheet server

			if (sheet.empty())
			{
				bool ok = _SheetIdToAccess.insert( std::make_pair(std::make_pair(sheetClientId, sheetId), package)).second;
				if (!ok)
				{
					std::string previousPackage = _SheetIdToAccess[std::make_pair(sheetClientId, sheetId)];
					// only display warning if one key has multiple package
					if ( previousPackage != package )
					{
						nlwarning("%s: Entity %s sheet(%s) is defined more than once with different package definition. Previous definition is '%s', current definition is '%s'", RingAccessFilename.c_str(), namePtr.getDatas(), sheetClientPtr.getDatas(), previousPackage.c_str(), package.c_str());
					}

				}
			}
			else
			{


				sheetId = CSheetId(sheet);
				if (_CustomNpcSheetId.find(sheetClientId) != _CustomNpcSheetId.end())
				{

					bool ok = _SheetIdToAccess.insert( std::make_pair(std::make_pair(sheetClientId, sheetId), package)).second;
					if (!ok)
					{
						std::string previousPackage = _SheetIdToAccess[std::make_pair(sheetClientId, sheetId)];
						// only display warning if one key has multiple package
						if ( previousPackage != package )
						{
							nlwarning("%s: Entity %s sheet(%s) is defined more than once. Previous definition is '%s', current definition is '%s'", RingAccessFilename.c_str(), namePtr.getDatas(), sheetPtr.getDatas(), previousPackage.c_str(), package.c_str());
						}
					}
				}
				else
				{
					nlwarning("%s: Entity %s has invalid sheets %s %s", RingAccessFilename.c_str(), namePtr.getDatas(), sheetClientPtr.getDatas(), sheetPtr.getDatas());
				}
			}


			entityAccess = input.getNextChildNode(entityAccess, "entityAccess");
		}
	}

	// Close the file
	file.close ();

	_Initialised = true;

}
Ejemplo n.º 15
0
// ***************************************************************************
void	makeAnimByRace(const std::string &animSetFile, const std::vector<string> &animList)
{
	// *** Read the animset file.
	CIFile	iFile;
	iFile.open(animSetFile, true);
	// Read all text
	static vector<string>	animSetText;
	animSetText.clear();
	while(!iFile.eof())
	{
		char	tmp[50000];
		iFile.getline(tmp, 50000);
		animSetText.push_back(tmp);
	}
	iFile.close();


	bool	someChangeDone= false;

	// *** For each possible anim
	for(uint i=0;i<animList.size();i++)
	{
		// get the possible anim file name (lowered)
		static vector<string>	raceAnimNames;
		raceAnimNames.clear();
		buildRaceAnimNames(raceAnimNames, toLower(CFile::getFilename(animList[i])));

		// For each line of the animSet
		uint	lastStructLine= 0;
		bool	raceRestrictionFound= false;
		for(uint j=0;j<animSetText.size();)
		{
			string	line= animSetText[j];
			string	lineLwr= toLower(line);

			// Find <LOG> TAg? => stop
			if(line.find("<LOG>")!=string::npos)
				break;

			// Find a STRUCT start?
			if(line.find("<STRUCT>")!=string::npos)
			{
				lastStructLine= j;
				raceRestrictionFound= false;
			}
			
			// Find a RaceRestriction?
			if( line.find("Name=\"Race Restriction\"")!=string::npos )
				raceRestrictionFound= true;

			// Find the anim name?
			uint	nameIndexInLine= findAnimName(lineLwr, raceAnimNames);
			if(nameIndexInLine!=-1)
			{
				// Find the enclosing struct
				nlassert(lastStructLine!=0);
				uint	startBlock= lastStructLine;
				uint	nameLineInBlock= j-startBlock;
				uint	endBlock= 0;
				for(uint k=j+1;k<animSetText.size();k++)
				{
					string	line= animSetText[k];

					// Find a RaceRestriction?
					if( line.find("Name=\"Race Restriction\"")!=string::npos )
						raceRestrictionFound= true;

					// end of block?
					if(line.find("</STRUCT>")!=string::npos)
					{
						// endBlock is exclusive 
						endBlock= k+1;
						break;
					}
				}

				// if not found, abort
				if(endBlock==0)
					break;

				// if a raceRestriction has been found, no op (already done)
				if(raceRestrictionFound)
				{
					j= endBlock;
				}
				else
				{
					// LOG
					InfoLog->displayRawNL("%s: Specifying %s by race", 
						CFile::getFilename(animSetFile).c_str(), 
						CFile::getFilename(animList[i]).c_str());

					// *** Start a copy paste ^^
					// Copy
					static vector<string>	copyText;
					copyText.clear();
					for(uint k=startBlock;k<endBlock;k++)
					{
						// add an empty line before </STRUCT>, for race selection node (filled later)
						if(k==endBlock-1)
							copyText.push_back(string());
						copyText.push_back(animSetText[k]);
					}

					// erase this part
					animSetText.erase(animSetText.begin()+startBlock, animSetText.begin()+endBlock);
					uint	nextBlock= startBlock;

					// Append for each race
					for(uint k=0;k<raceAnimNames.size();k++)
					{
						appendRaceAnim(animSetText, nextBlock, copyText, nameLineInBlock, nameIndexInLine, raceAnimNames[k]);
						// nextBlock is then shifted
						nextBlock+= copyText.size();
					}

					someChangeDone= true;

					// *** then let j point to next block
					j= nextBlock;
				}
			}
			else
			{
				j++;
			}
		}
	}

	// *** Write the animset file.
	if(someChangeDone)
	{
		COFile	oFile;
		oFile.open(animSetFile, false, true);
		// Write all text
		for(uint i=0;i<animSetText.size();i++)
		{
			string	str= animSetText[i];
			str+= "\n";
			oFile.serialBuffer((uint8*)str.c_str(), str.size());
		}
	}
}
Ejemplo n.º 16
0
// ***************************************************************************
int main(int argc, char *argv[])
{
	NLMISC::createDebug();

	// make_anim_melee_impact animset_dir
	if(argc!=2)
		return usage();
	string animSetDir= argv[1];

	// *** parse the anim.txt file
	set<CAnimCombatSet>		combatAnimSets;
	CIFile	animFile;
	if(!animFile.open("anim.txt", true))
	{
		nlwarning("Can't open anim.txt file. abort");
		return 0;
	}
	else
	{
		char	tmp[5000];
		CAnimCombatSet	lastAnimSet;
		// parse all lines
		while(!animFile.eof())
		{
			animFile.getline(tmp, 5000);
			string	line= tmp;
			if(line.empty())
				continue;

			// new anim set?
			if(line[0]!=' ')
			{
				// insert the last anim state
				if(!lastAnimSet.States.empty())
					combatAnimSets.insert(lastAnimSet);
				lastAnimSet.States.clear();
				lastAnimSet.Name= line;
			}
			// new anim state?
			else if(!lastAnimSet.Name.empty())
			{
				CAnimCombatState	state;
				state.build(line);
				lastAnimSet.States.insert(state);
			}
		}

		// append the last anim set if needed
		if(!lastAnimSet.States.empty())
			combatAnimSets.insert(lastAnimSet);

		animFile.close();
	}
	
	// *** Get the list of .animset to make by race
	vector<string>	files;
	files.clear();
	CPath::getPathContent(animSetDir, true, false, true, files);
	vector<string>	animSetList;
	InfoLog->displayRawNL("");
	InfoLog->displayRawNL("*****************************");
	InfoLog->displayRawNL("**** .animation_set list ****");
	InfoLog->displayRawNL("*****************************");
	for(uint i=0;i<files.size();i++)
	{
		if(testWildCard(files[i], "*.animation_set"))
		{
			animSetList.push_back(files[i]);
			InfoLog->displayRawNL(animSetList.back().c_str());
		}
	}
	
	// *** Init StateNameToStateCode
	StateNameToStateCode["attack1"]= "A1";
	StateNameToStateCode["attack2"]= "A2";
	StateNameToStateCode["walk atk"]= "Wa";
	StateNameToStateCode["run atk"]= "Ra";
	StateNameToStateCode["backward atk"]= "Ba";
	StateNameToStateCode["default atk low"]= "Dl";
	StateNameToStateCode["default atk middle"]= "Dm";
	StateNameToStateCode["default atk high"]= "Dh";
	StateNameToStateCode["powerful atk low"]= "Pl";
	StateNameToStateCode["powerful atk middle"]= "Pm";
	StateNameToStateCode["powerful atk high"]= "Ph";
	StateNameToStateCode["area atk low"]= "Al";
	StateNameToStateCode["area atk middle"]= "Am";
	StateNameToStateCode["area atk high"]= "Ah";

	
	// *** For each animset, test if can replace some anim
	InfoLog->displayRawNL("");
	InfoLog->displayRawNL("**************************");
	InfoLog->displayRawNL("**** Starting Process ****");
	InfoLog->displayRawNL("**************************");
	for(uint i=0;i<animSetList.size();i++)
	{
		makeAnimMeleeImpact(animSetList[i], combatAnimSets);
	}

	return 0;
}
Ejemplo n.º 17
0
// ***************************************************************************
void	makeAnimMeleeImpact(const std::string &animSetFile, const set<CAnimCombatSet> &combatAnimSets)
{
	// look if this animSetFile is in the combat list to patch
	string	shortName= CFile::getFilenameWithoutExtension(animSetFile);
	strlwr(shortName);
	CAnimCombatSet	key;
	key.Name= shortName;
	set<CAnimCombatSet>::const_iterator	it= combatAnimSets.find(key);
	if(it == combatAnimSets.end())
		return;

	const CAnimCombatSet	&currentCombatAnimSet= *it;

	InfoLog->displayRawNL("patching %s", animSetFile.c_str());


	// *** Read the animset file.
	CIFile	iFile;
	iFile.open(animSetFile, true);
	// Read all text
	static vector<string>	animSetText;
	animSetText.clear();
	while(!iFile.eof())
	{
		char	tmp[50000];
		iFile.getline(tmp, 50000);
		animSetText.push_back(tmp);
	}
	iFile.close();


	bool	someChangeDone= false;

	// *** Parse the animSet
	{
		// For each line of the animSet
		sint	structLevel= 0;
		sint	meleeImpactDelayLine= -1;
		string	currentStateName;
		for(uint j=0;j<animSetText.size();j++)
		{
			string	line= animSetText[j];
			string	lineLwr= toLower(line);

			// Find <LOG> TAg? => stop
			if(line.find("<LOG>")!=string::npos)
				break;

			// Find a STRUCT start?
			if(line.find("<STRUCT")!=string::npos)
			{
				// inc struct
				structLevel++;

				// if start a new State block
				if(structLevel==2)
				{
					// reset info for this state
					currentStateName.clear();
					meleeImpactDelayLine= -1;
					
					// try to get the name
					const string	tagStart= "name=\"";
					std::string::size_type	start= lineLwr.find(tagStart);
					if(start!=string::npos)
					{
						start+= tagStart.size();
						std::string::size_type	end= lineLwr.find("\"", start);
						if(end!=string::npos)
							currentStateName= lineLwr.substr(start, end-start);
					}
				}
			}

			// Find a STRUCT end?
			if(line.find("</STRUCT>")!=string::npos)
			{
				// if end a state block, may add or replace MeleeDelayImpact
				if(structLevel==2 && !currentStateName.empty())
				{
					// If the state is not in the combat state, no need to patch anything
					static CAnimCombatState		key;
					// must translate for instance "attack1" to "A1"
					key.StateCode= StateNameToStateCode[currentStateName];
					set<CAnimCombatState>::const_iterator		it= currentCombatAnimSet.States.find(key);
					if(it!=currentCombatAnimSet.States.end())
					{
						// else take the mean anim time
						string	format= "      <ATOM Name=\"MeleeImpactDelay\" Value=\"%.3f\"/>";
						string	newLine= toString(format.c_str(), it->MeanAnimTime * MeleeImpactTimeFactor);

						// melee impact delay doesn't exist?
						if(meleeImpactDelayLine==-1)
						{
							// add just before this line the Melee Impact Atom
							animSetText.insert(animSetText.begin()+j, newLine);
							j++;
							someChangeDone= true;
						}
						// else exist and want to replace?
						else if(ReplaceExistingMeleeImpactDelay)
						{
							animSetText[meleeImpactDelayLine]= newLine;
							someChangeDone= true;
						}
					}
				}

				// dec struct level
				structLevel--;
			}
				
			// if we are in level 2 structure, try to get the line to modify (if exist)
			if(structLevel==2)
			{
				if( line.find("Name=\"MeleeImpactDelay\"")!=string::npos )
					meleeImpactDelayLine= j;
			}
		}
	}

	// *** Write the animset file.
	if(someChangeDone)
	{
		COFile	oFile;
		oFile.open(animSetFile, false, true);
		// Write all text
		for(uint i=0;i<animSetText.size();i++)
		{
			string	str= animSetText[i];
			str+= "\n";
			oFile.serialBuffer((uint8*)str.c_str(), (uint)str.size());
		}
	}
}
void CSheetId::loadSheetId ()
{
	H_AUTO(CSheetIdInit);
	//nldebug("Loading sheet_id.bin");

	// Open the sheet id to sheet file name association
	CIFile file;
	std::string path = CPath::lookup("sheet_id.bin", false, false);
	if(!path.empty() && file.open(path))
	{
		// clear entries
		_FileExtensions.clear ();
		_SheetIdToName.clear ();
		_SheetNameToId.clear ();

		// reserve space for the vector of file extensions
		_FileExtensions.resize(1 << (NL_SHEET_ID_TYPE_BITS));

		// Get the map from the file
		map<uint32,string> tempMap;
		contReset(tempMap);
		file.serialCont(tempMap);
		file.close();

		if (_RemoveUnknownSheet)
		{
			uint32 removednbfiles = 0;
			uint32 nbfiles = (uint32)tempMap.size();

			// now we remove all files that not available
			map<uint32,string>::iterator itStr2;
			for( itStr2 = tempMap.begin(); itStr2 != tempMap.end(); )
			{
				if (CPath::exists ((*itStr2).second))
				{
					++itStr2;
				}
				else
				{
					map<uint32,string>::iterator olditStr = itStr2;
					//nldebug ("Removing file '%s' from CSheetId because the file not exists", (*olditStr).second.c_str ());
					itStr2++;
					tempMap.erase (olditStr);
					removednbfiles++;
				}
			}
			nlinfo ("SHEETID: Removed %d files on %d from CSheetId because these files doesn't exists", removednbfiles, nbfiles);
		}

		// Convert the map to one big string and 1 static map (id to name)
		{
			// Get the number and size of all strings
			vector<CChar> tempVec; // Used to initialise the first map
			uint32 nNb = 0;
			uint32 nSize = 0;
			map<uint32,string>::const_iterator it = tempMap.begin();
			while (it != tempMap.end())
			{
				nSize += (uint32)it->second.size()+1;
				nNb++;
				it++;
			}

			// Make the big string (composed of all strings) and a vector referencing each string
			tempVec.resize(nNb);
			_AllStrings.Ptr = new char[nSize];
			it = tempMap.begin();
			nSize = 0;
			nNb = 0;
			while (it != tempMap.end())
			{
				tempVec[nNb].Ptr = _AllStrings.Ptr+nSize;
				strcpy(_AllStrings.Ptr+nSize, it->second.c_str());
				toLower(_AllStrings.Ptr+nSize);
				nSize += (uint32)it->second.size()+1;
				nNb++;
				it++;
			}

			// Finally build the static map (id to name)
			_SheetIdToName.reserve(tempVec.size());
			it = tempMap.begin();
			nNb = 0;
			while (it != tempMap.end())
			{
				_SheetIdToName.add(pair<uint32, CChar>(it->first, CChar(tempVec[nNb])));

				nNb++;
				it++;
			}

			// The vector of all small string is not needed anymore we have all the info in
			// the static map and with the pointer AllStrings referencing the beginning.
		}

		// Build the invert map (Name to Id) & file extension vector
		{
			uint32 nSize = (uint32)_SheetIdToName.size();
			_SheetNameToId.reserve(nSize);
			CStaticMap<uint32,CChar>::iterator itStr;
			for( itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr )
			{
				// add entry to the inverse map
				_SheetNameToId.add( make_pair((*itStr).second, (*itStr).first) );

				// work out the type value for this entry in the map
				TSheetId sheetId;
				sheetId.Id=(*itStr).first;
				uint32 type = sheetId.IdInfos.Type;

				// check whether we need to add an entry to the file extensions vector
				if (_FileExtensions[type].empty())
				{
					// find the file extension part of the given file name
					_FileExtensions[type] = toLower(CFile::getExtension((*itStr).second.Ptr));
				}
				nSize--;
			}
			_SheetNameToId.endAdd();
		}
	}
	else
	{
		nlerror("<CSheetId::init> Can't open the file sheet_id.bin");
	}
	nldebug("Finished loading sheet_id.bin: %u entries read",_SheetIdToName.size());
}