CCastleInterface.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  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 <sstream>
  11. CBuildingRect::CBuildingRect(Structure *Str)
  12. :str(Str)
  13. {
  14. def = CGI->spriteh->giveDef(Str->defName);
  15. pos.x = str->pos.x;
  16. pos.y = str->pos.y;
  17. pos.w = def->ourImages[0].bitmap->w;
  18. pos.h = def->ourImages[0].bitmap->h;
  19. if(Str->ID<0 || (Str->ID>=27 && Str->ID<=29))
  20. {
  21. area = border = NULL;
  22. return;
  23. }
  24. if (border = CGI->bitmaph->loadBitmap(str->borderName))
  25. SDL_SetColorKey(border,SDL_SRCCOLORKEY,SDL_MapRGB(border->format,0,255,255));
  26. else
  27. std::cout << "Warning: no border for "<<Str->ID<<std::endl;
  28. if (area = CGI->bitmaph->loadBitmap(str->areaName))
  29. ;//SDL_SetColorKey(area,SDL_SRCCOLORKEY,SDL_MapRGB(area->format,0,255,255));
  30. else
  31. std::cout << "Warning: no area for "<<Str->ID<<std::endl;
  32. }
  33. CBuildingRect::~CBuildingRect()
  34. {
  35. delete def;
  36. if(border)
  37. SDL_FreeSurface(border);
  38. if(area)
  39. SDL_FreeSurface(area);
  40. }
  41. void CBuildingRect::activate()
  42. {
  43. Hoverable::activate();
  44. ClickableL::activate();
  45. ClickableR::activate();
  46. }
  47. void CBuildingRect::deactivate()
  48. {
  49. Hoverable::deactivate();
  50. ClickableL::deactivate();
  51. ClickableR::deactivate();
  52. }
  53. bool CBuildingRect::operator<(const CBuildingRect & p2) const
  54. {
  55. if(str->pos.z != p2.str->pos.z)
  56. return (str->pos.z) < (p2.str->pos.z);
  57. else
  58. return (str->ID) < (p2.str->ID);
  59. }
  60. void CBuildingRect::hover(bool on)
  61. {
  62. Hoverable::hover(on);
  63. if(on)
  64. {
  65. MotionInterested::activate();
  66. }
  67. else
  68. {
  69. MotionInterested::deactivate();
  70. if(LOCPLINT->castleInt->hBuild == this)
  71. {
  72. LOCPLINT->castleInt->hBuild = NULL;
  73. LOCPLINT->statusbar->clear();
  74. }
  75. }
  76. }
  77. void CBuildingRect::clickLeft (tribool down)
  78. {
  79. //todo - handle
  80. }
  81. void CBuildingRect::clickRight (tribool down)
  82. {
  83. //todo - handle
  84. }
  85. void CBuildingRect::mouseMoved (SDL_MouseMotionEvent & sEvent)
  86. {
  87. if(area)
  88. {
  89. if(CSDL_Ext::SDL_GetPixel(area,sEvent.x-pos.x,sEvent.y-pos.y) == 0) //najechany piksel jest poza polem
  90. {
  91. if(LOCPLINT->castleInt->hBuild == this)
  92. {
  93. LOCPLINT->castleInt->hBuild = NULL;
  94. LOCPLINT->statusbar->clear();
  95. }
  96. }
  97. else //w polu
  98. {
  99. if(LOCPLINT->castleInt->hBuild) //jakis budynek jest zaznaczony
  100. {
  101. if((*LOCPLINT->castleInt->hBuild)<(*this)) //ustawiamy sie, jesli jestesmy na wierzchu
  102. {
  103. LOCPLINT->castleInt->hBuild = this;
  104. LOCPLINT->statusbar->print(str->name);
  105. }
  106. }
  107. else //nie ma budynku, wiec damy nasz
  108. {
  109. LOCPLINT->castleInt->hBuild = this;
  110. LOCPLINT->statusbar->print(str->name);
  111. }
  112. }
  113. }
  114. //if(border)
  115. // blitAt(border,pos.x,pos.y);
  116. }
  117. std::string getBgName(int type) //TODO - co z tym zrobiæ?
  118. {
  119. switch (type)
  120. {
  121. case 0:
  122. return "TBCSBACK.bmp";
  123. case 1:
  124. return "TBRMBACK.bmp";
  125. case 2:
  126. return "TBTWBACK.bmp";
  127. case 3:
  128. return "TBINBACK.bmp";
  129. case 4:
  130. return "TBNCBACK.bmp";
  131. case 5:
  132. return "TBDNBACK.bmp";
  133. case 6:
  134. return "TBSTBACK.bmp";
  135. case 7:
  136. return "TBFRBACK.bmp";
  137. case 8:
  138. return "TBELBACK.bmp";
  139. default:
  140. throw new std::exception("std::string getBgName(int type): invalid type");
  141. }
  142. }
  143. class SORTHELP
  144. {
  145. public:
  146. bool operator ()
  147. (const CBuildingRect *a ,
  148. const CBuildingRect *b)
  149. {
  150. return (*a)<(*b);
  151. }
  152. } srthlp ;
  153. CCastleInterface::CCastleInterface(const CGTownInstance * Town, bool Activate)
  154. {
  155. townInt = CGI->bitmaph->loadBitmap("TOWNSCRN.bmp");
  156. cityBg = CGI->bitmaph->loadBitmap(getBgName(Town->subID));
  157. hall = CGI->spriteh->giveDef("ITMTL.DEF");
  158. fort = CGI->spriteh->giveDef("ITMCL.DEF");
  159. bigTownPic = CGI->spriteh->giveDef("ITPT.DEF");
  160. flag = CGI->spriteh->giveDef("CREST58.DEF");
  161. townlist = new CTownList<CCastleInterface>(3,&genRect(128,48,744,414),744,414,744,526);
  162. exit = new AdventureMapButton<CCastleInterface>
  163. (CGI->townh->tcommands[8],"",&CCastleInterface::close,744,544,"TSBTNS.DEF",this,false);
  164. split = new AdventureMapButton<CCastleInterface>
  165. (CGI->townh->tcommands[3],"",&CCastleInterface::splitF,744,382,"TSBTNS.DEF",this,false);
  166. statusbar = new CStatusBar(8,555,"TSTATBAR.bmp",732);
  167. townlist->owner = this;
  168. townlist->fun = &CCastleInterface::townChange;
  169. townlist->genList();
  170. townlist->selected = getIndexOf(townlist->items,Town);
  171. if((townlist->selected+1) > townlist->SIZE)
  172. townlist->from = townlist->selected - townlist->SIZE + 1;
  173. hBuild = NULL;
  174. count=0;
  175. town = Town;
  176. CSDL_Ext::blueToPlayersAdv(townInt,LOCPLINT->playerID);
  177. exit->bitmapOffset = 4;
  178. std::set< std::pair<int,int> > s; //group - id
  179. //buildings
  180. for (std::set<int>::const_iterator i=town->builtBuildings.begin();i!=town->builtBuildings.end();i++)
  181. {
  182. if(CGI->townh->structures.find(town->subID) != CGI->townh->structures.end()) //we have info about structures in this town
  183. {
  184. if(CGI->townh->structures[town->subID].find(*i)!=CGI->townh->structures[town->subID].end()) //we have info about that structure
  185. {
  186. Structure * st = CGI->townh->structures[town->subID][*i];
  187. if(st->group<0) //no group - just add it
  188. {
  189. buildings.push_back(new CBuildingRect(st));
  190. }
  191. else
  192. {
  193. std::set< std::pair<int,int> >::iterator obecny=s.end();
  194. for(std::set< std::pair<int,int> >::iterator seti = s.begin(); seti!=s.end(); seti++) //check if we have already building from same group
  195. {
  196. if(seti->first == st->group)
  197. {
  198. obecny = seti;
  199. break;
  200. }
  201. }
  202. if(obecny != s.end())
  203. {
  204. if((*(CGI->townh->structures[town->subID][obecny->second])) < (*(CGI->townh->structures[town->subID][st->ID]))) //we have to replace old building with current one
  205. {
  206. for(int itpb = 0; itpb<buildings.size(); itpb++)
  207. {
  208. if(buildings[itpb]->str->ID == obecny->second)
  209. {
  210. delete buildings[itpb];
  211. buildings.erase(buildings.begin() + itpb);
  212. obecny->second = st->ID;
  213. buildings.push_back(new CBuildingRect(st));
  214. }
  215. }
  216. }
  217. }
  218. else
  219. {
  220. buildings.push_back(new CBuildingRect(st));
  221. s.insert(std::pair<int,int>(st->group,st->ID));
  222. }
  223. }
  224. }
  225. else continue;
  226. }
  227. else
  228. break;
  229. }
  230. //garrison
  231. std::sort(buildings.begin(),buildings.end(),srthlp);
  232. garr = new CGarrisonInt(305,387,4,32,townInt,243,13,town,town->visitingHero);
  233. if(Activate)
  234. {
  235. LOCPLINT->objsToBlit.push_back(this);
  236. activate();
  237. showAll();
  238. }
  239. //blit buildings on bg
  240. //for(int i=0;i<buildings.size();i++)
  241. //{
  242. // blitAt(buildings[i]->def->ourImages[0].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,cityBg);
  243. //}
  244. }
  245. CCastleInterface::~CCastleInterface()
  246. {
  247. SDL_FreeSurface(townInt);
  248. SDL_FreeSurface(cityBg);
  249. delete exit;
  250. delete split;
  251. delete hall;
  252. delete fort;
  253. delete bigTownPic;
  254. delete flag;
  255. delete garr;
  256. delete townlist;
  257. delete statusbar;
  258. for(int i=0;i<buildings.size();i++)
  259. {
  260. delete buildings[i];
  261. }
  262. }
  263. void CCastleInterface::close()
  264. {
  265. LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),this));
  266. deactivate();
  267. LOCPLINT->castleInt = NULL;
  268. LOCPLINT->adventureInt->show();
  269. delete this;
  270. }
  271. void CCastleInterface::splitF()
  272. {
  273. }
  274. void CCastleInterface::showAll(SDL_Surface * to)
  275. {
  276. if (!to)
  277. to=ekran;
  278. statusbar->show();
  279. blitAt(cityBg,0,0,to);
  280. blitAt(townInt,0,374,to);
  281. LOCPLINT->adventureInt->resdatabar.draw();
  282. townlist->draw();
  283. int pom;
  284. //draw fort icon
  285. if(town->builtBuildings.find(9)!=town->builtBuildings.end())
  286. pom = 2;
  287. else if(town->builtBuildings.find(8)!=town->builtBuildings.end())
  288. pom = 1;
  289. else if(town->builtBuildings.find(7)!=town->builtBuildings.end())
  290. pom = 0;
  291. else pom = 3;
  292. blitAt(fort->ourImages[pom].bitmap,122,413,to);
  293. //draw ((village/town/city) hall)/capitol icon
  294. if(town->builtBuildings.find(13)!=town->builtBuildings.end())
  295. pom = 3;
  296. else if(town->builtBuildings.find(12)!=town->builtBuildings.end())
  297. pom = 2;
  298. else if(town->builtBuildings.find(11)!=town->builtBuildings.end())
  299. pom = 1;
  300. else pom = 0;
  301. blitAt(hall->ourImages[pom].bitmap,80,413,to);
  302. //draw creatures icons and their growths
  303. for(int i=0;i<CREATURES_PER_TOWN;i++)
  304. {
  305. int cid = -1;
  306. if (town->builtBuildings.find(30+i)!=town->builtBuildings.end())
  307. {
  308. cid = (14*town->subID)+(i*2);
  309. if (town->builtBuildings.find(30+CREATURES_PER_TOWN+i)!=town->builtBuildings.end())
  310. {
  311. cid++;
  312. }
  313. }
  314. if (cid>=0)
  315. {
  316. int pomx, pomy;
  317. pomx = 22 + (55*((i>3)?(i-4):i));
  318. pomy = (i>3)?(507):(459);
  319. blitAt(CGI->creh->smallImgs[cid],pomx,pomy,to);
  320. std::ostringstream oss;
  321. oss << '+' << (CGI->creh->creatures[cid].growth + town->creatureIncome[i]);
  322. CSDL_Ext::printAtMiddle(oss.str(),pomx+16,pomy+37,GEOR13,zwykly,to);
  323. }
  324. }
  325. //print name and income
  326. CSDL_Ext::printAt(town->name,85,389,GEOR13,zwykly,to);
  327. char temp[10];
  328. itoa(town->income,temp,10);
  329. CSDL_Ext::printAtMiddle(temp,195,442,GEOR13,zwykly,to);
  330. //blit town icon
  331. pom = town->subID*2;
  332. if (!town->hasFort())
  333. pom += F_NUMBER*2;
  334. if(town->builded >= MAX_BUILDING_PER_TURN)
  335. pom++;
  336. blitAt(bigTownPic->ourImages[pom].bitmap,15,387,to);
  337. //flag
  338. if(town->getOwner()<PLAYER_LIMIT)
  339. blitAt(flag->ourImages[town->getOwner()].bitmap,241,387,to);
  340. //print garrison
  341. //for(
  342. // std::map<int,std::pair<CCreature*,int> >::const_iterator i=town->garrison.slots.begin();
  343. // i!=town->garrison.slots.end();
  344. // i++
  345. // )
  346. //{
  347. // blitAt(CGI->creh->bigImgs[i->second.first->idNumber],305+(62*(i->first)),387,to);
  348. // itoa(i->second.second,temp,10);
  349. // CSDL_Ext::printTo(temp,305+(62*(i->first))+57,387+61,GEOR13,zwykly,to);
  350. //}
  351. show();
  352. }
  353. void CCastleInterface::townChange()
  354. {
  355. const CGTownInstance * nt = townlist->items[townlist->selected];
  356. deactivate();
  357. LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),this));
  358. delete this;
  359. LOCPLINT->castleInt = new CCastleInterface(nt,true);
  360. }
  361. void CCastleInterface::show(SDL_Surface * to)
  362. {
  363. if (!to)
  364. to=ekran;
  365. garr->show();
  366. count++;
  367. if(count==4)
  368. {
  369. count=0;
  370. animval++;
  371. }
  372. blitAt(cityBg,0,0,to);
  373. //blit buildings
  374. for(int i=0;i<buildings.size();i++)
  375. {
  376. if((animval)%(buildings[i]->def->ourImages.size()))
  377. {
  378. blitAt(buildings[i]->def->ourImages[0].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to);
  379. blitAt(buildings[i]->def->ourImages[(animval)%(buildings[i]->def->ourImages.size())].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to);
  380. }
  381. else
  382. blitAt(buildings[i]->def->ourImages[(animval)%(buildings[i]->def->ourImages.size())].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to);
  383. //if(buildings[i]->hovered && buildings[i]->border)
  384. // blitAt(buildings[i]->border,buildings[i]->pos.x,buildings[i]->pos.y);
  385. if(hBuild==buildings[i] && hBuild->border)
  386. blitAt(hBuild->border,hBuild->pos,to);
  387. }
  388. //for(int i=0;i<buildings.size();i++)
  389. //{
  390. // if((animval)%(buildings[i]->def->ourImages.size())==0)
  391. // blitAt(buildings[i]->def->ourImages[(animval)%(buildings[i]->def->ourImages.size())].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to);
  392. // else continue;
  393. //}
  394. }
  395. void CCastleInterface::activate()
  396. {
  397. townlist->activate();
  398. garr->activate();
  399. LOCPLINT->curint = this;
  400. LOCPLINT->statusbar = statusbar;
  401. exit->activate();
  402. split->activate();
  403. for(int i=0;i<buildings.size();i++)
  404. buildings[i]->activate();
  405. }
  406. void CCastleInterface::deactivate()
  407. {
  408. townlist->deactivate();
  409. garr->deactivate();
  410. exit->deactivate();
  411. split->deactivate();
  412. for(int i=0;i<buildings.size();i++)
  413. buildings[i]->deactivate();
  414. }