CHeroHandler.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. #include "stdafx.h"
  2. #include "CHeroHandler.h"
  3. #include "../CGameInfo.h"
  4. #include <sstream>
  5. #include "../CGameInfo.h"
  6. #include "CGeneralTextHandler.h"
  7. #include "CLodHandler.h"
  8. #include "CAbilityHandler.h"
  9. #include "SDL_Extensions.h"
  10. #include <cmath>
  11. #include <iomanip>
  12. CHeroHandler::~CHeroHandler()
  13. {
  14. for (int j=0;j<heroes.size();j++)
  15. {
  16. if (heroes[j]->portraitSmall)
  17. SDL_FreeSurface(heroes[j]->portraitSmall);
  18. delete heroes[j];
  19. }
  20. }
  21. void CHeroHandler::loadPortraits()
  22. {
  23. std::ifstream of("config/portrety.txt");
  24. for (int j=0;j<heroes.size();j++)
  25. {
  26. int ID;
  27. of>>ID;
  28. std::string path;
  29. of>>path;
  30. heroes[ID]->portraitSmall=CGI->bitmaph->loadBitmap(path);
  31. if (!heroes[ID]->portraitSmall)
  32. std::cout<<"Can't read small portrait for "<<ID<<" ("<<path<<")\n";
  33. path.replace(2,1,"L");
  34. heroes[ID]->portraitLarge=CGI->bitmaph->loadBitmap(path);
  35. if (!heroes[ID]->portraitLarge)
  36. std::cout<<"Can't read large portrait for "<<ID<<" ("<<path<<")\n";
  37. SDL_SetColorKey(heroes[ID]->portraitLarge,SDL_SRCCOLORKEY,SDL_MapRGB(heroes[ID]->portraitLarge->format,0,255,255));
  38. }
  39. of.close();
  40. }
  41. void CHeroHandler::loadHeroes()
  42. {
  43. int ID=0;
  44. std::string buf = CGameInfo::mainObj->bitmaph->getTextFile("HOTRAITS.TXT");
  45. int it=0;
  46. std::string dump;
  47. for(int i=0; i<2; ++i)
  48. {
  49. CGeneralTextHandler::loadToIt(dump,buf,it,3);
  50. }
  51. int numberOfCurrentClassHeroes = 0;
  52. int currentClass = 0;
  53. int additHero = 0;
  54. EHeroClasses addTab[12];
  55. addTab[0] = HERO_KNIGHT;
  56. addTab[1] = HERO_WITCH;
  57. addTab[2] = HERO_KNIGHT;
  58. addTab[3] = HERO_WIZARD;
  59. addTab[4] = HERO_RANGER;
  60. addTab[5] = HERO_BARBARIAN;
  61. addTab[6] = HERO_DEATHKNIGHT;
  62. addTab[7] = HERO_WARLOCK;
  63. addTab[8] = HERO_KNIGHT;
  64. addTab[9] = HERO_WARLOCK;
  65. addTab[10] = HERO_BARBARIAN;
  66. addTab[11] = HERO_DEMONIAC;
  67. for (int i=0; i<HEROES_QUANTITY; i++)
  68. {
  69. CHero * nher = new CHero;
  70. if(currentClass<18)
  71. {
  72. nher->heroType = (EHeroClasses)currentClass;
  73. ++numberOfCurrentClassHeroes;
  74. if(numberOfCurrentClassHeroes==8)
  75. {
  76. numberOfCurrentClassHeroes = 0;
  77. ++currentClass;
  78. }
  79. }
  80. else
  81. {
  82. nher->heroType = addTab[additHero++];
  83. }
  84. std::string pom ;
  85. CGeneralTextHandler::loadToIt(nher->name,buf,it,4);
  86. CGeneralTextHandler::loadToIt(pom,buf,it,4);
  87. nher->low1stack = atoi(pom.c_str());
  88. CGeneralTextHandler::loadToIt(pom,buf,it,4);
  89. nher->high1stack = atoi(pom.c_str());
  90. CGeneralTextHandler::loadToIt(nher->refType1stack,buf,it,4);
  91. CGeneralTextHandler::loadToIt(pom,buf,it,4);
  92. nher->low2stack = atoi(pom.c_str());
  93. CGeneralTextHandler::loadToIt(pom,buf,it,4);
  94. nher->high2stack = atoi(pom.c_str());
  95. CGeneralTextHandler::loadToIt(nher->refType2stack,buf,it,4);
  96. CGeneralTextHandler::loadToIt(pom,buf,it,4);
  97. nher->low3stack = atoi(pom.c_str());
  98. CGeneralTextHandler::loadToIt(pom,buf,it,4);
  99. nher->high3stack = atoi(pom.c_str());
  100. CGeneralTextHandler::loadToIt(nher->refType3stack,buf,it,3);
  101. nher->ID = heroes.size();
  102. heroes.push_back(nher);
  103. }
  104. loadSpecialAbilities();
  105. loadBiographies();
  106. loadHeroClasses();
  107. initHeroClasses();
  108. return;
  109. }
  110. void CHeroHandler::loadSpecialAbilities()
  111. {
  112. std::string buf = CGameInfo::mainObj->bitmaph->getTextFile("HEROSPEC.TXT");
  113. int it=0;
  114. std::string dump;
  115. for(int i=0; i<2; ++i)
  116. {
  117. CGeneralTextHandler::loadToIt(dump,buf,it,3);
  118. }
  119. for (int i=0;i<heroes.size();i++)
  120. {
  121. CGeneralTextHandler::loadToIt(heroes[i]->bonusName,buf,it,4);
  122. CGeneralTextHandler::loadToIt(heroes[i]->shortBonus,buf,it,4);
  123. CGeneralTextHandler::loadToIt(heroes[i]->longBonus,buf,it,3);
  124. }
  125. }
  126. void CHeroHandler::loadBiographies()
  127. {
  128. std::string buf = CGameInfo::mainObj->bitmaph->getTextFile("HEROBIOS.TXT");
  129. int it=0;
  130. for (int i=0;i<heroes.size();i++)
  131. {
  132. CGeneralTextHandler::loadToIt(heroes[i]->biography,buf,it,3);
  133. }
  134. }
  135. void CHeroHandler::loadHeroClasses()
  136. {
  137. std::string buf = CGameInfo::mainObj->bitmaph->getTextFile("HCTRAITS.TXT");
  138. int andame = buf.size();
  139. for(int y=0; y<andame; ++y)
  140. if(buf[y]==',')
  141. buf[y]='.';
  142. int i = 0; //buf iterator
  143. int hmcr = 0;
  144. for(i; i<andame; ++i) //omitting rubbish
  145. {
  146. if(buf[i]=='\r')
  147. ++hmcr;
  148. if(hmcr==2)
  149. break;
  150. }
  151. i+=2;
  152. for(int ss=0; ss<18; ++ss) //18 classes of hero (including conflux)
  153. {
  154. CHeroClass * hc = new CHeroClass;
  155. int befi=i;
  156. for(i; i<andame; ++i)
  157. {
  158. if(buf[i]=='\t')
  159. break;
  160. }
  161. hc->name = buf.substr(befi, i-befi);
  162. ++i;
  163. befi=i;
  164. for(i; i<andame; ++i)
  165. {
  166. if(buf[i]=='\t')
  167. break;
  168. }
  169. hc->aggression = atof(buf.substr(befi, i-befi).c_str());
  170. ++i;
  171. befi=i;
  172. for(i; i<andame; ++i)
  173. {
  174. if(buf[i]=='\t')
  175. break;
  176. }
  177. hc->initialAttack = atoi(buf.substr(befi, i-befi).c_str());
  178. ++i;
  179. befi=i;
  180. for(i; i<andame; ++i)
  181. {
  182. if(buf[i]=='\t')
  183. break;
  184. }
  185. hc->initialDefence = atoi(buf.substr(befi, i-befi).c_str());
  186. ++i;
  187. befi=i;
  188. for(i; i<andame; ++i)
  189. {
  190. if(buf[i]=='\t')
  191. break;
  192. }
  193. hc->initialPower = atoi(buf.substr(befi, i-befi).c_str());
  194. ++i;
  195. befi=i;
  196. for(i; i<andame; ++i)
  197. {
  198. if(buf[i]=='\t')
  199. break;
  200. }
  201. hc->initialKnowledge = atoi(buf.substr(befi, i-befi).c_str());
  202. ++i;
  203. befi=i;
  204. for(i; i<andame; ++i)
  205. {
  206. if(buf[i]=='\t')
  207. break;
  208. }
  209. hc->proAttack[0] = atoi(buf.substr(befi, i-befi).c_str());
  210. ++i;
  211. befi=i;
  212. for(i; i<andame; ++i)
  213. {
  214. if(buf[i]=='\t')
  215. break;
  216. }
  217. hc->proDefence[0] = atoi(buf.substr(befi, i-befi).c_str());
  218. ++i;
  219. befi=i;
  220. for(i; i<andame; ++i)
  221. {
  222. if(buf[i]=='\t')
  223. break;
  224. }
  225. hc->proPower[0] = atoi(buf.substr(befi, i-befi).c_str());
  226. ++i;
  227. befi=i;
  228. for(i; i<andame; ++i)
  229. {
  230. if(buf[i]=='\t')
  231. break;
  232. }
  233. hc->proKnowledge[0] = atoi(buf.substr(befi, i-befi).c_str());
  234. ++i;
  235. befi=i;
  236. for(i; i<andame; ++i)
  237. {
  238. if(buf[i]=='\t')
  239. break;
  240. }
  241. hc->proAttack[1] = atoi(buf.substr(befi, i-befi).c_str());
  242. ++i;
  243. befi=i;
  244. for(i; i<andame; ++i)
  245. {
  246. if(buf[i]=='\t')
  247. break;
  248. }
  249. hc->proDefence[1] = atoi(buf.substr(befi, i-befi).c_str());
  250. ++i;
  251. befi=i;
  252. for(i; i<andame; ++i)
  253. {
  254. if(buf[i]=='\t')
  255. break;
  256. }
  257. hc->proPower[1] = atoi(buf.substr(befi, i-befi).c_str());
  258. ++i;
  259. befi=i;
  260. for(i; i<andame; ++i)
  261. {
  262. if(buf[i]=='\t')
  263. break;
  264. }
  265. hc->proKnowledge[1] = atoi(buf.substr(befi, i-befi).c_str());
  266. ++i;
  267. //CHero kkk = heroes[0];
  268. for(int dd=0; dd<CGameInfo::mainObj->abilh->abilities.size(); ++dd)
  269. {
  270. befi=i;
  271. for(i; i<andame; ++i)
  272. {
  273. if(buf[i]=='\t')
  274. break;
  275. }
  276. int buff = atoi(buf.substr(befi, i-befi).c_str());
  277. ++i;
  278. hc->proSec.push_back(buff);
  279. }
  280. for(int dd=0; dd<9; ++dd)
  281. {
  282. befi=i;
  283. for(i; i<andame; ++i)
  284. {
  285. if(buf[i]=='\t' || buf[i]=='\r')
  286. break;
  287. }
  288. hc->selectionProbability[dd] = atoi(buf.substr(befi, i-befi).c_str());
  289. ++i;
  290. }
  291. ++i;
  292. std::stringstream nm;
  293. nm<<"AH";
  294. nm<<std::setw(2);
  295. nm<<std::setfill('0');
  296. nm<<heroClasses.size();
  297. nm<<"_.DEF";
  298. hc->moveAnim = CGI->spriteh->giveDef(nm.str());
  299. for(int o=0; o<hc->moveAnim->ourImages.size(); ++o)
  300. {
  301. if(hc->moveAnim->ourImages[o].groupNumber==6)
  302. {
  303. for(int e=0; e<8; ++e)
  304. {
  305. Cimage nci;
  306. nci.bitmap = CSDL_Ext::rotate01(hc->moveAnim->ourImages[o+e].bitmap);
  307. nci.groupNumber = 10;
  308. nci.imName = std::string();
  309. hc->moveAnim->ourImages.push_back(nci);
  310. }
  311. o+=8;
  312. }
  313. if(hc->moveAnim->ourImages[o].groupNumber==7)
  314. {
  315. for(int e=0; e<8; ++e)
  316. {
  317. Cimage nci;
  318. nci.bitmap = CSDL_Ext::rotate01(hc->moveAnim->ourImages[o+e].bitmap);
  319. nci.groupNumber = 11;
  320. nci.imName = std::string();
  321. hc->moveAnim->ourImages.push_back(nci);
  322. }
  323. o+=8;
  324. }
  325. if(hc->moveAnim->ourImages[o].groupNumber==8)
  326. {
  327. for(int e=0; e<8; ++e)
  328. {
  329. Cimage nci;
  330. nci.bitmap = CSDL_Ext::rotate01(hc->moveAnim->ourImages[o+e].bitmap);
  331. nci.groupNumber = 12;
  332. nci.imName = std::string();
  333. hc->moveAnim->ourImages.push_back(nci);
  334. }
  335. o+=8;
  336. }
  337. }
  338. for(int o=0; o<hc->moveAnim->ourImages.size(); ++o)
  339. {
  340. if(hc->moveAnim->ourImages[o].groupNumber==1)
  341. {
  342. Cimage nci;
  343. nci.bitmap = CSDL_Ext::rotate01(hc->moveAnim->ourImages[o].bitmap);
  344. nci.groupNumber = 13;
  345. nci.imName = std::string();
  346. hc->moveAnim->ourImages.push_back(nci);
  347. //o+=1;
  348. }
  349. if(hc->moveAnim->ourImages[o].groupNumber==2)
  350. {
  351. Cimage nci;
  352. nci.bitmap = CSDL_Ext::rotate01(hc->moveAnim->ourImages[o].bitmap);
  353. nci.groupNumber = 14;
  354. nci.imName = std::string();
  355. hc->moveAnim->ourImages.push_back(nci);
  356. //o+=1;
  357. }
  358. if(hc->moveAnim->ourImages[o].groupNumber==3)
  359. {
  360. Cimage nci;
  361. nci.bitmap = CSDL_Ext::rotate01(hc->moveAnim->ourImages[o].bitmap);
  362. nci.groupNumber = 15;
  363. nci.imName = std::string();
  364. hc->moveAnim->ourImages.push_back(nci);
  365. //o+=1;
  366. }
  367. }
  368. for(int ff=0; ff<hc->moveAnim->ourImages.size(); ++ff)
  369. {
  370. CSDL_Ext::fullAlphaTransform(hc->moveAnim->ourImages[ff].bitmap);
  371. }
  372. hc->moveAnim->alphaTransformed = true;
  373. heroClasses.push_back(hc);
  374. }
  375. }
  376. void CHeroHandler::initHeroClasses()
  377. {
  378. for(int gg=0; gg<heroes.size(); ++gg)
  379. {
  380. heroes[gg]->heroClass = heroClasses[heroes[gg]->heroType];
  381. }
  382. initTerrainCosts();
  383. }
  384. unsigned int CHeroInstance::getTileCost(EterrainType & ttype, Eroad & rdtype, Eriver & rvtype)
  385. {
  386. unsigned int ret = type->heroClass->terrCosts[ttype];
  387. switch(rdtype)
  388. {
  389. case Eroad::dirtRoad:
  390. ret*=0.75;
  391. break;
  392. case Eroad::grazvelRoad:
  393. ret*=0.667;
  394. break;
  395. case Eroad::cobblestoneRoad:
  396. ret*=0.5;
  397. break;
  398. }
  399. return ret;
  400. }
  401. unsigned int CHeroHandler::level(unsigned int experience)
  402. {
  403. if (experience==0)
  404. return 0;
  405. else if (experience<14700) //level < 10
  406. {
  407. return (-500+20*sqrt((float)experience+1025))/(200);
  408. }
  409. else if (experience<24320) //10 - 12
  410. {
  411. if (experience>20600)
  412. return 12;
  413. else if (experience>17500)
  414. return 11;
  415. else return 10;
  416. }
  417. else //>12
  418. {
  419. int lvl=12;
  420. int xp = 24320; //xp needed for 13 lvl
  421. int td = 4464; //diff 14-13
  422. float mp = 1.2;
  423. while (experience>xp)
  424. {
  425. xp+=td;
  426. td*=mp;
  427. lvl++;
  428. }
  429. return lvl;
  430. }
  431. }
  432. unsigned int CHeroInstance::getLowestCreatureSpeed()
  433. {
  434. unsigned int sl = 100;
  435. for(int h=0; h<army.slots.size(); ++h)
  436. {
  437. if(army.slots[h].first->speed<sl)
  438. sl = army.slots[h].first->speed;
  439. }
  440. return sl;
  441. }
  442. int3 CHeroInstance::convertPosition(int3 src, bool toh3m) //toh3m=true: manifest->h3m; toh3m=false: h3m->manifest
  443. {
  444. if (toh3m)
  445. {
  446. src.x+=1;
  447. return src;
  448. }
  449. else
  450. {
  451. src.x-=1;
  452. return src;
  453. }
  454. }
  455. int3 CHeroInstance::getPosition(bool h3m) const
  456. {
  457. if (h3m)
  458. return pos;
  459. else return convertPosition(pos,false);
  460. }
  461. void CHeroInstance::setPosition(int3 Pos, bool h3m)
  462. {
  463. if (h3m)
  464. pos = Pos;
  465. else
  466. pos = convertPosition(Pos,true);
  467. }
  468. bool CHeroInstance::canWalkOnSea() const
  469. {
  470. //TODO: write it - it should check if hero is flying, or something similiar
  471. return false;
  472. }
  473. int CHeroInstance::getCurrentLuck() const
  474. {
  475. //TODO: write it
  476. return 0;
  477. }
  478. int CHeroInstance::getCurrentMorale() const
  479. {
  480. //TODO: write it
  481. return 0;
  482. }
  483. void CHeroHandler::initTerrainCosts()
  484. {
  485. std::ifstream inp;
  486. inp.open("config\\TERCOSTS.TXT", std::ios_base::in|std::ios_base::binary);
  487. int tynum;
  488. inp>>tynum;
  489. for(int i=0; i<2*tynum; i+=2)
  490. {
  491. int catNum;
  492. inp>>catNum;
  493. for(int k=0; k<catNum; ++k)
  494. {
  495. int curCost;
  496. inp>>curCost;
  497. heroClasses[i]->terrCosts.push_back(curCost);
  498. heroClasses[i+1]->terrCosts.push_back(curCost);
  499. }
  500. }
  501. inp.close();
  502. }