CCastleInterface.cpp 29 KB

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