CCastleInterface.cpp 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042
  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 = CGI->townh->hcommands[state];
  615. std::vector<std::string> name;
  616. name.push_back(CGI->buildh->buildings[LOCPLINT->castleInt->town->subID][BID]->name);
  617. LOCPLINT->statusbar->print(CSDL_Ext::processStr(toPrint,name));
  618. }
  619. else
  620. LOCPLINT->statusbar->clear();
  621. }
  622. void CHallInterface::CBuildingBox::clickLeft (tribool down)
  623. {
  624. if(pressedL && (!down))
  625. {
  626. LOCPLINT->castleInt->hallInt->deactivate();
  627. new CHallInterface::CBuildWindow(LOCPLINT->castleInt->town->subID,BID,state,0);
  628. }
  629. ClickableL::clickLeft(down);
  630. }
  631. void CHallInterface::CBuildingBox::clickRight (tribool down)
  632. {
  633. if(down)
  634. {
  635. LOCPLINT->castleInt->hallInt->deactivate();
  636. new CHallInterface::CBuildWindow(LOCPLINT->castleInt->town->subID,BID,state,1);
  637. }
  638. ClickableR::clickRight(down);
  639. }
  640. void CHallInterface::CBuildingBox::show(SDL_Surface * to)
  641. {
  642. blitAt(LOCPLINT->castleInt->bicons->ourImages[BID].bitmap,pos.x,pos.y);
  643. int pom, pom2=-1;
  644. switch (state)
  645. {
  646. case 4:
  647. pom = 0;
  648. pom2 = 0;
  649. break;
  650. case 7:
  651. pom = 1;
  652. break;
  653. case 6:
  654. pom2 = 2;
  655. pom = 2;
  656. break;
  657. case 0: case 5: case 8:
  658. pom2 = 1;
  659. pom = 2;
  660. break;
  661. case 2: case 1: default:
  662. pom = 3;
  663. break;
  664. }
  665. blitAt(LOCPLINT->castleInt->hallInt->bars->ourImages[pom].bitmap,pos.x-1,pos.y+71);
  666. if(pom2>=0)
  667. blitAt(LOCPLINT->castleInt->hallInt->status->ourImages[pom2].bitmap,pos.x+135, pos.y+54);
  668. 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);
  669. }
  670. void CHallInterface::CBuildingBox::activate()
  671. {
  672. Hoverable::activate();
  673. ClickableL::activate();
  674. ClickableR::activate();
  675. }
  676. void CHallInterface::CBuildingBox::deactivate()
  677. {
  678. Hoverable::deactivate();
  679. ClickableL::deactivate();
  680. ClickableR::deactivate();
  681. }
  682. CHallInterface::CBuildingBox::~CBuildingBox()
  683. {
  684. }
  685. CHallInterface::CBuildingBox::CBuildingBox(int id)
  686. :BID(id)
  687. {
  688. pos.w = 150;
  689. pos.h = 70;
  690. }
  691. CHallInterface::CBuildingBox::CBuildingBox(int id, int x, int y)
  692. :BID(id)
  693. {
  694. pos.x = x;
  695. pos.y = y;
  696. pos.w = 150;
  697. pos.h = 70;
  698. }
  699. CHallInterface::CHallInterface(CCastleInterface * owner)
  700. {
  701. bg = CGI->bitmaph->loadBitmap(CGI->buildh->hall[owner->town->subID].first);
  702. CSDL_Ext::blueToPlayersAdv(bg,LOCPLINT->playerID);
  703. bars = CGI->spriteh->giveDefEss("TPTHBAR.DEF");
  704. status = CGI->spriteh->giveDefEss("TPTHCHK.DEF");
  705. exit = new AdventureMapButton
  706. (CGI->townh->tcommands[8],"",boost::bind(&CHallInterface::close,this),748,556,"TPMAGE1.DEF",false,NULL,false);
  707. //preparing boxes with buildings//
  708. boxes.resize(5);
  709. for(int i=0;i<5;i++) //for each row
  710. {
  711. for(int j=0; j<CGI->buildh->hall[owner->town->subID].second[i].size();j++) //for each box
  712. {
  713. int k=0;
  714. for(;k<CGI->buildh->hall[owner->town->subID].second[i][j].size();k++)//we are looking for the first not build structure
  715. {
  716. if(
  717. (owner->town->builtBuildings.find(CGI->buildh->hall[owner->town->subID].second[i][j][k]))
  718. ==
  719. (owner->town->builtBuildings.end()) )
  720. {
  721. int x = 34 + 194*j,
  722. y = 37 + 104*i,
  723. ID = CGI->buildh->hall[owner->town->subID].second[i][j][k];
  724. if(CGI->buildh->hall[owner->town->subID].second[i].size() == 2) //only two boxes in this row
  725. x+=194;
  726. else if(CGI->buildh->hall[owner->town->subID].second[i].size() == 3) //only three boxes in this row
  727. x+=97;
  728. boxes[i].push_back(new CBuildingBox(CGI->buildh->hall[owner->town->subID].second[i][j][k],x,y));
  729. boxes[i][boxes[i].size()-1]->state = 7; //allowed by default
  730. //can we build it?
  731. if(owner->town->forbiddenBuildings.find(CGI->buildh->hall[owner->town->subID].second[i][j][k])!=owner->town->forbiddenBuildings.end())
  732. boxes[i][boxes[i].size()-1]->state = 2; //forbidden
  733. else if(owner->town->builded >= MAX_BUILDING_PER_TURN)
  734. boxes[i][boxes[i].size()-1]->state = 5; //building limit
  735. //checking resources
  736. CBuilding * pom = CGI->buildh->buildings[owner->town->subID][CGI->buildh->hall[owner->town->subID].second[i][j][k]];
  737. for(int res=0;res<7;res++) //TODO: support custom amount of resources
  738. {
  739. if(pom->resources[res]>LOCPLINT->cb->getResourceAmount(res))
  740. boxes[i][boxes[i].size()-1]->state = 6; //lack of res
  741. }
  742. //checking for requirements
  743. for( std::set<int>::iterator ri = CGI->townh->requirements[owner->town->subID][ID].begin();
  744. ri != CGI->townh->requirements[owner->town->subID][ID].end();
  745. ri++ )
  746. {
  747. if(owner->town->builtBuildings.find(*ri)==owner->town->builtBuildings.end())
  748. boxes[i][boxes[i].size()-1]->state = 8; //lack of requirements - cannot build
  749. }
  750. //TODO: check if capital is already built, check if there is water for shipyard
  751. break;
  752. }
  753. }
  754. if(k==CGI->buildh->hall[owner->town->subID].second[i][j].size()) //all buildings built - let's take the last one
  755. {
  756. int x = 34 + 194*j,
  757. y = 37 + 104*i;
  758. if(CGI->buildh->hall[owner->town->subID].second[i].size() == 2)
  759. x+=194;
  760. else if(CGI->buildh->hall[owner->town->subID].second[i].size() == 3)
  761. x+=97;
  762. boxes[i].push_back(new CBuildingBox(CGI->buildh->hall[owner->town->subID].second[i][j][k-1],x,y));
  763. boxes[i][boxes[i].size()-1]->state = 4; //already exists
  764. }
  765. }
  766. }
  767. }
  768. CHallInterface::~CHallInterface()
  769. {
  770. delete bars;
  771. delete status;
  772. SDL_FreeSurface(bg);
  773. for(int i=0;i<boxes.size();i++)
  774. for(int j=0;j<boxes[i].size();j++)
  775. delete boxes[i][j];
  776. delete exit;
  777. }
  778. void CHallInterface::close()
  779. {
  780. deactivate();
  781. delete this;
  782. LOCPLINT->castleInt->activate();
  783. LOCPLINT->castleInt->showAll();
  784. }
  785. void CHallInterface::show(SDL_Surface * to)
  786. {
  787. blitAt(bg,0,0);
  788. resdatabar.show();
  789. exit->show();
  790. for(int i=0; i<5; i++)
  791. {
  792. for(int j=0;j<boxes[i].size();j++)
  793. boxes[i][j]->show();
  794. }
  795. }
  796. void CHallInterface::activate()
  797. {
  798. for(int i=0;i<5;i++)
  799. for(int j=0;j<boxes[i].size();j++)
  800. boxes[i][j]->activate();
  801. exit->activate();
  802. }
  803. void CHallInterface::deactivate()
  804. {
  805. for(int i=0;i<5;i++)
  806. {
  807. for(int j=0;j<boxes[i].size();j++)
  808. {
  809. boxes[i][j]->deactivate();
  810. }
  811. }
  812. exit->deactivate();
  813. }
  814. void CHallInterface::CBuildWindow::activate()
  815. {
  816. LOCPLINT->objsToBlit.push_back(this);
  817. ClickableR::activate();
  818. if(mode)
  819. return;
  820. if(state==7)
  821. buy->activate();
  822. cancel->activate();
  823. }
  824. void CHallInterface::CBuildWindow::deactivate()
  825. {
  826. LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),this));
  827. ClickableR::deactivate();
  828. if(mode)
  829. return;
  830. if(state==7)
  831. buy->deactivate();
  832. cancel->deactivate();
  833. }
  834. void CHallInterface::CBuildWindow::Buy()
  835. {
  836. LOCPLINT->cb->buildBuilding(LOCPLINT->castleInt->town,bid);
  837. deactivate();
  838. delete this;
  839. delete LOCPLINT->castleInt->hallInt;
  840. LOCPLINT->castleInt->hallInt = NULL;
  841. LOCPLINT->castleInt->activate();
  842. LOCPLINT->castleInt->showAll();
  843. }
  844. void CHallInterface::CBuildWindow::close()
  845. {
  846. deactivate();
  847. delete this;
  848. LOCPLINT->castleInt->hallInt->activate();
  849. LOCPLINT->castleInt->hallInt->show();
  850. }
  851. void CHallInterface::CBuildWindow::clickRight (tribool down)
  852. {
  853. if((!down || indeterminate(down)) && mode)
  854. close();
  855. }
  856. void CHallInterface::CBuildWindow::show(SDL_Surface * to)
  857. {
  858. SDL_Rect pom = genRect(bitmap->h-1,bitmap->w-1,pos.x,pos.y);
  859. SDL_Rect poms = pom; poms.x=0;poms.y=0;
  860. SDL_BlitSurface(bitmap,&poms,to?to:screen,&pom);
  861. if(!mode)
  862. {
  863. buy->show();
  864. cancel->show();
  865. }
  866. }
  867. std::string CHallInterface::CBuildWindow::getTextForState(int state)
  868. {
  869. std::string ret;
  870. if(state<7)
  871. ret = CGI->townh->hcommands[state];
  872. switch (state)
  873. {
  874. case 4:
  875. ret.replace(ret.find_first_of("%s"),2,CGI->buildh->buildings[tid][bid]->name);
  876. break;
  877. case 7:
  878. return CGI->generaltexth->allTexts[219]; //all prereq. are met
  879. case 8:
  880. {
  881. ret = CGI->generaltexth->allTexts[52];
  882. std::set<int> used;
  883. used.insert(bid);
  884. std::set<int> reqs;
  885. for(std::set<int>::iterator i=CGI->townh->requirements[tid][bid].begin();i!=CGI->townh->requirements[tid][bid].end();i++)
  886. if (LOCPLINT->castleInt->town->builtBuildings.find(*i) == LOCPLINT->castleInt->town->builtBuildings.end())
  887. reqs.insert(*i);
  888. while(true)
  889. {
  890. int czystych=0;
  891. for(std::set<int>::iterator i=reqs.begin();i!=reqs.end();i++)
  892. {
  893. if(used.find(*i)==used.end()) //we haven't added requirements for this building
  894. {
  895. used.insert(*i);
  896. for(
  897. std::set<int>::iterator j=CGI->townh->requirements[tid][*i].begin();
  898. j!=CGI->townh->requirements[tid][*i].end();
  899. j++
  900. )
  901. {
  902. if(LOCPLINT->castleInt->town->builtBuildings.find(*j) == //this building is not built
  903. LOCPLINT->castleInt->town->builtBuildings.end())
  904. reqs.insert(*j);
  905. }
  906. }
  907. else
  908. {
  909. czystych++;
  910. }
  911. }
  912. if(czystych==reqs.size())
  913. break;
  914. }
  915. bool first=true;
  916. for(std::set<int>::iterator i=reqs.begin();i!=reqs.end();i++)
  917. {
  918. ret+=(((first)?(" "):(", ")) + CGI->buildh->buildings[tid][*i]->name);
  919. first = false;
  920. }
  921. }
  922. }
  923. return ret;
  924. }
  925. CHallInterface::CBuildWindow::CBuildWindow(int Tid, int Bid, int State, bool Mode)
  926. :tid(Tid),bid(Bid),mode(Mode), state(State)
  927. {
  928. SDL_Surface *hhlp = CGI->bitmaph->loadBitmap("TPUBUILD.bmp");
  929. bitmap = SDL_ConvertSurface(hhlp,screen->format,0); //na 8bitowej mapie by sie psulo
  930. SDL_SetColorKey(hhlp,SDL_SRCCOLORKEY,SDL_MapRGB(hhlp->format,0,255,255));
  931. SDL_FreeSurface(hhlp);
  932. pos.x = screen->w/2 - bitmap->w/2;
  933. pos.y = screen->h/2 - bitmap->h/2;
  934. CSDL_Ext::blueToPlayersAdv(bitmap,LOCPLINT->playerID);
  935. blitAt(LOCPLINT->castleInt->bicons->ourImages[bid].bitmap,125,50,bitmap);
  936. std::vector<std::string> pom; pom.push_back(CGI->buildh->buildings[tid][bid]->name);
  937. CSDL_Ext::printAtMiddleWB(CGI->buildh->buildings[tid][bid]->description,197,168,GEOR16,40,zwykly,bitmap);
  938. CSDL_Ext::printAtMiddleWB(getTextForState(state),197,248,GEOR13,50,zwykly,bitmap);
  939. CSDL_Ext::printAtMiddle(CSDL_Ext::processStr(CGI->townh->hcommands[7],pom),197,30,GEOR16,tytulowy,bitmap);
  940. int resamount=0; for(int i=0;i<7;i++) if(CGI->buildh->buildings[tid][bid]->resources[i]) resamount++;
  941. int ah = (resamount>4) ? 304 : 341;
  942. int cn=-1, it=0;
  943. int row1w = std::min(resamount,4) * 32 + (std::min(resamount,4)-1) * 45,
  944. row2w = (resamount-4) * 32 + (resamount-5) * 45;
  945. char buf[15];
  946. while(++cn<7)
  947. {
  948. if(!CGI->buildh->buildings[tid][bid]->resources[cn])
  949. continue;
  950. itoa(CGI->buildh->buildings[tid][bid]->resources[cn],buf,10);
  951. if(it<4)
  952. {
  953. CSDL_Ext::printAtMiddle(buf,(bitmap->w/2-row1w/2)+77*it+16,ah+42,GEOR16,zwykly,bitmap);
  954. blitAt(CGI->townh->resources->ourImages[cn].bitmap,(bitmap->w/2-row1w/2)+77*it++,ah,bitmap);
  955. }
  956. else
  957. {
  958. CSDL_Ext::printAtMiddle(buf,(bitmap->w/2-row2w/2)+77*it+16-308,ah+42,GEOR16,zwykly,bitmap);
  959. blitAt(CGI->townh->resources->ourImages[cn].bitmap,(bitmap->w/2-row2w/2)+77*it++ - 308,ah,bitmap);
  960. }
  961. if(it==4)
  962. ah+=75;
  963. }
  964. if(!mode)
  965. {
  966. buy = new AdventureMapButton
  967. ("","",boost::bind(&CBuildWindow::Buy,this),pos.x+45,pos.y+446,"IBUY30.DEF",false,NULL,false);
  968. cancel = new AdventureMapButton
  969. ("","",boost::bind(&CBuildWindow::close,this),pos.x+290,pos.y+445,"ICANCEL.DEF",false,NULL,false);
  970. if(state!=7)
  971. buy->state=2;
  972. }
  973. activate();
  974. }
  975. CHallInterface::CBuildWindow::~CBuildWindow()
  976. {
  977. SDL_FreeSurface(bitmap);
  978. if(!mode)
  979. {
  980. delete buy;
  981. delete cancel;
  982. }
  983. }