CCastleInterface.cpp 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046
  1. #include "stdafx.h"
  2. #include "CCastleInterface.h"
  3. #include "hch/CObjectHandler.h"
  4. #include "CGameInfo.h"
  5. #include "hch/CLodHandler.h"
  6. #include "SDL_Extensions.h"
  7. #include "CAdvmapInterface.h"
  8. #include "hch/CTownHandler.h"
  9. #include "AdventureMapButton.h"
  10. #include "hch/CBuildingHandler.h"
  11. #include <sstream>
  12. #include "CMessage.h"
  13. #include "hch/CGeneralTextHandler.h"
  14. #include "CCallback.h"
  15. extern TTF_Font * GEOR16;
  16. CBuildingRect::CBuildingRect(Structure *Str)
  17. :str(Str), moi(false), offset(0)
  18. {
  19. def = CGI->spriteh->giveDef(Str->defName);
  20. max = def->ourImages.size();
  21. if(str->ID == 33 && str->townID == 4) //little 'hack' for estate in necropolis - background color is not always the first color in the palette
  22. {
  23. for(std::vector<Cimage>::iterator i=def->ourImages.begin();i!=def->ourImages.end();i++)
  24. {
  25. SDL_SetColorKey(i->bitmap,SDL_SRCCOLORKEY,*((char*)i->bitmap->pixels));
  26. }
  27. }
  28. pos.x = str->pos.x;
  29. pos.y = str->pos.y;
  30. pos.w = def->ourImages[0].bitmap->w;
  31. pos.h = def->ourImages[0].bitmap->h;
  32. if(Str->ID<0 || (Str->ID>=27 && Str->ID<=29))
  33. {
  34. area = border = NULL;
  35. return;
  36. }
  37. if (border = CGI->bitmaph->loadBitmap(str->borderName))
  38. SDL_SetColorKey(border,SDL_SRCCOLORKEY,SDL_MapRGB(border->format,0,255,255));
  39. else
  40. std::cout << "Warning: no border for "<<Str->ID<<std::endl;
  41. if (area = CGI->bitmaph->loadBitmap(str->areaName))
  42. ;//SDL_SetColorKey(area,SDL_SRCCOLORKEY,SDL_MapRGB(area->format,0,255,255));
  43. else
  44. std::cout << "Warning: no area for "<<Str->ID<<std::endl;
  45. }
  46. CBuildingRect::~CBuildingRect()
  47. {
  48. delete def;
  49. if(border)
  50. SDL_FreeSurface(border);
  51. if(area)
  52. SDL_FreeSurface(area);
  53. }
  54. void CBuildingRect::activate()
  55. {
  56. Hoverable::activate();
  57. ClickableL::activate();
  58. ClickableR::activate();
  59. }
  60. void CBuildingRect::deactivate()
  61. {
  62. Hoverable::deactivate();
  63. ClickableL::deactivate();
  64. ClickableR::deactivate();
  65. if(moi)
  66. MotionInterested::deactivate();
  67. moi=false;
  68. }
  69. bool CBuildingRect::operator<(const CBuildingRect & p2) const
  70. {
  71. if(str->pos.z != p2.str->pos.z)
  72. return (str->pos.z) < (p2.str->pos.z);
  73. else
  74. return (str->ID) < (p2.str->ID);
  75. }
  76. void CBuildingRect::hover(bool on)
  77. {
  78. Hoverable::hover(on);
  79. if(on)
  80. {
  81. if(!moi)
  82. MotionInterested::activate();
  83. moi = true;
  84. }
  85. else
  86. {
  87. if(moi)
  88. MotionInterested::deactivate();
  89. moi = false;
  90. if(LOCPLINT->castleInt->hBuild == this)
  91. {
  92. LOCPLINT->castleInt->hBuild = NULL;
  93. LOCPLINT->statusbar->clear();
  94. }
  95. }
  96. }
  97. void CBuildingRect::clickLeft (tribool down)
  98. {
  99. if(area && (LOCPLINT->castleInt->hBuild==this) && !(indeterminate(down)) && (CSDL_Ext::SDL_GetPixel(area,LOCPLINT->current->motion.x-pos.x,LOCPLINT->current->motion.y-pos.y) != 0)) //na polu
  100. {
  101. if(pressedL && !down)
  102. LOCPLINT->castleInt->buildingClicked(str->ID);
  103. ClickableL::clickLeft(down);
  104. }
  105. //todo - handle
  106. }
  107. void CBuildingRect::clickRight (tribool down)
  108. {
  109. if((!area) || (!((bool)down)) || (this!=LOCPLINT->castleInt->hBuild))
  110. return;
  111. if((CSDL_Ext::SDL_GetPixel(area,LOCPLINT->current->motion.x-pos.x,LOCPLINT->current->motion.y-pos.y) != 0)) //na polu
  112. {
  113. CInfoPopup *vinya = new CInfoPopup();
  114. vinya->free = true;
  115. vinya->bitmap = CMessage::drawBoxTextBitmapSub
  116. (LOCPLINT->playerID,
  117. CGI->buildh->buildings[str->townID][str->ID]->description,
  118. LOCPLINT->castleInt->bicons->ourImages[str->ID].bitmap,
  119. CGI->buildh->buildings[str->townID][str->ID]->name);
  120. vinya->pos.x = screen->w/2 - vinya->bitmap->w/2;
  121. vinya->pos.y = screen->h/2 - vinya->bitmap->h/2;
  122. vinya->activate();
  123. }
  124. }
  125. void CBuildingRect::mouseMoved (SDL_MouseMotionEvent & sEvent)
  126. {
  127. if(area)
  128. {
  129. if(CSDL_Ext::SDL_GetPixel(area,sEvent.x-pos.x,sEvent.y-pos.y) == 0) //hovered pixel is inside this building
  130. {
  131. if(LOCPLINT->castleInt->hBuild == this)
  132. {
  133. LOCPLINT->castleInt->hBuild = NULL;
  134. LOCPLINT->statusbar->clear();
  135. }
  136. }
  137. else //inside the area of this building
  138. {
  139. if(LOCPLINT->castleInt->hBuild) //a building is hovered
  140. {
  141. if((*LOCPLINT->castleInt->hBuild)<(*this)) //set if we are on top
  142. {
  143. LOCPLINT->castleInt->hBuild = this;
  144. if(CGI->buildh->buildings[str->townID][str->ID] && CGI->buildh->buildings[str->townID][str->ID]->name.length())
  145. LOCPLINT->statusbar->print(CGI->buildh->buildings[str->townID][str->ID]->name);
  146. else
  147. LOCPLINT->statusbar->print(str->name);
  148. }
  149. }
  150. else //no building hovered
  151. {
  152. LOCPLINT->castleInt->hBuild = this;
  153. if(CGI->buildh->buildings[str->townID][str->ID] && CGI->buildh->buildings[str->townID][str->ID]->name.length())
  154. LOCPLINT->statusbar->print(CGI->buildh->buildings[str->townID][str->ID]->name);
  155. else
  156. LOCPLINT->statusbar->print(str->name);
  157. }
  158. }
  159. }
  160. //if(border)
  161. // blitAt(border,pos.x,pos.y);
  162. }
  163. std::string getBgName(int type) //TODO - co z tym zrobiæ?
  164. {
  165. switch (type)
  166. {
  167. case 0:
  168. return "TBCSBACK.bmp";
  169. case 1:
  170. return "TBRMBACK.bmp";
  171. case 2:
  172. return "TBTWBACK.bmp";
  173. case 3:
  174. return "TBINBACK.bmp";
  175. case 4:
  176. return "TBNCBACK.bmp";
  177. case 5:
  178. return "TBDNBACK.bmp";
  179. case 6:
  180. return "TBSTBACK.bmp";
  181. case 7:
  182. return "TBFRBACK.bmp";
  183. case 8:
  184. return "TBELBACK.bmp";
  185. default:
  186. throw new std::exception("std::string getBgName(int type): invalid type");
  187. }
  188. }
  189. class SORTHELP
  190. {
  191. public:
  192. bool operator ()
  193. (const CBuildingRect *a ,
  194. const CBuildingRect *b)
  195. {
  196. return (*a)<(*b);
  197. }
  198. } srthlp ;
  199. CCastleInterface::CCastleInterface(const CGTownInstance * Town, bool Activate)
  200. {
  201. hall = NULL;
  202. townInt = CGI->bitmaph->loadBitmap("TOWNSCRN.bmp");
  203. cityBg = CGI->bitmaph->loadBitmap(getBgName(Town->subID));
  204. hall = CGI->spriteh->giveDef("ITMTL.DEF");
  205. fort = CGI->spriteh->giveDef("ITMCL.DEF");
  206. flag = CGI->spriteh->giveDef("CREST58.DEF");
  207. hBuild = NULL;
  208. count=0;
  209. town = Town;
  210. //garrison
  211. garr = new CGarrisonInt(305,387,4,32,townInt,243,13,town,town->visitingHero);
  212. townlist = new CTownList(3,&genRect(128,48,744,414),744,414,744,526);
  213. exit = new AdventureMapButton
  214. (CGI->townh->tcommands[8],"",boost::bind(&CCastleInterface::close,this),744,544,"TSBTNS.DEF",false,NULL,false);
  215. split = new AdventureMapButton
  216. (CGI->townh->tcommands[3],"",boost::bind(&CGarrisonInt::splitClick,garr),744,382,"TSBTNS.DEF",false,NULL,false);
  217. statusbar = new CStatusBar(8,555,"TSTATBAR.bmp",732);
  218. townlist->fun = boost::bind(&CCastleInterface::townChange,this);
  219. townlist->genList();
  220. townlist->selected = getIndexOf(townlist->items,Town);
  221. if((townlist->selected+1) > townlist->SIZE)
  222. townlist->from = townlist->selected - townlist->SIZE + 1;
  223. CSDL_Ext::blueToPlayersAdv(townInt,LOCPLINT->playerID);
  224. exit->bitmapOffset = 4;
  225. //buildings
  226. recreateBuildings();
  227. if(Activate)
  228. {
  229. LOCPLINT->objsToBlit.push_back(this);
  230. activate();
  231. showAll();
  232. }
  233. std::string defname;
  234. switch (town->subID)
  235. {
  236. case 0:
  237. defname = "HALLCSTL.DEF";
  238. break;
  239. case 1:
  240. defname = "HALLRAMP.DEF";
  241. break;
  242. case 2:
  243. defname = "HALLTOWR.DEF";
  244. break;
  245. case 3:
  246. defname = "HALLINFR.DEF";
  247. break;
  248. case 4:
  249. defname = "HALLNECR.DEF";
  250. break;
  251. case 5:
  252. defname = "HALLDUNG.DEF";
  253. break;
  254. case 6:
  255. defname = "HALLSTRN.DEF";
  256. break;
  257. case 7:
  258. defname = "HALLFORT.DEF";
  259. break;
  260. case 8:
  261. defname = "HALLELEM.DEF";
  262. break;
  263. default:
  264. throw new std::exception("Bad town subID");
  265. }
  266. bicons = CGI->spriteh->giveDefEss(defname);
  267. //blit buildings on bg
  268. //for(int i=0;i<buildings.size();i++)
  269. //{
  270. // blitAt(buildings[i]->def->ourImages[0].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,cityBg);
  271. //}
  272. }
  273. CCastleInterface::~CCastleInterface()
  274. {
  275. SDL_FreeSurface(townInt);
  276. SDL_FreeSurface(cityBg);
  277. delete exit;
  278. delete split;
  279. delete hall;
  280. delete fort;
  281. delete flag;
  282. delete garr;
  283. delete townlist;
  284. delete statusbar;
  285. for(int i=0;i<buildings.size();i++)
  286. {
  287. delete buildings[i];
  288. }
  289. delete bicons;
  290. }
  291. void CCastleInterface::close()
  292. {
  293. LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),this));
  294. deactivate();
  295. LOCPLINT->castleInt = NULL;
  296. LOCPLINT->adventureInt->activate();
  297. delete this;
  298. }
  299. void CCastleInterface::splitF()
  300. {
  301. }
  302. void CCastleInterface::buildingClicked(int building)
  303. {
  304. std::cout<<"You've clicked on "<<building<<std::endl;
  305. if(building==19 || building==18)
  306. {
  307. building = town->town->hordeLvl[0] + 30;
  308. }
  309. else if(building==24 || building==25)
  310. {
  311. building = town->town->hordeLvl[1] + 30;
  312. }
  313. if(building >= 30)
  314. {
  315. if(building>36)
  316. building-=7;
  317. std::vector<std::pair<int,int > > crs;
  318. int amount = (const_cast<CGTownInstance*>(town))->strInfo.creatures[building-30]; //trzeba odconstowac, bo inaczej operator [] by sypal :(
  319. if(town->builtBuildings.find(building+7) != town->builtBuildings.end()) //check if there is an upgraded building
  320. crs.push_back(std::make_pair(town->town->upgradedCreatures[building-30],amount));
  321. crs.push_back(std::make_pair(town->town->basicCreatures[building-30],amount));
  322. CRecrutationWindow *rw = new CRecrutationWindow(crs,this);
  323. rw->activate();
  324. }
  325. else
  326. {
  327. switch(building)
  328. {
  329. case 10: case 11: case 12: case 13:
  330. enterHall();
  331. break;
  332. default:
  333. std::cout<<"This building isn't handled...\n";
  334. }
  335. }
  336. }
  337. void CCastleInterface::enterHall()
  338. {
  339. deactivate();
  340. hallInt = new CHallInterface(this);
  341. hallInt->activate();
  342. hallInt->show();
  343. }
  344. void CCastleInterface::showAll(SDL_Surface * to)
  345. {
  346. if (!to)
  347. to=screen;
  348. blitAt(cityBg,0,0,to);
  349. blitAt(townInt,0,374,to);
  350. LOCPLINT->adventureInt->resdatabar.draw();
  351. townlist->draw();
  352. statusbar->show();
  353. garr->show();
  354. int pom;
  355. //draw fort icon
  356. if(town->builtBuildings.find(9)!=town->builtBuildings.end())
  357. pom = 2;
  358. else if(town->builtBuildings.find(8)!=town->builtBuildings.end())
  359. pom = 1;
  360. else if(town->builtBuildings.find(7)!=town->builtBuildings.end())
  361. pom = 0;
  362. else pom = 3;
  363. blitAt(fort->ourImages[pom].bitmap,122,413,to);
  364. //draw ((village/town/city) hall)/capitol icon
  365. if(town->builtBuildings.find(13)!=town->builtBuildings.end())
  366. pom = 3;
  367. else if(town->builtBuildings.find(12)!=town->builtBuildings.end())
  368. pom = 2;
  369. else if(town->builtBuildings.find(11)!=town->builtBuildings.end())
  370. pom = 1;
  371. else pom = 0;
  372. blitAt(hall->ourImages[pom].bitmap,80,413,to);
  373. //draw creatures icons and their growths
  374. for(int i=0;i<CREATURES_PER_TOWN;i++)
  375. {
  376. int cid = -1;
  377. if (town->builtBuildings.find(30+i)!=town->builtBuildings.end())
  378. {
  379. if (town->builtBuildings.find(30+CREATURES_PER_TOWN+i)!=town->builtBuildings.end())
  380. cid = town->town->upgradedCreatures[i];
  381. else
  382. cid = town->town->basicCreatures[i];
  383. }
  384. if (cid>=0)
  385. {
  386. int pomx, pomy;
  387. pomx = 22 + (55*((i>3)?(i-4):i));
  388. pomy = (i>3)?(507):(459);
  389. blitAt(CGI->creh->smallImgs[cid],pomx,pomy,to);
  390. std::ostringstream oss;
  391. oss << '+' << town->creatureGrowth(i);
  392. CSDL_Ext::printAtMiddle(oss.str(),pomx+16,pomy+37,GEOR13,zwykly,to);
  393. }
  394. }
  395. //print name and income
  396. CSDL_Ext::printAt(town->name,85,389,GEOR13,zwykly,to);
  397. char temp[10];
  398. itoa(town->dailyIncome(),temp,10);
  399. CSDL_Ext::printAtMiddle(temp,195,442,GEOR13,zwykly,to);
  400. //blit town icon
  401. pom = town->subID*2;
  402. if (!town->hasFort())
  403. pom += F_NUMBER*2;
  404. if(town->builded >= MAX_BUILDING_PER_TURN)
  405. pom++;
  406. blitAt(LOCPLINT->bigTownPic->ourImages[pom].bitmap,15,387,to);
  407. //flag
  408. if(town->getOwner()<PLAYER_LIMIT)
  409. blitAt(flag->ourImages[town->getOwner()].bitmap,241,387,to);
  410. show();
  411. }
  412. void CCastleInterface::townChange()
  413. {
  414. const CGTownInstance * nt = townlist->items[townlist->selected];
  415. deactivate();
  416. LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),this));
  417. delete this;
  418. LOCPLINT->castleInt = new CCastleInterface(nt,true);
  419. }
  420. void CCastleInterface::show(SDL_Surface * to)
  421. {
  422. if(!showing)
  423. return;
  424. if (!to)
  425. to=screen;
  426. count++;
  427. if(count==4)
  428. {
  429. count=0;
  430. animval++;
  431. }
  432. blitAt(cityBg,0,0,to);
  433. //blit buildings
  434. for(int i=0;i<buildings.size();i++)
  435. {
  436. int frame = (animval)%(buildings[i]->max - buildings[i]->offset);
  437. if(frame)
  438. {
  439. blitAt(buildings[i]->def->ourImages[0].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to);
  440. blitAt(buildings[i]->def->ourImages[frame].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to);
  441. }
  442. else
  443. blitAt(buildings[i]->def->ourImages[frame].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to);
  444. if(hBuild==buildings[i] && hBuild->border) //if this this higlighted structure and has border we'll blit it
  445. blitAt(hBuild->border,hBuild->pos,to);
  446. }
  447. }
  448. void CCastleInterface::activate()
  449. {
  450. showing = true;
  451. townlist->activate();
  452. garr->activate();
  453. LOCPLINT->curint = this;
  454. LOCPLINT->statusbar = statusbar;
  455. exit->activate();
  456. split->activate();
  457. for(int i=0;i<buildings.size();i++)
  458. buildings[i]->activate();
  459. }
  460. void CCastleInterface::deactivate()
  461. {
  462. showing = false;
  463. townlist->deactivate();
  464. garr->deactivate();
  465. exit->deactivate();
  466. split->deactivate();
  467. for(int i=0;i<buildings.size();i++)
  468. buildings[i]->deactivate();
  469. }
  470. void CCastleInterface::addBuilding(int bid)
  471. {
  472. //TODO: lepiej by bylo tylko dodawac co trzeba pamietajac o grupach
  473. recreateBuildings();
  474. }
  475. void CCastleInterface::removeBuilding(int bid)
  476. {
  477. //TODO: lepiej by bylo tylko usuwac co trzeba pamietajac o grupach
  478. recreateBuildings();
  479. }
  480. void CCastleInterface::recreateBuildings()
  481. {
  482. for(int i=0;i<buildings.size();i++)
  483. {
  484. if(showing)
  485. buildings[i]->deactivate();
  486. delete buildings[i];
  487. }
  488. buildings.clear();
  489. hBuild = NULL;
  490. std::set< std::pair<int,int> > s; //group - id
  491. for (std::set<int>::const_iterator i=town->builtBuildings.begin();i!=town->builtBuildings.end();i++)
  492. {
  493. if(CGI->townh->structures.find(town->subID) != CGI->townh->structures.end()) //we have info about structures in this town
  494. {
  495. if(CGI->townh->structures[town->subID].find(*i)!=CGI->townh->structures[town->subID].end()) //we have info about that structure
  496. {
  497. Structure * st = CGI->townh->structures[town->subID][*i];
  498. if(st->group<0) //no group - just add it
  499. {
  500. buildings.push_back(new CBuildingRect(st));
  501. }
  502. else
  503. {
  504. std::set< std::pair<int,int> >::iterator obecny=s.end();
  505. for(std::set< std::pair<int,int> >::iterator seti = s.begin(); seti!=s.end(); seti++) //check if we have already building from same group
  506. {
  507. if(seti->first == st->group)
  508. {
  509. obecny = seti;
  510. break;
  511. }
  512. }
  513. if(obecny != s.end())
  514. {
  515. if((*(CGI->townh->structures[town->subID][obecny->second])) < (*(CGI->townh->structures[town->subID][st->ID]))) //we have to replace old building with current one
  516. {
  517. for(int itpb = 0; itpb<buildings.size(); itpb++)
  518. {
  519. if(buildings[itpb]->str->ID == obecny->second)
  520. {
  521. delete buildings[itpb];
  522. buildings.erase(buildings.begin() + itpb);
  523. obecny->second = st->ID;
  524. buildings.push_back(new CBuildingRect(st));
  525. }
  526. }
  527. }
  528. }
  529. else
  530. {
  531. buildings.push_back(new CBuildingRect(st));
  532. s.insert(std::pair<int,int>(st->group,st->ID));
  533. }
  534. }
  535. }
  536. else continue;
  537. }
  538. else
  539. break;
  540. }
  541. std::sort(buildings.begin(),buildings.end(),srthlp);
  542. //code for Mana Vortex (there are two sets of animation frames - one without mage guild and one with
  543. if((town->subID == 5) && (town->builtBuildings.find(21)!=town->builtBuildings.end()))
  544. {
  545. CBuildingRect *vortex = NULL;
  546. for(int i=0;i<buildings.size();i++)
  547. {
  548. if(buildings[i]->str->ID==21)
  549. {
  550. vortex=buildings[i];
  551. break;
  552. }
  553. }
  554. if(town->builtBuildings.find(4)!=town->builtBuildings.end()) //there is mage Guild level 5
  555. {
  556. vortex->offset = 10;
  557. vortex->max = vortex->def->ourImages.size();
  558. }
  559. else
  560. {
  561. vortex->offset = 0;
  562. vortex->max = 10;
  563. }
  564. }
  565. }
  566. void CCastleInterface::recruit(int ID, int amount)
  567. {
  568. LOCPLINT->cb->recruitCreatures(town,ID,amount);
  569. }
  570. void CHallInterface::CResDataBar::show(SDL_Surface * to)
  571. {
  572. blitAt(bg,pos.x,pos.y);
  573. char * buf = new char[15];
  574. for (int i=0;i<7;i++)
  575. {
  576. itoa(LOCPLINT->cb->getResourceAmount(i),buf,10);
  577. CSDL_Ext::printAtMiddle(buf,pos.x + 50 + 76*i,pos.y+pos.h/2,GEOR13,zwykly);
  578. }
  579. std::vector<std::string> temp;
  580. itoa(LOCPLINT->cb->getDate(3),buf,10); temp.push_back(std::string(buf));
  581. itoa(LOCPLINT->cb->getDate(2),buf,10); temp.push_back(buf);
  582. itoa(LOCPLINT->cb->getDate(1),buf,10); temp.push_back(buf);
  583. CSDL_Ext::printAtMiddle(CSDL_Ext::processStr(
  584. CGI->generaltexth->allTexts[62]
  585. +": %s, "
  586. + CGI->generaltexth->allTexts[63]
  587. + ": %s, "
  588. + CGI->generaltexth->allTexts[64]
  589. + ": %s",temp)
  590. ,pos.x+545+(pos.w-545)/2,pos.y+pos.h/2,GEOR13,zwykly);
  591. temp.clear();
  592. //updateRect(&pos,screen);
  593. delete[] buf;
  594. }
  595. CHallInterface::CResDataBar::CResDataBar()
  596. {
  597. bg = CGI->bitmaph->loadBitmap("Z2ESBAR.bmp");
  598. SDL_SetColorKey(bg,SDL_SRCCOLORKEY,SDL_MapRGB(bg->format,0,255,255));
  599. CSDL_Ext::blueToPlayersAdv(bg,LOCPLINT->playerID);
  600. pos.x = 7;
  601. pos.y = 575;
  602. pos.w = bg->w;
  603. pos.h = bg->h;
  604. }
  605. CHallInterface::CResDataBar::~CResDataBar()
  606. {
  607. SDL_FreeSurface(bg);
  608. }
  609. void CHallInterface::CBuildingBox::hover(bool on)
  610. {
  611. Hoverable::hover(on);
  612. if(on)
  613. {
  614. std::string toPrint;
  615. if(state==8)
  616. toPrint = CGI->townh->hcommands[5];
  617. else
  618. toPrint = CGI->townh->hcommands[state];
  619. std::vector<std::string> name;
  620. name.push_back(CGI->buildh->buildings[LOCPLINT->castleInt->town->subID][BID]->name);
  621. LOCPLINT->statusbar->print(CSDL_Ext::processStr(toPrint,name));
  622. }
  623. else
  624. LOCPLINT->statusbar->clear();
  625. }
  626. void CHallInterface::CBuildingBox::clickLeft (tribool down)
  627. {
  628. if(pressedL && (!down))
  629. {
  630. LOCPLINT->castleInt->hallInt->deactivate();
  631. new CHallInterface::CBuildWindow(LOCPLINT->castleInt->town->subID,BID,state,0);
  632. }
  633. ClickableL::clickLeft(down);
  634. }
  635. void CHallInterface::CBuildingBox::clickRight (tribool down)
  636. {
  637. if(down)
  638. {
  639. LOCPLINT->castleInt->hallInt->deactivate();
  640. new CHallInterface::CBuildWindow(LOCPLINT->castleInt->town->subID,BID,state,1);
  641. }
  642. ClickableR::clickRight(down);
  643. }
  644. void CHallInterface::CBuildingBox::show(SDL_Surface * to)
  645. {
  646. blitAt(LOCPLINT->castleInt->bicons->ourImages[BID].bitmap,pos.x,pos.y);
  647. int pom, pom2=-1;
  648. switch (state)
  649. {
  650. case 4:
  651. pom = 0;
  652. pom2 = 0;
  653. break;
  654. case 7:
  655. pom = 1;
  656. break;
  657. case 6:
  658. pom2 = 2;
  659. pom = 2;
  660. break;
  661. case 0: case 5: case 8:
  662. pom2 = 1;
  663. pom = 2;
  664. break;
  665. case 2: case 1: default:
  666. pom = 3;
  667. break;
  668. }
  669. blitAt(LOCPLINT->castleInt->hallInt->bars->ourImages[pom].bitmap,pos.x-1,pos.y+71);
  670. if(pom2>=0)
  671. blitAt(LOCPLINT->castleInt->hallInt->status->ourImages[pom2].bitmap,pos.x+135, pos.y+54);
  672. CSDL_Ext::printAtMiddle(CGI->buildh->buildings[LOCPLINT->castleInt->town->subID][BID]->name,pos.x-1+LOCPLINT->castleInt->hallInt->bars->ourImages[0].bitmap->w/2,pos.y+71+LOCPLINT->castleInt->hallInt->bars->ourImages[0].bitmap->h/2, GEOR13,zwykly);
  673. }
  674. void CHallInterface::CBuildingBox::activate()
  675. {
  676. Hoverable::activate();
  677. ClickableL::activate();
  678. ClickableR::activate();
  679. }
  680. void CHallInterface::CBuildingBox::deactivate()
  681. {
  682. Hoverable::deactivate();
  683. ClickableL::deactivate();
  684. ClickableR::deactivate();
  685. }
  686. CHallInterface::CBuildingBox::~CBuildingBox()
  687. {
  688. }
  689. CHallInterface::CBuildingBox::CBuildingBox(int id)
  690. :BID(id)
  691. {
  692. pos.w = 150;
  693. pos.h = 70;
  694. }
  695. CHallInterface::CBuildingBox::CBuildingBox(int id, int x, int y)
  696. :BID(id)
  697. {
  698. pos.x = x;
  699. pos.y = y;
  700. pos.w = 150;
  701. pos.h = 70;
  702. }
  703. CHallInterface::CHallInterface(CCastleInterface * owner)
  704. {
  705. bg = CGI->bitmaph->loadBitmap(CGI->buildh->hall[owner->town->subID].first);
  706. CSDL_Ext::blueToPlayersAdv(bg,LOCPLINT->playerID);
  707. bars = CGI->spriteh->giveDefEss("TPTHBAR.DEF");
  708. status = CGI->spriteh->giveDefEss("TPTHCHK.DEF");
  709. exit = new AdventureMapButton
  710. (CGI->townh->tcommands[8],"",boost::bind(&CHallInterface::close,this),748,556,"TPMAGE1.DEF",false,NULL,false);
  711. //preparing boxes with buildings//
  712. boxes.resize(5);
  713. for(int i=0;i<5;i++) //for each row
  714. {
  715. for(int j=0; j<CGI->buildh->hall[owner->town->subID].second[i].size();j++) //for each box
  716. {
  717. int k=0;
  718. for(;k<CGI->buildh->hall[owner->town->subID].second[i][j].size();k++)//we are looking for the first not build structure
  719. {
  720. if(
  721. (owner->town->builtBuildings.find(CGI->buildh->hall[owner->town->subID].second[i][j][k]))
  722. ==
  723. (owner->town->builtBuildings.end()) )
  724. {
  725. int x = 34 + 194*j,
  726. y = 37 + 104*i,
  727. ID = CGI->buildh->hall[owner->town->subID].second[i][j][k];
  728. if(CGI->buildh->hall[owner->town->subID].second[i].size() == 2) //only two boxes in this row
  729. x+=194;
  730. else if(CGI->buildh->hall[owner->town->subID].second[i].size() == 3) //only three boxes in this row
  731. x+=97;
  732. boxes[i].push_back(new CBuildingBox(CGI->buildh->hall[owner->town->subID].second[i][j][k],x,y));
  733. boxes[i][boxes[i].size()-1]->state = 7; //allowed by default
  734. //can we build it?
  735. if(owner->town->forbiddenBuildings.find(CGI->buildh->hall[owner->town->subID].second[i][j][k])!=owner->town->forbiddenBuildings.end())
  736. boxes[i][boxes[i].size()-1]->state = 2; //forbidden
  737. else if(owner->town->builded >= MAX_BUILDING_PER_TURN)
  738. boxes[i][boxes[i].size()-1]->state = 5; //building limit
  739. //checking resources
  740. CBuilding * pom = CGI->buildh->buildings[owner->town->subID][CGI->buildh->hall[owner->town->subID].second[i][j][k]];
  741. for(int res=0;res<7;res++) //TODO: support custom amount of resources
  742. {
  743. if(pom->resources[res]>LOCPLINT->cb->getResourceAmount(res))
  744. boxes[i][boxes[i].size()-1]->state = 6; //lack of res
  745. }
  746. //checking for requirements
  747. for( std::set<int>::iterator ri = CGI->townh->requirements[owner->town->subID][ID].begin();
  748. ri != CGI->townh->requirements[owner->town->subID][ID].end();
  749. ri++ )
  750. {
  751. if(owner->town->builtBuildings.find(*ri)==owner->town->builtBuildings.end())
  752. boxes[i][boxes[i].size()-1]->state = 8; //lack of requirements - cannot build
  753. }
  754. //TODO: check if capital is already built, check if there is water for shipyard
  755. break;
  756. }
  757. }
  758. if(k==CGI->buildh->hall[owner->town->subID].second[i][j].size()) //all buildings built - let's take the last one
  759. {
  760. int x = 34 + 194*j,
  761. y = 37 + 104*i;
  762. if(CGI->buildh->hall[owner->town->subID].second[i].size() == 2)
  763. x+=194;
  764. else if(CGI->buildh->hall[owner->town->subID].second[i].size() == 3)
  765. x+=97;
  766. boxes[i].push_back(new CBuildingBox(CGI->buildh->hall[owner->town->subID].second[i][j][k-1],x,y));
  767. boxes[i][boxes[i].size()-1]->state = 4; //already exists
  768. }
  769. }
  770. }
  771. }
  772. CHallInterface::~CHallInterface()
  773. {
  774. delete bars;
  775. delete status;
  776. SDL_FreeSurface(bg);
  777. for(int i=0;i<boxes.size();i++)
  778. for(int j=0;j<boxes[i].size();j++)
  779. delete boxes[i][j];
  780. delete exit;
  781. }
  782. void CHallInterface::close()
  783. {
  784. deactivate();
  785. delete this;
  786. LOCPLINT->castleInt->activate();
  787. LOCPLINT->castleInt->showAll();
  788. }
  789. void CHallInterface::show(SDL_Surface * to)
  790. {
  791. blitAt(bg,0,0);
  792. resdatabar.show();
  793. exit->show();
  794. for(int i=0; i<5; i++)
  795. {
  796. for(int j=0;j<boxes[i].size();j++)
  797. boxes[i][j]->show();
  798. }
  799. }
  800. void CHallInterface::activate()
  801. {
  802. for(int i=0;i<5;i++)
  803. for(int j=0;j<boxes[i].size();j++)
  804. boxes[i][j]->activate();
  805. exit->activate();
  806. }
  807. void CHallInterface::deactivate()
  808. {
  809. for(int i=0;i<5;i++)
  810. {
  811. for(int j=0;j<boxes[i].size();j++)
  812. {
  813. boxes[i][j]->deactivate();
  814. }
  815. }
  816. exit->deactivate();
  817. }
  818. void CHallInterface::CBuildWindow::activate()
  819. {
  820. LOCPLINT->objsToBlit.push_back(this);
  821. ClickableR::activate();
  822. if(mode)
  823. return;
  824. if(state==7)
  825. buy->activate();
  826. cancel->activate();
  827. }
  828. void CHallInterface::CBuildWindow::deactivate()
  829. {
  830. LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),this));
  831. ClickableR::deactivate();
  832. if(mode)
  833. return;
  834. if(state==7)
  835. buy->deactivate();
  836. cancel->deactivate();
  837. }
  838. void CHallInterface::CBuildWindow::Buy()
  839. {
  840. LOCPLINT->cb->buildBuilding(LOCPLINT->castleInt->town,bid);
  841. deactivate();
  842. delete this;
  843. delete LOCPLINT->castleInt->hallInt;
  844. LOCPLINT->castleInt->hallInt = NULL;
  845. LOCPLINT->castleInt->activate();
  846. LOCPLINT->castleInt->showAll();
  847. }
  848. void CHallInterface::CBuildWindow::close()
  849. {
  850. deactivate();
  851. delete this;
  852. LOCPLINT->castleInt->hallInt->activate();
  853. LOCPLINT->castleInt->hallInt->show();
  854. }
  855. void CHallInterface::CBuildWindow::clickRight (tribool down)
  856. {
  857. if((!down || indeterminate(down)) && mode)
  858. close();
  859. }
  860. void CHallInterface::CBuildWindow::show(SDL_Surface * to)
  861. {
  862. SDL_Rect pom = genRect(bitmap->h-1,bitmap->w-1,pos.x,pos.y);
  863. SDL_Rect poms = pom; poms.x=0;poms.y=0;
  864. SDL_BlitSurface(bitmap,&poms,to?to:screen,&pom);
  865. if(!mode)
  866. {
  867. buy->show();
  868. cancel->show();
  869. }
  870. }
  871. std::string CHallInterface::CBuildWindow::getTextForState(int state)
  872. {
  873. std::string ret;
  874. if(state<7)
  875. ret = CGI->townh->hcommands[state];
  876. switch (state)
  877. {
  878. case 4: case 5: case 6:
  879. ret.replace(ret.find_first_of("%s"),2,CGI->buildh->buildings[tid][bid]->name);
  880. break;
  881. case 7:
  882. return CGI->generaltexth->allTexts[219]; //all prereq. are met
  883. case 8:
  884. {
  885. ret = CGI->generaltexth->allTexts[52];
  886. std::set<int> used;
  887. used.insert(bid);
  888. std::set<int> reqs;
  889. for(std::set<int>::iterator i=CGI->townh->requirements[tid][bid].begin();i!=CGI->townh->requirements[tid][bid].end();i++)
  890. if (LOCPLINT->castleInt->town->builtBuildings.find(*i) == LOCPLINT->castleInt->town->builtBuildings.end())
  891. reqs.insert(*i);
  892. while(true)
  893. {
  894. int czystych=0;
  895. for(std::set<int>::iterator i=reqs.begin();i!=reqs.end();i++)
  896. {
  897. if(used.find(*i)==used.end()) //we haven't added requirements for this building
  898. {
  899. used.insert(*i);
  900. for(
  901. std::set<int>::iterator j=CGI->townh->requirements[tid][*i].begin();
  902. j!=CGI->townh->requirements[tid][*i].end();
  903. j++
  904. )
  905. {
  906. if(LOCPLINT->castleInt->town->builtBuildings.find(*j) == //this building is not built
  907. LOCPLINT->castleInt->town->builtBuildings.end())
  908. reqs.insert(*j);
  909. }
  910. }
  911. else
  912. {
  913. czystych++;
  914. }
  915. }
  916. if(czystych==reqs.size())
  917. break;
  918. }
  919. bool first=true;
  920. for(std::set<int>::iterator i=reqs.begin();i!=reqs.end();i++)
  921. {
  922. ret+=(((first)?(" "):(", ")) + CGI->buildh->buildings[tid][*i]->name);
  923. first = false;
  924. }
  925. }
  926. }
  927. return ret;
  928. }
  929. CHallInterface::CBuildWindow::CBuildWindow(int Tid, int Bid, int State, bool Mode)
  930. :tid(Tid),bid(Bid),mode(Mode), state(State)
  931. {
  932. SDL_Surface *hhlp = CGI->bitmaph->loadBitmap("TPUBUILD.bmp");
  933. bitmap = SDL_ConvertSurface(hhlp,screen->format,0); //na 8bitowej mapie by sie psulo
  934. SDL_SetColorKey(hhlp,SDL_SRCCOLORKEY,SDL_MapRGB(hhlp->format,0,255,255));
  935. SDL_FreeSurface(hhlp);
  936. pos.x = screen->w/2 - bitmap->w/2;
  937. pos.y = screen->h/2 - bitmap->h/2;
  938. CSDL_Ext::blueToPlayersAdv(bitmap,LOCPLINT->playerID);
  939. blitAt(LOCPLINT->castleInt->bicons->ourImages[bid].bitmap,125,50,bitmap);
  940. std::vector<std::string> pom; pom.push_back(CGI->buildh->buildings[tid][bid]->name);
  941. CSDL_Ext::printAtMiddleWB(CGI->buildh->buildings[tid][bid]->description,197,168,GEOR16,40,zwykly,bitmap);
  942. CSDL_Ext::printAtMiddleWB(getTextForState(state),197,248,GEOR13,50,zwykly,bitmap);
  943. CSDL_Ext::printAtMiddle(CSDL_Ext::processStr(CGI->townh->hcommands[7],pom),197,30,GEOR16,tytulowy,bitmap);
  944. int resamount=0; for(int i=0;i<7;i++) if(CGI->buildh->buildings[tid][bid]->resources[i]) resamount++;
  945. int ah = (resamount>4) ? 304 : 341;
  946. int cn=-1, it=0;
  947. int row1w = std::min(resamount,4) * 32 + (std::min(resamount,4)-1) * 45,
  948. row2w = (resamount-4) * 32 + (resamount-5) * 45;
  949. char buf[15];
  950. while(++cn<7)
  951. {
  952. if(!CGI->buildh->buildings[tid][bid]->resources[cn])
  953. continue;
  954. itoa(CGI->buildh->buildings[tid][bid]->resources[cn],buf,10);
  955. if(it<4)
  956. {
  957. CSDL_Ext::printAtMiddle(buf,(bitmap->w/2-row1w/2)+77*it+16,ah+42,GEOR16,zwykly,bitmap);
  958. blitAt(CGI->townh->resources->ourImages[cn].bitmap,(bitmap->w/2-row1w/2)+77*it++,ah,bitmap);
  959. }
  960. else
  961. {
  962. CSDL_Ext::printAtMiddle(buf,(bitmap->w/2-row2w/2)+77*it+16-308,ah+42,GEOR16,zwykly,bitmap);
  963. blitAt(CGI->townh->resources->ourImages[cn].bitmap,(bitmap->w/2-row2w/2)+77*it++ - 308,ah,bitmap);
  964. }
  965. if(it==4)
  966. ah+=75;
  967. }
  968. if(!mode)
  969. {
  970. buy = new AdventureMapButton
  971. ("","",boost::bind(&CBuildWindow::Buy,this),pos.x+45,pos.y+446,"IBUY30.DEF",false,NULL,false);
  972. cancel = new AdventureMapButton
  973. ("","",boost::bind(&CBuildWindow::close,this),pos.x+290,pos.y+445,"ICANCEL.DEF",false,NULL,false);
  974. if(state!=7)
  975. buy->state=2;
  976. }
  977. activate();
  978. }
  979. CHallInterface::CBuildWindow::~CBuildWindow()
  980. {
  981. SDL_FreeSurface(bitmap);
  982. if(!mode)
  983. {
  984. delete buy;
  985. delete cancel;
  986. }
  987. }