CCastleInterface.cpp 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067
  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. recreateBuildings();
  476. }
  477. void CCastleInterface::removeBuilding(int bid)
  478. {
  479. //TODO: lepiej by bylo tylko usuwac co trzeba pamietajac o grupach
  480. recreateBuildings();
  481. }
  482. void CCastleInterface::recreateBuildings()
  483. {
  484. for(int i=0;i<buildings.size();i++)
  485. {
  486. if(showing)
  487. buildings[i]->deactivate();
  488. delete buildings[i];
  489. }
  490. buildings.clear();
  491. hBuild = NULL;
  492. std::set< std::pair<int,int> > s; //group - id
  493. for (std::set<si32>::const_iterator i=town->builtBuildings.begin();i!=town->builtBuildings.end();i++)
  494. {
  495. if(CGI->townh->structures.find(town->subID) != CGI->townh->structures.end()) //we have info about structures in this town
  496. {
  497. if(CGI->townh->structures[town->subID].find(*i)!=CGI->townh->structures[town->subID].end()) //we have info about that structure
  498. {
  499. Structure * st = CGI->townh->structures[town->subID][*i];
  500. if(st->group<0) //no group - just add it
  501. {
  502. buildings.push_back(new CBuildingRect(st));
  503. }
  504. else
  505. {
  506. std::set< std::pair<int,int> >::iterator obecny=s.end();
  507. for(std::set< std::pair<int,int> >::iterator seti = s.begin(); seti!=s.end(); seti++) //check if we have already building from same group
  508. {
  509. if(seti->first == st->group)
  510. {
  511. obecny = seti;
  512. break;
  513. }
  514. }
  515. if(obecny != s.end())
  516. {
  517. if((*(CGI->townh->structures[town->subID][obecny->second])) < (*(CGI->townh->structures[town->subID][st->ID]))) //we have to replace old building with current one
  518. {
  519. for(int itpb = 0; itpb<buildings.size(); itpb++)
  520. {
  521. if(buildings[itpb]->str->ID == obecny->second)
  522. {
  523. delete buildings[itpb];
  524. buildings.erase(buildings.begin() + itpb);
  525. obecny->second = st->ID;
  526. buildings.push_back(new CBuildingRect(st));
  527. }
  528. }
  529. }
  530. }
  531. else
  532. {
  533. buildings.push_back(new CBuildingRect(st));
  534. s.insert(std::pair<int,int>(st->group,st->ID));
  535. }
  536. }
  537. }
  538. else continue;
  539. }
  540. else
  541. break;
  542. }
  543. std::sort(buildings.begin(),buildings.end(),srthlp);
  544. //code for Mana Vortex (there are two sets of animation frames - one without mage guild and one with
  545. if((town->subID == 5) && (town->builtBuildings.find(21)!=town->builtBuildings.end()))
  546. {
  547. CBuildingRect *vortex = NULL;
  548. for(int i=0;i<buildings.size();i++)
  549. {
  550. if(buildings[i]->str->ID==21)
  551. {
  552. vortex=buildings[i];
  553. break;
  554. }
  555. }
  556. if(town->builtBuildings.find(4)!=town->builtBuildings.end()) //there is mage Guild level 5
  557. {
  558. vortex->offset = 10;
  559. vortex->max = vortex->def->ourImages.size();
  560. }
  561. else
  562. {
  563. vortex->offset = 0;
  564. vortex->max = 10;
  565. }
  566. }
  567. //code for the shipyard in the Castle
  568. else if((town->subID == 0) && (town->builtBuildings.find(6)!=town->builtBuildings.end()))
  569. {
  570. CBuildingRect *shipyard = NULL;
  571. for(int i=0;i<buildings.size();i++)
  572. {
  573. if(buildings[i]->str->ID==6)
  574. {
  575. shipyard=buildings[i];
  576. break;
  577. }
  578. }
  579. if(town->builtBuildings.find(8)!=town->builtBuildings.end()) //there is citadel
  580. {
  581. shipyard->offset = 1;
  582. shipyard->max = shipyard->def->ourImages.size();
  583. }
  584. else
  585. {
  586. shipyard->offset = 0;
  587. shipyard->max = 1;
  588. }
  589. }
  590. }
  591. void CHallInterface::CResDataBar::show(SDL_Surface * to)
  592. {
  593. blitAt(bg,pos.x,pos.y);
  594. char * buf = new char[15];
  595. for (int i=0;i<7;i++)
  596. {
  597. itoa(LOCPLINT->cb->getResourceAmount(i),buf,10);
  598. CSDL_Ext::printAtMiddle(buf,pos.x + 50 + 76*i,pos.y+pos.h/2,GEOR13,zwykly);
  599. }
  600. std::vector<std::string> temp;
  601. itoa(LOCPLINT->cb->getDate(3),buf,10); temp.push_back(std::string(buf));
  602. itoa(LOCPLINT->cb->getDate(2),buf,10); temp.push_back(buf);
  603. itoa(LOCPLINT->cb->getDate(1),buf,10); temp.push_back(buf);
  604. CSDL_Ext::printAtMiddle(CSDL_Ext::processStr(
  605. CGI->generaltexth->allTexts[62]
  606. +": %s, "
  607. + CGI->generaltexth->allTexts[63]
  608. + ": %s, "
  609. + CGI->generaltexth->allTexts[64]
  610. + ": %s",temp)
  611. ,pos.x+545+(pos.w-545)/2,pos.y+pos.h/2,GEOR13,zwykly);
  612. temp.clear();
  613. //updateRect(&pos,screen);
  614. delete[] buf;
  615. }
  616. CHallInterface::CResDataBar::CResDataBar()
  617. {
  618. bg = BitmapHandler::loadBitmap("Z2ESBAR.bmp");
  619. SDL_SetColorKey(bg,SDL_SRCCOLORKEY,SDL_MapRGB(bg->format,0,255,255));
  620. graphics->blueToPlayersAdv(bg,LOCPLINT->playerID);
  621. pos.x = 7;
  622. pos.y = 575;
  623. pos.w = bg->w;
  624. pos.h = bg->h;
  625. }
  626. CHallInterface::CResDataBar::~CResDataBar()
  627. {
  628. SDL_FreeSurface(bg);
  629. }
  630. void CHallInterface::CBuildingBox::hover(bool on)
  631. {
  632. Hoverable::hover(on);
  633. if(on)
  634. {
  635. std::string toPrint;
  636. if(state==8)
  637. toPrint = CGI->townh->hcommands[5];
  638. else
  639. toPrint = CGI->townh->hcommands[state];
  640. std::vector<std::string> name;
  641. name.push_back(CGI->buildh->buildings[LOCPLINT->castleInt->town->subID][BID]->name);
  642. LOCPLINT->statusbar->print(CSDL_Ext::processStr(toPrint,name));
  643. }
  644. else
  645. LOCPLINT->statusbar->clear();
  646. }
  647. void CHallInterface::CBuildingBox::clickLeft (tribool down)
  648. {
  649. if(pressedL && (!down))
  650. {
  651. LOCPLINT->castleInt->hallInt->deactivate();
  652. new CHallInterface::CBuildWindow(LOCPLINT->castleInt->town->subID,BID,state,0);
  653. }
  654. ClickableL::clickLeft(down);
  655. }
  656. void CHallInterface::CBuildingBox::clickRight (tribool down)
  657. {
  658. if(down)
  659. {
  660. LOCPLINT->castleInt->hallInt->deactivate();
  661. new CHallInterface::CBuildWindow(LOCPLINT->castleInt->town->subID,BID,state,1);
  662. }
  663. ClickableR::clickRight(down);
  664. }
  665. void CHallInterface::CBuildingBox::show(SDL_Surface * to)
  666. {
  667. blitAt(LOCPLINT->castleInt->bicons->ourImages[BID].bitmap,pos.x,pos.y);
  668. int pom, pom2=-1;
  669. switch (state)
  670. {
  671. case 4:
  672. pom = 0;
  673. pom2 = 0;
  674. break;
  675. case 7:
  676. pom = 1;
  677. break;
  678. case 6:
  679. pom2 = 2;
  680. pom = 2;
  681. break;
  682. case 0: case 5: case 8:
  683. pom2 = 1;
  684. pom = 2;
  685. break;
  686. case 2: case 1: default:
  687. pom = 3;
  688. break;
  689. }
  690. blitAt(LOCPLINT->castleInt->hallInt->bars->ourImages[pom].bitmap,pos.x-1,pos.y+71);
  691. if(pom2>=0)
  692. blitAt(LOCPLINT->castleInt->hallInt->status->ourImages[pom2].bitmap,pos.x+135, pos.y+54);
  693. 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);
  694. }
  695. void CHallInterface::CBuildingBox::activate()
  696. {
  697. Hoverable::activate();
  698. ClickableL::activate();
  699. ClickableR::activate();
  700. }
  701. void CHallInterface::CBuildingBox::deactivate()
  702. {
  703. Hoverable::deactivate();
  704. ClickableL::deactivate();
  705. ClickableR::deactivate();
  706. }
  707. CHallInterface::CBuildingBox::~CBuildingBox()
  708. {
  709. }
  710. CHallInterface::CBuildingBox::CBuildingBox(int id)
  711. :BID(id)
  712. {
  713. pos.w = 150;
  714. pos.h = 70;
  715. }
  716. CHallInterface::CBuildingBox::CBuildingBox(int id, int x, int y)
  717. :BID(id)
  718. {
  719. pos.x = x;
  720. pos.y = y;
  721. pos.w = 150;
  722. pos.h = 70;
  723. }
  724. CHallInterface::CHallInterface(CCastleInterface * owner)
  725. {
  726. bg = BitmapHandler::loadBitmap(CGI->buildh->hall[owner->town->subID].first);
  727. graphics->blueToPlayersAdv(bg,LOCPLINT->playerID);
  728. bars = CDefHandler::giveDefEss("TPTHBAR.DEF");
  729. status = CDefHandler::giveDefEss("TPTHCHK.DEF");
  730. exit = new AdventureMapButton
  731. (CGI->townh->tcommands[8],"",boost::bind(&CHallInterface::close,this),748,556,"TPMAGE1.DEF",false,NULL,false);
  732. //preparing boxes with buildings//
  733. boxes.resize(5);
  734. for(int i=0;i<5;i++) //for each row
  735. {
  736. for(int j=0; j<CGI->buildh->hall[owner->town->subID].second[i].size();j++) //for each box
  737. {
  738. int k=0;
  739. for(;k<CGI->buildh->hall[owner->town->subID].second[i][j].size();k++)//we are looking for the first not build structure
  740. {
  741. if(
  742. (owner->town->builtBuildings.find(CGI->buildh->hall[owner->town->subID].second[i][j][k]))
  743. ==
  744. (owner->town->builtBuildings.end()) )
  745. {
  746. int x = 34 + 194*j,
  747. y = 37 + 104*i,
  748. ID = CGI->buildh->hall[owner->town->subID].second[i][j][k];
  749. if(CGI->buildh->hall[owner->town->subID].second[i].size() == 2) //only two boxes in this row
  750. x+=194;
  751. else if(CGI->buildh->hall[owner->town->subID].second[i].size() == 3) //only three boxes in this row
  752. x+=97;
  753. boxes[i].push_back(new CBuildingBox(CGI->buildh->hall[owner->town->subID].second[i][j][k],x,y));
  754. boxes[i][boxes[i].size()-1]->state = 7; //allowed by default
  755. //can we build it?
  756. if(owner->town->forbiddenBuildings.find(CGI->buildh->hall[owner->town->subID].second[i][j][k])!=owner->town->forbiddenBuildings.end())
  757. boxes[i][boxes[i].size()-1]->state = 2; //forbidden
  758. else if(owner->town->builded >= MAX_BUILDING_PER_TURN)
  759. boxes[i][boxes[i].size()-1]->state = 5; //building limit
  760. //checking resources
  761. CBuilding * pom = CGI->buildh->buildings[owner->town->subID][CGI->buildh->hall[owner->town->subID].second[i][j][k]];
  762. for(int res=0;res<7;res++) //TODO: support custom amount of resources
  763. {
  764. if(pom->resources[res]>LOCPLINT->cb->getResourceAmount(res))
  765. boxes[i][boxes[i].size()-1]->state = 6; //lack of res
  766. }
  767. //checking for requirements
  768. for( std::set<int>::iterator ri = CGI->townh->requirements[owner->town->subID][ID].begin();
  769. ri != CGI->townh->requirements[owner->town->subID][ID].end();
  770. ri++ )
  771. {
  772. if(owner->town->builtBuildings.find(*ri)==owner->town->builtBuildings.end())
  773. boxes[i][boxes[i].size()-1]->state = 8; //lack of requirements - cannot build
  774. }
  775. //TODO: check if capital is already built, check if there is water for shipyard
  776. break;
  777. }
  778. }
  779. if(k==CGI->buildh->hall[owner->town->subID].second[i][j].size()) //all buildings built - let's take the last one
  780. {
  781. int x = 34 + 194*j,
  782. y = 37 + 104*i;
  783. if(CGI->buildh->hall[owner->town->subID].second[i].size() == 2)
  784. x+=194;
  785. else if(CGI->buildh->hall[owner->town->subID].second[i].size() == 3)
  786. x+=97;
  787. boxes[i].push_back(new CBuildingBox(CGI->buildh->hall[owner->town->subID].second[i][j][k-1],x,y));
  788. boxes[i][boxes[i].size()-1]->state = 4; //already exists
  789. }
  790. }
  791. }
  792. }
  793. CHallInterface::~CHallInterface()
  794. {
  795. delete bars;
  796. delete status;
  797. SDL_FreeSurface(bg);
  798. for(int i=0;i<boxes.size();i++)
  799. for(int j=0;j<boxes[i].size();j++)
  800. delete boxes[i][j];
  801. delete exit;
  802. }
  803. void CHallInterface::close()
  804. {
  805. deactivate();
  806. delete this;
  807. LOCPLINT->castleInt->activate();
  808. LOCPLINT->castleInt->showAll();
  809. }
  810. void CHallInterface::show(SDL_Surface * to)
  811. {
  812. blitAt(bg,0,0);
  813. resdatabar.show();
  814. exit->show();
  815. for(int i=0; i<5; i++)
  816. {
  817. for(int j=0;j<boxes[i].size();j++)
  818. boxes[i][j]->show();
  819. }
  820. }
  821. void CHallInterface::activate()
  822. {
  823. for(int i=0;i<5;i++)
  824. for(int j=0;j<boxes[i].size();j++)
  825. boxes[i][j]->activate();
  826. exit->activate();
  827. }
  828. void CHallInterface::deactivate()
  829. {
  830. for(int i=0;i<5;i++)
  831. {
  832. for(int j=0;j<boxes[i].size();j++)
  833. {
  834. boxes[i][j]->deactivate();
  835. }
  836. }
  837. exit->deactivate();
  838. }
  839. void CHallInterface::CBuildWindow::activate()
  840. {
  841. LOCPLINT->objsToBlit.push_back(this);
  842. ClickableR::activate();
  843. if(mode)
  844. return;
  845. if(state==7)
  846. buy->activate();
  847. cancel->activate();
  848. }
  849. void CHallInterface::CBuildWindow::deactivate()
  850. {
  851. LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),this));
  852. ClickableR::deactivate();
  853. if(mode)
  854. return;
  855. if(state==7)
  856. buy->deactivate();
  857. cancel->deactivate();
  858. }
  859. void CHallInterface::CBuildWindow::Buy()
  860. {
  861. LOCPLINT->cb->buildBuilding(LOCPLINT->castleInt->town,bid);
  862. deactivate();
  863. delete this;
  864. delete LOCPLINT->castleInt->hallInt;
  865. LOCPLINT->castleInt->hallInt = NULL;
  866. LOCPLINT->castleInt->activate();
  867. LOCPLINT->castleInt->showAll();
  868. }
  869. void CHallInterface::CBuildWindow::close()
  870. {
  871. deactivate();
  872. delete this;
  873. LOCPLINT->castleInt->hallInt->activate();
  874. LOCPLINT->castleInt->hallInt->show();
  875. }
  876. void CHallInterface::CBuildWindow::clickRight (tribool down)
  877. {
  878. if((!down || indeterminate(down)) && mode)
  879. close();
  880. }
  881. void CHallInterface::CBuildWindow::show(SDL_Surface * to)
  882. {
  883. SDL_Rect pom = genRect(bitmap->h-1,bitmap->w-1,pos.x,pos.y);
  884. SDL_Rect poms = pom; poms.x=0;poms.y=0;
  885. SDL_BlitSurface(bitmap,&poms,to?to:screen,&pom);
  886. if(!mode)
  887. {
  888. buy->show();
  889. cancel->show();
  890. }
  891. }
  892. std::string CHallInterface::CBuildWindow::getTextForState(int state)
  893. {
  894. std::string ret;
  895. if(state<7)
  896. ret = CGI->townh->hcommands[state];
  897. switch (state)
  898. {
  899. case 4: case 5: case 6:
  900. ret.replace(ret.find_first_of("%s"),2,CGI->buildh->buildings[tid][bid]->name);
  901. break;
  902. case 7:
  903. return CGI->generaltexth->allTexts[219]; //all prereq. are met
  904. case 8:
  905. {
  906. ret = CGI->generaltexth->allTexts[52];
  907. std::set<int> used;
  908. used.insert(bid);
  909. std::set<int> reqs;
  910. for(std::set<int>::iterator i=CGI->townh->requirements[tid][bid].begin();i!=CGI->townh->requirements[tid][bid].end();i++)
  911. if (LOCPLINT->castleInt->town->builtBuildings.find(*i) == LOCPLINT->castleInt->town->builtBuildings.end())
  912. reqs.insert(*i);
  913. while(true)
  914. {
  915. int czystych=0;
  916. for(std::set<int>::iterator i=reqs.begin();i!=reqs.end();i++)
  917. {
  918. if(used.find(*i)==used.end()) //we haven't added requirements for this building
  919. {
  920. used.insert(*i);
  921. for(
  922. std::set<int>::iterator j=CGI->townh->requirements[tid][*i].begin();
  923. j!=CGI->townh->requirements[tid][*i].end();
  924. j++
  925. )
  926. {
  927. if(LOCPLINT->castleInt->town->builtBuildings.find(*j) == //this building is not built
  928. LOCPLINT->castleInt->town->builtBuildings.end())
  929. reqs.insert(*j);
  930. }
  931. }
  932. else
  933. {
  934. czystych++;
  935. }
  936. }
  937. if(czystych==reqs.size())
  938. break;
  939. }
  940. bool first=true;
  941. for(std::set<int>::iterator i=reqs.begin();i!=reqs.end();i++)
  942. {
  943. ret+=(((first)?(" "):(", ")) + CGI->buildh->buildings[tid][*i]->name);
  944. first = false;
  945. }
  946. }
  947. }
  948. return ret;
  949. }
  950. CHallInterface::CBuildWindow::CBuildWindow(int Tid, int Bid, int State, bool Mode)
  951. :tid(Tid),bid(Bid),mode(Mode), state(State)
  952. {
  953. SDL_Surface *hhlp = BitmapHandler::loadBitmap("TPUBUILD.bmp");
  954. bitmap = SDL_ConvertSurface(hhlp,screen->format,0); //na 8bitowej mapie by sie psulo
  955. SDL_SetColorKey(hhlp,SDL_SRCCOLORKEY,SDL_MapRGB(hhlp->format,0,255,255));
  956. SDL_FreeSurface(hhlp);
  957. pos.x = screen->w/2 - bitmap->w/2;
  958. pos.y = screen->h/2 - bitmap->h/2;
  959. graphics->blueToPlayersAdv(bitmap,LOCPLINT->playerID);
  960. blitAt(LOCPLINT->castleInt->bicons->ourImages[bid].bitmap,125,50,bitmap);
  961. std::vector<std::string> pom; pom.push_back(CGI->buildh->buildings[tid][bid]->name);
  962. CSDL_Ext::printAtMiddleWB(CGI->buildh->buildings[tid][bid]->description,197,168,GEOR16,40,zwykly,bitmap);
  963. CSDL_Ext::printAtMiddleWB(getTextForState(state),197,248,GEOR13,50,zwykly,bitmap);
  964. CSDL_Ext::printAtMiddle(CSDL_Ext::processStr(CGI->townh->hcommands[7],pom),197,30,GEOR16,tytulowy,bitmap);
  965. int resamount=0; for(int i=0;i<7;i++) if(CGI->buildh->buildings[tid][bid]->resources[i]) resamount++;
  966. int ah = (resamount>4) ? 304 : 341;
  967. int cn=-1, it=0;
  968. int row1w = std::min(resamount,4) * 32 + (std::min(resamount,4)-1) * 45,
  969. row2w = (resamount-4) * 32 + (resamount-5) * 45;
  970. char buf[15];
  971. while(++cn<7)
  972. {
  973. if(!CGI->buildh->buildings[tid][bid]->resources[cn])
  974. continue;
  975. itoa(CGI->buildh->buildings[tid][bid]->resources[cn],buf,10);
  976. if(it<4)
  977. {
  978. CSDL_Ext::printAtMiddle(buf,(bitmap->w/2-row1w/2)+77*it+16,ah+42,GEOR16,zwykly,bitmap);
  979. blitAt(graphics->resources32->ourImages[cn].bitmap,(bitmap->w/2-row1w/2)+77*it++,ah,bitmap);
  980. }
  981. else
  982. {
  983. CSDL_Ext::printAtMiddle(buf,(bitmap->w/2-row2w/2)+77*it+16-308,ah+42,GEOR16,zwykly,bitmap);
  984. blitAt(graphics->resources32->ourImages[cn].bitmap,(bitmap->w/2-row2w/2)+77*it++ - 308,ah,bitmap);
  985. }
  986. if(it==4)
  987. ah+=75;
  988. }
  989. if(!mode)
  990. {
  991. buy = new AdventureMapButton
  992. ("","",boost::bind(&CBuildWindow::Buy,this),pos.x+45,pos.y+446,"IBUY30.DEF",false,NULL,false);
  993. cancel = new AdventureMapButton
  994. ("","",boost::bind(&CBuildWindow::close,this),pos.x+290,pos.y+445,"ICANCEL.DEF",false,NULL,false);
  995. if(state!=7)
  996. buy->state=2;
  997. }
  998. activate();
  999. }
  1000. CHallInterface::CBuildWindow::~CBuildWindow()
  1001. {
  1002. SDL_FreeSurface(bitmap);
  1003. if(!mode)
  1004. {
  1005. delete buy;
  1006. delete cancel;
  1007. }
  1008. }