CBuildingHandler.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. #include "StdInc.h"
  2. #include "CBuildingHandler.h"
  3. #include "CGeneralTextHandler.h"
  4. #include "../lib/Filesystem/CResourceLoader.h"
  5. #include "../lib/VCMI_Lib.h"
  6. #include "../lib/JsonNode.h"
  7. #include "GameConstants.h"
  8. /*
  9. * CBuildingHandler.cpp, part of VCMI engine
  10. *
  11. * Authors: listed in file AUTHORS in main folder
  12. *
  13. * License: GNU General Public License v2.0 or later
  14. * Full text of license available in license.txt file, in main folder
  15. *
  16. */
  17. static ui32 readNr(std::string &in, int &it)
  18. {
  19. int last=it;
  20. for(;last<in.size();last++)
  21. if(in[last]=='\t' || in[last]=='\n' || in[last]==' ' || in[last]=='\r' || in[last]=='\n')
  22. break;
  23. if(last==in.size())
  24. throw std::runtime_error("Cannot read number...");
  25. std::istringstream ss(in.substr(it,last-it));
  26. it+=(1+last-it);
  27. ss >> last;
  28. return last;
  29. }
  30. static CBuilding * readBg(std::string &buf, int& it)
  31. {
  32. CBuilding * nb = new CBuilding();
  33. for(int res=0;res<7;res++)
  34. nb->resources[res] = readNr(buf,it);
  35. /*nb->refName = */readTo(buf,it,'\n');
  36. //reference name is omitted, it's seems to be useless
  37. return nb;
  38. }
  39. void CBuildingHandler::loadBuildings()
  40. {
  41. auto textFile = CResourceHandler::get()->loadData(ResourceID("DATA/BUILDING.TXT"));
  42. std::string buf((char*)textFile.first.get(), textFile.second);
  43. std::string temp;
  44. int it=0; //buf iterator
  45. temp = readTo(buf,it,'\n');temp = readTo(buf,it,'\n');//read 2 lines of file info
  46. //read 9 special buildings for every faction
  47. buildings.resize(GameConstants::F_NUMBER);
  48. for(int i=0;i<GameConstants::F_NUMBER;i++)
  49. {
  50. temp = readTo(buf,it,'\n');//read blank line and faction name
  51. temp = readTo(buf,it,'\n');
  52. for(int bg = 0; bg<9; bg++)
  53. {
  54. CBuilding *nb = readBg(buf,it);
  55. nb->tid = i;
  56. nb->bid = bg+17;
  57. buildings[i][bg+17] = nb;
  58. }
  59. }
  60. //reading 17 neutral (common) buildings
  61. temp = readTo(buf,it,'\n');temp = readTo(buf,it,'\n');temp = readTo(buf,it,'\n');//neutral buildings - skip 3 lines
  62. for(int bg = 0; bg<17; bg++)
  63. {
  64. CBuilding *nb = readBg(buf,it);
  65. for(int f=0;f<GameConstants::F_NUMBER;f++)
  66. {
  67. buildings[f][bg] = new CBuilding(*nb);
  68. buildings[f][bg]->tid = f;
  69. buildings[f][bg]->bid = bg;
  70. }
  71. delete nb;
  72. }
  73. //create Grail entries
  74. for(int i=0; i<GameConstants::F_NUMBER; i++)
  75. buildings[i][26] = new CBuilding(i,26);
  76. //reading 14 per faction dwellings
  77. temp = readTo(buf,it,'\n');temp = readTo(buf,it,'\n');//dwellings - skip 2 lines
  78. for(int i=0;i<GameConstants::F_NUMBER;i++)
  79. {
  80. temp = readTo(buf,it,'\n');//read blank line
  81. temp = readTo(buf,it,'\n');// and faction name
  82. for(int bg = 0; ; bg++)
  83. {
  84. CBuilding *nb = readBg(buf,it);
  85. nb->tid = i;
  86. nb->bid = bg+30;
  87. buildings[i][bg+30] = nb;
  88. if (it >= buf.size() || buf[it] == '\t') //read till empty line
  89. break;
  90. }
  91. }
  92. /////done reading BUILDING.TXT*****************************
  93. const JsonNode config(ResourceID("config/hall.json"));
  94. BOOST_FOREACH(const JsonNode &town, config["town"].Vector())
  95. {
  96. int tid = town["id"].Float();
  97. hall[tid].first = town["image"].String();
  98. (hall[tid].second).resize(5); //rows
  99. int row_num = 0;
  100. BOOST_FOREACH(const JsonNode &row, town["boxes"].Vector())
  101. {
  102. BOOST_FOREACH(const JsonNode &box, row.Vector())
  103. {
  104. (hall[tid].second)[row_num].push_back(std::vector<int>()); //push new box
  105. std::vector<int> &box_vec = (hall[tid].second)[row_num].back();
  106. BOOST_FOREACH(const JsonNode &value, box.Vector())
  107. {
  108. box_vec.push_back(value.Float());
  109. }
  110. }
  111. row_num ++;
  112. }
  113. assert (row_num == 5);
  114. }
  115. // Buildings dependencies. Which building depend on which other building.
  116. const JsonNode buildingsConf(ResourceID("config/buildings.json"));
  117. // Iterate for each city type
  118. int townID = 0;
  119. BOOST_FOREACH(const JsonNode &town_node, buildingsConf["town_type"].Vector())
  120. {
  121. BOOST_FOREACH(const JsonNode &node, town_node["building_requirements"].Vector())
  122. {
  123. int id = node["id"].Float();
  124. CBuilding * build = buildings[townID][id];
  125. if (build)
  126. {
  127. BOOST_FOREACH(const JsonNode &building, node["requires"].Vector())
  128. {
  129. build->requirements.insert(building.Float());
  130. }
  131. }
  132. }
  133. townID++;
  134. }
  135. }
  136. CBuildingHandler::~CBuildingHandler()
  137. {
  138. for(std::vector< bmap<int, ConstTransitivePtr<CBuilding> > >::iterator i=buildings.begin(); i!=buildings.end(); i++)
  139. for(std::map<int, ConstTransitivePtr<CBuilding> >::iterator j=i->begin(); j!=i->end(); j++)
  140. j->second.dellNull();
  141. }
  142. static std::string emptyStr = "";
  143. const std::string & CBuilding::Name() const
  144. {
  145. if(name.length())
  146. return name;
  147. else if(vstd::contains(VLC->generaltexth->buildings,tid) && vstd::contains(VLC->generaltexth->buildings[tid],bid))
  148. return VLC->generaltexth->buildings[tid][bid].first;
  149. tlog2 << "Warning: Cannot find name text for building " << bid << "for " << tid << "town.\n";
  150. return emptyStr;
  151. }
  152. const std::string & CBuilding::Description() const
  153. {
  154. if(description.length())
  155. return description;
  156. else if(vstd::contains(VLC->generaltexth->buildings,tid) && vstd::contains(VLC->generaltexth->buildings[tid],bid))
  157. return VLC->generaltexth->buildings[tid][bid].second;
  158. tlog2 << "Warning: Cannot find description text for building " << bid << "for " << tid << "town.\n";
  159. return emptyStr;
  160. }
  161. CBuilding::CBuilding( int TID, int BID )
  162. {
  163. tid = TID;
  164. bid = BID;
  165. }
  166. int CBuildingHandler::campToERMU( int camp, int townType, std::set<si32> builtBuildings )
  167. {
  168. using namespace boost::assign;
  169. static const std::vector<int> campToERMU = list_of(11)(12)(13)(7)(8)(9)(5)(16)(14)(15)(-1)(0)(1)(2)(3)(4)
  170. (6)(26)(17)(21)(22)(23)
  171. ; //creature generators with banks - handled separately
  172. if (camp < campToERMU.size())
  173. {
  174. return campToERMU[camp];
  175. }
  176. static const std::vector<int> hordeLvlsPerTType[GameConstants::F_NUMBER] = {list_of(2), list_of(1), list_of(1)(4), list_of(0)(2),
  177. list_of(0), list_of(0), list_of(0), list_of(0), list_of(0)};
  178. int curPos = campToERMU.size();
  179. for (int i=0; i<7; ++i)
  180. {
  181. if(camp == curPos) //non-upgraded
  182. return 30 + i;
  183. curPos++;
  184. if(camp == curPos) //upgraded
  185. return 37 + i;
  186. curPos++;
  187. //horde building
  188. if (vstd::contains(hordeLvlsPerTType[townType], i))
  189. {
  190. if (camp == curPos)
  191. {
  192. if (hordeLvlsPerTType[townType][0] == i)
  193. {
  194. if(vstd::contains(builtBuildings, 37 + hordeLvlsPerTType[townType][0])) //if upgraded dwelling is built
  195. return 19;
  196. else //upgraded dwelling not presents
  197. return 18;
  198. }
  199. else
  200. {
  201. if(hordeLvlsPerTType[townType].size() > 1)
  202. {
  203. if(vstd::contains(builtBuildings, 37 + hordeLvlsPerTType[townType][1])) //if upgraded dwelling is built
  204. return 25;
  205. else //upgraded dwelling not presents
  206. return 24;
  207. }
  208. }
  209. }
  210. curPos++;
  211. }
  212. }
  213. assert(0);
  214. return -1; //not found
  215. }