CSpellHandler.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. #define VCMI_DLL
  2. #include "../stdafx.h"
  3. #include "CSpellHandler.h"
  4. #include "CLodHandler.h"
  5. #include "../lib/VCMI_Lib.h"
  6. #include <boost/algorithm/string/replace.hpp>
  7. #include <cctype>
  8. extern CLodHandler *bitmaph;
  9. /*
  10. * CSpellHandler.cpp, part of VCMI engine
  11. *
  12. * Authors: listed in file AUTHORS in main folder
  13. *
  14. * License: GNU General Public License v2.0 or later
  15. * Full text of license available in license.txt file, in main folder
  16. *
  17. */
  18. namespace SRSLPraserHelpers
  19. {
  20. int XYToHex(int x, int y)
  21. {
  22. return x + 17 * y;
  23. }
  24. int XYToHex(std::pair<int, int> xy)
  25. {
  26. return XYToHex(xy.first, xy.second);
  27. }
  28. int hexToY(int battleFieldPosition)
  29. {
  30. return battleFieldPosition/17;
  31. }
  32. int hexToX(int battleFieldPosition)
  33. {
  34. int pos = battleFieldPosition - hexToY(battleFieldPosition) * 17;
  35. return pos;
  36. }
  37. std::pair<int, int> hexToPair(int battleFieldPosition)
  38. {
  39. return std::make_pair(hexToX(battleFieldPosition), hexToY(battleFieldPosition));
  40. }
  41. //moves hex by one hex in given direction
  42. //0 - left top, 1 - right top, 2 - right, 3 - right bottom, 4 - left bottom, 5 - left
  43. std::pair<int, int> gotoDir(int x, int y, int direction)
  44. {
  45. switch(direction)
  46. {
  47. case 0: //top left
  48. return std::make_pair(y%2 ? x-1 : x, y-1);
  49. case 1: //top right
  50. return std::make_pair(y%2 ? x : x+1, y-1);
  51. case 2: //right
  52. return std::make_pair(x+1, y);
  53. case 3: //right bottom
  54. return std::make_pair(y%2 ? x : x+1, y+1);
  55. case 4: //left bottom
  56. return std::make_pair(y%2 ? x-1 : x, y+1);
  57. case 5: //left
  58. return std::make_pair(x-1, y);
  59. }
  60. }
  61. std::pair<int, int> gotoDir(std::pair<int, int> xy, int direction)
  62. {
  63. return gotoDir(xy.first, xy.second, direction);
  64. }
  65. bool isGoodHex(std::pair<int, int> xy)
  66. {
  67. return xy.first >=0 && xy.first < 17 && xy.second >= 0 && xy.second < 11;
  68. }
  69. //helper fonction for std::set<ui16> CSpell::rangeInHexes(unsigned int centralHex, ui8 schoolLvl ) const
  70. std::set<ui16> getInRange(unsigned int center, int low, int high)
  71. {
  72. std::set<ui16> ret;
  73. if(low == 0)
  74. {
  75. ret.insert(center);
  76. }
  77. std::pair<int, int> mainPointForLayer[6]; //A, B, C, D, E, F points
  78. for(int b=0; b<6; ++b)
  79. mainPointForLayer[b] = hexToPair(center);
  80. for(int it=1; it<=high; ++it) //it - distance to the center
  81. {
  82. for(int b=0; b<6; ++b)
  83. mainPointForLayer[b] = gotoDir(mainPointForLayer[b], b);
  84. if(it>=low)
  85. {
  86. std::pair<int, int> curHex;
  87. //adding lines (A-b, B-c, C-d, etc)
  88. for(int v=0; v<6; ++v)
  89. {
  90. curHex = mainPointForLayer[v];
  91. for(int h=0; h<it; ++h)
  92. {
  93. if(isGoodHex(curHex))
  94. ret.insert(XYToHex(curHex));
  95. curHex = gotoDir(curHex, (v+2)%6);
  96. }
  97. }
  98. } //if(it>=low)
  99. }
  100. return ret;
  101. }
  102. }
  103. using namespace SRSLPraserHelpers;
  104. std::set<ui16> CSpell::rangeInHexes(unsigned int centralHex, ui8 schoolLvl ) const
  105. {
  106. std::set<ui16> ret;
  107. std::string rng = range[schoolLvl] + ','; //copy + artificial comma for easier handling
  108. if(rng.size() >= 1 && rng[0] != 'X') //there is at lest one hex in range
  109. {
  110. std::string number1, number2;
  111. int beg, end;
  112. bool readingFirst = true;
  113. for(int it=0; it<rng.size(); ++it)
  114. {
  115. if( std::isdigit(rng[it]) ) //reading numer
  116. {
  117. if(readingFirst)
  118. number1 += rng[it];
  119. else
  120. number2 += rng[it];
  121. }
  122. else if(rng[it] == ',') //comma
  123. {
  124. //calculating variables
  125. if(readingFirst)
  126. {
  127. beg = atoi(number1.c_str());
  128. number1 = "";
  129. }
  130. else
  131. {
  132. end = atoi(number2.c_str());
  133. number2 = "";
  134. }
  135. //obtaining new hexes
  136. std::set<ui16> curLayer;
  137. if(readingFirst)
  138. {
  139. curLayer = getInRange(centralHex, beg, beg);
  140. }
  141. else
  142. {
  143. curLayer = getInRange(centralHex, beg, end);
  144. readingFirst = true;
  145. }
  146. //adding abtained hexes
  147. for(std::set<ui16>::iterator it = curLayer.begin(); it != curLayer.end(); ++it)
  148. {
  149. ret.insert(*it);
  150. }
  151. }
  152. else if(rng[it] == '-') //dash
  153. {
  154. beg = atoi(number1.c_str());
  155. number1 = "";
  156. readingFirst = false;
  157. }
  158. }
  159. }
  160. return ret;
  161. }
  162. void CSpellHandler::loadSpells()
  163. {
  164. std::string buf = bitmaph->getTextFile("SPTRAITS.TXT"), pom;
  165. int andame = buf.size(), i=0; //buf iterator
  166. for(int z=0; z<5; ++z)
  167. loadToIt(pom,buf,i,3);
  168. bool combSpells=false; //true, if we are reading combat spells
  169. bool creatureAbility=false; //if true, only creature can use this spell
  170. int ifHit = 0;
  171. while(i<andame)
  172. {
  173. if(spells.size()==81)
  174. break;
  175. CSpell nsp; //new currently being read spell
  176. loadToIt(nsp.name,buf,i,4);
  177. if(nsp.name == std::string(""))
  178. {
  179. if(ifHit == 0)
  180. {
  181. combSpells = true;
  182. }
  183. if(ifHit == 1)
  184. {
  185. creatureAbility = true;
  186. }
  187. for(int z=0; z<3; ++z)
  188. loadToIt(pom,buf,i,3);
  189. loadToIt(nsp.name,buf,i,4);
  190. ++ifHit;
  191. }
  192. loadToIt(nsp.abbName,buf,i,4);
  193. loadToIt(nsp.level,buf,i,4);
  194. loadToIt(pom,buf,i,4);
  195. nsp.earth = pom[0]=='x' ? true : false;
  196. loadToIt(pom,buf,i,4);
  197. nsp.water = pom[0]=='x' ? true : false;
  198. loadToIt(pom,buf,i,4);
  199. nsp.fire = pom[0]=='x' ? true : false;
  200. loadToIt(pom,buf,i,4);
  201. nsp.air = pom[0]=='x' ? true : false;
  202. nsp.costs.resize(4);
  203. for (int z = 0; z < 4 ; z++)
  204. loadToIt(nsp.costs[z],buf,i,4);
  205. loadToIt(nsp.power,buf,i,4);
  206. nsp.powers.resize(4);
  207. for (int z = 0; z < 4 ; z++)
  208. loadToIt(nsp.powers[z],buf,i,4);
  209. nsp.probabilities.resize(9);
  210. for (int z = 0; z < 9 ; z++)
  211. loadToIt(nsp.probabilities[z],buf,i,4);
  212. nsp.AIVals.resize(4);
  213. for (int z = 0; z < 4 ; z++)
  214. loadToIt(nsp.AIVals[z],buf,i,4);
  215. nsp.descriptions.resize(4);
  216. for (int z = 0; z < 4 ; z++)
  217. {
  218. loadToIt(nsp.descriptions[z],buf,i,4);
  219. boost::algorithm::replace_all(nsp.descriptions[z],"\"","");
  220. }
  221. loadToIt(nsp.attributes,buf,i,3);
  222. nsp.id = spells.size();
  223. nsp.combatSpell = combSpells;
  224. nsp.creatureAbility = creatureAbility;
  225. nsp.mainEffectAnim = -1;
  226. spells.push_back(nsp);
  227. }
  228. //loading of additional spell traits
  229. std::ifstream ast;
  230. ast.open("config/spell_info.txt", std::ios::binary);
  231. if(!ast.is_open())
  232. {
  233. tlog1<<"lack of config/spell_info.txt file!"<<std::endl;
  234. }
  235. else
  236. {
  237. //reading header
  238. std::string dump;
  239. for(int i=0; i<60; ++i) ast>>dump;
  240. //reading exact info
  241. int spellID;
  242. ast>>spellID;
  243. while(spellID != -1)
  244. {
  245. int buf;
  246. ast >> buf;
  247. spells[spellID].positiveness = buf;
  248. ast >> buf;
  249. spells[spellID].mainEffectAnim = buf;
  250. spells[spellID].range.resize(4);
  251. for(int g=0; g<4; ++g)
  252. ast>>spells[spellID].range[g];
  253. ast>>spellID;
  254. }
  255. }
  256. }