CCastleInterface.cpp 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645
  1. #include "stdafx.h"
  2. #include "AdventureMapButton.h"
  3. #include "CAdvmapInterface.h"
  4. #include "CCallback.h"
  5. #include "CCastleInterface.h"
  6. #include "CGameInfo.h"
  7. #include "CHeroWindow.h"
  8. #include "CMessage.h"
  9. #include "SDL_Extensions.h"
  10. #include "client/CCreatureAnimation.h"
  11. #include "client/Graphics.h"
  12. #include "hch/CArtHandler.h"
  13. #include "hch/CBuildingHandler.h"
  14. #include "hch/CDefHandler.h"
  15. #include "hch/CGeneralTextHandler.h"
  16. #include "hch/CLodHandler.h"
  17. #include "hch/CObjectHandler.h"
  18. #include "hch/CSpellHandler.h"
  19. #include "hch/CTownHandler.h"
  20. #include <boost/algorithm/string.hpp>
  21. #include <boost/algorithm/string/replace.hpp>
  22. #include <boost/assign/std/vector.hpp>
  23. #include <cmath>
  24. #include <sstream>
  25. using namespace boost::assign;
  26. using namespace CSDL_Ext;
  27. extern TTF_Font * GEOR16;
  28. CBuildingRect::CBuildingRect(Structure *Str)
  29. :str(Str), moi(false), offset(0)
  30. {
  31. def = CDefHandler::giveDef(Str->defName);
  32. max = def->ourImages.size();
  33. if(str->ID == 33 && str->townID == 4) //little 'hack' for estate in necropolis - background color is not always the first color in the palette
  34. {
  35. for(std::vector<Cimage>::iterator i=def->ourImages.begin();i!=def->ourImages.end();i++)
  36. {
  37. SDL_SetColorKey(i->bitmap,SDL_SRCCOLORKEY,*((char*)i->bitmap->pixels));
  38. }
  39. }
  40. pos.x = str->pos.x + LOCPLINT->castleInt->pos.x;
  41. pos.y = str->pos.y + LOCPLINT->castleInt->pos.y;
  42. pos.w = def->ourImages[0].bitmap->w;
  43. pos.h = def->ourImages[0].bitmap->h;
  44. if(Str->ID<0 || (Str->ID>=27 && Str->ID<=29))
  45. {
  46. area = border = NULL;
  47. return;
  48. }
  49. if (border = BitmapHandler::loadBitmap(str->borderName))
  50. SDL_SetColorKey(border,SDL_SRCCOLORKEY,SDL_MapRGB(border->format,0,255,255));
  51. else
  52. tlog2 << "Warning: no border for "<<Str->ID<<std::endl;
  53. if (area = BitmapHandler::loadBitmap(str->areaName))
  54. ;//SDL_SetColorKey(area,SDL_SRCCOLORKEY,SDL_MapRGB(area->format,0,255,255));
  55. else
  56. tlog2 << "Warning: no area for "<<Str->ID<<std::endl;
  57. }
  58. CBuildingRect::~CBuildingRect()
  59. {
  60. delete def;
  61. if(border)
  62. SDL_FreeSurface(border);
  63. if(area)
  64. SDL_FreeSurface(area);
  65. }
  66. void CBuildingRect::activate()
  67. {
  68. Hoverable::activate();
  69. ClickableL::activate();
  70. ClickableR::activate();
  71. }
  72. void CBuildingRect::deactivate()
  73. {
  74. Hoverable::deactivate();
  75. ClickableL::deactivate();
  76. ClickableR::deactivate();
  77. if(moi)
  78. MotionInterested::deactivate();
  79. moi=false;
  80. }
  81. bool CBuildingRect::operator<(const CBuildingRect & p2) const
  82. {
  83. if(str->pos.z != p2.str->pos.z)
  84. return (str->pos.z) < (p2.str->pos.z);
  85. else
  86. return (str->ID) < (p2.str->ID);
  87. }
  88. void CBuildingRect::hover(bool on)
  89. {
  90. Hoverable::hover(on);
  91. if(on)
  92. {
  93. if(!moi)
  94. MotionInterested::activate();
  95. moi = true;
  96. }
  97. else
  98. {
  99. if(moi)
  100. MotionInterested::deactivate();
  101. moi = false;
  102. if(LOCPLINT->castleInt->hBuild == this)
  103. {
  104. LOCPLINT->castleInt->hBuild = NULL;
  105. LOCPLINT->statusbar->clear();
  106. }
  107. }
  108. }
  109. void CBuildingRect::clickLeft (tribool down)
  110. {
  111. 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
  112. {
  113. if(pressedL && !down)
  114. LOCPLINT->castleInt->buildingClicked(str->ID);
  115. ClickableL::clickLeft(down);
  116. }
  117. //todo - handle
  118. }
  119. void CBuildingRect::clickRight (tribool down)
  120. {
  121. if((!area) || (!((bool)down)) || (this!=LOCPLINT->castleInt->hBuild))
  122. return;
  123. if((CSDL_Ext::SDL_GetPixel(area,LOCPLINT->current->motion.x-pos.x,LOCPLINT->current->motion.y-pos.y) != 0)) //na polu
  124. {
  125. CInfoPopup *vinya = new CInfoPopup();
  126. vinya->free = true;
  127. vinya->bitmap = CMessage::drawBoxTextBitmapSub
  128. (LOCPLINT->playerID,
  129. CGI->buildh->buildings[str->townID][str->ID]->description,
  130. LOCPLINT->castleInt->bicons->ourImages[str->ID].bitmap,
  131. CGI->buildh->buildings[str->townID][str->ID]->name);
  132. vinya->pos.x = screen->w/2 - vinya->bitmap->w/2;
  133. vinya->pos.y = screen->h/2 - vinya->bitmap->h/2;
  134. vinya->activate();
  135. }
  136. }
  137. void CBuildingRect::mouseMoved (const SDL_MouseMotionEvent & sEvent)
  138. {
  139. if(area)
  140. {
  141. if(CSDL_Ext::SDL_GetPixel(area,sEvent.x-pos.x,sEvent.y-pos.y) == 0) //hovered pixel is inside this building
  142. {
  143. if(LOCPLINT->castleInt->hBuild == this)
  144. {
  145. LOCPLINT->castleInt->hBuild = NULL;
  146. LOCPLINT->statusbar->clear();
  147. }
  148. }
  149. else //inside the area of this building
  150. {
  151. if(LOCPLINT->castleInt->hBuild) //a building is hovered
  152. {
  153. if((*LOCPLINT->castleInt->hBuild)<(*this)) //set if we are on top
  154. {
  155. LOCPLINT->castleInt->hBuild = this;
  156. if(CGI->buildh->buildings[str->townID][str->ID] && CGI->buildh->buildings[str->townID][str->ID]->name.length())
  157. LOCPLINT->statusbar->print(CGI->buildh->buildings[str->townID][str->ID]->name);
  158. else
  159. LOCPLINT->statusbar->print(str->name);
  160. }
  161. }
  162. else //no building hovered
  163. {
  164. LOCPLINT->castleInt->hBuild = this;
  165. if(CGI->buildh->buildings[str->townID][str->ID] && CGI->buildh->buildings[str->townID][str->ID]->name.length())
  166. LOCPLINT->statusbar->print(CGI->buildh->buildings[str->townID][str->ID]->name);
  167. else
  168. LOCPLINT->statusbar->print(str->name);
  169. }
  170. }
  171. }
  172. //if(border)
  173. // blitAt(border,pos.x,pos.y);
  174. }
  175. void CHeroGSlot::hover (bool on)
  176. {
  177. if(!on) return;
  178. CHeroGSlot *other = upg ? &owner->hslotup : &owner->hslotdown;
  179. std::string temp;
  180. if(hero)
  181. {
  182. if(highlight)//view NNN
  183. {
  184. temp = CGI->townh->tcommands[4];
  185. boost::algorithm::replace_first(temp,"%s",hero->name);
  186. }
  187. else if(other->hero && other->highlight)//exchange
  188. {
  189. temp = CGI->townh->tcommands[7];
  190. boost::algorithm::replace_first(temp,"%s",hero->name);
  191. boost::algorithm::replace_first(temp,"%s",other->hero->name);
  192. }
  193. else// select NNN (in ZZZ)
  194. {
  195. if(upg)//down - visiting
  196. {
  197. temp = CGI->townh->tcommands[32];
  198. boost::algorithm::replace_first(temp,"%s",hero->name);
  199. }
  200. else //up - garrison
  201. {
  202. temp = CGI->townh->tcommands[12];
  203. boost::algorithm::replace_first(temp,"%s",hero->name);
  204. }
  205. }
  206. }
  207. else //we are empty slot
  208. {
  209. if(other->highlight && other->hero) //move NNNN
  210. {
  211. temp = CGI->townh->tcommands[6];
  212. boost::algorithm::replace_first(temp,"%s",other->hero->name);
  213. }
  214. else //empty
  215. {
  216. temp = CGI->generaltexth->allTexts[507];
  217. }
  218. }
  219. if(temp.size())
  220. LOCPLINT->statusbar->print(temp);
  221. }
  222. void CHeroGSlot::clickRight (boost::logic::tribool down)
  223. {
  224. }
  225. void CHeroGSlot::clickLeft(boost::logic::tribool down)
  226. {
  227. CHeroGSlot *other = upg ? &owner->hslotup : &owner->hslotdown;
  228. if(!down)
  229. {
  230. if(hero && highlight)
  231. {
  232. highlight = false;
  233. LOCPLINT->openHeroWindow(hero);
  234. LOCPLINT->adventureInt->heroWindow->quitButton->callback += boost::bind(&CCastleInterface::showAll,owner,screen,true);
  235. }
  236. else if(other->hero && other->highlight)
  237. {
  238. other->highlight = highlight = false;
  239. LOCPLINT->cb->swapGarrisonHero(owner->town);
  240. }
  241. else if(hero)
  242. {
  243. highlight = true;
  244. owner->garr->highlighted = NULL;
  245. owner->showAll();
  246. }
  247. hover(false);hover(true); //refresh statusbar
  248. }
  249. if(indeterminate(down) && !isItIn(&other->pos,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y))
  250. {
  251. other->highlight = highlight = false;
  252. show();
  253. }
  254. }
  255. void CHeroGSlot::activate()
  256. {
  257. ClickableL::activate();
  258. ClickableR::activate();
  259. Hoverable::activate();
  260. }
  261. void CHeroGSlot::deactivate()
  262. {
  263. highlight = false;
  264. ClickableL::deactivate();
  265. ClickableR::deactivate();
  266. Hoverable::deactivate();
  267. }
  268. void CHeroGSlot::show()
  269. {
  270. if(hero) //there is hero
  271. blitAt(graphics->portraitLarge[hero->portrait],pos);
  272. else if(!upg) //up garrison
  273. blitAt(graphics->flags->ourImages[(static_cast<CCastleInterface*>(LOCPLINT->curint))->town->getOwner()].bitmap,pos);
  274. if(highlight)
  275. blitAt(graphics->bigImgs[-1],pos);
  276. }
  277. CHeroGSlot::CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h, CCastleInterface * Owner)
  278. {
  279. owner = Owner;
  280. pos.x = x;
  281. pos.y = y;
  282. pos.w = 58;
  283. pos.h = 64;
  284. hero = h;
  285. upg = updown;
  286. highlight = false;
  287. }
  288. CHeroGSlot::~CHeroGSlot()
  289. {
  290. }
  291. std::string getBgName(int type) //TODO - co z tym zrobiæ?
  292. {
  293. switch (type)
  294. {
  295. case 0:
  296. return "TBCSBACK.bmp";
  297. case 1:
  298. return "TBRMBACK.bmp";
  299. case 2:
  300. return "TBTWBACK.bmp";
  301. case 3:
  302. return "TBINBACK.bmp";
  303. case 4:
  304. return "TBNCBACK.bmp";
  305. case 5:
  306. return "TBDNBACK.bmp";
  307. case 6:
  308. return "TBSTBACK.bmp";
  309. case 7:
  310. return "TBFRBACK.bmp";
  311. case 8:
  312. return "TBELBACK.bmp";
  313. default:
  314. #ifndef __GNUC__
  315. throw new std::exception("std::string getBgName(int type): invalid type");
  316. #else
  317. throw new std::exception();
  318. #endif
  319. }
  320. }
  321. class SORTHELP
  322. {
  323. public:
  324. bool operator ()
  325. (const CBuildingRect *a ,
  326. const CBuildingRect *b)
  327. {
  328. return (*a)<(*b);
  329. }
  330. } srthlp ;
  331. CCastleInterface::CCastleInterface(const CGTownInstance * Town, bool Activate)
  332. :hslotup(241,387,0,Town->garrisonHero,this),hslotdown(241,483,1,Town->visitingHero,this)
  333. {
  334. LOCPLINT->castleInt = this;
  335. subInt = NULL;
  336. hall = NULL;
  337. townInt = BitmapHandler::loadBitmap("TOWNSCRN.bmp");
  338. cityBg = BitmapHandler::loadBitmap(getBgName(Town->subID));
  339. pos.x = screen->w/2 - 400;
  340. pos.y = screen->h/2 - 300;
  341. hslotup.pos.x += pos.x;
  342. hslotup.pos.y += pos.y;
  343. hslotdown.pos.x += pos.x;
  344. hslotdown.pos.y += pos.y;
  345. hall = CDefHandler::giveDef("ITMTL.DEF");
  346. fort = CDefHandler::giveDef("ITMCL.DEF");
  347. hBuild = NULL;
  348. count=0;
  349. town = Town;
  350. //garrison
  351. garr = new CGarrisonInt(pos.x+305,pos.y+387,4,32,townInt,243,13,town,town->visitingHero);
  352. townlist = new CTownList(3,pos.x+744,pos.y+414,"IAM014.DEF","IAM015.DEF");//744,526);
  353. exit = new AdventureMapButton
  354. (CGI->townh->tcommands[8],"",boost::bind(&CCastleInterface::close,this),pos.x+744,pos.y+544,"TSBTNS.DEF",SDLK_RETURN);
  355. split = new AdventureMapButton
  356. (CGI->townh->tcommands[3],"",boost::bind(&CGarrisonInt::splitClick,garr),pos.x+744,pos.y+382,"TSBTNS.DEF");
  357. statusbar = new CStatusBar(pos.x+7,pos.y+555,"TSTATBAR.bmp",732);
  358. resdatabar = new CResDataBar("ZRESBAR.bmp",pos.x+3,pos.y+575,32,2,85,85);
  359. resdatabar->pos.x = pos.x+3; resdatabar->pos.y = pos.y+575;
  360. townlist->fun = boost::bind(&CCastleInterface::townChange,this);
  361. townlist->genList();
  362. townlist->selected = getIndexOf(townlist->items,Town);
  363. if((townlist->selected+1) > townlist->SIZE)
  364. townlist->from = townlist->selected - townlist->SIZE + 2;
  365. graphics->blueToPlayersAdv(townInt,LOCPLINT->playerID);
  366. exit->bitmapOffset = 4;
  367. //buildings
  368. recreateBuildings();
  369. if(Activate)
  370. {
  371. LOCPLINT->objsToBlit.push_back(this);
  372. activate();
  373. }
  374. std::string defname;
  375. switch (town->subID)
  376. {
  377. case 0:
  378. defname = "HALLCSTL.DEF";
  379. break;
  380. case 1:
  381. defname = "HALLRAMP.DEF";
  382. break;
  383. case 2:
  384. defname = "HALLTOWR.DEF";
  385. break;
  386. case 3:
  387. defname = "HALLINFR.DEF";
  388. break;
  389. case 4:
  390. defname = "HALLNECR.DEF";
  391. break;
  392. case 5:
  393. defname = "HALLDUNG.DEF";
  394. break;
  395. case 6:
  396. defname = "HALLSTRN.DEF";
  397. break;
  398. case 7:
  399. defname = "HALLFORT.DEF";
  400. break;
  401. case 8:
  402. defname = "HALLELEM.DEF";
  403. break;
  404. default:
  405. throw new std::string("Wrong town subID");
  406. }
  407. bicons = CDefHandler::giveDefEss(defname);
  408. }
  409. CCastleInterface::~CCastleInterface()
  410. {
  411. SDL_FreeSurface(townInt);
  412. SDL_FreeSurface(cityBg);
  413. delete exit;
  414. delete split;
  415. delete hall;
  416. delete fort;
  417. delete garr;
  418. delete townlist;
  419. delete statusbar;
  420. delete resdatabar;
  421. for(int i=0;i<buildings.size();i++)
  422. {
  423. delete buildings[i];
  424. }
  425. delete bicons;
  426. }
  427. void CCastleInterface::close()
  428. {
  429. LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),this));
  430. deactivate();
  431. LOCPLINT->castleInt = NULL;
  432. if(town->visitingHero)
  433. LOCPLINT->adventureInt->select(town->visitingHero);
  434. LOCPLINT->adventureInt->activate();
  435. delete this;
  436. }
  437. void CCastleInterface::splitF()
  438. {
  439. }
  440. void CCastleInterface::buildingClicked(int building)
  441. {
  442. tlog5<<"You've clicked on "<<building<<std::endl;
  443. if(building==19 || building==18)
  444. {
  445. building = town->town->hordeLvl[0] + 30;
  446. }
  447. else if(building==24 || building==25)
  448. {
  449. building = town->town->hordeLvl[1] + 30;
  450. }
  451. if(building >= 30)
  452. {
  453. LOCPLINT->curint->deactivate();
  454. showRecruitmentWindow(building);
  455. }
  456. else
  457. {
  458. switch(building)
  459. {
  460. case 0: case 1: case 2: case 3: case 4: //mage guild
  461. {
  462. if(town->visitingHero && !vstd::contains(town->visitingHero->artifWorn,ui16(17))) //visiting hero doesn't have spellboks
  463. {
  464. if(LOCPLINT->cb->getResourceAmount(6) < 500) //not enough gold to buy spellbook
  465. {
  466. LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[213],std::vector<SComponent*>());
  467. }
  468. else
  469. {
  470. CFunctionList<void()> fl = boost::bind(&CCallback::buyArtifact,LOCPLINT->cb,town->visitingHero,0);
  471. fl += boost::bind(&CCastleInterface::enterMageGuild,this);
  472. std::vector<SComponent*> vvv(1,new SComponent(SComponent::artifact,0,0));
  473. LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[214],vvv,
  474. fl,boost::bind(&CCastleInterface::activate,this),
  475. true,true);
  476. }
  477. }
  478. else
  479. {
  480. deactivate();
  481. enterMageGuild();
  482. }
  483. break;
  484. }
  485. case 5: //tavern
  486. {
  487. std::vector<const CGHeroInstance*> h = LOCPLINT->cb->getAvailableHeroes(town);
  488. CTavernWindow *tv = new CTavernWindow(h[0],h[1],"GOSSIP TEST");
  489. deactivate();
  490. tv->activate();
  491. break;
  492. }
  493. case 7: case 8: case 9: //fort/citadel/castle
  494. {
  495. deactivate();
  496. CFortScreen *fs = new CFortScreen(this);
  497. fs->activate();
  498. fs->show();
  499. break;
  500. }
  501. case 10: case 11: case 12: case 13: //hall
  502. enterHall();
  503. break;
  504. case 14: //marketplace
  505. {
  506. deactivate();
  507. CMarketplaceWindow *cmw = new CMarketplaceWindow(0);
  508. cmw->activate();
  509. break;
  510. }
  511. case 15: //resource silo
  512. {
  513. LOCPLINT->showInfoDialog(CGI->buildh->buildings[town->subID][15]->description,std::vector<SComponent*>());
  514. break;
  515. }
  516. case 16: //blacksmith
  517. {
  518. const CGHeroInstance *hero = town->visitingHero;
  519. if(!hero)
  520. {
  521. std::string pom = CGI->generaltexth->allTexts[273];
  522. boost::algorithm::replace_first(pom,"%s",CGI->buildh->buildings[town->subID][16]->name);
  523. LOCPLINT->showInfoDialog(pom,std::vector<SComponent*>());
  524. return;
  525. }
  526. int aid = town->town->warMachine;
  527. int price = CGI->arth->artifacts[aid].price;
  528. bool possible = (LOCPLINT->cb->getResourceAmount(6) >= price);
  529. if(vstd::contains(hero->artifWorn,ui16(aid+9))) //hero already has machine
  530. possible = false;
  531. deactivate();
  532. (new CBlacksmithDialog(possible,CArtHandler::convertMachineID(aid,false),aid,hero->id))->activate();
  533. break;
  534. }
  535. default:
  536. tlog4<<"This building isn't handled...\n";
  537. }
  538. }
  539. }
  540. void CCastleInterface::enterHall()
  541. {
  542. deactivate();
  543. CHallInterface *h = new CHallInterface(this);
  544. subInt = h;
  545. h->activate();
  546. h->show();
  547. }
  548. void CCastleInterface::showAll( SDL_Surface * to/*=NULL*/, bool forceTotalRedraw /*= false*/)
  549. {
  550. if (!to)
  551. to=screen;
  552. blitAt(cityBg,pos,to);
  553. blitAt(townInt,pos.x,pos.y+374,to);
  554. LOCPLINT->adventureInt->resdatabar.draw();
  555. townlist->draw();
  556. statusbar->show();
  557. resdatabar->draw();
  558. garr->show();
  559. int pom;
  560. //draw fort icon
  561. if(town->builtBuildings.find(9)!=town->builtBuildings.end())
  562. pom = 2;
  563. else if(town->builtBuildings.find(8)!=town->builtBuildings.end())
  564. pom = 1;
  565. else if(town->builtBuildings.find(7)!=town->builtBuildings.end())
  566. pom = 0;
  567. else pom = 3;
  568. blitAt(fort->ourImages[pom].bitmap,pos.x+122,pos.y+413,to);
  569. //draw ((village/town/city) hall)/capitol icon
  570. if(town->builtBuildings.find(13)!=town->builtBuildings.end())
  571. pom = 3;
  572. else if(town->builtBuildings.find(12)!=town->builtBuildings.end())
  573. pom = 2;
  574. else if(town->builtBuildings.find(11)!=town->builtBuildings.end())
  575. pom = 1;
  576. else pom = 0;
  577. blitAt(hall->ourImages[pom].bitmap,pos.x+80,pos.y+413,to);
  578. //draw creatures icons and their growths
  579. for(int i=0;i<CREATURES_PER_TOWN;i++)
  580. {
  581. int cid = -1;
  582. if (town->builtBuildings.find(30+i)!=town->builtBuildings.end())
  583. {
  584. if (town->builtBuildings.find(30+CREATURES_PER_TOWN+i)!=town->builtBuildings.end())
  585. cid = town->town->upgradedCreatures[i];
  586. else
  587. cid = town->town->basicCreatures[i];
  588. }
  589. if (cid>=0)
  590. {
  591. int pomx, pomy;
  592. pomx = 22 + (55*((i>3)?(i-4):i));
  593. pomy = (i>3)?(507):(459);
  594. blitAt(graphics->smallImgs[cid],pos.x+pomx,pos.y+pomy,to);
  595. std::ostringstream oss;
  596. oss << '+' << town->creatureGrowth(i);
  597. CSDL_Ext::printAtMiddle(oss.str(),pos.x+pomx+16,pos.y+pomy+37,GEOR13,zwykly,to);
  598. }
  599. }
  600. //print name and income
  601. CSDL_Ext::printAt(town->name,pos.x+85,pos.y+389,GEOR13,zwykly,to);
  602. char temp[10];
  603. SDL_itoa(town->dailyIncome(),temp,10);
  604. CSDL_Ext::printAtMiddle(temp,pos.x+195,pos.y+442,GEOR13,zwykly,to);
  605. //blit town icon
  606. pom = town->subID*2;
  607. if (!town->hasFort())
  608. pom += F_NUMBER*2;
  609. if(town->builded >= MAX_BUILDING_PER_TURN)
  610. pom++;
  611. blitAt(graphics->bigTownPic->ourImages[pom].bitmap,pos.x+15,pos.y+387,to);
  612. hslotup.show();
  613. hslotdown.show();
  614. pom=false;
  615. if(forceTotalRedraw && !showing)
  616. pom = showing = true;
  617. show();
  618. if(pom)
  619. showing = false;
  620. CMessage::drawBorder(LOCPLINT->playerID,to,828,628,pos.x-14,pos.y-15);
  621. }
  622. void CCastleInterface::townChange()
  623. {
  624. const CGTownInstance * nt = townlist->items[townlist->selected];
  625. deactivate();
  626. LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),this));
  627. delete this;
  628. LOCPLINT->castleInt = new CCastleInterface(nt,true);
  629. }
  630. void CCastleInterface::show(SDL_Surface * to)
  631. {
  632. if(!showing)
  633. return;
  634. if (!to)
  635. to=screen;
  636. count++;
  637. if(count==8)
  638. {
  639. count=0;
  640. animval++;
  641. }
  642. blitAt(cityBg,pos,to);
  643. //blit buildings
  644. for(int i=0;i<buildings.size();i++)
  645. {
  646. int frame = ((animval)%(buildings[i]->max - buildings[i]->offset)) + buildings[i]->offset;
  647. if(frame)
  648. {
  649. blitAt(buildings[i]->def->ourImages[0].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to);
  650. blitAt(buildings[i]->def->ourImages[frame].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to);
  651. }
  652. else
  653. blitAt(buildings[i]->def->ourImages[frame].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to);
  654. if(hBuild==buildings[i] && hBuild->border) //if this this higlighted structure and has border we'll blit it
  655. blitAt(hBuild->border,hBuild->pos,to);
  656. }
  657. }
  658. void CCastleInterface::activate()
  659. {
  660. if(subInt)
  661. {
  662. subInt->activate();
  663. return;
  664. }
  665. showing = true;
  666. townlist->activate();
  667. garr->activate();
  668. LOCPLINT->curint = this;
  669. LOCPLINT->statusbar = statusbar;
  670. exit->activate();
  671. split->activate();
  672. for(int i=0;i<buildings.size();i++)
  673. buildings[i]->activate();
  674. hslotdown.activate();
  675. hslotup.activate();
  676. showAll(0,true);
  677. }
  678. void CCastleInterface::deactivate()
  679. {
  680. if(subInt)
  681. {
  682. subInt->deactivate();
  683. return;
  684. }
  685. showing = false;
  686. townlist->deactivate();
  687. garr->deactivate();
  688. exit->deactivate();
  689. split->deactivate();
  690. for(int i=0;i<buildings.size();i++)
  691. buildings[i]->deactivate();
  692. hslotdown.deactivate();
  693. hslotup.deactivate();
  694. }
  695. void CCastleInterface::addBuilding(int bid)
  696. {
  697. //TODO: lepiej by bylo tylko dodawac co trzeba pamietajac o grupach
  698. deactivate();
  699. recreateBuildings();
  700. activate();
  701. }
  702. void CCastleInterface::removeBuilding(int bid)
  703. {
  704. //TODO: lepiej by bylo tylko usuwac co trzeba pamietajac o grupach
  705. recreateBuildings();
  706. }
  707. void CCastleInterface::recreateBuildings()
  708. {
  709. for(int i=0;i<buildings.size();i++)
  710. {
  711. if(showing)
  712. buildings[i]->deactivate();
  713. delete buildings[i];
  714. }
  715. buildings.clear();
  716. hBuild = NULL;
  717. std::set< std::pair<int,int> > s; //group - id
  718. for (std::set<si32>::const_iterator i=town->builtBuildings.begin();i!=town->builtBuildings.end();i++)
  719. {
  720. if(CGI->townh->structures.find(town->subID) != CGI->townh->structures.end()) //we have info about structures in this town
  721. {
  722. if(CGI->townh->structures[town->subID].find(*i)!=CGI->townh->structures[town->subID].end()) //we have info about that structure
  723. {
  724. Structure * st = CGI->townh->structures[town->subID][*i];
  725. if(st->group<0) //no group - just add it
  726. {
  727. buildings.push_back(new CBuildingRect(st));
  728. }
  729. else
  730. {
  731. std::set< std::pair<int,int> >::iterator obecny=s.end();
  732. for(std::set< std::pair<int,int> >::iterator seti = s.begin(); seti!=s.end(); seti++) //check if we have already building from same group
  733. {
  734. if(seti->first == st->group)
  735. {
  736. obecny = seti;
  737. break;
  738. }
  739. }
  740. if(obecny != s.end())
  741. {
  742. if((*(CGI->townh->structures[town->subID][obecny->second])) < (*(CGI->townh->structures[town->subID][st->ID]))) //we have to replace old building with current one
  743. {
  744. for(int itpb = 0; itpb<buildings.size(); itpb++)
  745. {
  746. if(buildings[itpb]->str->ID == obecny->second)
  747. {
  748. delete buildings[itpb];
  749. buildings.erase(buildings.begin() + itpb);
  750. #ifndef __GNUC__
  751. obecny->second = st->ID;
  752. #else
  753. *(const_cast<int*>(&(obecny->second))) = st->ID;
  754. #endif
  755. buildings.push_back(new CBuildingRect(st));
  756. }
  757. }
  758. }
  759. }
  760. else
  761. {
  762. buildings.push_back(new CBuildingRect(st));
  763. s.insert(std::pair<int,int>(st->group,st->ID));
  764. }
  765. }
  766. }
  767. else continue;
  768. }
  769. else
  770. break;
  771. }
  772. std::sort(buildings.begin(),buildings.end(),srthlp);
  773. //code for Mana Vortex (there are two sets of animation frames - one without mage guild and one with
  774. if((town->subID == 5) && (town->builtBuildings.find(21)!=town->builtBuildings.end()))
  775. {
  776. CBuildingRect *vortex = NULL;
  777. for(int i=0;i<buildings.size();i++)
  778. {
  779. if(buildings[i]->str->ID==21)
  780. {
  781. vortex=buildings[i];
  782. break;
  783. }
  784. }
  785. if(town->builtBuildings.find(4)!=town->builtBuildings.end()) //there is mage Guild level 5
  786. {
  787. vortex->offset = 10;
  788. vortex->max = vortex->def->ourImages.size();
  789. }
  790. else
  791. {
  792. vortex->offset = 0;
  793. vortex->max = 10;
  794. }
  795. }
  796. //code for the shipyard in the Castle
  797. else if((town->subID == 0) && (town->builtBuildings.find(6)!=town->builtBuildings.end()))
  798. {
  799. CBuildingRect *shipyard = NULL;
  800. for(int i=0;i<buildings.size();i++)
  801. {
  802. if(buildings[i]->str->ID==6)
  803. {
  804. shipyard=buildings[i];
  805. break;
  806. }
  807. }
  808. if(town->builtBuildings.find(8)!=town->builtBuildings.end()) //there is citadel
  809. {
  810. shipyard->offset = 1;
  811. shipyard->max = shipyard->def->ourImages.size();
  812. }
  813. else
  814. {
  815. shipyard->offset = 0;
  816. shipyard->max = 1;
  817. }
  818. }
  819. }
  820. CRecrutationWindow * CCastleInterface::showRecruitmentWindow( int building )
  821. {
  822. if(building>36)
  823. building-=7;
  824. std::vector<std::pair<int,int > > crs;
  825. int amount = (const_cast<CGTownInstance*>(town))->strInfo.creatures[building-30]; //trzeba odconstowac, bo inaczej operator [] by sypal :(
  826. if(town->builtBuildings.find(building+7) != town->builtBuildings.end()) //check if there is an upgraded building
  827. crs.push_back(std::make_pair(town->town->upgradedCreatures[building-30],amount));
  828. crs.push_back(std::make_pair(town->town->basicCreatures[building-30],amount));
  829. CRecrutationWindow *rw = new CRecrutationWindow(crs,boost::bind(&CCallback::recruitCreatures,LOCPLINT->cb,town,_1,_2));
  830. rw->activate();
  831. return rw;
  832. }
  833. void CCastleInterface::enterMageGuild()
  834. {
  835. (new CMageGuildScreen(this))->activate();
  836. }
  837. void CHallInterface::CBuildingBox::hover(bool on)
  838. {
  839. Hoverable::hover(on);
  840. if(on)
  841. {
  842. std::string toPrint;
  843. if(state==8)
  844. toPrint = CGI->townh->hcommands[5];
  845. else
  846. toPrint = CGI->townh->hcommands[state];
  847. std::vector<std::string> name;
  848. name.push_back(CGI->buildh->buildings[LOCPLINT->castleInt->town->subID][BID]->name);
  849. LOCPLINT->statusbar->print(CSDL_Ext::processStr(toPrint,name));
  850. }
  851. else
  852. LOCPLINT->statusbar->clear();
  853. }
  854. void CHallInterface::CBuildingBox::clickLeft (tribool down)
  855. {
  856. if(pressedL && (!down))
  857. {
  858. LOCPLINT->castleInt->subInt->deactivate();
  859. new CHallInterface::CBuildWindow(LOCPLINT->castleInt->town->subID,BID,state,0);
  860. }
  861. ClickableL::clickLeft(down);
  862. }
  863. void CHallInterface::CBuildingBox::clickRight (tribool down)
  864. {
  865. if(down)
  866. {
  867. LOCPLINT->castleInt->subInt->deactivate();
  868. new CHallInterface::CBuildWindow(LOCPLINT->castleInt->town->subID,BID,state,1);
  869. }
  870. ClickableR::clickRight(down);
  871. }
  872. void CHallInterface::CBuildingBox::show(SDL_Surface * to)
  873. {
  874. CHallInterface *hi = static_cast<CHallInterface*>(LOCPLINT->castleInt->subInt);
  875. blitAt(LOCPLINT->castleInt->bicons->ourImages[BID].bitmap,pos.x,pos.y);
  876. int pom, pom2=-1;
  877. switch (state)
  878. {
  879. case 4:
  880. pom = 0;
  881. pom2 = 0;
  882. break;
  883. case 7:
  884. pom = 1;
  885. break;
  886. case 6:
  887. pom2 = 2;
  888. pom = 2;
  889. break;
  890. case 0: case 5: case 8:
  891. pom2 = 1;
  892. pom = 2;
  893. break;
  894. case 2: case 1: default:
  895. pom = 3;
  896. break;
  897. }
  898. blitAt(hi->bars->ourImages[pom].bitmap,pos.x-1,pos.y+71);
  899. if(pom2>=0)
  900. blitAt(hi->status->ourImages[pom2].bitmap,pos.x+135, pos.y+54);
  901. CSDL_Ext::printAtMiddle(CGI->buildh->buildings[LOCPLINT->castleInt->town->subID][BID]->name,pos.x-1+hi->bars->ourImages[0].bitmap->w/2,pos.y+71+hi->bars->ourImages[0].bitmap->h/2, GEOR13,zwykly);
  902. }
  903. void CHallInterface::CBuildingBox::activate()
  904. {
  905. Hoverable::activate();
  906. ClickableL::activate();
  907. ClickableR::activate();
  908. }
  909. void CHallInterface::CBuildingBox::deactivate()
  910. {
  911. Hoverable::deactivate();
  912. ClickableL::deactivate();
  913. ClickableR::deactivate();
  914. }
  915. CHallInterface::CBuildingBox::~CBuildingBox()
  916. {
  917. }
  918. CHallInterface::CBuildingBox::CBuildingBox(int id)
  919. :BID(id)
  920. {
  921. pos.w = 150;
  922. pos.h = 70;
  923. }
  924. CHallInterface::CBuildingBox::CBuildingBox(int id, int x, int y)
  925. :BID(id)
  926. {
  927. pos.x = x;
  928. pos.y = y;
  929. pos.w = 150;
  930. pos.h = 70;
  931. }
  932. CHallInterface::CHallInterface(CCastleInterface * owner)
  933. {
  934. pos = owner->pos;
  935. resdatabar.pos.x += pos.x;
  936. resdatabar.pos.y += pos.y;
  937. bg = BitmapHandler::loadBitmap(CGI->buildh->hall[owner->town->subID].first);
  938. graphics->blueToPlayersAdv(bg,LOCPLINT->playerID);
  939. bars = CDefHandler::giveDefEss("TPTHBAR.DEF");
  940. status = CDefHandler::giveDefEss("TPTHCHK.DEF");
  941. exit = new AdventureMapButton
  942. (CGI->townh->tcommands[8],"",boost::bind(&CHallInterface::close,this),pos.x+748,pos.y+556,"TPMAGE1.DEF",SDLK_RETURN);
  943. exit->assignedKeys.insert(SDLK_ESCAPE);
  944. //preparing boxes with buildings//
  945. boxes.resize(5);
  946. for(int i=0;i<5;i++) //for each row
  947. {
  948. for(int j=0; j<CGI->buildh->hall[owner->town->subID].second[i].size();j++) //for each box
  949. {
  950. int k=0;
  951. for(;k<CGI->buildh->hall[owner->town->subID].second[i][j].size();k++)//we are looking for the first not build structure
  952. {
  953. if(
  954. (owner->town->builtBuildings.find(CGI->buildh->hall[owner->town->subID].second[i][j][k]))
  955. ==
  956. (owner->town->builtBuildings.end()) )
  957. {
  958. int x = 34 + 194*j,
  959. y = 37 + 104*i,
  960. ID = CGI->buildh->hall[owner->town->subID].second[i][j][k];
  961. if(CGI->buildh->hall[owner->town->subID].second[i].size() == 2) //only two boxes in this row
  962. x+=194;
  963. else if(CGI->buildh->hall[owner->town->subID].second[i].size() == 3) //only three boxes in this row
  964. x+=97;
  965. boxes[i].push_back(new CBuildingBox(CGI->buildh->hall[owner->town->subID].second[i][j][k],pos.x+x,pos.y+y));
  966. boxes[i][boxes[i].size()-1]->state = 7; //allowed by default
  967. //can we build it?
  968. if(owner->town->forbiddenBuildings.find(CGI->buildh->hall[owner->town->subID].second[i][j][k])!=owner->town->forbiddenBuildings.end())
  969. boxes[i][boxes[i].size()-1]->state = 2; //forbidden
  970. else if(owner->town->builded >= MAX_BUILDING_PER_TURN)
  971. boxes[i][boxes[i].size()-1]->state = 5; //building limit
  972. //checking resources
  973. CBuilding * pom = CGI->buildh->buildings[owner->town->subID][CGI->buildh->hall[owner->town->subID].second[i][j][k]];
  974. for(int res=0;res<7;res++) //TODO: support custom amount of resources
  975. {
  976. if(pom->resources[res]>LOCPLINT->cb->getResourceAmount(res))
  977. boxes[i][boxes[i].size()-1]->state = 6; //lack of res
  978. }
  979. //checking for requirements
  980. for( std::set<int>::iterator ri = CGI->townh->requirements[owner->town->subID][ID].begin();
  981. ri != CGI->townh->requirements[owner->town->subID][ID].end();
  982. ri++ )
  983. {
  984. if(owner->town->builtBuildings.find(*ri)==owner->town->builtBuildings.end())
  985. boxes[i][boxes[i].size()-1]->state = 8; //lack of requirements - cannot build
  986. }
  987. //TODO: check if capital is already built, check if there is water for shipyard
  988. break;
  989. }
  990. }
  991. if(k==CGI->buildh->hall[owner->town->subID].second[i][j].size()) //all buildings built - let's take the last one
  992. {
  993. int x = 34 + 194*j,
  994. y = 37 + 104*i;
  995. if(CGI->buildh->hall[owner->town->subID].second[i].size() == 2)
  996. x+=194;
  997. else if(CGI->buildh->hall[owner->town->subID].second[i].size() == 3)
  998. x+=97;
  999. boxes[i].push_back(new CBuildingBox(CGI->buildh->hall[owner->town->subID].second[i][j][k-1],pos.x+x,pos.y+y));
  1000. boxes[i][boxes[i].size()-1]->state = 4; //already exists
  1001. }
  1002. }
  1003. }
  1004. }
  1005. CHallInterface::~CHallInterface()
  1006. {
  1007. delete bars;
  1008. delete status;
  1009. SDL_FreeSurface(bg);
  1010. for(int i=0;i<boxes.size();i++)
  1011. for(int j=0;j<boxes[i].size();j++)
  1012. delete boxes[i][j];
  1013. delete exit;
  1014. }
  1015. void CHallInterface::close()
  1016. {
  1017. LOCPLINT->castleInt->subInt = NULL;
  1018. deactivate();
  1019. delete this;
  1020. LOCPLINT->castleInt->activate();
  1021. }
  1022. void CHallInterface::show(SDL_Surface * to)
  1023. {
  1024. blitAt(bg,pos);
  1025. resdatabar.show();
  1026. exit->show();
  1027. for(int i=0; i<5; i++)
  1028. {
  1029. for(int j=0;j<boxes[i].size();j++)
  1030. boxes[i][j]->show();
  1031. }
  1032. }
  1033. void CHallInterface::activate()
  1034. {
  1035. for(int i=0;i<5;i++)
  1036. for(int j=0;j<boxes[i].size();j++)
  1037. boxes[i][j]->activate();
  1038. exit->activate();
  1039. }
  1040. void CHallInterface::deactivate()
  1041. {
  1042. for(int i=0;i<5;i++)
  1043. {
  1044. for(int j=0;j<boxes[i].size();j++)
  1045. {
  1046. boxes[i][j]->deactivate();
  1047. }
  1048. }
  1049. exit->deactivate();
  1050. }
  1051. void CHallInterface::CBuildWindow::activate()
  1052. {
  1053. LOCPLINT->objsToBlit.push_back(this);
  1054. ClickableR::activate();
  1055. if(mode)
  1056. return;
  1057. if(state==7)
  1058. buy->activate();
  1059. cancel->activate();
  1060. }
  1061. void CHallInterface::CBuildWindow::deactivate()
  1062. {
  1063. LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),this));
  1064. ClickableR::deactivate();
  1065. if(mode)
  1066. return;
  1067. if(state==7)
  1068. buy->deactivate();
  1069. cancel->deactivate();
  1070. }
  1071. void CHallInterface::CBuildWindow::Buy()
  1072. {
  1073. deactivate();
  1074. LOCPLINT->castleInt->subInt = NULL;
  1075. LOCPLINT->castleInt->activate();
  1076. LOCPLINT->cb->buildBuilding(LOCPLINT->castleInt->town,bid);
  1077. delete this;
  1078. delete LOCPLINT->castleInt->subInt;
  1079. }
  1080. void CHallInterface::CBuildWindow::close()
  1081. {
  1082. deactivate();
  1083. delete this;
  1084. LOCPLINT->castleInt->subInt->activate();
  1085. LOCPLINT->castleInt->subInt->show();
  1086. }
  1087. void CHallInterface::CBuildWindow::clickRight (tribool down)
  1088. {
  1089. if((!down || indeterminate(down)) && mode)
  1090. close();
  1091. }
  1092. void CHallInterface::CBuildWindow::show(SDL_Surface * to)
  1093. {
  1094. SDL_Rect pom = genRect(bitmap->h-1,bitmap->w-1,pos.x,pos.y);
  1095. SDL_Rect poms = pom; poms.x=0;poms.y=0;
  1096. SDL_BlitSurface(bitmap,&poms,to?to:screen,&pom);
  1097. if(!mode)
  1098. {
  1099. buy->show();
  1100. cancel->show();
  1101. }
  1102. }
  1103. std::string CHallInterface::CBuildWindow::getTextForState(int state)
  1104. {
  1105. std::string ret;
  1106. if(state<7)
  1107. ret = CGI->townh->hcommands[state];
  1108. switch (state)
  1109. {
  1110. case 4: case 5: case 6:
  1111. ret.replace(ret.find_first_of("%s"),2,CGI->buildh->buildings[tid][bid]->name);
  1112. break;
  1113. case 7:
  1114. return CGI->generaltexth->allTexts[219]; //all prereq. are met
  1115. case 8:
  1116. {
  1117. ret = CGI->generaltexth->allTexts[52];
  1118. std::set<int> used;
  1119. used.insert(bid);
  1120. std::set<int> reqs;
  1121. for(std::set<int>::iterator i=CGI->townh->requirements[tid][bid].begin();
  1122. i!=CGI->townh->requirements[tid][bid].end();
  1123. i++
  1124. )
  1125. {
  1126. if (LOCPLINT->castleInt->town->builtBuildings.find(*i) == LOCPLINT->castleInt->town->builtBuildings.end())
  1127. reqs.insert(*i);
  1128. }
  1129. while(true)
  1130. {
  1131. int czystych=0;
  1132. for(std::set<int>::iterator i=reqs.begin();i!=reqs.end();i++)
  1133. {
  1134. if(used.find(*i)==used.end()) //we haven't added requirements for this building
  1135. {
  1136. used.insert(*i);
  1137. for(
  1138. std::set<int>::iterator j=CGI->townh->requirements[tid][*i].begin();
  1139. j!=CGI->townh->requirements[tid][*i].end();
  1140. j++
  1141. )
  1142. {
  1143. if(LOCPLINT->castleInt->town->builtBuildings.find(*j) == //this building is not built
  1144. LOCPLINT->castleInt->town->builtBuildings.end())
  1145. reqs.insert(*j);
  1146. }
  1147. }
  1148. else
  1149. {
  1150. czystych++;
  1151. }
  1152. }
  1153. if(czystych==reqs.size())
  1154. break;
  1155. }
  1156. bool first=true;
  1157. for(std::set<int>::iterator i=reqs.begin();i!=reqs.end();i++)
  1158. {
  1159. ret+=(((first)?(" "):(", ")) + CGI->buildh->buildings[tid][*i]->name);
  1160. first = false;
  1161. }
  1162. }
  1163. }
  1164. return ret;
  1165. }
  1166. CHallInterface::CBuildWindow::CBuildWindow(int Tid, int Bid, int State, bool Mode)
  1167. :tid(Tid),bid(Bid),mode(Mode), state(State)
  1168. {
  1169. SDL_Surface *hhlp = BitmapHandler::loadBitmap("TPUBUILD.bmp");
  1170. graphics->blueToPlayersAdv(hhlp,LOCPLINT->playerID);
  1171. bitmap = SDL_ConvertSurface(hhlp,screen->format,0); //na 8bitowej mapie by sie psulo
  1172. SDL_SetColorKey(hhlp,SDL_SRCCOLORKEY,SDL_MapRGB(hhlp->format,0,255,255));
  1173. SDL_FreeSurface(hhlp);
  1174. pos.x = screen->w/2 - bitmap->w/2;
  1175. pos.y = screen->h/2 - bitmap->h/2;
  1176. blitAt(LOCPLINT->castleInt->bicons->ourImages[bid].bitmap,125,50,bitmap);
  1177. std::vector<std::string> pom; pom.push_back(CGI->buildh->buildings[tid][bid]->name);
  1178. CSDL_Ext::printAtMiddleWB(CGI->buildh->buildings[tid][bid]->description,197,168,GEOR16,40,zwykly,bitmap);
  1179. CSDL_Ext::printAtMiddleWB(getTextForState(state),197,248,GEOR13,50,zwykly,bitmap);
  1180. CSDL_Ext::printAtMiddle(CSDL_Ext::processStr(CGI->townh->hcommands[7],pom),197,30,GEOR16,tytulowy,bitmap);
  1181. int resamount=0; for(int i=0;i<7;i++) if(CGI->buildh->buildings[tid][bid]->resources[i]) resamount++;
  1182. int ah = (resamount>4) ? 304 : 341;
  1183. int cn=-1, it=0;
  1184. int row1w = std::min(resamount,4) * 32 + (std::min(resamount,4)-1) * 45,
  1185. row2w = (resamount-4) * 32 + (resamount-5) * 45;
  1186. char buf[15];
  1187. while(++cn<7)
  1188. {
  1189. if(!CGI->buildh->buildings[tid][bid]->resources[cn])
  1190. continue;
  1191. SDL_itoa(CGI->buildh->buildings[tid][bid]->resources[cn],buf,10);
  1192. if(it<4)
  1193. {
  1194. CSDL_Ext::printAtMiddle(buf,(bitmap->w/2-row1w/2)+77*it+16,ah+42,GEOR16,zwykly,bitmap);
  1195. blitAt(graphics->resources32->ourImages[cn].bitmap,(bitmap->w/2-row1w/2)+77*it++,ah,bitmap);
  1196. }
  1197. else
  1198. {
  1199. CSDL_Ext::printAtMiddle(buf,(bitmap->w/2-row2w/2)+77*it+16-308,ah+42,GEOR16,zwykly,bitmap);
  1200. blitAt(graphics->resources32->ourImages[cn].bitmap,(bitmap->w/2-row2w/2)+77*it++ - 308,ah,bitmap);
  1201. }
  1202. if(it==4)
  1203. ah+=75;
  1204. }
  1205. if(!mode)
  1206. {
  1207. buy = new AdventureMapButton
  1208. ("","",boost::bind(&CBuildWindow::Buy,this),pos.x+45,pos.y+446,"IBUY30.DEF",SDLK_RETURN);
  1209. cancel = new AdventureMapButton
  1210. ("","",boost::bind(&CBuildWindow::close,this),pos.x+290,pos.y+445,"ICANCEL.DEF",SDLK_ESCAPE);
  1211. if(state!=7)
  1212. buy->state=2;
  1213. }
  1214. activate();
  1215. }
  1216. CHallInterface::CBuildWindow::~CBuildWindow()
  1217. {
  1218. SDL_FreeSurface(bitmap);
  1219. if(!mode)
  1220. {
  1221. delete buy;
  1222. delete cancel;
  1223. }
  1224. }
  1225. CFortScreen::~CFortScreen()
  1226. {
  1227. LOCPLINT->curint->subInt = NULL;
  1228. for(int i=0;i<crePics.size();i++)
  1229. delete crePics[i];
  1230. for (int i=0;i<recAreas.size();i++)
  1231. delete recAreas[i];
  1232. SDL_FreeSurface(bg);
  1233. delete exit;
  1234. }
  1235. void CFortScreen::show( SDL_Surface * to)
  1236. {
  1237. blitAt(bg,pos);
  1238. static unsigned char anim = 1;
  1239. for (int i=0; i<CREATURES_PER_TOWN; i++)
  1240. {
  1241. crePics[i]->blitPic(screen,pos.x+positions[i].x+159,pos.y+positions[i].y+4,!(anim%4));
  1242. }
  1243. anim++;
  1244. exit->show();
  1245. resdatabar.show();
  1246. LOCPLINT->statusbar->show();
  1247. }
  1248. void CFortScreen::activate()
  1249. {
  1250. LOCPLINT->curint->subInt = this;
  1251. exit->activate();
  1252. for (int i=0;i<recAreas.size();i++)
  1253. {
  1254. recAreas[i]->activate();
  1255. }
  1256. LOCPLINT->objsToBlit -= LOCPLINT->castleInt;
  1257. LOCPLINT->objsToBlit += this;
  1258. }
  1259. void CFortScreen::deactivate()
  1260. {
  1261. exit->deactivate();
  1262. for (int i=0;i<recAreas.size();i++)
  1263. {
  1264. recAreas[i]->deactivate();
  1265. }
  1266. LOCPLINT->objsToBlit -= this;
  1267. LOCPLINT->objsToBlit += LOCPLINT->castleInt;
  1268. }
  1269. void CFortScreen::close()
  1270. {
  1271. deactivate();
  1272. delete this;
  1273. LOCPLINT->castleInt->activate();
  1274. }
  1275. CFortScreen::CFortScreen( CCastleInterface * owner )
  1276. {
  1277. pos = owner->pos;
  1278. LOCPLINT->curint->subInt = this;
  1279. bg = NULL;
  1280. exit = new AdventureMapButton(CGI->townh->tcommands[8],"",boost::bind(&CFortScreen::close,this),pos.x+748,pos.y+556,"TPMAGE1.DEF",SDLK_RETURN);
  1281. positions += genRect(126,386,10,22),genRect(126,386,404,22),
  1282. genRect(126,386,10,155),genRect(126,386,404,155),
  1283. genRect(126,386,10,288),genRect(126,386,404,288),
  1284. genRect(126,386,206,421);
  1285. draw(owner,true);
  1286. resdatabar.pos.x += pos.x;
  1287. resdatabar.pos.y += pos.y;
  1288. }
  1289. void CFortScreen::draw( CCastleInterface * owner, bool first)
  1290. {
  1291. if(bg)
  1292. SDL_FreeSurface(bg);
  1293. char buf[20];
  1294. memset(buf,0,20);
  1295. SDL_Surface *bg2 = BitmapHandler::loadBitmap("TPCASTL7.bmp"),
  1296. *icons = BitmapHandler::loadBitmap("ZPCAINFO.bmp");
  1297. SDL_SetColorKey(icons,SDL_SRCCOLORKEY,SDL_MapRGB(icons->format,0,255,255));
  1298. graphics->blueToPlayersAdv(bg2,LOCPLINT->playerID);
  1299. bg = SDL_ConvertSurface(bg2,screen->format,0);
  1300. SDL_FreeSurface(bg2);
  1301. printAtMiddle(CGI->buildh->buildings[owner->town->subID][owner->town->fortLevel()+6]->name,400,13,GEORXX,zwykly,bg);
  1302. for(int i=0;i<CREATURES_PER_TOWN; i++)
  1303. {
  1304. bool upgraded = owner->town->creatureDwelling(i,true);
  1305. bool present = owner->town->creatureDwelling(i,false);
  1306. CCreature *c = &CGI->creh->creatures[upgraded ? owner->town->town->upgradedCreatures[i] : owner->town->town->basicCreatures[i]];
  1307. printAtMiddle(c->namePl,positions[i].x+79,positions[i].y+10,GEOR13,zwykly,bg); //cr. name
  1308. blitAt(owner->bicons->ourImages[30+i+upgraded*7].bitmap,positions[i].x+4,positions[i].y+21,bg); //dwelling pic
  1309. printAtMiddle(CGI->buildh->buildings[owner->town->subID][30+i+upgraded*7]->name,positions[i].x+79,positions[i].y+100,GEOR13,zwykly,bg); //dwelling name
  1310. if(present) //if creature is present print avail able quantity
  1311. {
  1312. SDL_itoa(owner->town->strInfo.creatures.find(i)->second,buf,10);
  1313. printAtMiddle(CGI->generaltexth->allTexts[217] + buf,positions[i].x+79,positions[i].y+118,GEOR13,zwykly,bg);
  1314. }
  1315. blitAt(icons,positions[i].x+261,positions[i].y+3,bg);
  1316. //atttack
  1317. printAt(CGI->generaltexth->allTexts[190],positions[i].x+288,positions[i].y+5,GEOR13,zwykly,bg);
  1318. SDL_itoa(c->attack,buf,10);
  1319. printToWR(buf,positions[i].x+381,positions[i].y+18,GEOR13,zwykly,bg);
  1320. //defense
  1321. printAt(CGI->generaltexth->allTexts[191],positions[i].x+288,positions[i].y+25,GEOR13,zwykly,bg);
  1322. SDL_itoa(c->defence,buf,10);
  1323. printToWR(buf,positions[i].x+381,positions[i].y+38,GEOR13,zwykly,bg);
  1324. //damage
  1325. printAt(CGI->generaltexth->allTexts[199],positions[i].x+288,positions[i].y+46,GEOR13,zwykly,bg);
  1326. SDL_itoa(c->damageMin,buf,10);
  1327. int hlp;
  1328. if(c->damageMin > 0)
  1329. hlp = log10f(c->damageMin)+2;
  1330. else
  1331. hlp = 2;
  1332. buf[hlp-1]=' '; buf[hlp]='-'; buf[hlp+1]=' ';
  1333. SDL_itoa(c->damageMax,buf+hlp+2,10);
  1334. printToWR(buf,positions[i].x+381,positions[i].y+59,GEOR13,zwykly,bg);
  1335. //health
  1336. printAt(CGI->generaltexth->zelp[439].first,positions[i].x+288,positions[i].y+66,GEOR13,zwykly,bg);
  1337. SDL_itoa(c->hitPoints,buf,10);
  1338. printToWR(buf,positions[i].x+381,positions[i].y+79,GEOR13,zwykly,bg);
  1339. //speed
  1340. printAt(CGI->generaltexth->zelp[441].first,positions[i].x+288,positions[i].y+87,GEOR13,zwykly,bg);
  1341. SDL_itoa(c->speed,buf,10);
  1342. printToWR(buf,positions[i].x+381,positions[i].y+100,GEOR13,zwykly,bg);
  1343. if(present)//growth
  1344. {
  1345. printAt(CGI->generaltexth->allTexts[194],positions[i].x+288,positions[i].y+107,GEOR13,zwykly,bg);
  1346. SDL_itoa(owner->town->creatureGrowth(i),buf,10);
  1347. printToWR(buf,positions[i].x+381,positions[i].y+120,GEOR13,zwykly,bg);
  1348. }
  1349. if(first)
  1350. {
  1351. crePics.push_back(new CCreaturePic(c,false));
  1352. if(present)
  1353. {
  1354. recAreas.push_back(new RecArea(30+i+upgraded*7));
  1355. recAreas[recAreas.size()-1]->pos = positions[i];
  1356. }
  1357. }
  1358. }
  1359. SDL_FreeSurface(icons);
  1360. }
  1361. void CFortScreen::RecArea::clickLeft (tribool down)
  1362. {
  1363. if(!down && pressedL)
  1364. {
  1365. LOCPLINT->curint->deactivate();
  1366. CRecrutationWindow *rw = LOCPLINT->castleInt->showRecruitmentWindow(bid);
  1367. }
  1368. ClickableL::clickLeft(down);
  1369. }
  1370. void CFortScreen::RecArea::activate()
  1371. {
  1372. ClickableL::activate();
  1373. }
  1374. void CFortScreen::RecArea::deactivate()
  1375. {
  1376. ClickableL::deactivate();
  1377. }
  1378. CMageGuildScreen::CMageGuildScreen(CCastleInterface * owner)
  1379. {
  1380. pos = owner->pos;
  1381. resdatabar.pos.x += pos.x;
  1382. resdatabar.pos.y += pos.y;
  1383. bg = BitmapHandler::loadBitmap("TPMAGE.bmp");
  1384. exit = new AdventureMapButton(CGI->townh->tcommands[8],"",boost::bind(&CMageGuildScreen::close,this),pos.x+748,pos.y+556,"TPMAGE1.DEF",SDLK_RETURN);
  1385. exit->assignedKeys.insert(SDLK_ESCAPE);
  1386. scrolls = CDefHandler::giveDefEss("SPELLSCR.DEF");
  1387. scrolls2 = CDefHandler::giveDefEss("TPMAGES.DEF");
  1388. SDL_Surface *view = BitmapHandler::loadBitmap(graphics->guildBgs[owner->town->subID]);
  1389. SDL_SetColorKey(view,SDL_SRCCOLORKEY,SDL_MapRGB(view->format,0,255,255));
  1390. positions.resize(5);
  1391. positions[0] += genRect(61,83,222,445), genRect(61,83,312,445), genRect(61,83,402,445), genRect(61,83,520,445), genRect(61,83,610,445), genRect(61,83,700,445);
  1392. positions[1] += genRect(61,83,48,53), genRect(61,83,48,147), genRect(61,83,48,241), genRect(61,83,48,335), genRect(61,83,48,429);
  1393. positions[2] += genRect(61,83,570,82), genRect(61,83,672,82), genRect(61,83,570,157), genRect(61,83,672,157);
  1394. positions[3] += genRect(61,83,183,42), genRect(61,83,183,148), genRect(61,83,183,253);
  1395. positions[4] += genRect(61,83,491,325), genRect(61,83,591,325);
  1396. blitAt(view,332,76,bg);
  1397. for(int i=0; i<owner->town->town->mageLevel; i++)
  1398. {
  1399. int sp = owner->town->spellsAtLevel(i+1,false);
  1400. for(int j=0; j<sp; j++)
  1401. {
  1402. if(i<owner->town->mageGuildLevel() && owner->town->spells[i].size()>j)
  1403. {
  1404. spells.push_back(Scroll(&CGI->spellh->spells[owner->town->spells[i][j]]));
  1405. spells[spells.size()-1].pos = positions[i][j];
  1406. blitAt(scrolls->ourImages[owner->town->spells[i][j]].bitmap,positions[i][j],bg);
  1407. }
  1408. else
  1409. {
  1410. blitAt(scrolls2->ourImages[1].bitmap,positions[i][j],bg);
  1411. }
  1412. }
  1413. }
  1414. SDL_FreeSurface(view);
  1415. for(int i=0;i<spells.size();i++)
  1416. {
  1417. spells[i].pos.x += pos.x;
  1418. spells[i].pos.y += pos.y;
  1419. }
  1420. delete scrolls2;
  1421. }
  1422. CMageGuildScreen::~CMageGuildScreen()
  1423. {
  1424. delete exit;
  1425. delete scrolls;
  1426. SDL_FreeSurface(bg);
  1427. }
  1428. void CMageGuildScreen::close()
  1429. {
  1430. deactivate();
  1431. delete this;
  1432. LOCPLINT->castleInt->subInt = NULL;
  1433. LOCPLINT->castleInt->activate();
  1434. }
  1435. void CMageGuildScreen::show(SDL_Surface * to)
  1436. {
  1437. blitAt(bg,pos);
  1438. resdatabar.show();
  1439. LOCPLINT->statusbar->show();
  1440. exit->show();
  1441. }
  1442. void CMageGuildScreen::activate()
  1443. {
  1444. LOCPLINT->objsToBlit += this;
  1445. LOCPLINT->castleInt->subInt = this;
  1446. exit->activate();
  1447. for(int i=0;i<spells.size();i++)
  1448. spells[i].activate();
  1449. }
  1450. void CMageGuildScreen::deactivate()
  1451. {
  1452. LOCPLINT->objsToBlit -= this;
  1453. exit->deactivate();
  1454. for(int i=0;i<spells.size();i++)
  1455. spells[i].deactivate();
  1456. }
  1457. void CMageGuildScreen::Scroll::clickLeft (tribool down)
  1458. {
  1459. if(down)
  1460. {
  1461. std::vector<SComponent*> comps(1,
  1462. new CCustomImgComponent(SComponent::spell,spell->id,0,
  1463. static_cast<CMageGuildScreen*>(LOCPLINT->castleInt->subInt)->scrolls->ourImages[spell->id].bitmap,false)
  1464. );
  1465. LOCPLINT->showInfoDialog(spell->descriptions[0],comps);
  1466. }
  1467. }
  1468. void CMageGuildScreen::Scroll::clickRight (tribool down)
  1469. {
  1470. if(down)
  1471. {
  1472. CInfoPopup *vinya = new CInfoPopup();
  1473. vinya->free = true;
  1474. vinya->bitmap = CMessage::drawBoxTextBitmapSub
  1475. (LOCPLINT->playerID,
  1476. spell->descriptions[0],
  1477. static_cast<CMageGuildScreen*>(LOCPLINT->castleInt->subInt)->scrolls->ourImages[spell->id].bitmap,
  1478. spell->name,30,30);
  1479. vinya->pos.x = screen->w/2 - vinya->bitmap->w/2;
  1480. vinya->pos.y = screen->h/2 - vinya->bitmap->h/2;
  1481. vinya->activate();
  1482. }
  1483. }
  1484. void CMageGuildScreen::Scroll::hover(bool on)
  1485. {
  1486. Hoverable::hover(on);
  1487. if(on)
  1488. LOCPLINT->statusbar->print(spell->name);
  1489. else
  1490. LOCPLINT->statusbar->clear();
  1491. }
  1492. void CMageGuildScreen::Scroll::activate()
  1493. {
  1494. ClickableL::activate();
  1495. ClickableR::activate();
  1496. Hoverable::activate();
  1497. }
  1498. void CMageGuildScreen::Scroll::deactivate()
  1499. {
  1500. ClickableL::deactivate();
  1501. ClickableR::deactivate();
  1502. Hoverable::deactivate();
  1503. }
  1504. CBlacksmithDialog::CBlacksmithDialog(bool possible, int creMachineID, int aid, int hid)
  1505. {
  1506. SDL_Surface *bg2 = BitmapHandler::loadBitmap("TPSMITH.bmp");
  1507. SDL_SetColorKey(bg2,SDL_SRCCOLORKEY,SDL_MapRGB(bg2->format,0,255,255));
  1508. graphics->blueToPlayersAdv(bg2,LOCPLINT->playerID);
  1509. bmp = SDL_ConvertSurface(bg2,screen->format,0);
  1510. SDL_FreeSurface(bg2);
  1511. bg2 = BitmapHandler::loadBitmap("TPSMITBK.bmp");
  1512. blitAt(bg2,64,50,bmp);
  1513. SDL_FreeSurface(bg2);
  1514. CCreatureAnimation cra(CGI->creh->creatures[creMachineID].animDefName);
  1515. cra.nextFrameMiddle(bmp,170,120,true,false);
  1516. char pom[75];
  1517. sprintf(pom,CGI->generaltexth->allTexts[274].c_str(),CGI->creh->creatures[creMachineID].nameSing.c_str()); //build a new ...
  1518. printAtMiddle(pom,165,28,GEORXX,tytulowy,bmp);
  1519. printAtMiddle(CGI->generaltexth->jktexts[43],165,218,GEOR16,zwykly,bmp); //resource cost
  1520. SDL_itoa(CGI->arth->artifacts[aid].price,pom,10);
  1521. printAtMiddle(pom,165,290,GEOR13,zwykly,bmp);
  1522. pos.w = bmp->w;
  1523. pos.h = bmp->h;
  1524. pos.x = screen->w/2 - pos.w/2;
  1525. pos.y = screen->h/2 - pos.h/2;
  1526. buy = new AdventureMapButton("","",boost::bind(&CBlacksmithDialog::close,this),pos.x + 42,pos.y + 312,"IBUY30.DEF",SDLK_RETURN);
  1527. cancel = new AdventureMapButton("","",boost::bind(&CBlacksmithDialog::close,this),pos.x + 224,pos.y + 312,"ICANCEL.DEF",SDLK_ESCAPE);
  1528. if(possible)
  1529. buy->callback += boost::bind(&CCallback::buyArtifact,LOCPLINT->cb,LOCPLINT->cb->getHeroInfo(hid,2),aid);
  1530. else
  1531. buy->bitmapOffset = 2;
  1532. blitAt(graphics->resources32->ourImages[6].bitmap,148,244,bmp);
  1533. }
  1534. void CBlacksmithDialog::show( SDL_Surface * to/*=NULL*/ )
  1535. {
  1536. blitAt(bmp,pos);
  1537. buy->show();
  1538. cancel->show();
  1539. }
  1540. void CBlacksmithDialog::activate()
  1541. {
  1542. LOCPLINT->objsToBlit += this;
  1543. if(!buy->bitmapOffset)
  1544. buy->activate();
  1545. cancel->activate();
  1546. }
  1547. void CBlacksmithDialog::deactivate()
  1548. {
  1549. LOCPLINT->objsToBlit -= this;
  1550. if(!buy->bitmapOffset)
  1551. buy->deactivate();
  1552. cancel->deactivate();
  1553. }
  1554. CBlacksmithDialog::~CBlacksmithDialog()
  1555. {
  1556. SDL_FreeSurface(bmp);
  1557. delete cancel;
  1558. delete buy;
  1559. }
  1560. void CBlacksmithDialog::close()
  1561. {
  1562. deactivate();
  1563. delete this;
  1564. LOCPLINT->curint->activate();
  1565. }