| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 | #include "StdInc.h"#include "CBuildingHandler.h"#include "CGeneralTextHandler.h"#include "../lib/Filesystem/CResourceLoader.h"#include "../lib/VCMI_Lib.h"#include "../lib/JsonNode.h"#include "GameConstants.h"/* * CBuildingHandler.cpp, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * * License: GNU General Public License v2.0 or later * Full text of license available in license.txt file, in main folder * */static ui32 readNr(std::string &in, int &it){	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...");	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;}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	buildings.resize(GameConstants::F_NUMBER);	for(int i=0;i<GameConstants::F_NUMBER;i++)	{		temp = readTo(buf,it,'\n');//read blank line and faction name		temp = readTo(buf,it,'\n');		for(int bg = 0; bg<9; bg++)		{			CBuilding *nb = readBg(buf,it);			nb->tid = i;			nb->bid = bg+17;			buildings[i][bg+17] = nb;		}	}	//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++)	{		CBuilding *nb = readBg(buf,it);		for(int f=0;f<GameConstants::F_NUMBER;f++)		{			buildings[f][bg] = new CBuilding(*nb);			buildings[f][bg]->tid = f;			buildings[f][bg]->bid = bg;		}		delete nb;	}	//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"));	BOOST_FOREACH(const JsonNode &town, config["town"].Vector())	{		int tid = town["id"].Float();		hall[tid].first = town["image"].String();		(hall[tid].second).resize(5); //rows		int row_num = 0;		BOOST_FOREACH(const JsonNode &row, town["boxes"].Vector())		{			BOOST_FOREACH(const JsonNode &box, row.Vector())			{				(hall[tid].second)[row_num].push_back(std::vector<int>()); //push new box				std::vector<int> &box_vec = (hall[tid].second)[row_num].back();				BOOST_FOREACH(const JsonNode &value, box.Vector())				{					box_vec.push_back(value.Float());				}			}			row_num ++;		}		assert (row_num == 5);	}	// Buildings dependencies. Which building depend on which other building.	const JsonNode buildingsConf(ResourceID("config/buildings.json"));	// Iterate for each city type	int townID = 0;	BOOST_FOREACH(const JsonNode &town_node, buildingsConf["town_type"].Vector())	{		BOOST_FOREACH(const JsonNode &node, town_node["building_requirements"].Vector())		{			int id = node["id"].Float();			CBuilding * build = buildings[townID][id];			if (build)			{				BOOST_FOREACH(const JsonNode &building, node["requires"].Vector())				{					build->requirements.insert(building.Float());				}			}		}		townID++;	}}CBuildingHandler::~CBuildingHandler(){	for(std::vector< bmap<int, ConstTransitivePtr<CBuilding> > >::iterator i=buildings.begin(); i!=buildings.end(); i++)		for(std::map<int, ConstTransitivePtr<CBuilding> >::iterator j=i->begin(); j!=i->end(); j++)			j->second.dellNull();}static std::string emptyStr = "";const std::string & CBuilding::Name() const{	if(name.length())		return name;	else if(vstd::contains(VLC->generaltexth->buildings,tid) && vstd::contains(VLC->generaltexth->buildings[tid],bid))		return VLC->generaltexth->buildings[tid][bid].first;	tlog2 << "Warning: Cannot find name text for building " << bid << "for " << tid << "town.\n";	return emptyStr;}const std::string & CBuilding::Description() const{	if(description.length())		return description;	else if(vstd::contains(VLC->generaltexth->buildings,tid) && vstd::contains(VLC->generaltexth->buildings[tid],bid))		return VLC->generaltexth->buildings[tid][bid].second;	tlog2 << "Warning: Cannot find description text for building " << bid << "for " << tid << "town.\n";	return emptyStr;}CBuilding::CBuilding( int TID, int BID ){	tid = TID;	bid = BID;}int CBuildingHandler::campToERMU( int camp, int townType, std::set<si32> builtBuildings ){	using namespace boost::assign;	static const std::vector<int> campToERMU = list_of(11)(12)(13)(7)(8)(9)(5)(16)(14)(15)(-1)(0)(1)(2)(3)(4)		(6)(26)(17)(21)(22)(23)		; //creature generators with banks - handled separately	if (camp < campToERMU.size())	{		return campToERMU[camp];	}	static const std::vector<int> hordeLvlsPerTType[GameConstants::F_NUMBER] = {list_of(2), list_of(1), list_of(1)(4), list_of(0)(2),		list_of(0), list_of(0), list_of(0), list_of(0), list_of(0)};	int curPos = campToERMU.size();	for (int i=0; i<7; ++i)	{		if(camp == curPos) //non-upgraded			return 30 + i;		curPos++;		if(camp == curPos) //upgraded			return 37 + i;		curPos++;		//horde building		if (vstd::contains(hordeLvlsPerTType[townType], i))		{			if (camp == curPos)			{				if (hordeLvlsPerTType[townType][0] == i)				{					if(vstd::contains(builtBuildings, 37 + hordeLvlsPerTType[townType][0])) //if upgraded dwelling is built						return 19;					else //upgraded dwelling not presents						return 18;				}				else				{					if(hordeLvlsPerTType[townType].size() > 1)					{						if(vstd::contains(builtBuildings, 37 + hordeLvlsPerTType[townType][1])) //if upgraded dwelling is built							return 25;						else //upgraded dwelling not presents							return 24;					}				}			}			curPos++;		}	}	assert(0);	return -1; //not found}
 |