CCreatureHandler.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  1. #define VCMI_DLL
  2. #include "../stdafx.h"
  3. #include "CCreatureHandler.h"
  4. #include "CLodHandler.h"
  5. #include <sstream>
  6. #include <boost/assign/std/vector.hpp>
  7. #include <boost/algorithm/string.hpp>
  8. #include <boost/algorithm/string/find.hpp>
  9. #include <boost/algorithm/string/replace.hpp>
  10. extern CLodHandler * bitmaph;
  11. int CCreature::getQuantityID(int quantity)
  12. {
  13. if (quantity<5)
  14. return 0;
  15. if (quantity<10)
  16. return 1;
  17. if (quantity<20)
  18. return 2;
  19. if (quantity<50)
  20. return 3;
  21. if (quantity<100)
  22. return 4;
  23. if (quantity<250)
  24. return 5;
  25. if (quantity<500)
  26. return 5;
  27. if (quantity<1000)
  28. return 6;
  29. if (quantity<4000)
  30. return 7;
  31. return 8;
  32. }
  33. bool CCreature::isDoubleWide()
  34. {
  35. return boost::algorithm::find_first(abilityRefs, "DOUBLE_WIDE");
  36. }
  37. bool CCreature::isFlying()
  38. {
  39. return boost::algorithm::find_first(abilityRefs, "FLYING_ARMY");
  40. }
  41. int CCreature::maxAmount(const std::vector<int> &res) const //how many creatures can be bought
  42. {
  43. int ret = 2147483645;
  44. int resAmnt = std::min(res.size(),cost.size());
  45. for(int i=0;i<resAmnt;i++)
  46. if(cost[i])
  47. ret = std::min(ret,res[i]/cost[i]);
  48. return ret;
  49. }
  50. void CCreatureHandler::loadCreatures()
  51. {
  52. std::string buf = bitmaph->getTextFile("ZCRTRAIT.TXT");
  53. int andame = buf.size();
  54. int i=0; //buf iterator
  55. int hmcr=0;
  56. for(i; i<andame; ++i)
  57. {
  58. if(buf[i]=='\r')
  59. ++hmcr;
  60. if(hmcr==2)
  61. break;
  62. }
  63. i+=2;
  64. while(i<buf.size())
  65. {
  66. CCreature ncre;
  67. ncre.cost.resize(RESOURCE_QUANTITY);
  68. ncre.level=0;
  69. int befi=i;
  70. for(i; i<andame; ++i)
  71. {
  72. if(buf[i]=='\t')
  73. break;
  74. }
  75. ncre.nameSing = buf.substr(befi, i-befi);
  76. ++i;
  77. befi=i;
  78. for(i; i<andame; ++i)
  79. {
  80. if(buf[i]=='\t')
  81. break;
  82. }
  83. ncre.namePl = buf.substr(befi, i-befi);
  84. ++i;
  85. befi=i;
  86. for(i; i<andame; ++i)
  87. {
  88. if(buf[i]=='\t')
  89. break;
  90. }
  91. ncre.cost[0] = atoi(buf.substr(befi, i-befi).c_str());
  92. ++i;
  93. befi=i;
  94. for(i; i<andame; ++i)
  95. {
  96. if(buf[i]=='\t')
  97. break;
  98. }
  99. ncre.cost[1] = atoi(buf.substr(befi, i-befi).c_str());
  100. ++i;
  101. befi=i;
  102. for(i; i<andame; ++i)
  103. {
  104. if(buf[i]=='\t')
  105. break;
  106. }
  107. ncre.cost[2] = atoi(buf.substr(befi, i-befi).c_str());
  108. ++i;
  109. befi=i;
  110. for(i; i<andame; ++i)
  111. {
  112. if(buf[i]=='\t')
  113. break;
  114. }
  115. ncre.cost[3] = atoi(buf.substr(befi, i-befi).c_str());
  116. ++i;
  117. befi=i;
  118. for(i; i<andame; ++i)
  119. {
  120. if(buf[i]=='\t')
  121. break;
  122. }
  123. ncre.cost[4] = atoi(buf.substr(befi, i-befi).c_str());
  124. ++i;
  125. befi=i;
  126. for(i; i<andame; ++i)
  127. {
  128. if(buf[i]=='\t')
  129. break;
  130. }
  131. ncre.cost[5] = atoi(buf.substr(befi, i-befi).c_str());
  132. ++i;
  133. befi=i;
  134. for(i; i<andame; ++i)
  135. {
  136. if(buf[i]=='\t')
  137. break;
  138. }
  139. ncre.cost[6] = atoi(buf.substr(befi, i-befi).c_str());
  140. ++i;
  141. befi=i;
  142. for(i; i<andame; ++i)
  143. {
  144. if(buf[i]=='\t')
  145. break;
  146. }
  147. ncre.fightValue = atoi(buf.substr(befi, i-befi).c_str());
  148. ++i;
  149. befi=i;
  150. for(i; i<andame; ++i)
  151. {
  152. if(buf[i]=='\t')
  153. break;
  154. }
  155. ncre.AIValue = atoi(buf.substr(befi, i-befi).c_str());
  156. ++i;
  157. befi=i;
  158. for(i; i<andame; ++i)
  159. {
  160. if(buf[i]=='\t')
  161. break;
  162. }
  163. ncre.growth = atoi(buf.substr(befi, i-befi).c_str());
  164. ++i;
  165. befi=i;
  166. for(i; i<andame; ++i)
  167. {
  168. if(buf[i]=='\t')
  169. break;
  170. }
  171. ncre.hordeGrowth = atoi(buf.substr(befi, i-befi).c_str());
  172. ++i;
  173. befi=i;
  174. for(i; i<andame; ++i)
  175. {
  176. if(buf[i]=='\t')
  177. break;
  178. }
  179. ncre.hitPoints = atoi(buf.substr(befi, i-befi).c_str());
  180. ++i;
  181. befi=i;
  182. for(i; i<andame; ++i)
  183. {
  184. if(buf[i]=='\t')
  185. break;
  186. }
  187. ncre.speed = atoi(buf.substr(befi, i-befi).c_str());
  188. ++i;
  189. befi=i;
  190. for(i; i<andame; ++i)
  191. {
  192. if(buf[i]=='\t')
  193. break;
  194. }
  195. ncre.attack = atoi(buf.substr(befi, i-befi).c_str());
  196. ++i;
  197. befi=i;
  198. for(i; i<andame; ++i)
  199. {
  200. if(buf[i]=='\t')
  201. break;
  202. }
  203. ncre.defence = atoi(buf.substr(befi, i-befi).c_str());
  204. ++i;
  205. befi=i;
  206. for(i; i<andame; ++i)
  207. {
  208. if(buf[i]=='\t')
  209. break;
  210. }
  211. ncre.damageMin = atoi(buf.substr(befi, i-befi).c_str());
  212. ++i;
  213. befi=i;
  214. for(i; i<andame; ++i)
  215. {
  216. if(buf[i]=='\t')
  217. break;
  218. }
  219. ncre.damageMax = atoi(buf.substr(befi, i-befi).c_str());
  220. ++i;
  221. befi=i;
  222. for(i; i<andame; ++i)
  223. {
  224. if(buf[i]=='\t')
  225. break;
  226. }
  227. ncre.shots = atoi(buf.substr(befi, i-befi).c_str());
  228. ++i;
  229. befi=i;
  230. for(i; i<andame; ++i)
  231. {
  232. if(buf[i]=='\t')
  233. break;
  234. }
  235. ncre.spells = atoi(buf.substr(befi, i-befi).c_str());
  236. ++i;
  237. befi=i;
  238. for(i; i<andame; ++i)
  239. {
  240. if(buf[i]=='\t')
  241. break;
  242. }
  243. ncre.ammMin = atoi(buf.substr(befi, i-befi).c_str());
  244. ++i;
  245. befi=i;
  246. for(i; i<andame; ++i)
  247. {
  248. if(buf[i]=='\t')
  249. break;
  250. }
  251. ncre.ammMax = atoi(buf.substr(befi, i-befi).c_str());
  252. ++i;
  253. befi=i;
  254. for(i; i<andame; ++i)
  255. {
  256. if(buf[i]=='\t')
  257. break;
  258. }
  259. ncre.abilityText = buf.substr(befi, i-befi);
  260. ++i;
  261. befi=i;
  262. for(i; i<andame; ++i)
  263. {
  264. if(buf[i]=='\r')
  265. break;
  266. }
  267. ncre.abilityRefs = buf.substr(befi, i-befi);
  268. i+=2;
  269. if(ncre.nameSing!=std::string("") && ncre.namePl!=std::string(""))
  270. {
  271. ncre.idNumber = creatures.size();
  272. ncre.isDefinite = true;
  273. creatures.push_back(ncre);
  274. }
  275. }
  276. for(int bb=1; bb<8; ++bb)
  277. {
  278. CCreature ncre;
  279. ncre.isDefinite = false;
  280. ncre.indefLevel = bb;
  281. ncre.indefUpgraded = false;
  282. creatures.push_back(ncre);
  283. ncre.indefUpgraded = true;
  284. creatures.push_back(ncre);
  285. }
  286. //loading reference names
  287. std::ifstream ifs("config/crerefnam.txt");
  288. int tempi;
  289. std::string temps;
  290. for (;;)
  291. {
  292. ifs >> tempi >> temps;
  293. if (tempi>=creatures.size())
  294. break;
  295. boost::assign::insert(nameToID)(temps,tempi);
  296. creatures[tempi].nameRef=temps;
  297. }
  298. ifs.close();
  299. ifs.clear();
  300. for(int i=1;i<=10;i++)
  301. levelCreatures.insert(std::pair<int,std::vector<CCreature*> >(i,std::vector<CCreature*>()));
  302. ifs.open("config/monsters.txt");
  303. {
  304. while(!ifs.eof())
  305. {
  306. int id, lvl;
  307. ifs >> id >> lvl;
  308. if(lvl>0)
  309. {
  310. creatures[id].level = lvl;
  311. levelCreatures[lvl].push_back(&(creatures[id]));
  312. }
  313. }
  314. }
  315. ifs.close();
  316. ifs.clear();
  317. ifs.open("config/cr_factions.txt");
  318. while(!ifs.eof())
  319. {
  320. int id, fact;
  321. ifs >> id >> fact;
  322. creatures[id].faction = fact;
  323. }
  324. ifs.close();
  325. ifs.clear();
  326. ifs.open("config/cr_upgrade_list.txt");
  327. while(!ifs.eof())
  328. {
  329. int id, up;
  330. ifs >> id >> up;
  331. creatures[id].upgrades.insert(up);
  332. }
  333. ifs.close();
  334. ifs.clear();
  335. //loading unit animation def names
  336. std::ifstream inp("config/CREDEFS.TXT", std::ios::in | std::ios::binary); //this file is not in lod
  337. inp.seekg(0,std::ios::end); // na koniec
  338. int andame2 = inp.tellg(); // read length
  339. inp.seekg(0,std::ios::beg); // wracamy na poczatek
  340. char * bufor = new char[andame2]; // allocate memory
  341. inp.read((char*)bufor, andame2); // read map file to buffer
  342. inp.close();
  343. buf = std::string(bufor);
  344. delete [andame2] bufor;
  345. i = 0; //buf iterator
  346. hmcr = 0;
  347. for(i; i<andame2; ++i) //omitting rubbish
  348. {
  349. if(buf[i]=='\r')
  350. break;
  351. }
  352. i+=2;
  353. for(int s=0; s<creatures.size()-16; ++s)
  354. {
  355. int befi=i;
  356. std::string rub;
  357. for(i; i<andame2; ++i)
  358. {
  359. if(buf[i]==' ')
  360. break;
  361. }
  362. rub = buf.substr(befi, i-befi);
  363. ++i;
  364. befi=i;
  365. for(i; i<andame2; ++i)
  366. {
  367. if(buf[i]=='\r')
  368. break;
  369. }
  370. std::string defName = buf.substr(befi, i-befi);
  371. creatures[s].animDefName = defName;
  372. }
  373. loadAnimationInfo();
  374. }
  375. void CCreatureHandler::loadAnimationInfo()
  376. {
  377. std::string buf = bitmaph->getTextFile("CRANIM.TXT");
  378. int andame = buf.size();
  379. int i=0; //buf iterator
  380. int hmcr=0;
  381. for(i; i<andame; ++i)
  382. {
  383. if(buf[i]=='\r')
  384. ++hmcr;
  385. if(hmcr==2)
  386. break;
  387. }
  388. i+=2;
  389. for(int dd=0; dd<creatures.size()-16; ++dd)
  390. {
  391. loadUnitAnimInfo(creatures[dd], buf, i);
  392. }
  393. return;
  394. }
  395. void CCreatureHandler::loadUnitAnimInfo(CCreature & unit, std::string & src, int & i)
  396. {
  397. int befi=i;
  398. for(i; i<src.size(); ++i)
  399. {
  400. if(src[i]=='\t')
  401. break;
  402. }
  403. unit.timeBetweenFidgets = atof(src.substr(befi, i-befi).c_str());
  404. ++i;
  405. while(unit.timeBetweenFidgets == 0.0)
  406. {
  407. for(i; i<src.size(); ++i)
  408. {
  409. if(src[i]=='\r')
  410. break;
  411. }
  412. i+=2;
  413. befi=i;
  414. for(i; i<src.size(); ++i)
  415. {
  416. if(src[i]=='\t')
  417. break;
  418. }
  419. unit.timeBetweenFidgets = atof(src.substr(befi, i-befi).c_str());
  420. ++i;
  421. }
  422. befi=i;
  423. for(i; i<src.size(); ++i)
  424. {
  425. if(src[i]=='\t')
  426. break;
  427. }
  428. unit.walkAnimationTime = atof(src.substr(befi, i-befi).c_str());
  429. ++i;
  430. befi=i;
  431. for(i; i<src.size(); ++i)
  432. {
  433. if(src[i]=='\t')
  434. break;
  435. }
  436. unit.attackAnimationTime = atof(src.substr(befi, i-befi).c_str());
  437. ++i;
  438. befi=i;
  439. for(i; i<src.size(); ++i)
  440. {
  441. if(src[i]=='\t')
  442. break;
  443. }
  444. unit.flightAnimationDistance = atof(src.substr(befi, i-befi).c_str());
  445. ++i;
  446. ///////////////////////
  447. befi=i;
  448. for(i; i<src.size(); ++i)
  449. {
  450. if(src[i]=='\t')
  451. break;
  452. }
  453. unit.upperRightMissleOffsetX = atoi(src.substr(befi, i-befi).c_str());
  454. ++i;
  455. befi=i;
  456. for(i; i<src.size(); ++i)
  457. {
  458. if(src[i]=='\t')
  459. break;
  460. }
  461. unit.upperRightMissleOffsetY = atoi(src.substr(befi, i-befi).c_str());
  462. ++i;
  463. befi=i;
  464. for(i; i<src.size(); ++i)
  465. {
  466. if(src[i]=='\t')
  467. break;
  468. }
  469. unit.rightMissleOffsetX = atoi(src.substr(befi, i-befi).c_str());
  470. ++i;
  471. befi=i;
  472. for(i; i<src.size(); ++i)
  473. {
  474. if(src[i]=='\t')
  475. break;
  476. }
  477. unit.rightMissleOffsetY = atoi(src.substr(befi, i-befi).c_str());
  478. ++i;
  479. befi=i;
  480. for(i; i<src.size(); ++i)
  481. {
  482. if(src[i]=='\t')
  483. break;
  484. }
  485. unit.lowerRightMissleOffsetX = atoi(src.substr(befi, i-befi).c_str());
  486. ++i;
  487. befi=i;
  488. for(i; i<src.size(); ++i)
  489. {
  490. if(src[i]=='\t')
  491. break;
  492. }
  493. unit.lowerRightMissleOffsetY = atoi(src.substr(befi, i-befi).c_str());
  494. ++i;
  495. ///////////////////////
  496. for(int jjj=0; jjj<12; ++jjj)
  497. {
  498. befi=i;
  499. for(i; i<src.size(); ++i)
  500. {
  501. if(src[i]=='\t')
  502. break;
  503. }
  504. unit.missleFrameAngles[jjj] = atof(src.substr(befi, i-befi).c_str());
  505. ++i;
  506. }
  507. befi=i;
  508. for(i; i<src.size(); ++i)
  509. {
  510. if(src[i]=='\t')
  511. break;
  512. }
  513. unit.troopCountLocationOffset= atoi(src.substr(befi, i-befi).c_str());
  514. ++i;
  515. befi=i;
  516. for(i; i<src.size(); ++i)
  517. {
  518. if(src[i]=='\t')
  519. break;
  520. }
  521. unit.attackClimaxFrame = atoi(src.substr(befi, i-befi).c_str());
  522. ++i;
  523. for(i; i<src.size(); ++i)
  524. {
  525. if(src[i]=='\r')
  526. break;
  527. }
  528. i+=2;
  529. }