1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00
vcmi/lib/CBuildingHandler.cpp
2012-08-07 21:46:24 +00:00

221 lines
6.2 KiB
C++

#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);
}
}
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
}