mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	- replaced loadToIt with better H3 parser.
- moved hero class to heroes.json
This commit is contained in:
		
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -240,14 +240,11 @@ void CArtHandler::loadArtifacts(bool onlyTxt) | ||||
| 	static std::map<char, CArtifact::EartClass> classes =  | ||||
| 	  map_list_of('S',CArtifact::ART_SPECIAL)('T',CArtifact::ART_TREASURE)('N',CArtifact::ART_MINOR)('J',CArtifact::ART_MAJOR)('R',CArtifact::ART_RELIC); | ||||
|  | ||||
| 	auto textFile = CResourceHandler::get()->loadData(ResourceID("DATA/ARTRAITS.TXT")); | ||||
| 	std::string buf((char*)textFile.first.get(), textFile.second); | ||||
| 	std::string dump, pom; | ||||
| 	int it=0; | ||||
| 	for(int i=0; i<2; ++i) | ||||
| 	{ | ||||
| 		loadToIt(dump,buf,it,3); | ||||
| 	} | ||||
| 	CLegacyConfigParser parser("DATA/ARTRAITS.TXT"); | ||||
|  | ||||
| 	parser.endLine(); // header | ||||
| 	parser.endLine(); | ||||
|  | ||||
| 	VLC->generaltexth->artifNames.resize(GameConstants::ARTIFACTS_QUANTITY); | ||||
| 	VLC->generaltexth->artifDescriptions.resize(GameConstants::ARTIFACTS_QUANTITY); | ||||
| 	std::map<ui32,ui8>::iterator itr; | ||||
| @@ -265,26 +262,25 @@ void CArtHandler::loadArtifacts(bool onlyTxt) | ||||
| 		} | ||||
| 		CArtifact &nart = *art; | ||||
| 		nart.id=i; | ||||
| 		loadToIt(VLC->generaltexth->artifNames[i],buf,it,4); | ||||
| 		loadToIt(pom,buf,it,4); | ||||
| 		nart.price=atoi(pom.c_str()); | ||||
| 		VLC->generaltexth->artifNames[i] = parser.readString(); | ||||
|  | ||||
| 		nart.price= parser.readNumber(); | ||||
|  | ||||
| 		nart.possibleSlots[ArtBearer::HERO]; //we want to generate map entry even if it will be empty | ||||
| 		nart.possibleSlots[ArtBearer::CREATURE]; //we want to generate map entry even if it will be empty | ||||
| 		nart.possibleSlots[ArtBearer::COMMANDER]; | ||||
|  | ||||
| 		for(int j=0;j<slots.size();j++) | ||||
| 		{ | ||||
| 			loadToIt(pom,buf,it,4); | ||||
| 			if(pom.size() && pom[0]=='x') | ||||
| 			if(parser.readString() == "x") | ||||
| 				nart.possibleSlots[ArtBearer::HERO].push_back(slots[j]); | ||||
| 		} | ||||
| 		loadToIt(pom,buf,it,4); | ||||
| 		nart.aClass = classes[pom[0]]; | ||||
| 		nart.aClass = classes[parser.readString()[0]]; | ||||
|  | ||||
| 		//load description and remove quotation marks | ||||
| 		std::string &desc = VLC->generaltexth->artifDescriptions[i]; | ||||
| 		loadToIt(desc,buf,it,3); | ||||
| 		if(desc[0] == '\"' && desc[desc.size()-1] == '\"') | ||||
| 			desc = desc.substr(1,desc.size()-2); | ||||
| 		VLC->generaltexth->artifDescriptions[i] = parser.readString(); | ||||
|  | ||||
| 		parser.endLine(); | ||||
|  | ||||
| 		if(onlyTxt) | ||||
| 			continue; | ||||
|   | ||||
| @@ -2,9 +2,9 @@ | ||||
| #include "CBuildingHandler.h" | ||||
|  | ||||
| #include "CGeneralTextHandler.h" | ||||
| #include "../lib/Filesystem/CResourceLoader.h" | ||||
| #include "../lib/VCMI_Lib.h" | ||||
| #include "../lib/JsonNode.h" | ||||
| #include "VCMI_Lib.h" | ||||
| #include "Filesystem/CResourceLoader.h" | ||||
| #include "JsonNode.h" | ||||
| #include "GameConstants.h" | ||||
|  | ||||
| /* | ||||
| @@ -17,88 +17,78 @@ | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| static ui32 readNr(std::string &in, int &it) | ||||
| CBuilding * readBuilding(CLegacyConfigParser & parser, int townID, int buildID) | ||||
| { | ||||
| 	int last=it; | ||||
| 	for(;last<in.size();last++) | ||||
| 		if(in[last]=='\t' || in[last]=='\n' || in[last]==' ' || in[last]=='\r' || in[last]=='\n') | ||||
| 			break; | ||||
| 	if(last==in.size()) | ||||
| 		throw std::runtime_error("Cannot read number..."); | ||||
| 	CBuilding * ret = new CBuilding; | ||||
| 	ret->tid = townID; | ||||
| 	ret->bid = buildID; | ||||
| 	for (size_t i=0; i< ret->resources.size(); i++) | ||||
| 		ret->resources[i] = parser.readNumber(); | ||||
|  | ||||
| 	std::istringstream ss(in.substr(it,last-it)); | ||||
| 	it+=(1+last-it); | ||||
| 	ss >> last; | ||||
| 	return last; | ||||
| } | ||||
| static CBuilding * readBg(std::string &buf, int& it) | ||||
| { | ||||
| 	CBuilding * nb = new CBuilding(); | ||||
| 	for(int res=0;res<7;res++) | ||||
| 		nb->resources[res] = readNr(buf,it); | ||||
| 	/*nb->refName = */readTo(buf,it,'\n'); | ||||
| 	//reference name is omitted, it's seems to be useless | ||||
| 	return nb; | ||||
| 	parser.endLine(); | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| void CBuildingHandler::loadBuildings() | ||||
| { | ||||
| 	auto textFile = CResourceHandler::get()->loadData(ResourceID("DATA/BUILDING.TXT")); | ||||
| 	std::string buf((char*)textFile.first.get(), textFile.second); | ||||
|  | ||||
| 	std::string temp; | ||||
| 	int it=0; //buf iterator | ||||
|  | ||||
| 	temp = readTo(buf,it,'\n');temp = readTo(buf,it,'\n');//read 2 lines of file info | ||||
|  | ||||
| 	//read 9 special buildings for every faction | ||||
| 	CLegacyConfigParser parser("DATA/BUILDING.TXT"); | ||||
| 	buildings.resize(GameConstants::F_NUMBER); | ||||
| 	for(int i=0;i<GameConstants::F_NUMBER;i++) | ||||
|  | ||||
| 	parser.endLine(); // header | ||||
| 	parser.endLine(); | ||||
|  | ||||
| 	//Unique buildings | ||||
| 	for (size_t town=0; town<GameConstants::F_NUMBER; town++) | ||||
| 	{ | ||||
| 		temp = readTo(buf,it,'\n');//read blank line and faction name | ||||
| 		temp = readTo(buf,it,'\n'); | ||||
| 		for(int bg = 0; bg<9; bg++) | ||||
| 		parser.endLine(); //header | ||||
| 		parser.endLine(); | ||||
|  | ||||
| 		int buildID = 17; | ||||
| 		do | ||||
| 		{ | ||||
| 			CBuilding *nb = readBg(buf,it); | ||||
| 			nb->tid = i; | ||||
| 			nb->bid = bg+17; | ||||
| 			buildings[i][bg+17] = nb; | ||||
| 			buildings[town][buildID] = readBuilding(parser, town, buildID); | ||||
| 			buildID++; | ||||
| 		} | ||||
| 		while (!parser.isNextEntryEmpty()); | ||||
| 	} | ||||
|  | ||||
| 	//reading 17 neutral (common) buildings | ||||
| 	temp = readTo(buf,it,'\n');temp = readTo(buf,it,'\n');temp = readTo(buf,it,'\n');//neutral buildings - skip 3 lines | ||||
| 	for(int bg = 0; bg<17; bg++) | ||||
| 	// Common buildings | ||||
| 	parser.endLine(); // header | ||||
| 	parser.endLine(); | ||||
| 	parser.endLine(); | ||||
|  | ||||
| 	int buildID = 0; | ||||
| 	do | ||||
| 	{ | ||||
| 		CBuilding *nb = readBg(buf,it); | ||||
| 		for(int f=0;f<GameConstants::F_NUMBER;f++) | ||||
| 		buildings[0][buildID] = readBuilding(parser, 0, buildID); | ||||
|  | ||||
| 		for (size_t town=1; town<GameConstants::F_NUMBER; town++) | ||||
| 		{ | ||||
| 			buildings[f][bg] = new CBuilding(*nb); | ||||
| 			buildings[f][bg]->tid = f; | ||||
| 			buildings[f][bg]->bid = bg; | ||||
| 			buildings[town][buildID] = new CBuilding(*buildings[0][buildID]); | ||||
| 			buildings[town][buildID]->tid = town; | ||||
| 		} | ||||
| 		delete nb; | ||||
| 		buildID++; | ||||
| 	} | ||||
| 	while (!parser.isNextEntryEmpty()); | ||||
|  | ||||
| 	parser.endLine(); //header | ||||
| 	parser.endLine(); | ||||
|  | ||||
| 	//Dwellings | ||||
| 	for (size_t town=0; town<GameConstants::F_NUMBER; town++) | ||||
| 	{ | ||||
| 		parser.endLine(); //header | ||||
| 		parser.endLine(); | ||||
|  | ||||
| 		int buildID = 30; | ||||
| 		do | ||||
| 		{ | ||||
| 			buildings[town][buildID] = readBuilding(parser, town, buildID); | ||||
| 			buildID++; | ||||
| 		} | ||||
| 		while (!parser.isNextEntryEmpty()); | ||||
| 	} | ||||
|  | ||||
| 	//create Grail entries | ||||
| 	for(int i=0; i<GameConstants::F_NUMBER; i++) | ||||
| 		buildings[i][26] = new CBuilding(i,26); | ||||
|  | ||||
| 	//reading 14 per faction dwellings | ||||
| 	temp = readTo(buf,it,'\n');temp = readTo(buf,it,'\n');//dwellings - skip 2 lines | ||||
| 	for(int i=0;i<GameConstants::F_NUMBER;i++) | ||||
| 	{ | ||||
| 		temp = readTo(buf,it,'\n');//read blank line | ||||
| 		temp = readTo(buf,it,'\n');// and faction name | ||||
| 		for(int bg = 0; ; bg++) | ||||
| 		{ | ||||
| 			CBuilding *nb = readBg(buf,it); | ||||
| 			nb->tid = i; | ||||
| 			nb->bid = bg+30; | ||||
| 			buildings[i][bg+30] = nb; | ||||
| 			if (it >= buf.size() || buf[it] == '\t') //read till empty line | ||||
| 				break; | ||||
| 		} | ||||
| 	} | ||||
| 	/////done reading BUILDING.TXT***************************** | ||||
| 	const JsonNode config(ResourceID("config/hall.json")); | ||||
|  | ||||
|   | ||||
| @@ -1,10 +1,11 @@ | ||||
| #include "StdInc.h" | ||||
| #include "CCreatureHandler.h" | ||||
|  | ||||
| #include "CGeneralTextHandler.h" | ||||
| #include "Filesystem/CResourceLoader.h" | ||||
| #include "../lib/VCMI_Lib.h" | ||||
| #include "../lib/CGameState.h" | ||||
| #include "../lib/JsonNode.h" | ||||
| #include "VCMI_Lib.h" | ||||
| #include "CGameState.h" | ||||
| #include "JsonNode.h" | ||||
| #include "CHeroHandler.h" | ||||
| #include "CModHandler.h" | ||||
|  | ||||
| @@ -496,10 +497,8 @@ void CCreatureHandler::loadCreatures() | ||||
|  | ||||
| 	if (VLC->modh->modules.STACK_EXP) 	//reading default stack experience bonuses | ||||
| 	{ | ||||
| 		auto textFile = CResourceHandler::get()->loadData(ResourceID("DATA/CREXPBON.TXT")); | ||||
| 		std::string buf((char*)textFile.first.get(), textFile.second); | ||||
| 		int it = 0; | ||||
| 		si32 creid = -1; | ||||
| 		CLegacyConfigParser parser("DATA/CREXPBON.TXT"); | ||||
|  | ||||
| 		Bonus b; //prototype with some default properties | ||||
| 		b.source = Bonus::STACK_EXPERIENCE; | ||||
| 		b.duration = Bonus::PERMANENT; | ||||
| @@ -508,52 +507,50 @@ void CCreatureHandler::loadCreatures() | ||||
| 		b.additionalInfo = 0; | ||||
| 		b.turnsRemain = 0; | ||||
| 		BonusList bl; | ||||
| 		std::string dump2; | ||||
|  | ||||
| 		loadToIt (dump2, buf, it, 3); //ignore first line | ||||
| 		loadToIt (dump2, buf, it, 4); //ignore index | ||||
| 		parser.endLine(); | ||||
|  | ||||
| 		loadStackExp(b, bl, buf, it); | ||||
| 		parser.readString(); //ignore index | ||||
| 		loadStackExp(b, bl, parser); | ||||
| 		BOOST_FOREACH(Bonus * b, bl) | ||||
| 			addBonusForAllCreatures(b); //health bonus is common for all | ||||
| 		parser.endLine(); | ||||
|  | ||||
| 		loadToIt (dump2, buf, it, 3); //crop comment | ||||
| 		for (i = 1; i < 7; ++i) | ||||
| 		{ | ||||
| 			for (int j = 0; j < 4; ++j) //four modifiers common for tiers | ||||
| 			{ | ||||
| 				loadToIt (dump2, buf, it, 4); //ignore index | ||||
| 				parser.readString(); //ignore index | ||||
| 				bl.clear(); | ||||
| 				loadStackExp(b, bl, buf, it); | ||||
| 				loadStackExp(b, bl, parser); | ||||
| 				BOOST_FOREACH(Bonus * b, bl) | ||||
| 					addBonusForTier(i, b); | ||||
| 				loadToIt (dump2, buf, it, 3); //crop comment | ||||
| 				parser.endLine(); | ||||
| 			} | ||||
| 		} | ||||
| 		for (int j = 0; j < 4; ++j) //tier 7 | ||||
| 		{ | ||||
| 			loadToIt (dump2, buf, it, 4); //ignore index | ||||
| 			parser.readString(); //ignore index | ||||
| 			bl.clear(); | ||||
| 			loadStackExp(b, bl, buf, it); | ||||
| 			loadStackExp(b, bl, parser); | ||||
| 			BOOST_FOREACH(Bonus * b, bl) | ||||
| 			{ | ||||
| 				addBonusForTier(7, b); | ||||
| 				creaturesOfLevel[0].addNewBonus(b); //bonuses from level 7 are given to high-level creatures | ||||
| 			} | ||||
| 			loadToIt (dump2, buf, it, 3); //crop comment | ||||
| 			parser.endLine(); | ||||
| 		} | ||||
| 		do //parse everything that's left | ||||
| 		{ | ||||
| 			loadToIt(creid, buf, it, 4); //get index | ||||
| 			b.sid = creid; //id = this particular creature ID | ||||
| 			loadStackExp(b, creatures[creid]->getBonusList(), buf, it); //add directly to CCreature Node | ||||
| 			loadToIt (dump2, buf, it, 3); //crop comment | ||||
| 		} while (it < buf.size()); | ||||
| 			b.sid = parser.readNumber(); //id = this particular creature ID | ||||
| 			loadStackExp(b, creatures[b.sid]->getBonusList(), parser); //add directly to CCreature Node | ||||
| 		} | ||||
| 		while (parser.endLine()); | ||||
|  | ||||
| 		//Calculate rank exp values, formula appears complicated bu no parsing needed | ||||
| 		expRanks.resize(8); | ||||
| 		int dif = 0; | ||||
| 		it = 8000; //ignore name of this variable | ||||
| 		int it = 8000; //ignore name of this variable | ||||
| 		expRanks[0].push_back(it); | ||||
| 		for (int j = 1; j < 10; ++j) //used for tiers 8-10, and all other probably | ||||
| 		{ | ||||
| @@ -572,25 +569,22 @@ void CCreatureHandler::loadCreatures() | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		textFile = CResourceHandler::get()->loadData(ResourceID("DATA/CREXPMOD.TXT")); | ||||
| 		buf = std::string((char*)textFile.first.get(), textFile.second); | ||||
| 		it = 0; | ||||
| 		loadToIt (dump2, buf, it, 3); //ignore first line | ||||
| 		CLegacyConfigParser expBonParser("DATA/CREXPMOD.TXT"); | ||||
|  | ||||
| 		expBonParser.endLine(); //header | ||||
|  | ||||
| 		maxExpPerBattle.resize(8); | ||||
| 		si32 val; | ||||
| 		for (i = 1; i < 8; ++i) | ||||
| 		{ | ||||
| 			loadToIt (dump2, buf, it, 4); //index | ||||
| 			loadToIt (dump2, buf, it, 4); //float multiplier -> hardcoded | ||||
| 			loadToIt (dump2, buf, it, 4); //ignore upgrade mod? ->hardcoded | ||||
| 			loadToIt (dump2, buf, it, 4); //already calculated | ||||
| 			loadToIt (val, buf, it, 4); | ||||
| 			maxExpPerBattle[i] = (ui32)val; | ||||
| 			loadToIt (val, buf, it, 4); //11th level | ||||
| 			val += (si32)expRanks[i].back(); | ||||
| 			expRanks[i].push_back((ui32)val); | ||||
| 			loadToIt (dump2, buf, it, 3); //crop comment | ||||
| 			expBonParser.readString(); //index | ||||
| 			expBonParser.readString(); //float multiplier -> hardcoded | ||||
| 			expBonParser.readString(); //ignore upgrade mod? ->hardcoded | ||||
| 			expBonParser.readString(); //already calculated | ||||
|  | ||||
| 			maxExpPerBattle[i] = expBonParser.readNumber(); | ||||
| 			expRanks[i].push_back(expRanks[i].back() + expBonParser.readNumber()); | ||||
|  | ||||
| 			expBonParser.endLine(); | ||||
| 		} | ||||
| 		//skeleton gets exp penalty | ||||
| 			creatures[56].get()->addBonus(-50, Bonus::EXP_MULTIPLIER, -1); | ||||
| @@ -601,9 +595,6 @@ void CCreatureHandler::loadCreatures() | ||||
| 			maxExpPerBattle[0] = maxExpPerBattle[7]; | ||||
|  | ||||
| 	}//end of Stack Experience | ||||
| 	//experiment - add 100 to attack for creatures of tier 1 | ||||
| // 	Bonus *b = new Bonus(Bonus::PERMANENT, Bonus::PRIMARY_SKILL, Bonus::OTHER, +100, 0, 0); | ||||
| // 	addBonusForTier(1, b); | ||||
|  | ||||
| 	tlog5 << "\t\tReading config/commanders.json" << std::endl; | ||||
| 	const JsonNode config3(ResourceID("config/commanders.json")); | ||||
| @@ -709,12 +700,11 @@ void CCreatureHandler::loadUnitAnimInfo(CCreature & unit, std::string & src, int | ||||
| 	i+=2; | ||||
| } | ||||
|  | ||||
| void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, std::string & src, int & it) //help function for parsing CREXPBON.txt | ||||
| void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigParser & parser) //help function for parsing CREXPBON.txt | ||||
| { | ||||
| 	std::string buf, mod; | ||||
| 	bool enable = false; //some bonuses are activated with values 2 or 1 | ||||
| 	loadToIt(buf, src, it, 4); | ||||
| 	loadToIt(mod, src, it, 4); | ||||
| 	std::string buf = parser.readString(); | ||||
| 	std::string mod = parser.readString(); | ||||
|  | ||||
| 	switch (buf[0]) | ||||
| 	{ | ||||
| @@ -954,10 +944,10 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, std::string & src | ||||
| 	{ | ||||
| 		if (b.type != Bonus::REBIRTH) | ||||
| 			b.val = 0; //on-off ability, no value specified | ||||
| 		loadToIt (curVal, src, it, 4); // 0 level is never active | ||||
| 		curVal = parser.readNumber();// 0 level is never active | ||||
| 		for (int i = 1; i < 11; ++i) | ||||
| 		{ | ||||
| 			loadToIt (curVal, src, it, 4); | ||||
| 			curVal = parser.readNumber(); | ||||
| 			if (curVal == 1) | ||||
| 			{ | ||||
| 				b.limiter.reset (new RankRangeLimiter(i)); | ||||
| @@ -968,10 +958,10 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, std::string & src | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		loadToIt (lastVal, src, it, 4); //basic value, not particularly useful but existent | ||||
| 		lastVal = parser.readNumber(); //basic value, not particularly useful but existent | ||||
| 		for (int i = 1; i < 11; ++i) | ||||
| 		{ | ||||
| 			loadToIt (curVal, src, it, 4); | ||||
| 			curVal = parser.readNumber(); | ||||
| 			if (b.type == Bonus::HATE) | ||||
| 				curVal *= 10; //odd fix | ||||
| 			if (curVal > lastVal) //threshold, add new bonus | ||||
|   | ||||
| @@ -16,6 +16,7 @@ | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| class CLegacyConfigParser; | ||||
| class CCreatureHandler; | ||||
| class CCreature; | ||||
|  | ||||
| @@ -125,7 +126,7 @@ public: | ||||
| 	void buildBonusTreeForTiers(); | ||||
| 	void loadAnimationInfo(); | ||||
| 	void loadUnitAnimInfo(CCreature & unit, std::string & src, int & i); | ||||
| 	void loadStackExp(Bonus & b, BonusList & bl, std::string & src, int & it); | ||||
| 	void loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigParser &parser); | ||||
| 	int stringToNumber(std::string & s);//help function for parsing CREXPBON.txt | ||||
|  | ||||
| 	bool isGood (si8 faction) const; | ||||
|   | ||||
| @@ -2,9 +2,11 @@ | ||||
| #include "CGeneralTextHandler.h" | ||||
|  | ||||
| #include "Filesystem/CResourceLoader.h" | ||||
| #include "VCMI_Lib.h" | ||||
| #include "Filesystem/CInputStream.h" | ||||
| #include "GameConstants.h" | ||||
|  | ||||
| // #include <locale> //needed? | ||||
|  | ||||
| /* | ||||
|  * CGeneralTextHandler.cpp, part of VCMI engine | ||||
|  * | ||||
| @@ -15,561 +17,419 @@ | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| std::string readTo(const std::string &in, int &it, char end) | ||||
| //Helper for string -> float conversion | ||||
| class LocaleWithComma: public std::numpunct<char> | ||||
| { | ||||
| 	int pom = it; | ||||
| 	int last = in.find_first_of(end,it); | ||||
| 	it+=(1+last-it); | ||||
| 	return in.substr(pom,last-pom); | ||||
| protected: | ||||
| 	char do_decimal_point() const | ||||
| 	{ | ||||
| 		return ','; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| CLegacyConfigParser::CLegacyConfigParser(std::string URI) | ||||
| { | ||||
| 	init(CResourceHandler::get()->load(ResourceID(URI, EResType::TEXT))); | ||||
| } | ||||
|  | ||||
| void trimQuotation(std::string &op) | ||||
| CLegacyConfigParser::CLegacyConfigParser(const std::unique_ptr<CInputStream> & input) | ||||
| { | ||||
| 	if(op.length() && op[0] == '\"' && op[op.size()-1] == '\"') | ||||
| 		op = op.substr(1,op.size()-2); | ||||
| 	init(input); | ||||
| } | ||||
|  | ||||
| std::string getTextFile(std::string filename) | ||||
| void CLegacyConfigParser::init(const std::unique_ptr<CInputStream> & input) | ||||
| { | ||||
| 	auto file = CResourceHandler::get()->loadData( | ||||
| 	               ResourceID(std::string("DATA/") + filename, EResType::TEXT)); | ||||
| 	data.reset(new char[input->getSize()]); | ||||
| 	input->read((ui8*)data.get(), input->getSize()); | ||||
|  | ||||
| 	return std::string((char*)file.first.get(), file.second); | ||||
| 	curr = data.get(); | ||||
| 	end = curr + input->getSize(); | ||||
| } | ||||
|  | ||||
| std::string CLegacyConfigParser::extractQuotedPart() | ||||
| { | ||||
| 	assert(*curr == '\"'); | ||||
|  | ||||
| 	curr++; // skip quote | ||||
| 	char * begin = curr; | ||||
|  | ||||
| 	while (curr != end && *curr != '\"') | ||||
| 		curr++; | ||||
|  | ||||
| 	return std::string(begin, curr++); //increment curr to close quote | ||||
| } | ||||
|  | ||||
| std::string CLegacyConfigParser::extractQuotedString() | ||||
| { | ||||
| 	assert(*curr == '\"'); | ||||
|  | ||||
| 	std::string ret; | ||||
| 	while (true) | ||||
| 	{ | ||||
| 		ret += extractQuotedPart(); | ||||
|  | ||||
| 		if (curr < end && *curr == '\"') //double quote - add it to string and continue | ||||
| 			ret += '\"'; | ||||
| 		else // end of string | ||||
| 			return ret; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| std::string CLegacyConfigParser::extractNormalString() | ||||
| { | ||||
| 	char * begin = curr; | ||||
|  | ||||
| 	while (curr < end && *curr != '\t' && *curr != '\r')//find end of string | ||||
| 		curr++; | ||||
|  | ||||
| 	return std::string(begin, curr); | ||||
| } | ||||
|  | ||||
| std::string CLegacyConfigParser::readString() | ||||
| { | ||||
| 	if (curr >= end || *curr == '\n') | ||||
| 		return ""; | ||||
|  | ||||
| 	std::string ret; | ||||
|  | ||||
| 	if (*curr == '\"') | ||||
| 		ret = extractQuotedString();// quoted text - find closing quote | ||||
| 	else | ||||
| 		ret = extractNormalString();//string without quotes - copy till \t or \r | ||||
|  | ||||
| 	curr++; | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| float CLegacyConfigParser::readNumber() | ||||
| { | ||||
| 	std::string input = readString(); | ||||
|  | ||||
| 	std::istringstream stream(input); | ||||
|  | ||||
| 	if (input.find(',') != std::string::npos) // code to handle conversion with comma as decimal separator | ||||
| 		stream.imbue(std::locale(std::locale(), new LocaleWithComma)); | ||||
|  | ||||
| 	int result; | ||||
| 	if ( !(stream >> result) ) | ||||
| 		return 0; | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| bool CLegacyConfigParser::isNextEntryEmpty() | ||||
| { | ||||
| 	return curr >= end || *curr == '\n' || *curr == '\r' || *curr == '\t'; | ||||
| } | ||||
|  | ||||
| bool CLegacyConfigParser::endLine() | ||||
| { | ||||
| 	while (curr < end && *curr !=  '\n') | ||||
| 		readString(); | ||||
|  | ||||
| 	curr++; | ||||
|  | ||||
| 	return curr < end; | ||||
| } | ||||
|  | ||||
| void readToVector(std::string sourceName, std::vector<std::string> & dest) | ||||
| { | ||||
| 	CLegacyConfigParser parser(sourceName); | ||||
| 	do | ||||
| 	{ | ||||
| 		dest.push_back(parser.readString()); | ||||
| 	} | ||||
| 	while (parser.endLine()); | ||||
| } | ||||
|  | ||||
| void CGeneralTextHandler::load() | ||||
| { | ||||
| 	std::string buf1 = getTextFile("ZELP.TXT"); | ||||
| 	int itr=0, eol=-1, eolnext=-1, pom; | ||||
| 	eolnext = buf1.find_first_of('\r',itr); | ||||
| 	while(itr<buf1.size()) | ||||
| 	readToVector("DATA/VCDESC.TXT",   victoryConditions); | ||||
| 	readToVector("DATA/LCDESC.TXT",   lossCondtions); | ||||
| 	readToVector("DATA/TCOMMAND.TXT", tcommands); | ||||
| 	readToVector("DATA/HALLINFO.TXT", hcommands); | ||||
| 	readToVector("DATA/CASTINFO.TXT", fcommands); | ||||
| 	readToVector("DATA/ADVEVENT.TXT", advobtxt); | ||||
| 	readToVector("DATA/XTRAINFO.TXT", xtrainfo); | ||||
| 	readToVector("DATA/RESTYPES.TXT", restypes); | ||||
| 	readToVector("DATA/TERRNAME.TXT", terrainNames); | ||||
| 	readToVector("DATA/RANDSIGN.TXT", randsign); | ||||
| 	readToVector("DATA/ZCRGN1.TXT",   creGens); | ||||
| 	readToVector("DATA/CRGEN4.TXT",   creGens4); | ||||
| 	readToVector("DATA/OVERVIEW.TXT", overview); | ||||
| 	readToVector("DATA/ARRAYTXT.TXT", arraytxt); | ||||
| 	readToVector("DATA/PRISKILL.TXT", primarySkillNames); | ||||
| 	readToVector("DATA/JKTEXT.TXT",   jktexts); | ||||
| 	readToVector("DATA/TVRNINFO.TXT", tavernInfo); | ||||
| 	readToVector("DATA/TURNDUR.TXT",  turnDurations); | ||||
| 	readToVector("DATA/HEROSCRN.TXT", heroscrn); | ||||
| 	readToVector("DATA/ARTEVENT.TXT", artifEvents); | ||||
| 	readToVector("DATA/TENTCOLR.TXT", tentColors); | ||||
| 	readToVector("DATA/SKILLLEV.TXT", levels); | ||||
| 	readToVector("DATA/OBJNAMES.TXT", names); | ||||
|  | ||||
| 	{ | ||||
| 		eol = eolnext; //end of this line | ||||
| 		eolnext = buf1.find_first_of('\r',eol+1); //end of the next line | ||||
| 		pom=buf1.find_first_of('\t',itr); //upcoming tab | ||||
| 		if(eol<0 || pom<0) | ||||
| 			break; | ||||
| 		if(pom>eol) //in current line there is not tab | ||||
| 			zelp.push_back(std::pair<std::string,std::string>()); | ||||
| 		else | ||||
| 		CLegacyConfigParser parser("DATA/GENRLTXT.TXT"); | ||||
| 		parser.endLine(); | ||||
| 		do | ||||
| 		{ | ||||
| 			zelp.push_back | ||||
| 				(std::pair<std::string,std::string> | ||||
| 				(buf1.substr(itr,pom-itr), | ||||
| 				buf1.substr(pom+1,eol-pom-1))); | ||||
| 			boost::algorithm::replace_all(zelp[zelp.size()-1].first,"\t",""); | ||||
| 			boost::algorithm::replace_all(zelp[zelp.size()-1].second,"\t",""); | ||||
| 			trimQuotation(zelp.back().second); | ||||
| 			allTexts.push_back(parser.readString()); | ||||
| 		} | ||||
| 		itr=eol+2; | ||||
| 		while (parser.endLine()); | ||||
| 	} | ||||
| 	std::string buf = getTextFile("VCDESC.TXT"); | ||||
| 	int andame = buf.size(); | ||||
| 	int i=0; //buf iterator | ||||
| 	for(int gg=0; gg<14; ++gg) | ||||
| 	{ | ||||
| 		int befi=i; | ||||
| 		for(; i<andame; ++i) | ||||
| 		CLegacyConfigParser parser("DATA/ZELP.TXT"); | ||||
| 		do | ||||
| 		{ | ||||
| 			if(buf[i]=='\r') | ||||
| 				break; | ||||
| 			std::string first = parser.readString(); | ||||
| 			std::string second = parser.readString(); | ||||
| 			zelp.push_back(std::make_pair(first, second)); | ||||
| 		} | ||||
| 		victoryConditions[gg] = buf.substr(befi, i-befi); | ||||
| 		i+=2; | ||||
| 		while (parser.endLine()); | ||||
| 	} | ||||
| 	buf = getTextFile("LCDESC.TXT"); | ||||
| 	andame = buf.size(); | ||||
| 	i=0; //buf iterator | ||||
| 	for(int gg=0; gg<4; ++gg) | ||||
| 	{ | ||||
| 		int befi=i; | ||||
| 		for(; i<andame; ++i) | ||||
| 		CLegacyConfigParser parser("DATA/HEROSPEC.TXT"); | ||||
| 		CLegacyConfigParser bioParser("DATA/HEROBIOS.TXT"); | ||||
|  | ||||
| 		//skip header | ||||
| 		parser.endLine(); | ||||
| 		parser.endLine(); | ||||
|  | ||||
| 		do | ||||
| 		{ | ||||
| 			if(buf[i]=='\r') | ||||
| 				break; | ||||
| 			HeroTexts texts; | ||||
| 			texts.bonusName  = parser.readString(); | ||||
| 			texts.shortBonus = parser.readString(); | ||||
| 			texts.longBonus  = parser.readString(); | ||||
| 			texts.biography  = bioParser.readString(); | ||||
| 			hTxts.push_back(texts); | ||||
| 		} | ||||
| 		lossCondtions[gg] = buf.substr(befi, i-befi); | ||||
| 		i+=2; | ||||
| 		while (parser.endLine() && bioParser.endLine()); | ||||
| 	} | ||||
|  | ||||
| 	hTxts.resize(GameConstants::HEROES_QUANTITY); | ||||
|  | ||||
| 	buf = getTextFile("HEROSPEC.TXT"); | ||||
| 	i=0; | ||||
| 	std::string dump; | ||||
| 	for(int iii=0; iii<2; ++iii) | ||||
| 	{ | ||||
| 		loadToIt(dump,buf,i,3); | ||||
| 	} | ||||
| 	for (int iii=0;iii<hTxts.size();iii++) | ||||
| 	{ | ||||
| 		loadToIt(hTxts[iii].bonusName,buf,i,4); | ||||
| 		loadToIt(hTxts[iii].shortBonus,buf,i,4); | ||||
| 		loadToIt(hTxts[iii].longBonus,buf,i,3); | ||||
| 		trimQuotation(hTxts[iii].longBonus); | ||||
| 	} | ||||
| 		CLegacyConfigParser parser("DATA/BLDGNEUT.TXT"); | ||||
|  | ||||
| 	buf = getTextFile("HEROBIOS.TXT"); | ||||
| 	i=0; | ||||
| 	for (int iii=0;iii<hTxts.size();iii++) | ||||
| 	{ | ||||
| 		loadToIt(hTxts[iii].biography,buf,i,3); | ||||
| 		trimQuotation(hTxts[iii].biography); | ||||
| 	} | ||||
|  | ||||
| 	int it; | ||||
| 	buf = getTextFile("BLDGNEUT.TXT"); | ||||
| 	andame = buf.size(), it=0; | ||||
|  | ||||
| 	for(int b=0;b<15;b++) | ||||
| 	{ | ||||
| 		std::string name = readTo(buf,it,'\t'), | ||||
| 			description = readTo(buf,it,'\n'); | ||||
| 		for(int fi=0;fi<GameConstants::F_NUMBER;fi++) | ||||
| 		for(int i=0; i<15; i++) | ||||
| 		{ | ||||
| 			buildings[fi][b].first = name; | ||||
| 			buildings[fi][b].second = description; | ||||
| 		} | ||||
| 	} | ||||
| 	buf1 = readTo(buf,it,'\n');buf1 = readTo(buf,it,'\n');buf1 = readTo(buf,it,'\n');//silo,blacksmith,moat - useless??? | ||||
| 	//shipyard with the ship | ||||
| 	std::string name = readTo(buf,it,'\t'), | ||||
| 		description = readTo(buf,it,'\n'); | ||||
| 	for(int fi=0;fi<GameConstants::F_NUMBER;fi++) | ||||
| 	{ | ||||
| 		buildings[fi][20].first = name; | ||||
| 		buildings[fi][20].second = description; | ||||
| 	} | ||||
| 			std::string name  = parser.readString(); | ||||
| 			std::string descr = parser.readString(); | ||||
| 			parser.endLine(); | ||||
|  | ||||
| 	for(int fi=0;fi<GameConstants::F_NUMBER;fi++) | ||||
| 	{ | ||||
| 		buildings[fi][16].first = readTo(buf,it,'\t'), | ||||
| 			buildings[fi][16].second = readTo(buf,it,'\n'); | ||||
| 	} | ||||
| 	/////done reading "BLDGNEUT.TXT"****************************** | ||||
|  | ||||
| 	buf = getTextFile("BLDGSPEC.TXT"); | ||||
| 	andame = buf.size(), it=0; | ||||
| 	for(int f=0;f<GameConstants::F_NUMBER;f++) | ||||
| 	{ | ||||
| 		for(int b=0;b<9;b++) | ||||
| 		{ | ||||
| 			buildings[f][17+b].first = readTo(buf,it,'\t'); | ||||
| 			buildings[f][17+b].second = readTo(buf,it,'\n'); | ||||
| 		} | ||||
| 		buildings[f][26].first = readTo(buf,it,'\t'); | ||||
| 		buildings[f][26].second = readTo(buf,it,'\n'); | ||||
| 		buildings[f][15].first = readTo(buf,it,'\t'); //resource silo | ||||
| 		buildings[f][15].second = readTo(buf,it,'\n');//resource silo | ||||
| 	} | ||||
| 	/////done reading BLDGSPEC.TXT********************************* | ||||
|  | ||||
| 	buf = getTextFile("DWELLING.TXT"); | ||||
| 	andame = buf.size(), it=0; | ||||
| 	for(int f=0;f<GameConstants::F_NUMBER;f++) | ||||
| 	{ | ||||
| 		for(int b=0;b<14;b++) | ||||
| 		{ | ||||
| 			buildings[f][30+b].first = readTo(buf,it,'\t'); | ||||
| 			buildings[f][30+b].second = readTo(buf,it,'\n'); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	//remove prceeding / trailing whitespaces nad quoation marks from buildings descriptions | ||||
| 	for(std::map<int, std::map<int, std::pair<std::string, std::string> > >::iterator i = buildings.begin(); i != buildings.end(); i++) | ||||
| 	{ | ||||
| 		for(std::map<int, std::pair<std::string, std::string> >::iterator j = i->second.begin(); j != i->second.end(); j++) | ||||
| 		{ | ||||
| 			std::string &str = j->second.second; | ||||
| 			boost::algorithm::trim(str); | ||||
| 			trimQuotation(str); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	buf = getTextFile("TCOMMAND.TXT"); | ||||
| 	itr=0; | ||||
| 	while(itr<buf.length()-1) | ||||
| 	{ | ||||
| 		std::string tmp; | ||||
| 		loadToIt(tmp, buf, itr, 3); | ||||
| 		tcommands.push_back(tmp); | ||||
| 	} | ||||
|  | ||||
| 	buf = getTextFile("HALLINFO.TXT"); | ||||
| 	itr=0; | ||||
| 	while(itr<buf.length()-1) | ||||
| 	{ | ||||
| 		std::string tmp; | ||||
| 		loadToIt(tmp, buf, itr, 3); | ||||
| 		hcommands.push_back(tmp); | ||||
| 	} | ||||
|  | ||||
| 	buf = getTextFile("CASTINFO.TXT"); | ||||
| 	itr=0; | ||||
| 	while(itr<buf.length()-1) | ||||
| 	{ | ||||
| 		std::string tmp; | ||||
| 		loadToIt(tmp, buf, itr, 3); | ||||
| 		fcommands.push_back(tmp); | ||||
| 	} | ||||
|  | ||||
| 	std::istringstream ins, namess; | ||||
| 	ins.str(getTextFile("TOWNTYPE.TXT")); | ||||
| 	namess.str(getTextFile("TOWNNAME.TXT")); | ||||
| 	int si=0; | ||||
| 	char bufname[75]; | ||||
| 	while (!ins.eof()) | ||||
| 	{ | ||||
| 		ins.getline(bufname,50); | ||||
| 		townTypes.push_back(std::string(bufname).substr(0,strlen(bufname)-1)); | ||||
| 		townNames.resize(si+1); | ||||
|  | ||||
| 		for (int i=0; i<GameConstants::NAMES_PER_TOWN; i++) | ||||
| 		{ | ||||
| 			namess.getline(bufname,50); | ||||
| 			townNames[si].push_back(std::string(bufname).substr(0,strlen(bufname)-1)); | ||||
| 		} | ||||
| 		si++; | ||||
| 	} | ||||
|  | ||||
| 	tlog5 << "\t\tReading OBJNAMES \n"; | ||||
| 	buf = getTextFile("OBJNAMES.TXT"); | ||||
| 	it=0; //hope that -1 will not break this | ||||
| 	while (it<buf.length()-1) | ||||
| 	{ | ||||
| 		std::string nobj; | ||||
| 		loadToIt(nobj, buf, it, 3); | ||||
| 		if(nobj.size() && (nobj[nobj.size()-1]==(char)10 || nobj[nobj.size()-1]==(char)13 || nobj[nobj.size()-1]==(char)9)) | ||||
| 		{ | ||||
| 			nobj = nobj.substr(0, nobj.size()-1); | ||||
| 		} | ||||
| 		names.push_back(nobj); | ||||
| 	} | ||||
|  | ||||
| 	tlog5 << "\t\tReading ADVEVENT \n"; | ||||
| 	buf = getTextFile("ADVEVENT.TXT"); | ||||
| 	it=0; | ||||
| 	std::string temp; | ||||
| 	while (it<buf.length()-1) | ||||
| 	{ | ||||
| 		loadToIt(temp,buf,it,3); | ||||
| 		if (temp[0]=='\"') | ||||
| 		{ | ||||
| 			temp = temp.substr(1,temp.length()-2); | ||||
| 		} | ||||
| 		boost::algorithm::replace_all(temp,"\"\"","\""); | ||||
| 		advobtxt.push_back(temp); | ||||
| 	} | ||||
|  | ||||
| 	tlog5 << "\t\tReading XTRAINFO \n"; | ||||
| 	buf = getTextFile("XTRAINFO.TXT"); | ||||
| 	it=0; | ||||
| 	while (it<buf.length()-1) | ||||
| 	{ | ||||
| 		loadToIt(temp,buf,it,3); | ||||
| 		xtrainfo.push_back(temp); | ||||
| 	} | ||||
|  | ||||
| 	tlog5 << "\t\tReading MINENAME \n"; | ||||
| 	buf = getTextFile("MINENAME.TXT"); | ||||
| 	it=0; | ||||
| 	while (it<buf.length()-1) | ||||
| 	{ | ||||
| 		loadToIt(temp,buf,it,3); | ||||
| 		mines.push_back(std::pair<std::string,std::string>(temp,"")); | ||||
| 	} | ||||
|  | ||||
| 	tlog5 << "\t\tReading MINEEVNT \n"; | ||||
| 	buf = getTextFile("MINEEVNT.TXT"); | ||||
| 	it=0; | ||||
| 	i=0; | ||||
| 	while (it<buf.length()-1) | ||||
| 	{ | ||||
| 		loadToIt(temp,buf,it,3); | ||||
| 		temp = temp.substr(1,temp.length()-2); | ||||
| 		if(i < mines.size()) | ||||
| 			mines[i++].second = temp; | ||||
| 		else | ||||
| 			tlog2 << "Warning - too much entries in MINEEVNT. Omitting this one: " << temp << std::endl; | ||||
| 	} | ||||
|  | ||||
| 	tlog5 << "\t\tReading RESTYPES \n"; | ||||
| 	buf = getTextFile("RESTYPES.TXT"); | ||||
| 	it=0; | ||||
| 	while (it<buf.length()-1) | ||||
| 	{ | ||||
| 		loadToIt(temp,buf,it,3); | ||||
| 		restypes.push_back(temp); | ||||
| 	} | ||||
|  | ||||
| 	tlog5 << "\t\tReading TERRNAME \n"; | ||||
| 	buf = getTextFile("TERRNAME.TXT"); | ||||
| 	it=0; | ||||
| 	while (it<buf.length()-1) | ||||
| 	{ | ||||
| 		loadToIt(temp,buf,it,3); | ||||
| 		terrainNames.push_back(temp); | ||||
| 	} | ||||
|  | ||||
| 	tlog5 << "\t\tReading RANDSIGN \n"; | ||||
| 	buf = getTextFile("RANDSIGN.TXT"); | ||||
| 	it=0; | ||||
| 	while (it<buf.length()-1) | ||||
| 	{ | ||||
| 		loadToIt(temp,buf,it,3); | ||||
| 		randsign.push_back(temp); | ||||
| 	}	 | ||||
|  | ||||
| 	tlog5 << "\t\tReading ZCRGN1 \n"; | ||||
| 	buf = getTextFile("ZCRGN1.TXT"); | ||||
| 	it=0; | ||||
| 	while (it<buf.length()-1) | ||||
| 	{ | ||||
| 		loadToIt(temp,buf,it,3); | ||||
| 		creGens.push_back(temp); | ||||
| 	} | ||||
|  | ||||
| 	tlog5 << "\t\tReading CRGN4 \n"; | ||||
| 	buf = getTextFile("CRGEN4.TXT"); | ||||
| 	it=0; | ||||
| 	while (it<buf.length()-1) | ||||
| 	{ | ||||
| 		loadToIt(temp,buf,it,3); | ||||
| 		creGens4.push_back(temp); | ||||
| 	} | ||||
|  | ||||
| 	buf = getTextFile("GENRLTXT.TXT"); | ||||
| 	std::string tmp; | ||||
| 	andame = buf.size(); | ||||
| 	i=0; //buf iterator | ||||
| 	for(; i<andame; ++i) | ||||
| 	{ | ||||
| 		if(buf[i]=='\r') | ||||
| 			break; | ||||
| 	} | ||||
|  | ||||
| 	i+=2; | ||||
| 	std::string buflet; | ||||
| 	for(int jj=0; jj<764; ++jj) | ||||
| 	{ | ||||
| 		loadToIt(buflet, buf, i, 2); | ||||
| 		trimQuotation(buflet); | ||||
| 		boost::algorithm::replace_all(buflet,"\"\"","\""); | ||||
| 		allTexts.push_back(buflet); | ||||
| 	} | ||||
|  | ||||
| 	std::string  stro = getTextFile("Overview.txt"); | ||||
| 	itr=0; | ||||
| 	while(itr<stro.length()-1) | ||||
| 	{ | ||||
| 		loadToIt(tmp, stro, itr, 3); | ||||
| 		trimQuotation(tmp); | ||||
| 		overview.push_back(tmp); | ||||
| 	} | ||||
|  | ||||
| 	std::string  strc = getTextFile("PLCOLORS.TXT"); | ||||
| 	itr=0; | ||||
| 	while(itr<strc.length()-1) | ||||
| 	{ | ||||
| 		loadToIt(tmp, strc, itr, 3); | ||||
| 		colors.push_back(tmp); | ||||
| 		tmp[0] = toupper(tmp[0]); | ||||
| 		capColors.push_back(tmp); | ||||
| 	} | ||||
|  | ||||
| 	std::string  strs = getTextFile("ARRAYTXT.TXT"); | ||||
|  | ||||
| 	itr=0; | ||||
| 	while(itr<strs.length()-1) | ||||
| 	{ | ||||
| 		loadToIt(tmp, strs, itr, 3); | ||||
| 		trimQuotation(tmp); | ||||
| 		arraytxt.push_back(tmp); | ||||
| 	} | ||||
|  | ||||
| 	itr = 0; | ||||
| 	std::string strin = getTextFile("PRISKILL.TXT"); | ||||
| 	for(int hh=0; hh<4; ++hh) | ||||
| 	{ | ||||
| 		loadToIt(tmp, strin, itr, 3); | ||||
| 		primarySkillNames.push_back(tmp); | ||||
| 	} | ||||
|  | ||||
| 	itr = 0; | ||||
| 	strin = getTextFile("JKTEXT.TXT"); | ||||
| 	for(int hh=0; hh<45; ++hh) | ||||
| 	{ | ||||
| 		loadToIt(tmp, strin, itr, 3); | ||||
| 		trimQuotation(tmp);  | ||||
| 		jktexts.push_back(tmp); | ||||
| 	} | ||||
|  | ||||
| 	itr = 0; | ||||
| 	strin = getTextFile("TVRNINFO.TXT"); | ||||
| 	for(int hh=0; hh<8; ++hh) | ||||
| 	{ | ||||
| 		loadToIt(tmp, strin, itr, 3); | ||||
| 		tavernInfo.push_back(tmp); | ||||
| 	} | ||||
|  | ||||
| 	itr = 0; | ||||
| 	strin = getTextFile("TURNDUR.TXT"); | ||||
| 	for(int hh=0; hh<11; ++hh) | ||||
| 	{ | ||||
| 		loadToIt(tmp, strin, itr, 3); | ||||
| 		turnDurations.push_back(tmp); | ||||
| 	} | ||||
|  | ||||
| 	itr = 0; | ||||
| 	strin = getTextFile("HEROSCRN.TXT"); | ||||
| 	for(int hh=0; hh<33; ++hh) | ||||
| 	{ | ||||
| 		loadToIt(tmp, strin, itr, 3); | ||||
| 		heroscrn.push_back(tmp); | ||||
| 	} | ||||
|  | ||||
| 	itr = 0; | ||||
| 	strin = getTextFile("ARTEVENT.TXT"); | ||||
| 	for(; itr<strin.size();) | ||||
| 	{ | ||||
| 		loadToIt(tmp, strin, itr, 2); | ||||
| 	//	boost::algorithm::trim(tmp); | ||||
| 		trimQuotation(tmp); | ||||
| 		boost::algorithm::replace_all(tmp,"\"\"","\""); | ||||
| 		artifEvents.push_back(tmp); | ||||
| 	} | ||||
|  | ||||
| 	buf = getTextFile("SSTRAITS.TXT"); | ||||
| 	it=0; | ||||
|  | ||||
| 	for(int i=0; i<2; ++i) | ||||
| 		loadToIt(dump,buf,it,3); | ||||
|  | ||||
| 	skillName.resize(GameConstants::SKILL_QUANTITY); | ||||
| 	skillInfoTexts.resize(GameConstants::SKILL_QUANTITY); | ||||
| 	for (int i=0; i<GameConstants::SKILL_QUANTITY; i++) | ||||
| 	{ | ||||
| 		skillInfoTexts[i].resize(3); | ||||
| 		loadToIt(skillName[i],buf,it,4); | ||||
| 		loadToIt(skillInfoTexts[i][0],buf,it,4); | ||||
| 		loadToIt(skillInfoTexts[i][1],buf,it,4); | ||||
| 		loadToIt(skillInfoTexts[i][2],buf,it,3); | ||||
| 		for(int j = 0; j < 3; j++) | ||||
| 			trimQuotation(skillInfoTexts[i][j]); | ||||
| 	} | ||||
| 	buf = getTextFile("SKILLLEV.TXT"); | ||||
| 	it=0; | ||||
| 	for(int i=0; i<6; ++i) | ||||
| 	{ | ||||
| 		std::string buffo; | ||||
| 		loadToIt(buffo,buf,it,3); | ||||
| 		levels.push_back(buffo); | ||||
| 	} | ||||
|  | ||||
| 	buf = getTextFile ("SEERHUT.TXT"); | ||||
| 	it = 0; | ||||
| 	loadToIt (dump, buf, it, 3); | ||||
| 	loadToIt (dump, buf, it, 4); //dump description | ||||
| 	seerEmpty.resize(6); | ||||
| 	for (i = 0; i < 5; ++i) | ||||
| 	{ | ||||
| 		loadToIt(seerEmpty[i], buf, it, 4); | ||||
| 		trimQuotation (seerEmpty[i]); | ||||
| 	} | ||||
| 	loadToIt (seerEmpty[5], buf, it, 3); | ||||
| 	trimQuotation (seerEmpty[5]); | ||||
| 	int j,k; | ||||
| 	quests.resize(10); | ||||
| 	for (i = 0; i < 9; ++i) //9 types of quests | ||||
| 	{ | ||||
| 		quests[i].resize(5); | ||||
| 		for (j = 0; j < 5; ++j) | ||||
| 		{ | ||||
| 			loadToIt (dump, buf, it, 4); //front description | ||||
| 			quests[i][j].resize(6); | ||||
| 			for (k = 0; k < 5; ++k) | ||||
| 			for(int j=0; j<GameConstants::F_NUMBER; j++) | ||||
| 			{ | ||||
| 				loadToIt (quests[i][j][k], buf, it, 4); | ||||
| 				trimQuotation (quests[i][j][k]); | ||||
| 				buildings[j][i].first = name; | ||||
| 				buildings[j][i].second = descr; | ||||
| 			} | ||||
| 			loadToIt (quests[i][j][5], buf, it, 3); | ||||
| 			trimQuotation (quests[i][j][5]); | ||||
| 		} | ||||
| 		parser.endLine(); // silo | ||||
| 		parser.endLine(); // blacksmith  //unused entries | ||||
| 		parser.endLine(); // moat | ||||
|  | ||||
| 		//shipyard with the ship | ||||
| 		std::string name  = parser.readString(); | ||||
| 		std::string descr = parser.readString(); | ||||
| 		parser.endLine(); | ||||
|  | ||||
| 		for(int j=0; j<GameConstants::F_NUMBER; j++) | ||||
| 		{ | ||||
| 			buildings[j][20].first = name; | ||||
| 			buildings[j][20].second = descr; | ||||
| 		} | ||||
|  | ||||
| 		//blacksmith | ||||
| 		for(int j=0; j<GameConstants::F_NUMBER; j++) | ||||
| 		{ | ||||
| 			buildings[j][16].first =  parser.readString(); | ||||
| 			buildings[j][16].second = parser.readString(); | ||||
| 			parser.endLine(); | ||||
| 		} | ||||
| 	} | ||||
| 	quests[9].resize(1); | ||||
| 	quests[9][0].resize(6); | ||||
|  | ||||
| 	for (k = 0; k < 5; ++k) //Time limit | ||||
| 	{ | ||||
| 		loadToIt (quests[9][0][k], buf, it, 4); | ||||
| 	} | ||||
| 	loadToIt (quests[9][0][k], buf, it, 3); | ||||
| 	for (i = 0; i < 2; ++i) //gap description | ||||
| 		loadToIt(dump,buf,it,3); | ||||
| 	seerNames.resize(48); | ||||
| 	for (i = 0; i < 48; ++i) | ||||
| 		loadToIt(seerNames[i], buf, it, 3); | ||||
| 		CLegacyConfigParser parser("DATA/BLDGSPEC.TXT"); | ||||
|  | ||||
| 	buf = getTextFile("TENTCOLR.TXT"); | ||||
| 	itr=0; | ||||
| 	while(itr<buf.length()-1) | ||||
| 	{ | ||||
| 		std::string tmp; | ||||
| 		loadToIt(tmp, buf, itr, 3); | ||||
| 		tentColors.push_back(tmp); | ||||
| 	} | ||||
|  | ||||
| 	//campaigns | ||||
| 	buf = getTextFile ("CAMPTEXT.TXT"); | ||||
| 	it = 0; | ||||
| 	loadToIt (dump, buf, it, 3); //comment | ||||
| 	std::string nameBuf; | ||||
| 	do //map names | ||||
| 	{ | ||||
| 		loadToIt(nameBuf, buf, it, 3); | ||||
| 		if(nameBuf.size()) | ||||
| 		for(int town=0; town<GameConstants::F_NUMBER; town++) | ||||
| 		{ | ||||
| 			campaignMapNames.push_back(nameBuf); | ||||
| 		} | ||||
| 	} while (nameBuf.size()); | ||||
|  | ||||
| 	campaignRegionNames.resize(campaignMapNames.size()); //allocating space | ||||
| 	for(int g=0; g<campaignMapNames.size(); ++g) //region names | ||||
| 	{ | ||||
| 		do //dump comments and empty lines | ||||
| 		{ | ||||
| 			loadToIt(nameBuf, buf, it, 3); | ||||
| 		} while (!nameBuf.size() || nameBuf[0] != '/'); | ||||
| 		do //actual names | ||||
| 		{ | ||||
| 			loadToIt(nameBuf, buf, it, 3); | ||||
| 			if(nameBuf.size()) | ||||
| 			for(int build=0; build<9; build++) | ||||
| 			{ | ||||
| 				campaignRegionNames[g].push_back(nameBuf); | ||||
| 				buildings[town][17+build].first =  parser.readString(); | ||||
| 				buildings[town][17+build].second = parser.readString(); | ||||
| 				parser.endLine(); | ||||
| 			} | ||||
| 		} while (nameBuf.size()); | ||||
| 	} | ||||
| 			buildings[town][26].first =  parser.readString(); // Grail | ||||
| 			buildings[town][26].second = parser.readString(); | ||||
| 			parser.endLine(); | ||||
|  | ||||
| 	buf = getTextFile ("ZCREXP.TXT"); | ||||
| 	it = 0; | ||||
| 	loadToIt (dump, buf, it, 3); //comment | ||||
| 	for (int i = 0; i < 459; ++i) //some texts seem to be empty | ||||
| 			buildings[town][15].first =  parser.readString(); // Resource silo | ||||
| 			buildings[town][15].second = parser.readString(); | ||||
| 			parser.endLine(); | ||||
| 		} | ||||
| 	} | ||||
| 	{ | ||||
| 		loadToIt(dump, buf, it, 4); //description, usually useless | ||||
| 		loadToIt(nameBuf, buf, it, 3); | ||||
| 		zcrexp.push_back(nameBuf); | ||||
| 		CLegacyConfigParser parser("DATA/DWELLING.TXT"); | ||||
|  | ||||
| 		for(int town=0; town<GameConstants::F_NUMBER; town++) | ||||
| 		{ | ||||
| 			for(int build=0; build<14; build++) | ||||
| 			{ | ||||
| 				buildings[town][30+build].first =  parser.readString(); | ||||
| 				buildings[town][30+build].second = parser.readString(); | ||||
| 				parser.endLine(); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	{ | ||||
| 		CLegacyConfigParser typeParser("DATA/TOWNTYPE.TXT"); | ||||
| 		CLegacyConfigParser nameParser("DATA/TOWNNAME.TXT"); | ||||
| 		do | ||||
| 		{ | ||||
| 			townTypes.push_back(typeParser.readString()); | ||||
|  | ||||
| 			townNames.push_back(std::vector<std::string>()); | ||||
| 			for (int i=0; i<GameConstants::NAMES_PER_TOWN; i++) | ||||
| 			{ | ||||
| 				townNames.back().push_back(nameParser.readString()); | ||||
| 				nameParser.endLine(); | ||||
| 			} | ||||
| 		} | ||||
| 		while (typeParser.endLine()); | ||||
| 	} | ||||
| 	{ | ||||
| 		CLegacyConfigParser nameParser("DATA/MINENAME.TXT"); | ||||
| 		CLegacyConfigParser eventParser("DATA/MINEEVNT.TXT"); | ||||
|  | ||||
| 		do | ||||
| 		{ | ||||
| 			std::string name  = nameParser.readString(); | ||||
| 			std::string event = eventParser.readString(); | ||||
| 			mines.push_back(std::make_pair(name, event)); | ||||
| 		} | ||||
| 		while (nameParser.endLine() && eventParser.endLine()); | ||||
| 	} | ||||
| 	{ | ||||
| 		CLegacyConfigParser parser("DATA/PLCOLORS.TXT"); | ||||
| 		do | ||||
| 		{ | ||||
| 			std::string color = parser.readString(); | ||||
| 			colors.push_back(color); | ||||
|  | ||||
| 			color[0] = toupper(color[0]); | ||||
| 			capColors.push_back(color); | ||||
| 		} | ||||
| 		while (parser.endLine()); | ||||
| 	} | ||||
| 	{ | ||||
| 		CLegacyConfigParser parser("DATA/SSTRAITS.TXT"); | ||||
|  | ||||
| 		//skip header | ||||
| 		parser.endLine(); | ||||
| 		parser.endLine(); | ||||
|  | ||||
| 		do | ||||
| 		{ | ||||
| 			skillName.push_back(parser.readString()); | ||||
|  | ||||
| 			skillInfoTexts.push_back(std::vector<std::string>()); | ||||
| 			for(int j = 0; j < 3; j++) | ||||
| 				skillInfoTexts.back().push_back(parser.readString()); | ||||
| 		} | ||||
| 		while (parser.endLine()); | ||||
| 	} | ||||
| 	{ | ||||
| 		CLegacyConfigParser parser("DATA/SEERHUT.TXT"); | ||||
|  | ||||
| 		//skip header | ||||
| 		parser.endLine(); | ||||
|  | ||||
| 		while (parser.endLine()); | ||||
|  | ||||
| 		for (int i = 0; i < 6; ++i) | ||||
| 			seerEmpty.push_back(parser.readString()); | ||||
|  | ||||
| 		quests.resize(10); | ||||
| 		for (int i = 0; i < 9; ++i) //9 types of quests | ||||
| 		{ | ||||
| 			quests[i].resize(5); | ||||
| 			for (int j = 0; j < 5; ++j) | ||||
| 			{ | ||||
| 				parser.readString(); //front description | ||||
| 				for (int k = 0; k < 6; ++k) | ||||
| 					quests[i][j].push_back(parser.readString()); | ||||
|  | ||||
| 				parser.endLine(); | ||||
| 			} | ||||
| 		} | ||||
| 		quests[9].resize(1); | ||||
|  | ||||
| 		for (int k = 0; k < 6; ++k) //Time limit | ||||
| 		{ | ||||
| 			quests[9][0].push_back(parser.readString()); | ||||
| 		} | ||||
| 		parser.endLine(); | ||||
|  | ||||
| 		parser.endLine(); // empty line | ||||
| 		parser.endLine(); // header | ||||
|  | ||||
| 		for (int i = 0; i < 48; ++i) | ||||
| 		{ | ||||
| 			seerNames.push_back(parser.readString()); | ||||
| 			parser.endLine(); | ||||
| 		} | ||||
| 	} | ||||
| 	{ | ||||
| 		CLegacyConfigParser parser("DATA/CAMPTEXT.TXT"); | ||||
|  | ||||
| 		//skip header | ||||
| 		parser.endLine(); | ||||
|  | ||||
| 		std::string text; | ||||
| 		do | ||||
| 		{ | ||||
| 			text = parser.readString(); | ||||
| 			parser.endLine(); | ||||
| 			if (!text.empty()) | ||||
| 				campaignMapNames.push_back(parser.readString()); | ||||
| 		} | ||||
| 		while (parser.endLine() && !text.empty()); | ||||
|  | ||||
| 		for (size_t i=0; i<campaignMapNames.size(); i++) | ||||
| 		{ | ||||
| 			do // skip empty space and header | ||||
| 			{ | ||||
| 				text = parser.readString(); | ||||
| 			} | ||||
| 			while (parser.endLine() && text.empty()); | ||||
|  | ||||
| 			campaignRegionNames.push_back(std::vector<std::string>()); | ||||
| 			do | ||||
| 			{ | ||||
| 				text = parser.readString(); | ||||
| 				parser.endLine(); | ||||
| 				if (!text.empty()) | ||||
| 					campaignRegionNames.back().push_back(parser.readString()); | ||||
| 			} | ||||
| 			while (parser.endLine() && !text.empty()); | ||||
| 		} | ||||
| 	} | ||||
| 	{ | ||||
| 		CLegacyConfigParser parser("DATA/ZCREXP.TXT"); | ||||
| 		parser.endLine();//header | ||||
| 		do | ||||
| 		{ | ||||
| 			parser.readString(); //ignore 1st column with description | ||||
| 			zcrexp.push_back(parser.readString()); | ||||
| 		} | ||||
| 		while (parser.endLine()); | ||||
| 	} | ||||
|  | ||||
| 	std::string buffer; | ||||
| 	std::ifstream ifs(CResourceHandler::get()->getResourceName(ResourceID("config/threatlevel.txt")), std::ios::binary); | ||||
| 	getline(ifs, buf); //skip 1st line | ||||
| 	getline(ifs, buffer); //skip 1st line | ||||
| 	for (int i = 0; i < 13; ++i) | ||||
| 	{ | ||||
| 		getline(ifs, buf); | ||||
| 		threat.push_back(buf); | ||||
| 		getline(ifs, buffer); | ||||
| 		threat.push_back(buffer); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| std::string CGeneralTextHandler::getTitle(const std::string & text) | ||||
| { | ||||
| 	std::string ret; | ||||
|   | ||||
| @@ -1,7 +1,5 @@ | ||||
| #pragma once | ||||
|  | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * CGeneralTextHandler.h, part of VCMI engine | ||||
|  * | ||||
| @@ -12,8 +10,41 @@ | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| DLL_LINKAGE void loadToIt(std::string &dest, const std::string &src, int &iter, int mode); | ||||
| std::string readTo(const std::string &in, int &it, char end); | ||||
| class CInputStream; | ||||
|  | ||||
| /// Parser for any text files from H3 | ||||
| class CLegacyConfigParser | ||||
| { | ||||
| 	std::unique_ptr<char[]> data; | ||||
| 	char * curr; | ||||
| 	char * end; | ||||
|  | ||||
| 	void init(const std::unique_ptr<CInputStream> & input); | ||||
|  | ||||
| 	/// extracts part of quoted string. | ||||
| 	std::string extractQuotedPart(); | ||||
|  | ||||
| 	/// extracts quoted string. Any end of lines are ignored, double-quote is considered as "escaping" | ||||
| 	std::string extractQuotedString(); | ||||
|  | ||||
| 	/// extracts non-quoted string | ||||
| 	std::string extractNormalString(); | ||||
|  | ||||
| public: | ||||
| 	/// read one entry from current line. Return ""/0 if end of line reached | ||||
| 	std::string readString(); | ||||
| 	float readNumber(); | ||||
|  | ||||
| 	/// returns true if next entry is empty | ||||
| 	bool isNextEntryEmpty(); | ||||
|  | ||||
| 	/// end current line | ||||
| 	bool endLine(); | ||||
|  | ||||
| 	CLegacyConfigParser(std::string URI); | ||||
| 	CLegacyConfigParser(const std::unique_ptr<CInputStream> & input); | ||||
| }; | ||||
|  | ||||
| class DLL_LINKAGE CGeneralTextHandler //Handles general texts | ||||
| { | ||||
| public: | ||||
| @@ -49,8 +80,8 @@ public: | ||||
| 	std::map<int, std::map<int, std::pair<std::string, std::string> > > buildings; //map[town id][building id] => pair<name, description> | ||||
|  | ||||
| 	std::vector<std::pair<std::string,std::string> > zelp; | ||||
| 	std::string lossCondtions[4]; | ||||
| 	std::string victoryConditions[14]; | ||||
| 	std::vector<std::string> lossCondtions; | ||||
| 	std::vector<std::string> victoryConditions; | ||||
|  | ||||
| 	//objects | ||||
| 	std::vector<std::string> names; //vector of objects; i-th object in vector has subnumber i | ||||
|   | ||||
| @@ -1,14 +1,13 @@ | ||||
| #include "StdInc.h" | ||||
| #include "CHeroHandler.h" | ||||
|  | ||||
| #include "CGeneralTextHandler.h" | ||||
| #include "Filesystem/CResourceLoader.h" | ||||
| #include "../lib/VCMI_Lib.h" | ||||
| #include "../lib/JsonNode.h" | ||||
| #include "VCMI_Lib.h" | ||||
| #include "JsonNode.h" | ||||
| #include "GameConstants.h" | ||||
| #include <boost/version.hpp> | ||||
| #include "BattleHex.h" | ||||
|  | ||||
| void loadToIt(std::string &dest, const std::string &src, int &iter, int mode); | ||||
| /* | ||||
|  * CHeroHandler.cpp, part of VCMI engine | ||||
|  * | ||||
| @@ -114,7 +113,6 @@ void CHeroHandler::loadObstacles() | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
|  | ||||
| 	const JsonNode config(ResourceID("config/obstacles.json")); | ||||
| 	loadObstacles(config["obstacles"], false, obstacles); | ||||
| 	loadObstacles(config["absoluteObstacles"], true, absoluteObstacles); | ||||
| @@ -164,68 +162,27 @@ void CHeroHandler::loadPuzzleInfo() | ||||
| void CHeroHandler::loadHeroes() | ||||
| { | ||||
| 	VLC->heroh = this; | ||||
| 	auto textFile = CResourceHandler::get()->loadData(ResourceID("DATA/HOTRAITS.TXT")); | ||||
| 	std::string buf((char*)textFile.first.get(), textFile.second); | ||||
| 	int it=0; | ||||
| 	std::string dump; | ||||
| 	for(int i=0; i<2; ++i) | ||||
| 	{ | ||||
| 		loadToIt(dump,buf,it,3); | ||||
| 	} | ||||
| 	CLegacyConfigParser parser("DATA/HOTRAITS.TXT"); | ||||
|  | ||||
| 	int numberOfCurrentClassHeroes = 0; | ||||
| 	int currentClass = 0; | ||||
| 	int additHero = 0; | ||||
| 	CHero::EHeroClasses addTab[12]; | ||||
| 	addTab[0] = CHero::KNIGHT; | ||||
| 	addTab[1] = CHero::WITCH; | ||||
| 	addTab[2] = CHero::KNIGHT; | ||||
| 	addTab[3] = CHero::WIZARD; | ||||
| 	addTab[4] = CHero::RANGER; | ||||
| 	addTab[5] = CHero::BARBARIAN; | ||||
| 	addTab[6] = CHero::DEATHKNIGHT; | ||||
| 	addTab[7] = CHero::WARLOCK; | ||||
| 	addTab[8] = CHero::KNIGHT; | ||||
| 	addTab[9] = CHero::WARLOCK; | ||||
| 	addTab[10] = CHero::BARBARIAN; | ||||
| 	addTab[11] = CHero::DEMONIAC; | ||||
| 	parser.endLine(); //ignore header | ||||
| 	parser.endLine(); | ||||
|  | ||||
| 	 | ||||
| 	for (int i=0; i<GameConstants::HEROES_QUANTITY; i++) | ||||
| 	{ | ||||
| 		CHero * nher = new CHero; | ||||
| 		if(currentClass<18) | ||||
| 		{ | ||||
| 			nher->heroType = static_cast<CHero::EHeroClasses>(currentClass); | ||||
| 			++numberOfCurrentClassHeroes; | ||||
| 			if(numberOfCurrentClassHeroes==8) | ||||
| 			{ | ||||
| 				numberOfCurrentClassHeroes = 0; | ||||
| 				++currentClass; | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			nher->heroType = addTab[additHero++]; | ||||
| 		} | ||||
|  | ||||
| 		std::string pom ; | ||||
| 		loadToIt(nher->name,buf,it,4); | ||||
| 		CHero * hero = new CHero; | ||||
| 		hero->name = parser.readString(); | ||||
|  | ||||
| 		for(int x=0;x<3;x++) | ||||
| 		{ | ||||
| 			loadToIt(pom,buf,it,4); | ||||
| 			nher->lowStack[x] = atoi(pom.c_str()); | ||||
| 			loadToIt(pom,buf,it,4); | ||||
| 			nher->highStack[x] = atoi(pom.c_str()); | ||||
| 			loadToIt(nher->refTypeStack[x],buf,it,(x==2) ? (3) : (4)); | ||||
| 			int hlp = nher->refTypeStack[x].find_first_of(' ',0); | ||||
| 			if(hlp>=0) | ||||
| 				nher->refTypeStack[x].replace(hlp,1,""); | ||||
| 			hero->lowStack[x] = parser.readNumber(); | ||||
| 			hero->highStack[x] = parser.readNumber(); | ||||
| 			hero->refTypeStack[x] = parser.readString(); | ||||
| 			boost::algorithm::replace_all(hero->refTypeStack[x], " ", ""); //remove spaces | ||||
| 		} | ||||
| 	 | ||||
| 		nher->ID = heroes.size(); | ||||
| 		heroes.push_back(nher); | ||||
| 		parser.endLine(); | ||||
|  | ||||
| 		hero->ID = heroes.size(); | ||||
| 		heroes.push_back(hero); | ||||
| 	} | ||||
|  | ||||
| 	// Load heroes information | ||||
| @@ -236,6 +193,7 @@ void CHeroHandler::loadHeroes() | ||||
|  | ||||
| 		// sex: 0=male, 1=female | ||||
| 		heroes[hid]->sex = !!hero["female"].Bool(); | ||||
| 		heroes[hid]->heroType = CHero::EHeroClasses(hero["class"].Float()); | ||||
|  | ||||
| 		BOOST_FOREACH(const JsonNode &set, hero["skill_set"].Vector()) { | ||||
| 			heroes[hid]->secSkillsInit.push_back(std::make_pair(set["skill"].Float(), set["level"].Float())); | ||||
| @@ -246,18 +204,16 @@ void CHeroHandler::loadHeroes() | ||||
| 			heroes[hid]->startingSpell = value->Float(); | ||||
| 		} | ||||
|  | ||||
| 		value = &hero["specialties"]; | ||||
| 		if (!value->isNull()) { | ||||
| 			BOOST_FOREACH(const JsonNode &specialty, value->Vector()) { | ||||
| 				SSpecialtyInfo dummy; | ||||
| 		BOOST_FOREACH(const JsonNode &specialty, hero["specialties"].Vector()) | ||||
| 		{ | ||||
| 			SSpecialtyInfo dummy; | ||||
|  | ||||
| 				dummy.type = specialty["type"].Float(); | ||||
| 				dummy.val = specialty["val"].Float(); | ||||
| 				dummy.subtype = specialty["subtype"].Float(); | ||||
| 				dummy.additionalinfo = specialty["info"].Float(); | ||||
| 			dummy.type = specialty["type"].Float(); | ||||
| 			dummy.val = specialty["val"].Float(); | ||||
| 			dummy.subtype = specialty["subtype"].Float(); | ||||
| 			dummy.additionalinfo = specialty["info"].Float(); | ||||
|  | ||||
| 				heroes[hid]->spec.push_back(dummy); //put a copy of dummy | ||||
| 			} | ||||
| 			heroes[hid]->spec.push_back(dummy); //put a copy of dummy | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -285,98 +241,74 @@ void CHeroHandler::loadHeroes() | ||||
| 	} | ||||
| 	expPerLevel.pop_back();//last value is broken | ||||
|  | ||||
| 	//ballistics info | ||||
| 	textFile = CResourceHandler::get()->loadData(ResourceID("DATA/BALLIST.TXT")); | ||||
| 	buf = std::string((char*)textFile.first.get(), textFile.second); | ||||
| 	it = 0; | ||||
| 	for(int i=0; i<22; ++i) | ||||
| 	{ | ||||
| 		loadToIt(dump,buf,it,4); | ||||
| 	} | ||||
| 	for(int lvl=0; lvl<4; ++lvl) | ||||
| 	CLegacyConfigParser ballParser("DATA/BALLIST.TXT"); | ||||
|  | ||||
| 	ballParser.endLine(); //header | ||||
| 	ballParser.endLine(); | ||||
|  | ||||
| 	do | ||||
| 	{ | ||||
| 		ballParser.readString(); | ||||
| 		ballParser.readString(); | ||||
|  | ||||
| 		CHeroHandler::SBallisticsLevelInfo bli; | ||||
| 		si32 tempNum; | ||||
| 		loadToIt(tempNum,buf,it,4); | ||||
| 		bli.keep = tempNum; | ||||
| 		loadToIt(tempNum,buf,it,4); | ||||
| 		bli.tower = tempNum; | ||||
| 		loadToIt(tempNum,buf,it,4); | ||||
| 		bli.gate = tempNum; | ||||
| 		loadToIt(tempNum,buf,it,4); | ||||
| 		bli.wall = tempNum; | ||||
| 		loadToIt(tempNum,buf,it,4); | ||||
| 		bli.shots = tempNum; | ||||
| 		loadToIt(tempNum,buf,it,4); | ||||
| 		bli.noDmg = tempNum; | ||||
| 		loadToIt(tempNum,buf,it,4); | ||||
| 		bli.oneDmg = tempNum; | ||||
| 		loadToIt(tempNum,buf,it,4); | ||||
| 		bli.twoDmg = tempNum; | ||||
| 		loadToIt(tempNum,buf,it,4); | ||||
| 		bli.sum = tempNum; | ||||
| 		if(lvl!=3) | ||||
| 		{ | ||||
| 			loadToIt(dump,buf,it,4); | ||||
| 		} | ||||
| 		bli.keep   = ballParser.readNumber(); | ||||
| 		bli.tower  = ballParser.readNumber(); | ||||
| 		bli.gate   = ballParser.readNumber(); | ||||
| 		bli.wall   = ballParser.readNumber(); | ||||
| 		bli.shots  = ballParser.readNumber(); | ||||
| 		bli.noDmg  = ballParser.readNumber(); | ||||
| 		bli.oneDmg = ballParser.readNumber(); | ||||
| 		bli.twoDmg = ballParser.readNumber(); | ||||
| 		bli.sum    = ballParser.readNumber(); | ||||
| 		ballistics.push_back(bli); | ||||
| 	} | ||||
| 	while (ballParser.endLine()); | ||||
| } | ||||
|  | ||||
| void CHeroHandler::loadHeroClasses() | ||||
| { | ||||
| 	auto textFile = CResourceHandler::get()->loadData(ResourceID("DATA/HCTRAITS.TXT")); | ||||
| 	std::istringstream str(std::string((char*)textFile.first.get(), textFile.second)); //we'll be reading from it | ||||
| 	const int BUFFER_SIZE = 5000; | ||||
| 	char buffer[BUFFER_SIZE+1]; | ||||
| 	CLegacyConfigParser parser("DATA/HCTRAITS.TXT"); | ||||
|  | ||||
| 	for(int i=0; i<3; ++i) str.getline(buffer, BUFFER_SIZE); //omitting rubbish | ||||
| 	parser.endLine(); // header | ||||
| 	parser.endLine(); | ||||
|  | ||||
|  | ||||
| 	for(int ss=0; ss<18; ++ss) //18 classes of hero (including conflux) | ||||
| 	do | ||||
| 	{ | ||||
| 		CHeroClass * hc = new CHeroClass; | ||||
| 		hc->alignment = ss / 6; | ||||
| 		hc->alignment = heroClasses.size() / 6; | ||||
|  | ||||
| 		char name[BUFFER_SIZE+1]; | ||||
| 		str.get(name, BUFFER_SIZE, '\t'); | ||||
| 		hc->name = name; | ||||
| 		//workaround for locale issue (different localisations use different decimal separator) | ||||
| 		int intPart,fracPart; | ||||
| 		str >> intPart; | ||||
| 		str.ignore();//ignore decimal separator | ||||
| 		str >> fracPart; | ||||
| 		hc->aggression = intPart + fracPart/100.0; | ||||
| 		 | ||||
| 		str >> hc->initialAttack; | ||||
| 		str >> hc->initialDefence; | ||||
| 		str >> hc->initialPower; | ||||
| 		str >> hc->initialKnowledge; | ||||
| 		hc->name             = parser.readString(); | ||||
| 		hc->aggression       = parser.readNumber(); | ||||
| 		hc->initialAttack    = parser.readNumber(); | ||||
| 		hc->initialDefence   = parser.readNumber(); | ||||
| 		hc->initialPower     = parser.readNumber(); | ||||
| 		hc->initialKnowledge = parser.readNumber(); | ||||
|  | ||||
| 		hc->primChance.resize(GameConstants::PRIMARY_SKILLS); | ||||
| 		for(int x=0; x<GameConstants::PRIMARY_SKILLS; ++x) | ||||
| 		{ | ||||
| 			str >> hc->primChance[x].first; | ||||
| 			hc->primChance[x].first = parser.readNumber(); | ||||
| 		} | ||||
| 		for(int x=0; x<GameConstants::PRIMARY_SKILLS; ++x) | ||||
| 		{ | ||||
| 			str >> hc->primChance[x].second; | ||||
| 			hc->primChance[x].second = parser.readNumber(); | ||||
| 		} | ||||
|  | ||||
| 		hc->proSec.resize(GameConstants::SKILL_QUANTITY); | ||||
| 		for(int dd=0; dd<GameConstants::SKILL_QUANTITY; ++dd) | ||||
| 		{ | ||||
| 			str >> hc->proSec[dd]; | ||||
| 			hc->proSec[dd] = parser.readNumber(); | ||||
| 		} | ||||
|  | ||||
| 		for(int dd=0; dd<ARRAY_COUNT(hc->selectionProbability); ++dd) | ||||
| 		{ | ||||
| 			str >> hc->selectionProbability[dd]; | ||||
| 			hc->selectionProbability[dd] = parser.readNumber(); | ||||
| 		} | ||||
|  | ||||
| 		heroClasses.push_back(hc); | ||||
| 		str.getline(buffer, BUFFER_SIZE); //removing end of line characters | ||||
| 	} | ||||
| 	while (parser.endLine() && !parser.isNextEntryEmpty()); | ||||
| } | ||||
|  | ||||
| void CHeroHandler::initHeroClasses() | ||||
|   | ||||
| @@ -43,7 +43,6 @@ using namespace boost::assign; | ||||
| std::map<int,std::map<int, std::vector<int> > > CGTeleport::objs; | ||||
| std::vector<std::pair<int, int> > CGTeleport::gates; | ||||
| IGameCallback * IObjectInterface::cb = NULL; | ||||
| DLL_LINKAGE void loadToIt(std::string &dest, const std::string &src, int &iter, int mode); | ||||
| extern boost::rand48 ran; | ||||
| std::map <ui8, std::set <ui8> > CGKeys::playerKeyMap; | ||||
| std::map <si32, std::vector<si32> > CGMagi::eyelist; | ||||
|   | ||||
| @@ -1,9 +1,10 @@ | ||||
| #include "StdInc.h" | ||||
| #include "CSpellHandler.h" | ||||
|  | ||||
| #include "CGeneralTextHandler.h" | ||||
| #include "Filesystem/CResourceLoader.h" | ||||
| #include "../lib/VCMI_Lib.h" | ||||
| #include "../lib/JsonNode.h" | ||||
| #include "VCMI_Lib.h" | ||||
| #include "JsonNode.h" | ||||
| #include <cctype> | ||||
| #include "GameConstants.h" | ||||
| #include "BattleHex.h" | ||||
| @@ -255,11 +256,6 @@ bool CSpell::isRisingSpell() const | ||||
| 	return vstd::contains(VLC->spellh->risingSpells, id); | ||||
| } | ||||
|  | ||||
| static bool startsWithX(const std::string &s) | ||||
| { | ||||
| 	return s.size() && s[0] == 'x'; | ||||
| } | ||||
|  | ||||
| bool DLL_LINKAGE isInScreenRange(const int3 ¢er, const int3 &pos) | ||||
| { | ||||
| 	int3 diff = pos - center; | ||||
| @@ -269,83 +265,82 @@ bool DLL_LINKAGE isInScreenRange(const int3 ¢er, const int3 &pos) | ||||
| 		return false; | ||||
| } | ||||
|  | ||||
| CSpell * CSpellHandler::loadSpell(CLegacyConfigParser & parser) | ||||
| { | ||||
| 	CSpell * spell = new CSpell; //new currently being read spell | ||||
|  | ||||
| 	spell->name    = parser.readString(); | ||||
| 	spell->abbName = parser.readString(); | ||||
| 	spell->level   = parser.readNumber(); | ||||
| 	spell->earth   = parser.readString() == "x"; | ||||
| 	spell->water   = parser.readString() == "x"; | ||||
| 	spell->fire    = parser.readString() == "x"; | ||||
| 	spell->air     = parser.readString() == "x"; | ||||
|  | ||||
| 	for (int i = 0; i < 4 ; i++) | ||||
| 		spell->costs.push_back(parser.readNumber()); | ||||
|  | ||||
| 	spell->power = parser.readNumber(); | ||||
| 	for (int i = 0; i < 4 ; i++) | ||||
| 		spell->powers.push_back(parser.readNumber()); | ||||
|  | ||||
| 	for (int i = 0; i < 9 ; i++) | ||||
| 		spell->probabilities.push_back(parser.readNumber()); | ||||
|  | ||||
| 	for (int i = 0; i < 4 ; i++) | ||||
| 		spell->AIVals.push_back(parser.readNumber()); | ||||
|  | ||||
| 	for (int i = 0; i < 4 ; i++) | ||||
| 		spell->descriptions.push_back(parser.readString()); | ||||
|  | ||||
| 	spell->attributes = parser.readString(); | ||||
| 	spell->mainEffectAnim = -1; | ||||
| 	return spell; | ||||
| } | ||||
|  | ||||
| void CSpellHandler::loadSpells() | ||||
| { | ||||
| 	auto textFile = CResourceHandler::get()->loadData(ResourceID("DATA/SPTRAITS.TXT")); | ||||
| 	std::string buf((char*)textFile.first.get(), textFile.second); | ||||
| 	CLegacyConfigParser parser("DATA/SPTRAITS.TXT"); | ||||
|  | ||||
| 	std::string pom; | ||||
| 	int andame = buf.size(), i=0; //buf iterator | ||||
| 	for(int z=0; z<5; ++z) | ||||
| 		loadToIt(pom,buf,i,3); | ||||
| 	for(int i=0; i<5; i++) // header | ||||
| 		parser.endLine(); | ||||
|  | ||||
| 	bool combSpells=false; //true, if we are reading combat spells | ||||
| 	bool creatureAbility=false; //if true, only creature can use this spell | ||||
| 	int ifHit = 0; | ||||
| 	while(i<andame) | ||||
| 	do //read adventure map spells | ||||
| 	{ | ||||
| 		if(spells.size()==81) | ||||
| 			break; | ||||
| 		CSpell * nsp = new CSpell; //new currently being read spell | ||||
|  | ||||
| 		loadToIt(nsp->name,buf,i,4); | ||||
| 		if(nsp->name == std::string("")) | ||||
| 		{ | ||||
| 			if(ifHit == 0) | ||||
| 			{ | ||||
| 				combSpells = true; | ||||
| 			} | ||||
| 			if(ifHit == 1) | ||||
| 			{ | ||||
| 				creatureAbility = true; | ||||
| 			} | ||||
| 			for(int z=0; z<3; ++z) | ||||
| 				loadToIt(pom,buf,i,3); | ||||
| 			loadToIt(nsp->name,buf,i,4); | ||||
| 			++ifHit; | ||||
| 		} | ||||
|  | ||||
| 		loadToIt(nsp->abbName,buf,i,4); | ||||
| 		loadToIt(nsp->level,buf,i,4); | ||||
| 		loadToIt(pom,buf,i,4); | ||||
| 		nsp->earth = startsWithX(pom); | ||||
| 		loadToIt(pom,buf,i,4); | ||||
| 		nsp->water = startsWithX(pom); | ||||
| 		loadToIt(pom,buf,i,4); | ||||
| 		nsp->fire = startsWithX(pom); | ||||
| 		loadToIt(pom,buf,i,4); | ||||
| 		nsp->air = startsWithX(pom); | ||||
|  | ||||
| 		nsp->costs.resize(4); | ||||
| 		for (int z = 0; z < 4 ; z++) | ||||
| 			loadToIt(nsp->costs[z],buf,i,4); | ||||
| 		loadToIt(nsp->power,buf,i,4); | ||||
| 		nsp->powers.resize(4); | ||||
| 		for (int z = 0; z < 4 ; z++) | ||||
| 			loadToIt(nsp->powers[z],buf,i,4); | ||||
|  | ||||
| 		nsp->probabilities.resize(9); | ||||
| 		for (int z = 0; z < 9 ; z++) | ||||
| 			loadToIt(nsp->probabilities[z],buf,i,4); | ||||
|  | ||||
| 		nsp->AIVals.resize(4); | ||||
| 		for (int z = 0; z < 4 ; z++) | ||||
| 			loadToIt(nsp->AIVals[z],buf,i,4); | ||||
|  | ||||
| 		nsp->descriptions.resize(4); | ||||
| 		for (int z = 0; z < 4 ; z++) | ||||
| 		{ | ||||
| 			loadToIt(nsp->descriptions[z],buf,i,4); | ||||
| 			boost::algorithm::replace_all(nsp->descriptions[z],"\"",""); | ||||
| 		} | ||||
|  | ||||
| 		loadToIt(nsp->attributes,buf,i,3); | ||||
| 		nsp->id = spells.size(); | ||||
| 		nsp->combatSpell = combSpells; | ||||
| 		nsp->creatureAbility = creatureAbility; | ||||
| 		nsp->mainEffectAnim = -1; | ||||
| 		spells.push_back(nsp); | ||||
| 		CSpell * spell = loadSpell(parser); | ||||
| 		spell->id = spells.size(); | ||||
| 		spell->combatSpell = false; | ||||
| 		spell->creatureAbility = false; | ||||
| 		spells.push_back(spell); | ||||
| 	} | ||||
| 	while (parser.endLine() && !parser.isNextEntryEmpty()); | ||||
|  | ||||
| 	for(int i=0; i<3; i++) | ||||
| 		parser.endLine(); | ||||
|  | ||||
| 	do //read battle spells | ||||
| 	{ | ||||
| 		CSpell * spell = loadSpell(parser); | ||||
| 		spell->id = spells.size(); | ||||
| 		spell->combatSpell = true; | ||||
| 		spell->creatureAbility = false; | ||||
| 		spells.push_back(spell); | ||||
| 	} | ||||
| 	while (parser.endLine() && !parser.isNextEntryEmpty()); | ||||
|  | ||||
| 	for(int i=0; i<3; i++) | ||||
| 		parser.endLine(); | ||||
|  | ||||
| 	do //read creature abilities | ||||
| 	{ | ||||
| 		CSpell * spell = loadSpell(parser); | ||||
| 		spell->id = spells.size(); | ||||
| 		spell->combatSpell = true; | ||||
| 		spell->creatureAbility = true; | ||||
| 		spells.push_back(spell); | ||||
| 	} | ||||
| 	while (parser.endLine() && !parser.isNextEntryEmpty()); | ||||
|  | ||||
| 	boost::replace_first (spells[47]->attributes, "2", ""); // disrupting ray will now affect single creature | ||||
|  | ||||
| 	//loading of additional spell traits | ||||
|   | ||||
| @@ -14,6 +14,7 @@ | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| class CLegacyConfigParser; | ||||
| struct BattleHex; | ||||
|  | ||||
| class DLL_LINKAGE CSpell | ||||
| @@ -86,6 +87,8 @@ bool DLL_LINKAGE isInScreenRange(const int3 ¢er, const int3 &pos); //for spe | ||||
|  | ||||
| class DLL_LINKAGE CSpellHandler | ||||
| { | ||||
| 	CSpell * loadSpell(CLegacyConfigParser & parser); | ||||
|  | ||||
| public: | ||||
| 	CSpellHandler(); | ||||
| 	std::vector< ConstTransitivePtr<CSpell> > spells; | ||||
|   | ||||
| @@ -173,6 +173,10 @@ void CResourceLoader::addLoader(std::string mountPoint, shared_ptr<ISimpleResour | ||||
| 		// Create identifier and locator and add them to the resources list | ||||
| 		ResourceID ident(mountPoint, entry.first.getName(), entry.first.getType()); | ||||
| 		ResourceLocator locator(loader.get(), entry.second); | ||||
|  | ||||
| 		if (ident.getType() == EResType::OTHER) | ||||
| 			tlog5 << "Warning: unknown file type: " << entry.second << "\n"; | ||||
|  | ||||
| 		resources[ident].push_back(locator); | ||||
| 	} | ||||
| } | ||||
|   | ||||
							
								
								
									
										115
									
								
								lib/VCMI_Lib.cpp
									
									
									
									
									
								
							
							
						
						
									
										115
									
								
								lib/VCMI_Lib.cpp
									
									
									
									
									
								
							| @@ -44,121 +44,6 @@ DLL_LINKAGE void initDLL(CConsoleHandler *Console, std::ostream *Logfile) | ||||
| 	//HANDLE_EXCEPTION; | ||||
| } | ||||
|  | ||||
| DLL_LINKAGE void loadToIt(std::string &dest, const std::string &src, int &iter, int mode) | ||||
| { | ||||
| 	switch(mode) | ||||
| 	{ | ||||
| 	case 0: | ||||
| 		{ | ||||
| 			int hmcr = 0; | ||||
| 			for(; iter<src.size(); ++iter) | ||||
| 			{ | ||||
| 				if(src[iter]=='\t') | ||||
| 					++hmcr; | ||||
| 				if(hmcr==1) | ||||
| 					break; | ||||
| 			} | ||||
| 			++iter; | ||||
|  | ||||
| 			int befi=iter; | ||||
| 			for(; iter<src.size(); ++iter) | ||||
| 			{ | ||||
| 				if(src[iter]=='\t') | ||||
| 					break; | ||||
| 			} | ||||
| 			dest = src.substr(befi, iter-befi); | ||||
| 			++iter; | ||||
|  | ||||
| 			hmcr = 0; | ||||
| 			for(; iter<src.size(); ++iter) | ||||
| 			{ | ||||
| 				if(src[iter]=='\r') | ||||
| 					++hmcr; | ||||
| 				if(hmcr==1) | ||||
| 					break; | ||||
| 			} | ||||
| 			iter+=2; | ||||
| 			break; | ||||
| 		} | ||||
| 	case 1: | ||||
| 		{ | ||||
| 			int hmcr = 0; | ||||
| 			for(; iter<src.size(); ++iter) | ||||
| 			{ | ||||
| 				if(src[iter]=='\t') | ||||
| 					++hmcr; | ||||
| 				if(hmcr==1) | ||||
| 					break; | ||||
| 			} | ||||
| 			++iter; | ||||
|  | ||||
| 			int befi=iter; | ||||
| 			for(; iter<src.size(); ++iter) | ||||
| 			{ | ||||
| 				if(src[iter]=='\r') | ||||
| 					break; | ||||
| 			} | ||||
| 			dest = src.substr(befi, iter-befi); | ||||
| 			iter+=2; | ||||
| 			break; | ||||
| 		} | ||||
| 	case 2: | ||||
| 		{ | ||||
| 			int befi=iter; | ||||
| 			for(; iter<src.size(); ++iter) | ||||
| 			{ | ||||
| 				if(src[iter]=='\t') | ||||
| 					break; | ||||
| 			} | ||||
| 			dest = src.substr(befi, iter-befi); | ||||
| 			++iter; | ||||
|  | ||||
| 			int hmcr = 0; | ||||
| 			for(; iter<src.size(); ++iter) | ||||
| 			{ | ||||
| 				if(src[iter]=='\r') | ||||
| 					++hmcr; | ||||
| 				if(hmcr==1) | ||||
| 					break; | ||||
| 			} | ||||
| 			iter+=2; | ||||
| 			break; | ||||
| 		} | ||||
| 	case 3: | ||||
| 		{ | ||||
| 			int befi=iter; | ||||
| 			for(; iter<src.size(); ++iter) | ||||
| 			{ | ||||
| 				if(src[iter]=='\r') | ||||
| 					break; | ||||
| 			} | ||||
| 			dest = src.substr(befi, iter-befi); | ||||
| 			iter+=2; | ||||
| 			break; | ||||
| 		} | ||||
| 	case 4: | ||||
| 		{ | ||||
| 			int befi=iter; | ||||
| 			for(; iter<src.size(); ++iter) | ||||
| 			{ | ||||
| 				if(src[iter]=='\t') | ||||
| 					break; | ||||
| 			} | ||||
| 			dest = src.substr(befi, iter-befi); | ||||
| 			iter++; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| DLL_LINKAGE void loadToIt(si32 &dest, const std::string &src, int &iter, int mode) | ||||
| { | ||||
| 	std::string pom; | ||||
| 	loadToIt(pom,src,iter,mode); | ||||
| 	dest = atol(pom.c_str()); | ||||
| } | ||||
|  | ||||
| void LibClasses::loadFilesystem() | ||||
| { | ||||
| 	CStopWatch totalTime; | ||||
|   | ||||
| @@ -58,6 +58,4 @@ public: | ||||
|  | ||||
| extern DLL_LINKAGE LibClasses * VLC; | ||||
|  | ||||
| DLL_LINKAGE void loadToIt(std::string &dest, const std::string &src, int &iter, int mode); | ||||
| DLL_LINKAGE void loadToIt(si32 &dest, const std::string &src, int &iter, int mode); | ||||
| DLL_LINKAGE void initDLL(CConsoleHandler *Console, std::ostream *Logfile); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user