CCreatureHandler.cpp 20 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021
  1. #include "../stdafx.h"
  2. #include "../CGameInfo.h"
  3. #include "CDefHandler.h"
  4. #include "CCreatureHandler.h"
  5. #include "CLodHandler.h"
  6. #include <sstream>
  7. #include <boost/assign/std/vector.hpp>
  8. #include <boost/algorithm/string.hpp>
  9. #include <boost/algorithm/string/find.hpp>
  10. #include <boost/algorithm/string/replace.hpp>
  11. #include "../SDL_Extensions.h"
  12. int CCreature::getQuantityID(int quantity)
  13. {
  14. if (quantity<5)
  15. return 0;
  16. if (quantity<10)
  17. return 1;
  18. if (quantity<20)
  19. return 2;
  20. if (quantity<50)
  21. return 3;
  22. if (quantity<100)
  23. return 4;
  24. if (quantity<250)
  25. return 5;
  26. if (quantity<500)
  27. return 5;
  28. if (quantity<1000)
  29. return 6;
  30. if (quantity<4000)
  31. return 7;
  32. return 8;
  33. }
  34. bool CCreature::isDoubleWide()
  35. {
  36. return boost::algorithm::find_first(abilityRefs, "DOUBLE_WIDE");
  37. }
  38. bool CCreature::isFlying()
  39. {
  40. return boost::algorithm::find_first(abilityRefs, "FLYING_ARMY");
  41. }
  42. int CCreature::maxAmount(const std::vector<int> &res) const //how many creatures can be bought
  43. {
  44. int ret = 2147483645;
  45. int resAmnt = std::min(res.size(),cost.size());
  46. for(int i=0;i<resAmnt;i++)
  47. if(cost[i])
  48. ret = std::min(ret,res[i]/cost[i]);
  49. return ret;
  50. }
  51. void CCreatureHandler::loadCreatures()
  52. {
  53. std::string buf = CGameInfo::mainObj->bitmaph->getTextFile("ZCRTRAIT.TXT");
  54. int andame = buf.size();
  55. int i=0; //buf iterator
  56. int hmcr=0;
  57. for(i; i<andame; ++i)
  58. {
  59. if(buf[i]=='\r')
  60. ++hmcr;
  61. if(hmcr==2)
  62. break;
  63. }
  64. i+=2;
  65. while(i<buf.size())
  66. {
  67. CCreature ncre;
  68. ncre.cost.resize(RESOURCE_QUANTITY);
  69. ncre.level=0;
  70. int befi=i;
  71. for(i; i<andame; ++i)
  72. {
  73. if(buf[i]=='\t')
  74. break;
  75. }
  76. ncre.nameSing = buf.substr(befi, i-befi);
  77. ++i;
  78. befi=i;
  79. for(i; i<andame; ++i)
  80. {
  81. if(buf[i]=='\t')
  82. break;
  83. }
  84. ncre.namePl = buf.substr(befi, i-befi);
  85. ++i;
  86. befi=i;
  87. for(i; i<andame; ++i)
  88. {
  89. if(buf[i]=='\t')
  90. break;
  91. }
  92. ncre.cost[0] = atoi(buf.substr(befi, i-befi).c_str());
  93. ++i;
  94. befi=i;
  95. for(i; i<andame; ++i)
  96. {
  97. if(buf[i]=='\t')
  98. break;
  99. }
  100. ncre.cost[1] = atoi(buf.substr(befi, i-befi).c_str());
  101. ++i;
  102. befi=i;
  103. for(i; i<andame; ++i)
  104. {
  105. if(buf[i]=='\t')
  106. break;
  107. }
  108. ncre.cost[2] = atoi(buf.substr(befi, i-befi).c_str());
  109. ++i;
  110. befi=i;
  111. for(i; i<andame; ++i)
  112. {
  113. if(buf[i]=='\t')
  114. break;
  115. }
  116. ncre.cost[3] = atoi(buf.substr(befi, i-befi).c_str());
  117. ++i;
  118. befi=i;
  119. for(i; i<andame; ++i)
  120. {
  121. if(buf[i]=='\t')
  122. break;
  123. }
  124. ncre.cost[4] = atoi(buf.substr(befi, i-befi).c_str());
  125. ++i;
  126. befi=i;
  127. for(i; i<andame; ++i)
  128. {
  129. if(buf[i]=='\t')
  130. break;
  131. }
  132. ncre.cost[5] = atoi(buf.substr(befi, i-befi).c_str());
  133. ++i;
  134. befi=i;
  135. for(i; i<andame; ++i)
  136. {
  137. if(buf[i]=='\t')
  138. break;
  139. }
  140. ncre.cost[6] = atoi(buf.substr(befi, i-befi).c_str());
  141. ++i;
  142. befi=i;
  143. for(i; i<andame; ++i)
  144. {
  145. if(buf[i]=='\t')
  146. break;
  147. }
  148. ncre.fightValue = atoi(buf.substr(befi, i-befi).c_str());
  149. ++i;
  150. befi=i;
  151. for(i; i<andame; ++i)
  152. {
  153. if(buf[i]=='\t')
  154. break;
  155. }
  156. ncre.AIValue = atoi(buf.substr(befi, i-befi).c_str());
  157. ++i;
  158. befi=i;
  159. for(i; i<andame; ++i)
  160. {
  161. if(buf[i]=='\t')
  162. break;
  163. }
  164. ncre.growth = atoi(buf.substr(befi, i-befi).c_str());
  165. ++i;
  166. befi=i;
  167. for(i; i<andame; ++i)
  168. {
  169. if(buf[i]=='\t')
  170. break;
  171. }
  172. ncre.hordeGrowth = atoi(buf.substr(befi, i-befi).c_str());
  173. ++i;
  174. befi=i;
  175. for(i; i<andame; ++i)
  176. {
  177. if(buf[i]=='\t')
  178. break;
  179. }
  180. ncre.hitPoints = atoi(buf.substr(befi, i-befi).c_str());
  181. ++i;
  182. befi=i;
  183. for(i; i<andame; ++i)
  184. {
  185. if(buf[i]=='\t')
  186. break;
  187. }
  188. ncre.speed = atoi(buf.substr(befi, i-befi).c_str());
  189. ++i;
  190. befi=i;
  191. for(i; i<andame; ++i)
  192. {
  193. if(buf[i]=='\t')
  194. break;
  195. }
  196. ncre.attack = atoi(buf.substr(befi, i-befi).c_str());
  197. ++i;
  198. befi=i;
  199. for(i; i<andame; ++i)
  200. {
  201. if(buf[i]=='\t')
  202. break;
  203. }
  204. ncre.defence = atoi(buf.substr(befi, i-befi).c_str());
  205. ++i;
  206. befi=i;
  207. for(i; i<andame; ++i)
  208. {
  209. if(buf[i]=='\t')
  210. break;
  211. }
  212. ncre.damageMin = atoi(buf.substr(befi, i-befi).c_str());
  213. ++i;
  214. befi=i;
  215. for(i; i<andame; ++i)
  216. {
  217. if(buf[i]=='\t')
  218. break;
  219. }
  220. ncre.damageMax = atoi(buf.substr(befi, i-befi).c_str());
  221. ++i;
  222. befi=i;
  223. for(i; i<andame; ++i)
  224. {
  225. if(buf[i]=='\t')
  226. break;
  227. }
  228. ncre.shots = atoi(buf.substr(befi, i-befi).c_str());
  229. ++i;
  230. befi=i;
  231. for(i; i<andame; ++i)
  232. {
  233. if(buf[i]=='\t')
  234. break;
  235. }
  236. ncre.spells = atoi(buf.substr(befi, i-befi).c_str());
  237. ++i;
  238. befi=i;
  239. for(i; i<andame; ++i)
  240. {
  241. if(buf[i]=='\t')
  242. break;
  243. }
  244. ncre.ammMin = atoi(buf.substr(befi, i-befi).c_str());
  245. ++i;
  246. befi=i;
  247. for(i; i<andame; ++i)
  248. {
  249. if(buf[i]=='\t')
  250. break;
  251. }
  252. ncre.ammMax = atoi(buf.substr(befi, i-befi).c_str());
  253. ++i;
  254. befi=i;
  255. for(i; i<andame; ++i)
  256. {
  257. if(buf[i]=='\t')
  258. break;
  259. }
  260. ncre.abilityText = buf.substr(befi, i-befi);
  261. ++i;
  262. befi=i;
  263. for(i; i<andame; ++i)
  264. {
  265. if(buf[i]=='\r')
  266. break;
  267. }
  268. ncre.abilityRefs = buf.substr(befi, i-befi);
  269. i+=2;
  270. if(ncre.nameSing!=std::string("") && ncre.namePl!=std::string(""))
  271. {
  272. ncre.idNumber = creatures.size();
  273. ncre.isDefinite = true;
  274. creatures.push_back(ncre);
  275. }
  276. }
  277. for(int bb=1; bb<8; ++bb)
  278. {
  279. CCreature ncre;
  280. ncre.isDefinite = false;
  281. ncre.indefLevel = bb;
  282. ncre.indefUpgraded = false;
  283. creatures.push_back(ncre);
  284. ncre.indefUpgraded = true;
  285. creatures.push_back(ncre);
  286. }
  287. //loading reference names
  288. std::ifstream ifs("config/crerefnam.txt");
  289. int tempi;
  290. std::string temps;
  291. for (;;)
  292. {
  293. ifs >> tempi >> temps;
  294. if (tempi>=creatures.size())
  295. break;
  296. boost::assign::insert(nameToID)(temps,tempi);
  297. creatures[tempi].nameRef=temps;
  298. }
  299. ifs.close();
  300. ifs.clear();
  301. for(int i=1;i<=10;i++)
  302. levelCreatures.insert(std::pair<int,std::vector<CCreature*> >(i,std::vector<CCreature*>()));
  303. ifs.open("config/monsters.txt");
  304. {
  305. while(!ifs.eof())
  306. {
  307. int id, lvl;
  308. ifs >> id >> lvl;
  309. if(lvl>0)
  310. {
  311. creatures[id].level = lvl;
  312. levelCreatures[lvl].push_back(&(creatures[id]));
  313. }
  314. }
  315. }
  316. ifs.close();
  317. ifs.clear();
  318. ifs.open("config/cr_bgs.txt");
  319. while(!ifs.eof())
  320. {
  321. int id;
  322. std::string name;
  323. ifs >> id >> name;
  324. backgrounds[id]=CGI->bitmaph->loadBitmap(name);
  325. }
  326. ifs.close();
  327. ifs.clear();
  328. ifs.open("config/cr_factions.txt");
  329. while(!ifs.eof())
  330. {
  331. int id, fact;
  332. ifs >> id >> fact;
  333. creatures[id].faction = fact;
  334. }
  335. ifs.close();
  336. ifs.clear();
  337. //loading 32x32px imgs
  338. CDefHandler *smi = CGI->spriteh->giveDef("CPRSMALL.DEF");
  339. smi->notFreeImgs = true;
  340. for (int i=0; i<smi->ourImages.size(); i++)
  341. {
  342. boost::assign::insert(smallImgs)(i-2,smi->ourImages[i].bitmap);
  343. }
  344. delete smi;
  345. smi = CGI->spriteh->giveDef("TWCRPORT.DEF");
  346. smi->notFreeImgs = true;
  347. for (int i=0; i<smi->ourImages.size(); i++)
  348. {
  349. boost::assign::insert(bigImgs)(i-2,smi->ourImages[i].bitmap);
  350. }
  351. delete smi;
  352. //
  353. //loading unit animation def names
  354. std::ifstream inp("config/CREDEFS.TXT", std::ios::in | std::ios::binary); //this file is not in lod
  355. inp.seekg(0,std::ios::end); // na koniec
  356. int andame2 = inp.tellg(); // read length
  357. inp.seekg(0,std::ios::beg); // wracamy na poczatek
  358. char * bufor = new char[andame2]; // allocate memory
  359. inp.read((char*)bufor, andame2); // read map file to buffer
  360. inp.close();
  361. buf = std::string(bufor);
  362. delete [andame2] bufor;
  363. i = 0; //buf iterator
  364. hmcr = 0;
  365. for(i; i<andame2; ++i) //omitting rubbish
  366. {
  367. if(buf[i]=='\r')
  368. break;
  369. }
  370. i+=2;
  371. for(int s=0; s<creatures.size()-16; ++s)
  372. {
  373. int befi=i;
  374. std::string rub;
  375. for(i; i<andame2; ++i)
  376. {
  377. if(buf[i]==' ')
  378. break;
  379. }
  380. rub = buf.substr(befi, i-befi);
  381. ++i;
  382. befi=i;
  383. for(i; i<andame2; ++i)
  384. {
  385. if(buf[i]=='\r')
  386. break;
  387. }
  388. std::string defName = buf.substr(befi, i-befi);
  389. creatures[s].animDefName = defName;
  390. }
  391. loadAnimationInfo();
  392. }
  393. void CCreatureHandler::loadAnimationInfo()
  394. {
  395. std::string buf = CGameInfo::mainObj->bitmaph->getTextFile("CRANIM.TXT");
  396. int andame = buf.size();
  397. int i=0; //buf iterator
  398. int hmcr=0;
  399. for(i; i<andame; ++i)
  400. {
  401. if(buf[i]=='\r')
  402. ++hmcr;
  403. if(hmcr==2)
  404. break;
  405. }
  406. i+=2;
  407. for(int dd=0; dd<creatures.size()-16; ++dd)
  408. {
  409. loadUnitAnimInfo(creatures[dd], buf, i);
  410. }
  411. return;
  412. }
  413. void CCreatureHandler::loadUnitAnimInfo(CCreature & unit, std::string & src, int & i)
  414. {
  415. int befi=i;
  416. for(i; i<src.size(); ++i)
  417. {
  418. if(src[i]=='\t')
  419. break;
  420. }
  421. unit.timeBetweenFidgets = atof(src.substr(befi, i-befi).c_str());
  422. ++i;
  423. while(unit.timeBetweenFidgets == 0.0)
  424. {
  425. for(i; i<src.size(); ++i)
  426. {
  427. if(src[i]=='\r')
  428. break;
  429. }
  430. i+=2;
  431. befi=i;
  432. for(i; i<src.size(); ++i)
  433. {
  434. if(src[i]=='\t')
  435. break;
  436. }
  437. unit.timeBetweenFidgets = atof(src.substr(befi, i-befi).c_str());
  438. ++i;
  439. }
  440. befi=i;
  441. for(i; i<src.size(); ++i)
  442. {
  443. if(src[i]=='\t')
  444. break;
  445. }
  446. unit.walkAnimationTime = atof(src.substr(befi, i-befi).c_str());
  447. ++i;
  448. befi=i;
  449. for(i; i<src.size(); ++i)
  450. {
  451. if(src[i]=='\t')
  452. break;
  453. }
  454. unit.attackAnimationTime = atof(src.substr(befi, i-befi).c_str());
  455. ++i;
  456. befi=i;
  457. for(i; i<src.size(); ++i)
  458. {
  459. if(src[i]=='\t')
  460. break;
  461. }
  462. unit.flightAnimationDistance = atof(src.substr(befi, i-befi).c_str());
  463. ++i;
  464. ///////////////////////
  465. befi=i;
  466. for(i; i<src.size(); ++i)
  467. {
  468. if(src[i]=='\t')
  469. break;
  470. }
  471. unit.upperRightMissleOffsetX = atoi(src.substr(befi, i-befi).c_str());
  472. ++i;
  473. befi=i;
  474. for(i; i<src.size(); ++i)
  475. {
  476. if(src[i]=='\t')
  477. break;
  478. }
  479. unit.upperRightMissleOffsetY = atoi(src.substr(befi, i-befi).c_str());
  480. ++i;
  481. befi=i;
  482. for(i; i<src.size(); ++i)
  483. {
  484. if(src[i]=='\t')
  485. break;
  486. }
  487. unit.rightMissleOffsetX = atoi(src.substr(befi, i-befi).c_str());
  488. ++i;
  489. befi=i;
  490. for(i; i<src.size(); ++i)
  491. {
  492. if(src[i]=='\t')
  493. break;
  494. }
  495. unit.rightMissleOffsetY = atoi(src.substr(befi, i-befi).c_str());
  496. ++i;
  497. befi=i;
  498. for(i; i<src.size(); ++i)
  499. {
  500. if(src[i]=='\t')
  501. break;
  502. }
  503. unit.lowerRightMissleOffsetX = atoi(src.substr(befi, i-befi).c_str());
  504. ++i;
  505. befi=i;
  506. for(i; i<src.size(); ++i)
  507. {
  508. if(src[i]=='\t')
  509. break;
  510. }
  511. unit.lowerRightMissleOffsetY = atoi(src.substr(befi, i-befi).c_str());
  512. ++i;
  513. ///////////////////////
  514. for(int jjj=0; jjj<12; ++jjj)
  515. {
  516. befi=i;
  517. for(i; i<src.size(); ++i)
  518. {
  519. if(src[i]=='\t')
  520. break;
  521. }
  522. unit.missleFrameAngles[jjj] = atof(src.substr(befi, i-befi).c_str());
  523. ++i;
  524. }
  525. befi=i;
  526. for(i; i<src.size(); ++i)
  527. {
  528. if(src[i]=='\t')
  529. break;
  530. }
  531. unit.troopCountLocationOffset= atoi(src.substr(befi, i-befi).c_str());
  532. ++i;
  533. befi=i;
  534. for(i; i<src.size(); ++i)
  535. {
  536. if(src[i]=='\t')
  537. break;
  538. }
  539. unit.attackClimaxFrame = atoi(src.substr(befi, i-befi).c_str());
  540. ++i;
  541. for(i; i<src.size(); ++i)
  542. {
  543. if(src[i]=='\r')
  544. break;
  545. }
  546. i+=2;
  547. }
  548. void CCreatureHandler::loadUnitAnimations()
  549. {
  550. //std::ifstream inp("config/CREDEFS.TXT", std::ios::in | std::ios::binary); //this file is not in lod
  551. //inp.seekg(0,std::ios::end); // na koniec
  552. //int andame = inp.tellg(); // read length
  553. //inp.seekg(0,std::ios::beg); // wracamy na poczatek
  554. //char * bufor = new char[andame]; // allocate memory
  555. //inp.read((char*)bufor, andame); // read map file to buffer
  556. //inp.close();
  557. //std::string buf = std::string(bufor);
  558. //delete [andame] bufor;
  559. //int i = 0; //buf iterator
  560. //int hmcr = 0;
  561. //for(i; i<andame; ++i) //omitting rubbish
  562. //{
  563. // if(buf[i]=='\r')
  564. // break;
  565. //}
  566. //i+=2;
  567. //for(int s=0; s<creatures.size(); ++s)
  568. //{
  569. // int befi=i;
  570. // std::string rub;
  571. // for(i; i<andame; ++i)
  572. // {
  573. // if(buf[i]==' ')
  574. // break;
  575. // }
  576. // rub = buf.substr(befi, i-befi);
  577. // ++i;
  578. // befi=i;
  579. // for(i; i<andame; ++i)
  580. // {
  581. // if(buf[i]=='\r')
  582. // break;
  583. // }
  584. // std::string defName = buf.substr(befi, i-befi);
  585. // if(defName != std::string("x"))
  586. // creatures[s].battleAnimation = CGameInfo::mainObj->spriteh->giveDef(defName);
  587. // else
  588. // creatures[s].battleAnimation = NULL;
  589. // i+=2;
  590. //}
  591. }
  592. int CCreatureAnimation::getType() const
  593. {
  594. return type;
  595. }
  596. void CCreatureAnimation::setType(int type)
  597. {
  598. this->type = type;
  599. curFrame = 0;
  600. if(type!=-1)
  601. {
  602. if(SEntries[curFrame].group!=type) //rewind
  603. {
  604. int j=-1; //first frame in displayed group
  605. for(int g=0; g<SEntries.size(); ++g)
  606. {
  607. if(SEntries[g].group==type && j==-1)
  608. {
  609. j = g;
  610. break;
  611. }
  612. }
  613. if(curFrame!=-1)
  614. curFrame = j;
  615. }
  616. }
  617. else
  618. {
  619. if(curFrame>=frames)
  620. curFrame = 0;
  621. }
  622. }
  623. CCreatureAnimation::CCreatureAnimation(std::string name) : RLEntries(NULL), RWEntries(NULL)
  624. {
  625. //load main file
  626. std::string data2 = CGI->spriteh->getTextFile(name);
  627. if(data2.size()==0)
  628. throw new std::string("no such def!");
  629. FDef = new unsigned char[data2.size()];
  630. for(int g=0; g<data2.size(); ++g)
  631. {
  632. FDef[g] = data2[g];
  633. }
  634. //init anim data
  635. int i,j, totalInBlock;
  636. char Buffer[13];
  637. defName=name;
  638. int andame = data2.size();
  639. i = 0;
  640. DEFType = readNormalNr(i,4); i+=4;
  641. fullWidth = readNormalNr(i,4); i+=4;
  642. fullHeight = readNormalNr(i,4); i+=4;
  643. i=0xc;
  644. totalBlocks = readNormalNr(i,4); i+=4;
  645. i=0x10;
  646. for (int it=0;it<256;it++)
  647. {
  648. palette[it].R = FDef[i++];
  649. palette[it].G = FDef[i++];
  650. palette[it].B = FDef[i++];
  651. palette[it].F = 0;
  652. }
  653. i=0x310;
  654. totalEntries=0;
  655. for (int z=0; z<totalBlocks; z++)
  656. {
  657. int unknown1 = readNormalNr(i,4); i+=4;
  658. totalInBlock = readNormalNr(i,4); i+=4;
  659. for (j=SEntries.size(); j<totalEntries+totalInBlock; j++)
  660. SEntries.push_back(SEntry());
  661. int unknown2 = readNormalNr(i,4); i+=4;
  662. int unknown3 = readNormalNr(i,4); i+=4;
  663. for (j=0; j<totalInBlock; j++)
  664. {
  665. for (int k=0;k<13;k++) Buffer[k]=FDef[i+k];
  666. i+=13;
  667. SEntries[totalEntries+j].name=Buffer;
  668. }
  669. for (j=0; j<totalInBlock; j++)
  670. {
  671. SEntries[totalEntries+j].offset = readNormalNr(i,4);
  672. int unknown4 = readNormalNr(i,4); i+=4;
  673. }
  674. //totalEntries+=totalInBlock;
  675. for(int hh=0; hh<totalInBlock; ++hh)
  676. {
  677. SEntries[totalEntries].group = z;
  678. ++totalEntries;
  679. }
  680. }
  681. for(j=0; j<SEntries.size(); ++j)
  682. {
  683. SEntries[j].name = SEntries[j].name.substr(0, SEntries[j].name.find('.')+4);
  684. }
  685. //pictures don't have to be readed here
  686. //for(int i=0; i<SEntries.size(); ++i)
  687. //{
  688. // Cimage nimg;
  689. // nimg.bitmap = getSprite(i);
  690. // nimg.imName = SEntries[i].name;
  691. // nimg.groupNumber = SEntries[i].group;
  692. // ourImages.push_back(nimg);
  693. //}
  694. //delete FDef;
  695. //FDef = NULL;
  696. //init vars
  697. curFrame = 0;
  698. type = -1;
  699. frames = totalEntries;
  700. }
  701. int CCreatureAnimation::readNormalNr (int pos, int bytCon, unsigned char * str, bool cyclic)
  702. {
  703. int ret=0;
  704. int amp=1;
  705. if (str)
  706. {
  707. for (int i=0; i<bytCon; i++)
  708. {
  709. ret+=str[pos+i]*amp;
  710. amp*=256;
  711. }
  712. }
  713. else
  714. {
  715. for (int i=0; i<bytCon; i++)
  716. {
  717. ret+=FDef[pos+i]*amp;
  718. amp*=256;
  719. }
  720. }
  721. if(cyclic && bytCon<4 && ret>=amp/2)
  722. {
  723. ret = ret-amp;
  724. }
  725. return ret;
  726. }
  727. int CCreatureAnimation::nextFrameMiddle(SDL_Surface *dest, int x, int y, bool attacker, bool incrementFrame, bool yellowBorder, SDL_Rect * destRect)
  728. {
  729. return nextFrame(dest,x-fullWidth/2,y-fullHeight/2,attacker,incrementFrame,yellowBorder,destRect);
  730. }
  731. int CCreatureAnimation::nextFrame(SDL_Surface *dest, int x, int y, bool attacker, bool incrementFrame, bool yellowBorder, SDL_Rect * destRect)
  732. {
  733. if(dest->format->BytesPerPixel<3)
  734. return -1; //not enough depth
  735. //increasing frame numer
  736. int SIndex = -1;
  737. if(incrementFrame)
  738. {
  739. SIndex = curFrame++;
  740. if(type!=-1)
  741. {
  742. if(SEntries[curFrame].group!=type) //rewind
  743. {
  744. int j=-1; //first frame in displayed group
  745. for(int g=0; g<SEntries.size(); ++g)
  746. {
  747. if(SEntries[g].group==type && j==-1)
  748. {
  749. j = g;
  750. break;
  751. }
  752. }
  753. if(curFrame!=-1)
  754. curFrame = j;
  755. }
  756. }
  757. else
  758. {
  759. if(curFrame>=frames)
  760. curFrame = 0;
  761. }
  762. }
  763. else
  764. {
  765. SIndex = curFrame;
  766. }
  767. //frame number increased
  768. long BaseOffset,
  769. SpriteWidth, SpriteHeight, //sprite format
  770. LeftMargin, RightMargin, TopMargin,BottomMargin,
  771. i, add, FullHeight,FullWidth,
  772. TotalRowLength, // length of read segment
  773. RowAdd;
  774. unsigned char SegmentType, SegmentLength;
  775. i=BaseOffset=SEntries[SIndex].offset;
  776. int prSize=readNormalNr(i,4,FDef);i+=4;
  777. int defType2 = readNormalNr(i,4,FDef);i+=4;
  778. FullWidth = readNormalNr(i,4,FDef);i+=4;
  779. FullHeight = readNormalNr(i,4,FDef);i+=4;
  780. SpriteWidth = readNormalNr(i,4,FDef);i+=4;
  781. SpriteHeight = readNormalNr(i,4,FDef);i+=4;
  782. LeftMargin = readNormalNr(i,4,FDef);i+=4;
  783. TopMargin = readNormalNr(i,4,FDef);i+=4;
  784. RightMargin = FullWidth - SpriteWidth - LeftMargin;
  785. BottomMargin = FullHeight - SpriteHeight - TopMargin;
  786. add = 4 - FullWidth%4;
  787. int BaseOffsetor = BaseOffset = i;
  788. int ftcp = 0;
  789. if (defType2==1) //as it should be allways in creature animations
  790. {
  791. if (TopMargin>0)
  792. {
  793. for (int i=0;i<TopMargin;i++)
  794. {
  795. ftcp+=FullWidth+add;
  796. }
  797. }
  798. RLEntries = new int[SpriteHeight];
  799. for (int i=0;i<SpriteHeight;i++)
  800. {
  801. RLEntries[i]=readNormalNr(BaseOffset,4,FDef);BaseOffset+=4;
  802. }
  803. for (int i=0;i<SpriteHeight;i++)
  804. {
  805. BaseOffset=BaseOffsetor+RLEntries[i];
  806. if (LeftMargin>0)
  807. {
  808. ftcp+=LeftMargin;
  809. }
  810. TotalRowLength=0;
  811. do
  812. {
  813. SegmentType=FDef[BaseOffset++];
  814. SegmentLength=FDef[BaseOffset++];
  815. if (SegmentType==0xFF)
  816. {
  817. for (int k=0;k<=SegmentLength;k++)
  818. {
  819. int xB = (attacker ? ftcp%(FullWidth+add) : (FullWidth+add) - ftcp%(FullWidth+add) - 1) + x;
  820. int yB = ftcp/(FullWidth+add) + y;
  821. if(xB>=0 && yB>=0 && xB<dest->w && yB<dest->h)
  822. {
  823. if(!destRect || (destRect->x <= xB && destRect->x + destRect->w > xB && destRect->y <= yB && destRect->y + destRect->h > yB))
  824. putPixel(dest, xB + yB*dest->w, palette[FDef[BaseOffset+k]], FDef[BaseOffset+k], yellowBorder);
  825. }
  826. ftcp++; //increment pos
  827. if ((TotalRowLength+k+1)>=SpriteWidth)
  828. break;
  829. }
  830. BaseOffset+=SegmentLength+1;////
  831. TotalRowLength+=SegmentLength+1;
  832. }
  833. else
  834. {
  835. for (int k=0;k<SegmentLength+1;k++)
  836. {
  837. int xB = (attacker ? ftcp%(FullWidth+add) : (FullWidth+add) - ftcp%(FullWidth+add) - 1) + x;
  838. int yB = ftcp/(FullWidth+add) + y;
  839. if(xB>=0 && yB>=0 && xB<dest->w && yB<dest->h)
  840. {
  841. if(!destRect || (destRect->x <= xB && destRect->x + destRect->w > xB && destRect->y <= yB && destRect->y + destRect->h > yB))
  842. putPixel(dest, xB + yB*dest->w, palette[SegmentType], SegmentType, yellowBorder);
  843. }
  844. ftcp++; //increment pos
  845. }
  846. TotalRowLength+=SegmentLength+1;
  847. }
  848. }while(TotalRowLength<SpriteWidth);
  849. RowAdd=SpriteWidth-TotalRowLength;
  850. if (RightMargin>0)
  851. {
  852. ftcp+=RightMargin;
  853. }
  854. if (add>0)
  855. {
  856. ftcp+=add+RowAdd;
  857. }
  858. }
  859. delete [] RLEntries;
  860. RLEntries = NULL;
  861. if (BottomMargin>0)
  862. {
  863. ftcp += BottomMargin * (FullWidth+add);
  864. }
  865. }
  866. //SDL_UpdateRect(dest, x, y, FullWidth+add, FullHeight);
  867. return 0;
  868. }
  869. int CCreatureAnimation::framesInGroup(int group) const
  870. {
  871. int ret = 0; //number of frames in given group
  872. for(int g=0; g<SEntries.size(); ++g)
  873. {
  874. if(SEntries[g].group == group)
  875. ++ret;
  876. }
  877. return ret;
  878. }
  879. CCreatureAnimation::~CCreatureAnimation()
  880. {
  881. delete [] FDef;
  882. if (RWEntries)
  883. delete [] RWEntries;
  884. if (RLEntries)
  885. delete [] RLEntries;
  886. }
  887. void CCreatureAnimation::putPixel(SDL_Surface * dest, const int & ftcp, const BMPPalette & color, const unsigned char & palc, const bool & yellowBorder) const
  888. {
  889. if(palc!=0)
  890. {
  891. Uint8 * p = (Uint8*)dest->pixels + ftcp*3;
  892. if(palc > 7) //normal color
  893. {
  894. p[0] = color.B;
  895. p[1] = color.G;
  896. p[2] = color.R;
  897. }
  898. else if(yellowBorder && (palc == 6 || palc == 7)) //dark yellow border
  899. {
  900. p[0] = 0;
  901. p[1] = 0xff;
  902. p[2] = 0xff;
  903. }
  904. else if(yellowBorder && (palc == 5)) //yellow border
  905. {
  906. p[0] = color.B;
  907. p[1] = color.G;
  908. p[2] = color.R;
  909. }
  910. else if(palc < 5) //shadow
  911. {
  912. Uint16 alpha;
  913. switch(color.G)
  914. {
  915. case 0:
  916. alpha = 128;
  917. break;
  918. case 50:
  919. alpha = 50+32;
  920. break;
  921. case 100:
  922. alpha = 100+64;
  923. break;
  924. case 125:
  925. alpha = 125+64;
  926. break;
  927. case 128:
  928. alpha = 128+64;
  929. break;
  930. case 150:
  931. alpha = 150+64;
  932. break;
  933. default:
  934. alpha = 255;
  935. break;
  936. }
  937. //alpha counted
  938. p[0] = (p[0] * alpha)>>8;
  939. p[1] = (p[1] * alpha)>>8;
  940. p[2] = (p[2] * alpha)>>8;
  941. }
  942. }
  943. }