CHeroHandler.cpp 12 KB

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