CCastleInterface.cpp 28 KB

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