CBattleInterface.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  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 <queue>
  12. extern SDL_Surface * screen;
  13. SDL_Surface * CBattleInterface::cellBorder, * CBattleInterface::cellShade;
  14. CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2)
  15. : printCellBorders(true), attackingHeroInstance(hero1), defendingHeroInstance(hero2), animCount(0), activeStack(-1), curStackActed(false)
  16. {
  17. //initializing armies
  18. this->army1 = army1;
  19. this->army2 = army2;
  20. std::map<int, CStack> stacks = LOCPLINT->cb->battleGetStacks();
  21. for(std::map<int, CStack>::iterator b=stacks.begin(); b!=stacks.end(); ++b)
  22. {
  23. creAnims[b->second.ID] = (new CCreatureAnimation(b->second.creature->animDefName));
  24. creAnims[b->second.ID]->setType(2);
  25. }
  26. //preparing menu background and terrain
  27. std::vector< std::string > & backref = CGI->mh->battleBacks[ LOCPLINT->cb->battleGetBattlefieldType() ];
  28. background = CGI->bitmaph->loadBitmap(backref[ rand() % backref.size()] );
  29. menu = CGI->bitmaph->loadBitmap("CBAR.BMP");
  30. CSDL_Ext::blueToPlayersAdv(menu, hero1->tempOwner);
  31. //blitting menu background and terrain
  32. blitAt(background, 0, 0);
  33. blitAt(menu, 0, 556);
  34. CSDL_Ext::update();
  35. //preparing buttons
  36. bOptions = new AdventureMapButton<CBattleInterface> (std::string(), std::string(), &CBattleInterface::bOptionsf, 3, 561, "icm003.def", this, false, NULL, false);
  37. bSurrender = new AdventureMapButton<CBattleInterface> (std::string(), std::string(), &CBattleInterface::bSurrenderf, 54, 561, "icm001.def", this, false, NULL, false);
  38. bFlee = new AdventureMapButton<CBattleInterface> (std::string(), std::string(), &CBattleInterface::bFleef, 105, 561, "icm002.def", this, false, NULL, false);
  39. bAutofight = new AdventureMapButton<CBattleInterface> (std::string(), std::string(), &CBattleInterface::bAutofightf, 157, 561, "icm004.def", this, false, NULL, false);
  40. bSpell = new AdventureMapButton<CBattleInterface> (std::string(), std::string(), &CBattleInterface::bSpellf, 645, 561, "icm005.def", this, false, NULL, false);
  41. bWait = new AdventureMapButton<CBattleInterface> (std::string(), std::string(), &CBattleInterface::bWaitf, 696, 561, "icm006.def", this, false, NULL, false);
  42. bDefence = new AdventureMapButton<CBattleInterface> (std::string(), std::string(), &CBattleInterface::bDefencef, 747, 561, "icm007.def", this, false, NULL, false);
  43. bConsoleUp = new AdventureMapButton<CBattleInterface> (std::string(), std::string(), &CBattleInterface::bConsoleUpf, 624, 561, "ComSlide.def", this, false, NULL, false);
  44. bConsoleDown = new AdventureMapButton<CBattleInterface> (std::string(), std::string(), &CBattleInterface::bConsoleDownf, 624, 580, "ComSlide.def", this, false, NULL, false);
  45. bConsoleDown->bitmapOffset = 2;
  46. //loading hero animations
  47. if(hero1) // attacking hero
  48. {
  49. attackingHero = new CBattleHero(CGI->mh->battleHeroes[hero1->type->heroType], 0, 0, false, hero1->tempOwner);
  50. attackingHero->pos = genRect(attackingHero->dh->ourImages[0].bitmap->h, attackingHero->dh->ourImages[0].bitmap->w, -40, 0);
  51. }
  52. else
  53. {
  54. attackingHero = NULL;
  55. }
  56. if(hero2) // defending hero
  57. {
  58. defendingHero = new CBattleHero(CGI->mh->battleHeroes[hero2->type->heroType], 0, 0, true, hero2->tempOwner);
  59. defendingHero->pos = genRect(defendingHero->dh->ourImages[0].bitmap->h, defendingHero->dh->ourImages[0].bitmap->w, 690, 0);
  60. }
  61. else
  62. {
  63. defendingHero = NULL;
  64. }
  65. //preparing cells and hexes
  66. cellBorder = CGI->bitmaph->loadBitmap("CCELLGRD.BMP");
  67. cellBorder = CSDL_Ext::alphaTransform(cellBorder);
  68. cellShade = CGI->bitmaph->loadBitmap("CCELLSHD.BMP");
  69. cellShade = CSDL_Ext::alphaTransform(cellShade);
  70. for(int h=0; h<187; ++h)
  71. {
  72. bfield[h].myNumber = h;
  73. int x = 14 + ((h/17)%2==0 ? 22 : 0) + 44*(h%17);
  74. int y = 86 + 42 * (h/17);
  75. bfield[h].pos = genRect(cellShade->h, cellShade->w, x, y);
  76. bfield[h].accesible = true;
  77. bfield[h].myInterface = this;
  78. }
  79. //locking occupied positions on batlefield
  80. for(std::map<int, CStack>::iterator it = stacks.begin(); it!=stacks.end(); ++it) //stacks gained at top of this function
  81. {
  82. bfield[it->second.position].accesible = false;
  83. }
  84. }
  85. CBattleInterface::~CBattleInterface()
  86. {
  87. SDL_FreeSurface(background);
  88. SDL_FreeSurface(menu);
  89. delete bOptions;
  90. delete bSurrender;
  91. delete bFlee;
  92. delete bAutofight;
  93. delete bSpell;
  94. delete bWait;
  95. delete bDefence;
  96. delete bConsoleUp;
  97. delete bConsoleDown;
  98. delete attackingHero;
  99. delete defendingHero;
  100. SDL_FreeSurface(cellBorder);
  101. SDL_FreeSurface(cellShade);
  102. for(int g=0; g<creAnims.size(); ++g)
  103. delete creAnims[g];
  104. }
  105. void CBattleInterface::activate()
  106. {
  107. bOptions->activate();
  108. bSurrender->activate();
  109. bFlee->activate();
  110. bAutofight->activate();
  111. bSpell->activate();
  112. bWait->activate();
  113. bDefence->activate();
  114. bConsoleUp->activate();
  115. bConsoleDown->activate();
  116. for(int b=0; b<187; ++b)
  117. {
  118. bfield[b].activate();
  119. }
  120. }
  121. void CBattleInterface::deactivate()
  122. {
  123. bOptions->deactivate();
  124. bSurrender->deactivate();
  125. bFlee->deactivate();
  126. bAutofight->deactivate();
  127. bSpell->deactivate();
  128. bWait->deactivate();
  129. bDefence->deactivate();
  130. bConsoleUp->deactivate();
  131. bConsoleDown->deactivate();
  132. for(int b=0; b<187; ++b)
  133. {
  134. bfield[b].deactivate();
  135. }
  136. }
  137. void CBattleInterface::show(SDL_Surface * to)
  138. {
  139. std::map<int, CStack> stacks = LOCPLINT->cb->battleGetStacks(); //used in a few places
  140. ++animCount;
  141. if(!to) //"evaluating" to
  142. to = screen;
  143. //showing background
  144. blitAt(background, 0, 0, to);
  145. if(printCellBorders) //printing cell borders
  146. {
  147. for(int i=0; i<11; ++i) //rows
  148. {
  149. for(int j=0; j<15; ++j) //columns
  150. {
  151. int x = 58 + (i%2==0 ? 22 : 0) + 44*j;
  152. int y = 86 + 42 * i;
  153. CSDL_Ext::blit8bppAlphaTo24bpp(cellBorder, NULL, to, &genRect(cellBorder->h, cellBorder->w, x, y));
  154. }
  155. }
  156. }
  157. //printing hovered cell
  158. for(int b=0; b<187; ++b)
  159. {
  160. if(bfield[b].strictHovered && bfield[b].hovered)
  161. {
  162. int x = 14 + ((b/17)%2==0 ? 22 : 0) + 44*(b%17);
  163. int y = 86 + 42 * (b/17);
  164. CSDL_Ext::blit8bppAlphaTo24bpp(cellShade, NULL, to, &genRect(cellShade->h, cellShade->w, x, y));
  165. }
  166. }
  167. //showing selected unit's range
  168. showRange(to, activeStack);
  169. //showing menu background
  170. blitAt(menu, 0, 556, to);
  171. //showing buttons
  172. bOptions->show(to);
  173. bSurrender->show(to);
  174. bFlee->show(to);
  175. bAutofight->show(to);
  176. bSpell->show(to);
  177. bWait->show(to);
  178. bDefence->show(to);
  179. bConsoleUp->show(to);
  180. bConsoleDown->show(to);
  181. //showing hero animations
  182. if(attackingHero)
  183. attackingHero->show(to);
  184. if(defendingHero)
  185. defendingHero->show(to);
  186. //showing units //a lot of work...
  187. for(std::map<int, CCreatureAnimation*>::iterator j=creAnims.begin(); j!=creAnims.end(); ++j)
  188. {
  189. std::pair <int, int> coords = CBattleHex::getXYUnitAnim(stacks[j->first].position, stacks[j->first].owner == attackingHeroInstance->tempOwner);
  190. j->second->nextFrame(to, coords.first, coords.second, stacks[j->first].owner == attackingHeroInstance->tempOwner, animCount%2==0, j->first==activeStack);
  191. }
  192. //units shown
  193. CSDL_Ext::update();
  194. }
  195. void CBattleInterface::bOptionsf()
  196. {
  197. }
  198. void CBattleInterface::bSurrenderf()
  199. {
  200. }
  201. void CBattleInterface::bFleef()
  202. {
  203. for(int i=0; i<LOCPLINT->objsToBlit.size(); ++i)
  204. {
  205. if( dynamic_cast<CBattleInterface*>( LOCPLINT->objsToBlit[i] ) )
  206. {
  207. LOCPLINT->objsToBlit.erase(LOCPLINT->objsToBlit.begin()+i);
  208. }
  209. }
  210. deactivate();
  211. LOCPLINT->adventureInt->activate();
  212. delete this;
  213. }
  214. void CBattleInterface::bAutofightf()
  215. {
  216. }
  217. void CBattleInterface::bSpellf()
  218. {
  219. }
  220. void CBattleInterface::bWaitf()
  221. {
  222. }
  223. void CBattleInterface::bDefencef()
  224. {
  225. }
  226. void CBattleInterface::bConsoleUpf()
  227. {
  228. }
  229. void CBattleInterface::bConsoleDownf()
  230. {
  231. }
  232. void CBattleInterface::newStack(CStack stack)
  233. {
  234. creAnims[stack.ID] = new CCreatureAnimation(stack.creature->animDefName);
  235. creAnims[stack.ID]->setType(2);
  236. }
  237. void CBattleInterface::stackRemoved(CStack stack)
  238. {
  239. delete creAnims[stack.ID];
  240. creAnims.erase(stack.ID);
  241. }
  242. void CBattleInterface::stackActivated(int number)
  243. {
  244. curStackActed = false;
  245. activeStack = number;
  246. }
  247. void CBattleInterface::stackMoved(int number, int destHex)
  248. {
  249. int curStackPos = LOCPLINT->cb->battleGetPos(number);
  250. for(int i=0; i<6; ++i)
  251. {
  252. //creAnims[number]->setType(0);
  253. }
  254. }
  255. void CBattleInterface::hexLclicked(int whichOne)
  256. {
  257. if((whichOne%17)!=0 && (whichOne%17)!=16)
  258. {
  259. LOCPLINT->cb->battleMoveCreature(activeStack, whichOne);
  260. }
  261. }
  262. void CBattleInterface::showRange(SDL_Surface * to, int ID)
  263. {
  264. std::vector<int> shadedHexes = LOCPLINT->cb->battleGetAvailableHexes(ID);
  265. for(int i=0; i<shadedHexes.size(); ++i)
  266. {
  267. CSDL_Ext::blit8bppAlphaTo24bpp(CBattleInterface::cellShade, NULL, to, &bfield[shadedHexes[i]].pos);
  268. }
  269. }
  270. void CBattleHero::show(SDL_Surface *to)
  271. {
  272. int tick=-1;
  273. for(int i=0; i<dh->ourImages.size(); ++i)
  274. {
  275. if(dh->ourImages[i].groupNumber==phase)
  276. ++tick;
  277. if(tick==image)
  278. {
  279. SDL_Rect posb = pos;
  280. CSDL_Ext::blit8bppAlphaTo24bpp(dh->ourImages[i].bitmap, NULL, to, &posb);
  281. ++image;
  282. if(dh->ourImages[i+1].groupNumber!=phase) //back to appropriate frame
  283. {
  284. image = 0;
  285. }
  286. break;
  287. }
  288. }
  289. if(flip)
  290. {
  291. CSDL_Ext::blit8bppAlphaTo24bpp(flag->ourImages[flagAnim].bitmap, NULL, screen, &genRect(flag->ourImages[flagAnim].bitmap->h, flag->ourImages[flagAnim].bitmap->w, 752, 39));
  292. }
  293. else
  294. {
  295. CSDL_Ext::blit8bppAlphaTo24bpp(flag->ourImages[flagAnim].bitmap, NULL, screen, &genRect(flag->ourImages[flagAnim].bitmap->h, flag->ourImages[flagAnim].bitmap->w, 31, 39));
  296. }
  297. {
  298. ++flagAnim;
  299. flagAnim %= flag->ourImages.size();
  300. }
  301. }
  302. CBattleHero::CBattleHero(std::string defName, int phaseG, int imageG, bool flipG, unsigned char player): phase(phaseG), image(imageG), flip(flipG), flagAnim(0)
  303. {
  304. dh = CGI->spriteh->giveDef( defName );
  305. for(int i=0; i<dh->ourImages.size(); ++i) //transforming images
  306. {
  307. if(flip)
  308. dh->ourImages[i].bitmap = CSDL_Ext::rotate01(dh->ourImages[i].bitmap);
  309. dh->ourImages[i].bitmap = CSDL_Ext::alphaTransform(dh->ourImages[i].bitmap);
  310. }
  311. dh->alphaTransformed = true;
  312. if(flip)
  313. flag = CGI->spriteh->giveDef("CMFLAGR.DEF");
  314. else
  315. flag = CGI->spriteh->giveDef("CMFLAGL.DEF");
  316. //coloring flag and adding transparency
  317. for(int i=0; i<flag->ourImages.size(); ++i)
  318. {
  319. flag->ourImages[i].bitmap = CSDL_Ext::alphaTransform(flag->ourImages[i].bitmap);
  320. CSDL_Ext::blueToPlayersAdv(flag->ourImages[i].bitmap, player);
  321. }
  322. }
  323. CBattleHero::~CBattleHero()
  324. {
  325. delete dh;
  326. delete flag;
  327. }
  328. std::pair<int, int> CBattleHex::getXYUnitAnim(int hexNum, bool attacker)
  329. {
  330. std::pair<int, int> ret = std::make_pair(-500, -500); //returned value
  331. ret.second = -139 + 42 * (hexNum/17); //counting y
  332. //counting x
  333. if(attacker)
  334. {
  335. ret.first = -160 + 22 * ( ((hexNum/17) + 1)%2 ) + 44 * (hexNum % 17);
  336. }
  337. else
  338. {
  339. ret.first = -219 + 22 * ( ((hexNum/17) + 1)%2 ) + 44 * (hexNum % 17);
  340. }
  341. //returning
  342. return ret;
  343. }
  344. void CBattleHex::activate()
  345. {
  346. Hoverable::activate();
  347. MotionInterested::activate();
  348. ClickableL::activate();
  349. }
  350. void CBattleHex::deactivate()
  351. {
  352. Hoverable::deactivate();
  353. MotionInterested::deactivate();
  354. ClickableL::deactivate();
  355. }
  356. void CBattleHex::hover(bool on)
  357. {
  358. hovered = on;
  359. Hoverable::hover(on);
  360. }
  361. CBattleHex::CBattleHex() : myNumber(-1), accesible(true), hovered(false), strictHovered(false), myInterface(NULL)
  362. {
  363. }
  364. void CBattleHex::mouseMoved(SDL_MouseMotionEvent &sEvent)
  365. {
  366. if(CBattleInterface::cellShade)
  367. {
  368. if(CSDL_Ext::SDL_GetPixel(CBattleInterface::cellShade, sEvent.x-pos.x, sEvent.y-pos.y) == 0) //hovered pixel is outside hex
  369. {
  370. strictHovered = false;
  371. }
  372. else //hovered pixel is inside hex
  373. {
  374. strictHovered = true;
  375. }
  376. }
  377. }
  378. void CBattleHex::clickLeft(boost::logic::tribool down)
  379. {
  380. if(!down && hovered && strictHovered) //we've been really clicked!
  381. {
  382. myInterface->hexLclicked(myNumber);
  383. }
  384. }