CBuildingHandler.cpp 6.0 KB

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