CBattleInterface.cpp 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183
  1. #include "CBattleInterface.h"
  2. #include "CGameInfo.h"
  3. #include "hch\CLodHandler.h"
  4. #include "SDL_Extensions.h"
  5. #include "CAdvmapInterface.h"
  6. #include "AdventureMapButton.h"
  7. #include "hch\CHeroHandler.h"
  8. #include "hch\CDefHandler.h"
  9. #include "CCallback.h"
  10. #include "CGameState.h"
  11. #include "hch\CGeneralTextHandler.h"
  12. #include "client/CCreatureAnimation.h"
  13. #include "client/Graphics.h"
  14. #include <queue>
  15. #include <sstream>
  16. extern SDL_Surface * screen;
  17. extern TTF_Font * GEOR13;
  18. extern SDL_Color zwykly;
  19. SDL_Surface * CBattleInterface::cellBorder, * CBattleInterface::cellShade;
  20. CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2)
  21. : printCellBorders(true), attackingHeroInstance(hero1), defendingHeroInstance(hero2), animCount(0), activeStack(-1), givenCommand(NULL), attackingInfo(NULL)
  22. {
  23. //initializing armies
  24. this->army1 = army1;
  25. this->army2 = army2;
  26. std::map<int, CStack> stacks = LOCPLINT->cb->battleGetStacks();
  27. for(std::map<int, CStack>::iterator b=stacks.begin(); b!=stacks.end(); ++b)
  28. {
  29. std::pair <int, int> coords = CBattleHex::getXYUnitAnim(b->second.position, b->second.owner == attackingHeroInstance->tempOwner, b->second.creature);
  30. creAnims[b->second.ID] = (new CCreatureAnimation(b->second.creature->animDefName));
  31. creAnims[b->second.ID]->setType(2);
  32. creAnims[b->second.ID]->pos = genRect(creAnims[b->second.ID]->fullHeight, creAnims[b->second.ID]->fullWidth, coords.first, coords.second);
  33. creDir[b->second.ID] = b->second.owner==attackingHeroInstance->tempOwner;
  34. }
  35. //preparing menu background and terrain
  36. std::vector< std::string > & backref = CGI->mh->battleBacks[ LOCPLINT->cb->battleGetBattlefieldType() ];
  37. background = BitmapHandler::loadBitmap(backref[ rand() % backref.size()] );
  38. menu = BitmapHandler::loadBitmap("CBAR.BMP");
  39. graphics->blueToPlayersAdv(menu, hero1->tempOwner);
  40. //preparing graphics for displaying amounts of creatures
  41. amountBasic = BitmapHandler::loadBitmap("CMNUMWIN.BMP");
  42. amountNormal = BitmapHandler::loadBitmap("CMNUMWIN.BMP");
  43. CSDL_Ext::alphaTransform(amountNormal);
  44. for(int g=0; g<amountNormal->format->palette->ncolors; ++g)
  45. {
  46. if((amountNormal->format->palette->colors+g)->b != 132 &&
  47. (amountNormal->format->palette->colors+g)->g != 231 &&
  48. (amountNormal->format->palette->colors+g)->r != 255) //it's not yellow border
  49. {
  50. (amountNormal->format->palette->colors+g)->r = (float)((amountNormal->format->palette->colors+g)->r) * 0.54f;
  51. (amountNormal->format->palette->colors+g)->g = (float)((amountNormal->format->palette->colors+g)->g) * 0.19f;
  52. (amountNormal->format->palette->colors+g)->b = (float)((amountNormal->format->palette->colors+g)->b) * 0.93f;
  53. }
  54. }
  55. ////blitting menu background and terrain
  56. blitAt(background, 0, 0);
  57. blitAt(menu, 0, 556);
  58. CSDL_Ext::update();
  59. //preparing buttons and console
  60. bOptions = new AdventureMapButton (std::string(), std::string(), boost::bind(&CBattleInterface::bOptionsf,this), 3, 561, "icm003.def", false, NULL, false);
  61. bSurrender = new AdventureMapButton (std::string(), std::string(), boost::bind(&CBattleInterface::bSurrenderf,this), 54, 561, "icm001.def", false, NULL, false);
  62. bFlee = new AdventureMapButton (std::string(), std::string(), boost::bind(&CBattleInterface::bFleef,this), 105, 561, "icm002.def", false, NULL, false);
  63. bAutofight = new AdventureMapButton (std::string(), std::string(), boost::bind(&CBattleInterface::bAutofightf,this), 157, 561, "icm004.def", false, NULL, false);
  64. bSpell = new AdventureMapButton (std::string(), std::string(), boost::bind(&CBattleInterface::bSpellf,this), 645, 561, "icm005.def", false, NULL, false);
  65. bWait = new AdventureMapButton (std::string(), std::string(), boost::bind(&CBattleInterface::bWaitf,this), 696, 561, "icm006.def", false, NULL, false);
  66. bDefence = new AdventureMapButton (std::string(), std::string(), boost::bind(&CBattleInterface::bDefencef,this), 747, 561, "icm007.def", false, NULL, false);
  67. bConsoleUp = new AdventureMapButton (std::string(), std::string(), boost::bind(&CBattleInterface::bConsoleUpf,this), 624, 561, "ComSlide.def", false, NULL, false);
  68. bConsoleDown = new AdventureMapButton (std::string(), std::string(), boost::bind(&CBattleInterface::bConsoleDownf,this), 624, 580, "ComSlide.def", false, NULL, false);
  69. bConsoleDown->bitmapOffset = 2;
  70. console = new CBattleConsole();
  71. console->pos.x = 211;
  72. console->pos.y = 560;
  73. console->pos.w = 406;
  74. console->pos.h = 38;
  75. //loading hero animations
  76. if(hero1) // attacking hero
  77. {
  78. attackingHero = new CBattleHero(CGI->mh->battleHeroes[hero1->type->heroType], 0, 0, false, hero1->tempOwner);
  79. attackingHero->pos = genRect(attackingHero->dh->ourImages[0].bitmap->h, attackingHero->dh->ourImages[0].bitmap->w, -40, 0);
  80. }
  81. else
  82. {
  83. attackingHero = NULL;
  84. }
  85. if(hero2) // defending hero
  86. {
  87. defendingHero = new CBattleHero(CGI->mh->battleHeroes[hero2->type->heroType], 0, 0, true, hero2->tempOwner);
  88. defendingHero->pos = genRect(defendingHero->dh->ourImages[0].bitmap->h, defendingHero->dh->ourImages[0].bitmap->w, 690, 0);
  89. }
  90. else
  91. {
  92. defendingHero = NULL;
  93. }
  94. //preparing cells and hexes
  95. cellBorder = BitmapHandler::loadBitmap("CCELLGRD.BMP");
  96. CSDL_Ext::alphaTransform(cellBorder);
  97. cellShade = BitmapHandler::loadBitmap("CCELLSHD.BMP");
  98. CSDL_Ext::alphaTransform(cellShade);
  99. for(int h=0; h<187; ++h)
  100. {
  101. bfield[h].myNumber = h;
  102. int x = 14 + ((h/17)%2==0 ? 22 : 0) + 44*(h%17);
  103. int y = 86 + 42 * (h/17);
  104. bfield[h].pos = genRect(cellShade->h, cellShade->w, x, y);
  105. bfield[h].accesible = true;
  106. bfield[h].myInterface = this;
  107. }
  108. //locking occupied positions on batlefield
  109. for(std::map<int, CStack>::iterator it = stacks.begin(); it!=stacks.end(); ++it) //stacks gained at top of this function
  110. {
  111. bfield[it->second.position].accesible = false;
  112. }
  113. }
  114. CBattleInterface::~CBattleInterface()
  115. {
  116. SDL_FreeSurface(background);
  117. SDL_FreeSurface(menu);
  118. SDL_FreeSurface(amountBasic);
  119. SDL_FreeSurface(amountNormal);
  120. delete bOptions;
  121. delete bSurrender;
  122. delete bFlee;
  123. delete bAutofight;
  124. delete bSpell;
  125. delete bWait;
  126. delete bDefence;
  127. delete bConsoleUp;
  128. delete bConsoleDown;
  129. delete console;
  130. delete attackingHero;
  131. delete defendingHero;
  132. SDL_FreeSurface(cellBorder);
  133. SDL_FreeSurface(cellShade);
  134. for(std::map< int, CCreatureAnimation * >::iterator g=creAnims.begin(); g!=creAnims.end(); ++g)
  135. delete g->second;
  136. }
  137. void CBattleInterface::activate()
  138. {
  139. bOptions->activate();
  140. bSurrender->activate();
  141. bFlee->activate();
  142. bAutofight->activate();
  143. bSpell->activate();
  144. bWait->activate();
  145. bDefence->activate();
  146. bConsoleUp->activate();
  147. bConsoleDown->activate();
  148. for(int b=0; b<187; ++b)
  149. {
  150. bfield[b].activate();
  151. }
  152. }
  153. void CBattleInterface::deactivate()
  154. {
  155. bOptions->deactivate();
  156. bSurrender->deactivate();
  157. bFlee->deactivate();
  158. bAutofight->deactivate();
  159. bSpell->deactivate();
  160. bWait->deactivate();
  161. bDefence->deactivate();
  162. bConsoleUp->deactivate();
  163. bConsoleDown->deactivate();
  164. for(int b=0; b<187; ++b)
  165. {
  166. bfield[b].deactivate();
  167. }
  168. }
  169. void CBattleInterface::show(SDL_Surface * to)
  170. {
  171. std::map<int, CStack> stacks = LOCPLINT->cb->battleGetStacks(); //used in a few places
  172. ++animCount;
  173. if(!to) //"evaluating" to
  174. to = screen;
  175. //showing background
  176. blitAt(background, 0, 0, to);
  177. if(printCellBorders) //printing cell borders
  178. {
  179. for(int i=0; i<11; ++i) //rows
  180. {
  181. for(int j=0; j<15; ++j) //columns
  182. {
  183. int x = 58 + (i%2==0 ? 22 : 0) + 44*j;
  184. int y = 86 + 42 * i;
  185. CSDL_Ext::blit8bppAlphaTo24bpp(cellBorder, NULL, to, &genRect(cellBorder->h, cellBorder->w, x, y));
  186. }
  187. }
  188. }
  189. //printing hovered cell
  190. for(int b=0; b<187; ++b)
  191. {
  192. if(bfield[b].strictHovered && bfield[b].hovered)
  193. {
  194. int x = 14 + ((b/17)%2==0 ? 22 : 0) + 44*(b%17);
  195. int y = 86 + 42 * (b/17);
  196. CSDL_Ext::blit8bppAlphaTo24bpp(cellShade, NULL, to, &genRect(cellShade->h, cellShade->w, x, y));
  197. }
  198. }
  199. //showing selected unit's range
  200. if(activeStack != -1 && creAnims[activeStack]->getType() != 0) //don't show if unit is moving
  201. {
  202. showRange(to, activeStack);
  203. }
  204. //showing menu background and console
  205. blitAt(menu, 0, 556, to);
  206. console->show(to);
  207. //showing buttons
  208. bOptions->show(to);
  209. bSurrender->show(to);
  210. bFlee->show(to);
  211. bAutofight->show(to);
  212. bSpell->show(to);
  213. bWait->show(to);
  214. bDefence->show(to);
  215. bConsoleUp->show(to);
  216. bConsoleDown->show(to);
  217. //showing hero animations
  218. if(attackingHero)
  219. attackingHero->show(to);
  220. if(defendingHero)
  221. defendingHero->show(to);
  222. //showing units //a lot of work...
  223. std::vector<int> stackAliveByHex[187];
  224. //double loop because dead stacks should be printed first
  225. for(std::map<int, CStack>::iterator j=stacks.begin(); j!=stacks.end(); ++j)
  226. {
  227. if(j->second.alive)
  228. stackAliveByHex[j->second.position].push_back(j->second.ID);
  229. }
  230. std::vector<int> stackDeadByHex[187];
  231. for(std::map<int, CStack>::iterator j=stacks.begin(); j!=stacks.end(); ++j)
  232. {
  233. if(!j->second.alive)
  234. stackDeadByHex[j->second.position].push_back(j->second.ID);
  235. }
  236. attackingShowHelper(); // handle attack animation
  237. for(int b=0; b<187; ++b) //showing dead stacks
  238. {
  239. for(int v=0; v<stackDeadByHex[b].size(); ++v)
  240. {
  241. creAnims[stackDeadByHex[b][v]]->nextFrame(to, creAnims[stackDeadByHex[b][v]]->pos.x, creAnims[stackDeadByHex[b][v]]->pos.y, creDir[stackDeadByHex[b][v]], (animCount%2==0 || creAnims[stackDeadByHex[b][v]]->getType()!=2) && stacks[stackDeadByHex[b][v]].alive, stackDeadByHex[b][v]==activeStack); //increment always when moving, never if stack died
  242. //printing amount
  243. if(stacks[stackDeadByHex[b][v]].amount > 0) //don't print if stack is not alive
  244. {
  245. if(stacks[stackDeadByHex[b][v]].attackerOwned)
  246. {
  247. CSDL_Ext::blit8bppAlphaTo24bpp(amountNormal, NULL, to, &genRect(amountNormal->h, amountNormal->w, creAnims[stackDeadByHex[b][v]]->pos.x + 220, creAnims[stackDeadByHex[b][v]]->pos.y + 260));
  248. std::stringstream ss;
  249. ss<<stacks[stackDeadByHex[b][v]].amount;
  250. CSDL_Ext::printAtMiddleWB(ss.str(), creAnims[stackDeadByHex[b][v]]->pos.x + 220 + 14, creAnims[stackDeadByHex[b][v]]->pos.y + 260 + 4, GEOR13, 20, zwykly, to);
  251. }
  252. else
  253. {
  254. CSDL_Ext::blit8bppAlphaTo24bpp(amountNormal, NULL, to, &genRect(amountNormal->h, amountNormal->w, creAnims[stackDeadByHex[b][v]]->pos.x + 202, creAnims[stackDeadByHex[b][v]]->pos.y + 260));
  255. std::stringstream ss;
  256. ss<<stacks[stackDeadByHex[b][v]].amount;
  257. CSDL_Ext::printAtMiddleWB(ss.str(), creAnims[stackDeadByHex[b][v]]->pos.x + 202 + 14, creAnims[stackDeadByHex[b][v]]->pos.y + 260 + 4, GEOR13, 20, zwykly, to);
  258. }
  259. }
  260. }
  261. }
  262. for(int b=0; b<187; ++b) //showing alive stacks
  263. {
  264. for(int v=0; v<stackAliveByHex[b].size(); ++v)
  265. {
  266. creAnims[stackAliveByHex[b][v]]->nextFrame(to, creAnims[stackAliveByHex[b][v]]->pos.x, creAnims[stackAliveByHex[b][v]]->pos.y, creDir[stackAliveByHex[b][v]], (animCount%2==0 || creAnims[stackAliveByHex[b][v]]->getType()!=2) && stacks[stackAliveByHex[b][v]].alive, stackAliveByHex[b][v]==activeStack); //increment always when moving, never if stack died
  267. //printing amount
  268. if(stacks[stackAliveByHex[b][v]].amount > 0) //don't print if stack is not alive
  269. {
  270. if(stacks[stackAliveByHex[b][v]].attackerOwned)
  271. {
  272. CSDL_Ext::blit8bppAlphaTo24bpp(amountNormal, NULL, to, &genRect(amountNormal->h, amountNormal->w, creAnims[stackAliveByHex[b][v]]->pos.x + 220, creAnims[stackAliveByHex[b][v]]->pos.y + 260));
  273. std::stringstream ss;
  274. ss<<stacks[stackAliveByHex[b][v]].amount;
  275. CSDL_Ext::printAtMiddleWB(ss.str(), creAnims[stackAliveByHex[b][v]]->pos.x + 220 + 14, creAnims[stackAliveByHex[b][v]]->pos.y + 260 + 4, GEOR13, 20, zwykly, to);
  276. }
  277. else
  278. {
  279. CSDL_Ext::blit8bppAlphaTo24bpp(amountNormal, NULL, to, &genRect(amountNormal->h, amountNormal->w, creAnims[stackAliveByHex[b][v]]->pos.x + 202, creAnims[stackAliveByHex[b][v]]->pos.y + 260));
  280. std::stringstream ss;
  281. ss<<stacks[stackAliveByHex[b][v]].amount;
  282. CSDL_Ext::printAtMiddleWB(ss.str(), creAnims[stackAliveByHex[b][v]]->pos.x + 202 + 14, creAnims[stackAliveByHex[b][v]]->pos.y + 260 + 4, GEOR13, 20, zwykly, to);
  283. }
  284. }
  285. }
  286. }
  287. //units shown
  288. }
  289. bool CBattleInterface::reverseCreature(int number, int hex, bool wideTrick)
  290. {
  291. if(creAnims[number]==NULL)
  292. return false; //there is no such creature
  293. creAnims[number]->setType(8);
  294. for(int g=0; g<creAnims[number]->framesInGroup(8); ++g)
  295. {
  296. show();
  297. CSDL_Ext::update();
  298. SDL_framerateDelay(LOCPLINT->mainFPSmng);
  299. }
  300. creDir[number] = !creDir[number];
  301. CStack curs = LOCPLINT->cb->battleGetStackByID(number);
  302. std::pair <int, int> coords = CBattleHex::getXYUnitAnim(hex, creDir[number], curs.creature);
  303. creAnims[number]->pos.x = coords.first;
  304. //creAnims[number]->pos.y = coords.second;
  305. if(wideTrick && curs.creature->isDoubleWide())
  306. {
  307. creAnims[number]->pos.x -= 44;
  308. }
  309. creAnims[number]->setType(7);
  310. for(int g=0; g<creAnims[number]->framesInGroup(7); ++g)
  311. {
  312. show();
  313. CSDL_Ext::update();
  314. SDL_framerateDelay(LOCPLINT->mainFPSmng);
  315. }
  316. creAnims[number]->setType(2);
  317. return true;
  318. }
  319. void CBattleInterface::bOptionsf()
  320. {
  321. }
  322. void CBattleInterface::bSurrenderf()
  323. {
  324. }
  325. void CBattleInterface::bFleef()
  326. {
  327. BattleAction * ba = new BattleAction;
  328. ba->actionType = 4;
  329. givenCommand = ba;
  330. }
  331. void CBattleInterface::bAutofightf()
  332. {
  333. }
  334. void CBattleInterface::bSpellf()
  335. {
  336. }
  337. void CBattleInterface::bWaitf()
  338. {
  339. }
  340. void CBattleInterface::bDefencef()
  341. {
  342. BattleAction * ba = new BattleAction;
  343. ba->actionType = 3;
  344. ba->stackNumber = activeStack;
  345. givenCommand = ba;
  346. }
  347. void CBattleInterface::bConsoleUpf()
  348. {
  349. console->scrollUp();
  350. }
  351. void CBattleInterface::bConsoleDownf()
  352. {
  353. console->scrollDown();
  354. }
  355. void CBattleInterface::newStack(CStack stack)
  356. {
  357. creAnims[stack.ID] = new CCreatureAnimation(stack.creature->animDefName);
  358. creAnims[stack.ID]->setType(2);
  359. creDir[stack.ID] = stack.owner==attackingHeroInstance->tempOwner;
  360. }
  361. void CBattleInterface::stackRemoved(CStack stack)
  362. {
  363. delete creAnims[stack.ID];
  364. creAnims.erase(stack.ID);
  365. }
  366. void CBattleInterface::stackKilled(int ID, int dmg, int killed, int IDby)
  367. {
  368. creAnims[ID]->setType(5); //death
  369. for(int i=0; i<creAnims[ID]->framesInGroup(5)-1; ++i)
  370. {
  371. show();
  372. CSDL_Ext::update();
  373. SDL_framerateDelay(LOCPLINT->mainFPSmng);
  374. }
  375. printConsoleAttacked(ID, dmg, killed, IDby);
  376. }
  377. void CBattleInterface::stackActivated(int number)
  378. {
  379. givenCommand = NULL;
  380. activeStack = number;
  381. }
  382. void CBattleInterface::stackMoved(int number, int destHex, bool startMoving, bool endMoving)
  383. {
  384. //a few useful variables
  385. int curStackPos = LOCPLINT->cb->battleGetPos(number);
  386. int steps = creAnims[number]->framesInGroup(0);
  387. int hexWbase = 44, hexHbase = 42;
  388. if(startMoving) //animation of starting move
  389. {
  390. for(int i=0; i<creAnims[number]->framesInGroup(20); ++i)
  391. {
  392. show();
  393. CSDL_Ext::update();
  394. SDL_framerateDelay(LOCPLINT->mainFPSmng);
  395. }
  396. }
  397. int mutPos = CBattleHex::mutualPosition(curStackPos, destHex);
  398. if(LOCPLINT->cb->battleGetCreature(number).isDoubleWide() &&
  399. ((creDir[number] && mutPos == 5) || (creDir[number] && mutPos == 0) || (creDir[number] && mutPos == 4))) //for special cases
  400. {
  401. switch(CBattleHex::mutualPosition(curStackPos, destHex)) //reverse unit if necessary
  402. {
  403. case 0:
  404. if(creDir[number] == true)
  405. reverseCreature(number, curStackPos, true);
  406. break;
  407. case 1:
  408. if(creDir[number] == false)
  409. reverseCreature(number, curStackPos, true);
  410. break;
  411. case 2:
  412. if(creDir[number] == false)
  413. reverseCreature(number, curStackPos, true);
  414. break;
  415. case 3:
  416. if(creDir[number] == false)
  417. reverseCreature(number, curStackPos, true);
  418. break;
  419. case 4:
  420. if(creDir[number] == true)
  421. reverseCreature(number, curStackPos, true);
  422. break;
  423. case 5:
  424. if(creDir[number] == true)
  425. reverseCreature(number, curStackPos, true);
  426. break;
  427. }
  428. //moving instructions
  429. creAnims[number]->setType(0);
  430. for(int i=0; i<steps; ++i)
  431. {
  432. switch(CBattleHex::mutualPosition(curStackPos, destHex))
  433. {
  434. case 0:
  435. creAnims[number]->pos.x -= hexWbase/(2*steps);
  436. creAnims[number]->pos.y -= hexHbase/steps;
  437. break;
  438. case 1:
  439. creAnims[number]->pos.x += hexWbase/(2*steps);
  440. creAnims[number]->pos.y -= hexHbase/steps;
  441. break;
  442. case 2:
  443. creAnims[number]->pos.x += hexWbase/steps;
  444. break;
  445. case 3:
  446. creAnims[number]->pos.x += hexWbase/(2*steps);
  447. creAnims[number]->pos.y += hexHbase/steps;
  448. break;
  449. case 4:
  450. creAnims[number]->pos.x -= hexWbase/(2*steps);
  451. creAnims[number]->pos.y += hexHbase/steps;
  452. break;
  453. case 5:
  454. creAnims[number]->pos.x -= hexWbase/steps;
  455. break;
  456. }
  457. show();
  458. CSDL_Ext::update();
  459. SDL_framerateDelay(LOCPLINT->mainFPSmng);
  460. }
  461. if( (LOCPLINT->cb->battleGetStackByID(number).owner == attackingHeroInstance->tempOwner ) != creDir[number])
  462. {
  463. reverseCreature(number, curStackPos, true);
  464. }
  465. }
  466. else //normal move instructions
  467. {
  468. switch(CBattleHex::mutualPosition(curStackPos, destHex)) //reverse unit if necessary
  469. {
  470. case 0:
  471. if(creDir[number] == true)
  472. reverseCreature(number, curStackPos);
  473. break;
  474. case 1:
  475. if(creDir[number] == false)
  476. reverseCreature(number, curStackPos);
  477. break;
  478. case 2:
  479. if(creDir[number] == false)
  480. reverseCreature(number, curStackPos);
  481. break;
  482. case 3:
  483. if(creDir[number] == false)
  484. reverseCreature(number, curStackPos);
  485. break;
  486. case 4:
  487. if(creDir[number] == true)
  488. reverseCreature(number, curStackPos);
  489. break;
  490. case 5:
  491. if(creDir[number] == true)
  492. reverseCreature(number, curStackPos);
  493. break;
  494. }
  495. //moving instructions
  496. creAnims[number]->setType(0);
  497. for(int i=0; i<steps; ++i)
  498. {
  499. switch(CBattleHex::mutualPosition(curStackPos, destHex))
  500. {
  501. case 0:
  502. creAnims[number]->pos.x -= hexWbase/(2*steps);
  503. creAnims[number]->pos.y -= hexHbase/steps;
  504. break;
  505. case 1:
  506. creAnims[number]->pos.x += hexWbase/(2*steps);
  507. creAnims[number]->pos.y -= hexHbase/steps;
  508. break;
  509. case 2:
  510. creAnims[number]->pos.x += hexWbase/steps;
  511. break;
  512. case 3:
  513. creAnims[number]->pos.x += hexWbase/(2*steps);
  514. creAnims[number]->pos.y += hexHbase/steps;
  515. break;
  516. case 4:
  517. creAnims[number]->pos.x -= hexWbase/(2*steps);
  518. creAnims[number]->pos.y += hexHbase/steps;
  519. break;
  520. case 5:
  521. creAnims[number]->pos.x -= hexWbase/steps;
  522. break;
  523. }
  524. show();
  525. CSDL_Ext::update();
  526. SDL_framerateDelay(LOCPLINT->mainFPSmng);
  527. }
  528. }
  529. if(endMoving) //animation of ending move
  530. {
  531. for(int i=0; i<creAnims[number]->framesInGroup(21); ++i)
  532. {
  533. show();
  534. CSDL_Ext::update();
  535. SDL_framerateDelay(LOCPLINT->mainFPSmng);
  536. }
  537. }
  538. creAnims[number]->setType(2); //resetting to default
  539. CStack curs = LOCPLINT->cb->battleGetStackByID(number);
  540. if(endMoving) //resetting to default
  541. {
  542. if(creDir[number] != (curs.owner == attackingHeroInstance->tempOwner))
  543. reverseCreature(number, destHex);
  544. //creDir[number] = (curs.owner == attackingHeroInstance->tempOwner);
  545. }
  546. std::pair <int, int> coords = CBattleHex::getXYUnitAnim(destHex, creDir[number], curs.creature);
  547. creAnims[number]->pos.x = coords.first;
  548. creAnims[number]->pos.y = coords.second;
  549. }
  550. void CBattleInterface::stackIsAttacked(int ID, int dmg, int killed, int IDby)
  551. {
  552. creAnims[ID]->setType(3); //getting hit
  553. for(int i=0; i<creAnims[ID]->framesInGroup(3); ++i)
  554. {
  555. show();
  556. CSDL_Ext::update();
  557. SDL_framerateDelay(LOCPLINT->mainFPSmng);
  558. }
  559. creAnims[ID]->setType(2);
  560. printConsoleAttacked(ID, dmg, killed, IDby);
  561. }
  562. void CBattleInterface::stackAttacking(int ID, int dest)
  563. {
  564. CStack aStack = LOCPLINT->cb->battleGetStackByID(ID); //attacking stack
  565. if(aStack.creature->isDoubleWide())
  566. {
  567. switch(CBattleHex::mutualPosition(aStack.position, dest)) //attack direction
  568. {
  569. case 0:
  570. //reverseCreature(ID, aStack.position, true);
  571. break;
  572. case 1:
  573. break;
  574. case 2:
  575. break;
  576. case 3:
  577. break;
  578. case 4:
  579. //reverseCreature(ID, aStack.position, true);
  580. break;
  581. case 5:
  582. reverseCreature(ID, aStack.position, true);
  583. break;
  584. }
  585. }
  586. else //else for if(aStack.creature->isDoubleWide())
  587. {
  588. switch(CBattleHex::mutualPosition(aStack.position, dest)) //attack direction
  589. {
  590. case 0:
  591. reverseCreature(ID, aStack.position, true);
  592. break;
  593. case 1:
  594. break;
  595. case 2:
  596. break;
  597. case 3:
  598. break;
  599. case 4:
  600. reverseCreature(ID, aStack.position, true);
  601. break;
  602. case 5:
  603. reverseCreature(ID, aStack.position, true);
  604. break;
  605. }
  606. }
  607. attackingInfo = new CAttHelper;
  608. attackingInfo->dest = dest;
  609. attackingInfo->frame = 0;
  610. attackingInfo->ID = ID;
  611. attackingInfo->reversing = false;
  612. if(aStack.creature->isDoubleWide())
  613. {
  614. switch(CBattleHex::mutualPosition(aStack.position, dest)) //attack direction
  615. {
  616. case 0:
  617. attackingInfo->maxframe = creAnims[ID]->framesInGroup(10);
  618. break;
  619. case 1:
  620. attackingInfo->maxframe = creAnims[ID]->framesInGroup(10);
  621. break;
  622. case 2:
  623. attackingInfo->maxframe = creAnims[ID]->framesInGroup(11);
  624. break;
  625. case 3:
  626. attackingInfo->maxframe = creAnims[ID]->framesInGroup(12);
  627. break;
  628. case 4:
  629. attackingInfo->maxframe = creAnims[ID]->framesInGroup(12);
  630. break;
  631. case 5:
  632. attackingInfo->maxframe = creAnims[ID]->framesInGroup(11);
  633. break;
  634. }
  635. }
  636. else //else for if(aStack.creature->isDoubleWide())
  637. {
  638. switch(CBattleHex::mutualPosition(aStack.position, dest)) //attack direction
  639. {
  640. case 0:
  641. attackingInfo->maxframe = creAnims[ID]->framesInGroup(10);
  642. break;
  643. case 1:
  644. attackingInfo->maxframe = creAnims[ID]->framesInGroup(10);
  645. break;
  646. case 2:
  647. attackingInfo->maxframe = creAnims[ID]->framesInGroup(11);
  648. break;
  649. case 3:
  650. attackingInfo->maxframe = creAnims[ID]->framesInGroup(12);
  651. break;
  652. case 4:
  653. attackingInfo->maxframe = creAnims[ID]->framesInGroup(12);
  654. break;
  655. case 5:
  656. attackingInfo->maxframe = creAnims[ID]->framesInGroup(11);
  657. break;
  658. }
  659. }
  660. }
  661. void CBattleInterface::newRound(int number)
  662. {
  663. console->addText(CGI->generaltexth->allTexts[412]);
  664. }
  665. void CBattleInterface::hexLclicked(int whichOne)
  666. {
  667. if((whichOne%17)!=0 && (whichOne%17)!=16) //if player is trying to attack enemey unit or move creature stack
  668. {
  669. int atCre = LOCPLINT->cb->battleGetStack(whichOne); //creature at destination tile; -1 if there is no one
  670. //LOCPLINT->cb->battleGetCreature();
  671. if(atCre==-1) //normal move action
  672. {
  673. BattleAction * ba = new BattleAction(); //to be deleted by engine
  674. ba->actionType = 2;
  675. ba->destinationTile = whichOne;
  676. ba->stackNumber = activeStack;
  677. givenCommand = ba;
  678. }
  679. else if(LOCPLINT->cb->battleGetStackByID(atCre).owner != attackingHeroInstance->tempOwner) //attacking
  680. {
  681. BattleAction * ba = new BattleAction(); //to be deleted by engine
  682. ba->actionType = 6;
  683. ba->destinationTile = whichOne;
  684. ba->stackNumber = activeStack;
  685. givenCommand = ba;
  686. }
  687. }
  688. }
  689. void CBattleInterface::showRange(SDL_Surface * to, int ID)
  690. {
  691. std::vector<int> shadedHexes = LOCPLINT->cb->battleGetAvailableHexes(ID);
  692. for(int i=0; i<shadedHexes.size(); ++i)
  693. {
  694. CSDL_Ext::blit8bppAlphaTo24bpp(CBattleInterface::cellShade, NULL, to, &bfield[shadedHexes[i]].pos);
  695. }
  696. }
  697. void CBattleInterface::attackingShowHelper()
  698. {
  699. if(attackingInfo && !attackingInfo->reversing)
  700. {
  701. if(attackingInfo->frame == 0)
  702. {
  703. CStack aStack = LOCPLINT->cb->battleGetStackByID(attackingInfo->ID); //attacking stack
  704. if(aStack.creature->isDoubleWide())
  705. {
  706. switch(CBattleHex::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction
  707. {
  708. case 0:
  709. creAnims[attackingInfo->ID]->setType(10);
  710. break;
  711. case 1:
  712. creAnims[attackingInfo->ID]->setType(10);
  713. break;
  714. case 2:
  715. creAnims[attackingInfo->ID]->setType(11);
  716. break;
  717. case 3:
  718. creAnims[attackingInfo->ID]->setType(12);
  719. break;
  720. case 4:
  721. creAnims[attackingInfo->ID]->setType(12);
  722. break;
  723. case 5:
  724. creAnims[attackingInfo->ID]->setType(11);
  725. break;
  726. }
  727. }
  728. else //else for if(aStack.creature->isDoubleWide())
  729. {
  730. switch(CBattleHex::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction
  731. {
  732. case 0:
  733. creAnims[attackingInfo->ID]->setType(10);
  734. break;
  735. case 1:
  736. creAnims[attackingInfo->ID]->setType(10);
  737. break;
  738. case 2:
  739. creAnims[attackingInfo->ID]->setType(11);
  740. break;
  741. case 3:
  742. creAnims[attackingInfo->ID]->setType(12);
  743. break;
  744. case 4:
  745. creAnims[attackingInfo->ID]->setType(12);
  746. break;
  747. case 5:
  748. creAnims[attackingInfo->ID]->setType(11);
  749. break;
  750. }
  751. }
  752. }
  753. else if(attackingInfo->frame == (attackingInfo->maxframe - 1))
  754. {
  755. attackingInfo->reversing = true;
  756. CStack aStack = LOCPLINT->cb->battleGetStackByID(attackingInfo->ID); //attacking stack
  757. if(aStack.creature->isDoubleWide())
  758. {
  759. switch(CBattleHex::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction
  760. {
  761. case 0:
  762. //reverseCreature(ID, aStack.position, true);
  763. break;
  764. case 1:
  765. break;
  766. case 2:
  767. break;
  768. case 3:
  769. break;
  770. case 4:
  771. //reverseCreature(ID, aStack.position, true);
  772. break;
  773. case 5:
  774. reverseCreature(attackingInfo->ID, aStack.position, true);
  775. break;
  776. }
  777. }
  778. else //else for if(aStack.creature->isDoubleWide())
  779. {
  780. switch(CBattleHex::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction
  781. {
  782. case 0:
  783. reverseCreature(attackingInfo->ID, aStack.position, true);
  784. break;
  785. case 1:
  786. break;
  787. case 2:
  788. break;
  789. case 3:
  790. break;
  791. case 4:
  792. reverseCreature(attackingInfo->ID, aStack.position, true);
  793. break;
  794. case 5:
  795. reverseCreature(attackingInfo->ID, aStack.position, true);
  796. break;
  797. }
  798. }
  799. attackingInfo->reversing = false;
  800. creAnims[attackingInfo->ID]->setType(2);
  801. delete attackingInfo;
  802. attackingInfo = NULL;
  803. }
  804. if(attackingInfo)
  805. {
  806. attackingInfo->frame++;
  807. }
  808. }
  809. }
  810. void CBattleInterface::printConsoleAttacked(int ID, int dmg, int killed, int IDby)
  811. {
  812. char tabh[200];
  813. CStack attacker = LOCPLINT->cb->battleGetStackByID(IDby);
  814. CStack defender = LOCPLINT->cb->battleGetStackByID(ID);
  815. int end = sprintf(tabh, CGI->generaltexth->allTexts[attacker.amount > 1 ? 377 : 376].c_str(),
  816. (attacker.amount > 1 ? attacker.creature->namePl.c_str() : attacker.creature->nameSing.c_str()),
  817. dmg);
  818. if(killed > 0)
  819. {
  820. if(killed > 1)
  821. {
  822. sprintf(tabh + end, CGI->generaltexth->allTexts[379].c_str(), killed, defender.creature->namePl.c_str());
  823. }
  824. else //killed == 1
  825. {
  826. sprintf(tabh + end, CGI->generaltexth->allTexts[378].c_str(), defender.creature->nameSing.c_str());
  827. }
  828. }
  829. console->addText(std::string(tabh));
  830. }
  831. void CBattleHero::show(SDL_Surface *to)
  832. {
  833. //animation of flag
  834. if(flip)
  835. {
  836. CSDL_Ext::blit8bppAlphaTo24bpp(flag->ourImages[flagAnim].bitmap, NULL, screen, &genRect(flag->ourImages[flagAnim].bitmap->h, flag->ourImages[flagAnim].bitmap->w, 752, 39));
  837. }
  838. else
  839. {
  840. CSDL_Ext::blit8bppAlphaTo24bpp(flag->ourImages[flagAnim].bitmap, NULL, screen, &genRect(flag->ourImages[flagAnim].bitmap->h, flag->ourImages[flagAnim].bitmap->w, 31, 39));
  841. }
  842. {
  843. ++flagAnim;
  844. flagAnim %= flag->ourImages.size();
  845. }
  846. //animation of hero
  847. int tick=-1;
  848. for(int i=0; i<dh->ourImages.size(); ++i)
  849. {
  850. if(dh->ourImages[i].groupNumber==phase)
  851. ++tick;
  852. if(tick==image)
  853. {
  854. SDL_Rect posb = pos;
  855. CSDL_Ext::blit8bppAlphaTo24bpp(dh->ourImages[i].bitmap, NULL, to, &posb);
  856. ++image;
  857. if(dh->ourImages[i+1].groupNumber!=phase) //back to appropriate frame
  858. {
  859. image = 0;
  860. }
  861. break;
  862. }
  863. }
  864. }
  865. CBattleHero::CBattleHero(std::string defName, int phaseG, int imageG, bool flipG, unsigned char player): phase(phaseG), image(imageG), flip(flipG), flagAnim(0)
  866. {
  867. dh = CDefHandler::giveDef( defName );
  868. for(int i=0; i<dh->ourImages.size(); ++i) //transforming images
  869. {
  870. if(flip)
  871. {
  872. SDL_Surface * hlp = CSDL_Ext::rotate01(dh->ourImages[i].bitmap);
  873. SDL_FreeSurface(dh->ourImages[i].bitmap);
  874. dh->ourImages[i].bitmap = hlp;
  875. }
  876. dh->ourImages[i].bitmap = CSDL_Ext::alphaTransform(dh->ourImages[i].bitmap);
  877. }
  878. dh->alphaTransformed = true;
  879. if(flip)
  880. flag = CDefHandler::giveDef("CMFLAGR.DEF");
  881. else
  882. flag = CDefHandler::giveDef("CMFLAGL.DEF");
  883. //coloring flag and adding transparency
  884. for(int i=0; i<flag->ourImages.size(); ++i)
  885. {
  886. flag->ourImages[i].bitmap = CSDL_Ext::alphaTransform(flag->ourImages[i].bitmap);
  887. graphics->blueToPlayersAdv(flag->ourImages[i].bitmap, player);
  888. }
  889. }
  890. CBattleHero::~CBattleHero()
  891. {
  892. delete dh;
  893. delete flag;
  894. }
  895. std::pair<int, int> CBattleHex::getXYUnitAnim(int hexNum, bool attacker, CCreature * creature)
  896. {
  897. std::pair<int, int> ret = std::make_pair(-500, -500); //returned value
  898. ret.second = -139 + 42 * (hexNum/17); //counting y
  899. //counting x
  900. if(attacker)
  901. {
  902. ret.first = -160 + 22 * ( ((hexNum/17) + 1)%2 ) + 44 * (hexNum % 17);
  903. }
  904. else
  905. {
  906. ret.first = -219 + 22 * ( ((hexNum/17) + 1)%2 ) + 44 * (hexNum % 17);
  907. }
  908. //shifting position for double - hex creatures
  909. if(creature->isDoubleWide())
  910. {
  911. if(attacker)
  912. {
  913. ret.first -= 42;
  914. }
  915. else
  916. {
  917. ret.first += 42;
  918. }
  919. }
  920. //returning
  921. return ret;
  922. }
  923. signed char CBattleHex::mutualPosition(int hex1, int hex2)
  924. {
  925. if(hex2 == hex1 - ( (hex1/17)%2 ? 18 : 17 )) //top left
  926. return 0;
  927. if(hex2 == hex1 - ( (hex1/17)%2 ? 17 : 16 )) //top right
  928. return 1;
  929. if(hex2 == hex1 - 1 && hex1%17 != 0) //left
  930. return 5;
  931. if(hex2 == hex1 + 1 && hex1%17 != 16) //right
  932. return 2;
  933. if(hex2 == hex1 + ( (hex1/17)%2 ? 16 : 17 )) //bottom left
  934. return 4;
  935. if(hex2 == hex1 + ( (hex1/17)%2 ? 17 : 18 )) //bottom right
  936. return 3;
  937. return -1;
  938. }
  939. void CBattleHex::activate()
  940. {
  941. Hoverable::activate();
  942. MotionInterested::activate();
  943. ClickableL::activate();
  944. ClickableR::activate();
  945. }
  946. void CBattleHex::deactivate()
  947. {
  948. Hoverable::deactivate();
  949. MotionInterested::deactivate();
  950. ClickableL::deactivate();
  951. ClickableR::deactivate();
  952. }
  953. void CBattleHex::hover(bool on)
  954. {
  955. hovered = on;
  956. Hoverable::hover(on);
  957. if(!on && setAlterText)
  958. {
  959. myInterface->console->alterTxt = std::string();
  960. setAlterText = false;
  961. }
  962. }
  963. CBattleHex::CBattleHex() : myNumber(-1), accesible(true), hovered(false), strictHovered(false), myInterface(NULL), setAlterText(false)
  964. {
  965. }
  966. void CBattleHex::mouseMoved(SDL_MouseMotionEvent &sEvent)
  967. {
  968. if(CBattleInterface::cellShade)
  969. {
  970. if(CSDL_Ext::SDL_GetPixel(CBattleInterface::cellShade, sEvent.x-pos.x, sEvent.y-pos.y) == 0) //hovered pixel is outside hex
  971. {
  972. strictHovered = false;
  973. }
  974. else //hovered pixel is inside hex
  975. {
  976. strictHovered = true;
  977. }
  978. }
  979. if(hovered && strictHovered) //print attacked creature to console
  980. {
  981. if(myInterface->console->alterTxt.size() == 0 && LOCPLINT->cb->battleGetStack(myNumber) != -1 &&
  982. LOCPLINT->cb->battleGetStackByPos(myNumber).owner != LOCPLINT->playerID &&
  983. LOCPLINT->cb->battleGetStackByPos(myNumber).alive)
  984. {
  985. char tabh[160];
  986. CStack attackedStack = LOCPLINT->cb->battleGetStackByPos(myNumber);
  987. std::string attackedName = attackedStack.amount == 1 ? attackedStack.creature->nameSing : attackedStack.creature->namePl;
  988. sprintf(tabh, CGI->generaltexth->allTexts[220].c_str(), attackedName.c_str());
  989. myInterface->console->alterTxt = std::string(tabh);
  990. setAlterText = true;
  991. }
  992. }
  993. else if(setAlterText)
  994. {
  995. myInterface->console->alterTxt = std::string();
  996. setAlterText = false;
  997. }
  998. }
  999. void CBattleHex::clickLeft(boost::logic::tribool down)
  1000. {
  1001. if(!down && hovered && strictHovered) //we've been really clicked!
  1002. {
  1003. myInterface->hexLclicked(myNumber);
  1004. }
  1005. }
  1006. void CBattleHex::clickRight(boost::logic::tribool down)
  1007. {
  1008. int stID = LOCPLINT->cb->battleGetStack(myNumber); //id of stack being on this tile
  1009. if(hovered && strictHovered && stID!=-1)
  1010. {
  1011. CStack myst = LOCPLINT->cb->battleGetStackByID(stID); //stack info
  1012. StackState *pom = NULL;
  1013. if(down)
  1014. {
  1015. pom = new StackState();
  1016. const CGHeroInstance *h = myst.owner == myInterface->attackingHeroInstance->tempOwner ? myInterface->attackingHeroInstance : myInterface->defendingHeroInstance;
  1017. if(h)
  1018. {
  1019. pom->attackBonus = h->primSkills[0];
  1020. pom->defenseBonus = h->primSkills[1];
  1021. pom->luck = h->getCurrentLuck();
  1022. pom->morale = h->getCurrentMorale();
  1023. }
  1024. (new CCreInfoWindow(myst.creature->idNumber,0,pom,boost::function<void()>(),boost::function<void()>()))
  1025. ->activate();
  1026. }
  1027. delete pom;
  1028. }
  1029. }
  1030. CBattleConsole::CBattleConsole() : lastShown(-1), alterTxt("")
  1031. {
  1032. }
  1033. CBattleConsole::~CBattleConsole()
  1034. {
  1035. texts.clear();
  1036. }
  1037. void CBattleConsole::show(SDL_Surface * to)
  1038. {
  1039. if(alterTxt.size())
  1040. {
  1041. CSDL_Ext::printAtMiddleWB(alterTxt, pos.x + pos.w/2, pos.y + 10, GEOR13, 80, zwykly, to);
  1042. }
  1043. else if(texts.size())
  1044. {
  1045. if(texts.size()==1)
  1046. {
  1047. CSDL_Ext::printAtMiddleWB(texts[0], pos.x + pos.w/2, pos.y + 10, GEOR13, 80, zwykly, to);
  1048. }
  1049. else
  1050. {
  1051. CSDL_Ext::printAtMiddleWB(texts[lastShown-1], pos.x + pos.w/2, pos.y + 10, GEOR13, 80, zwykly, to);
  1052. CSDL_Ext::printAtMiddleWB(texts[lastShown], pos.x + pos.w/2, pos.y + 26, GEOR13, 80, zwykly, to);
  1053. }
  1054. }
  1055. }
  1056. bool CBattleConsole::addText(std::string text)
  1057. {
  1058. if(text.size()>70)
  1059. return false; //text too long!
  1060. int firstInToken = 0;
  1061. for(int i=0; i<text.size(); ++i) //tokenize
  1062. {
  1063. if(text[i] == 10)
  1064. {
  1065. texts.push_back( text.substr(firstInToken, i-firstInToken) );
  1066. firstInToken = i+1;
  1067. }
  1068. }
  1069. texts.push_back( text.substr(firstInToken, text.size()) );
  1070. lastShown = texts.size()-1;
  1071. return true;
  1072. }
  1073. void CBattleConsole::eraseText(unsigned int pos)
  1074. {
  1075. if(pos < texts.size())
  1076. {
  1077. texts.erase(texts.begin() + pos);
  1078. if(lastShown == texts.size())
  1079. --lastShown;
  1080. }
  1081. }
  1082. void CBattleConsole::changeTextAt(std::string text, unsigned int pos)
  1083. {
  1084. if(pos >= texts.size()) //no such pos
  1085. return;
  1086. texts[pos] = text;
  1087. }
  1088. void CBattleConsole::scrollUp(unsigned int by)
  1089. {
  1090. if(lastShown > by)
  1091. lastShown -= by;
  1092. }
  1093. void CBattleConsole::scrollDown(unsigned int by)
  1094. {
  1095. if(lastShown + by < texts.size())
  1096. lastShown += by;
  1097. }