CCastleInterface.cpp 29 KB

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