CCastleInterface.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  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. flag = CGI->spriteh->giveDef("CREST58.DEF");
  160. townlist = new CTownList<CCastleInterface>(3,&genRect(128,48,744,414),744,414,744,526);
  161. exit = new AdventureMapButton<CCastleInterface>
  162. (CGI->townh->tcommands[8],"",&CCastleInterface::close,744,544,"TSBTNS.DEF",this,false,NULL,false);
  163. split = new AdventureMapButton<CCastleInterface>
  164. (CGI->townh->tcommands[3],"",&CCastleInterface::splitF,744,382,"TSBTNS.DEF",this,false,NULL,false);
  165. statusbar = new CStatusBar(8,555,"TSTATBAR.bmp",732);
  166. townlist->owner = this;
  167. townlist->fun = &CCastleInterface::townChange;
  168. townlist->genList();
  169. townlist->selected = getIndexOf(townlist->items,Town);
  170. if((townlist->selected+1) > townlist->SIZE)
  171. townlist->from = townlist->selected - townlist->SIZE + 1;
  172. hBuild = NULL;
  173. count=0;
  174. town = Town;
  175. CSDL_Ext::blueToPlayersAdv(townInt,LOCPLINT->playerID);
  176. exit->bitmapOffset = 4;
  177. std::set< std::pair<int,int> > s; //group - id
  178. //buildings
  179. for (std::set<int>::const_iterator i=town->builtBuildings.begin();i!=town->builtBuildings.end();i++)
  180. {
  181. if(CGI->townh->structures.find(town->subID) != CGI->townh->structures.end()) //we have info about structures in this town
  182. {
  183. if(CGI->townh->structures[town->subID].find(*i)!=CGI->townh->structures[town->subID].end()) //we have info about that structure
  184. {
  185. Structure * st = CGI->townh->structures[town->subID][*i];
  186. if(st->group<0) //no group - just add it
  187. {
  188. buildings.push_back(new CBuildingRect(st));
  189. }
  190. else
  191. {
  192. std::set< std::pair<int,int> >::iterator obecny=s.end();
  193. for(std::set< std::pair<int,int> >::iterator seti = s.begin(); seti!=s.end(); seti++) //check if we have already building from same group
  194. {
  195. if(seti->first == st->group)
  196. {
  197. obecny = seti;
  198. break;
  199. }
  200. }
  201. if(obecny != s.end())
  202. {
  203. if((*(CGI->townh->structures[town->subID][obecny->second])) < (*(CGI->townh->structures[town->subID][st->ID]))) //we have to replace old building with current one
  204. {
  205. for(int itpb = 0; itpb<buildings.size(); itpb++)
  206. {
  207. if(buildings[itpb]->str->ID == obecny->second)
  208. {
  209. delete buildings[itpb];
  210. buildings.erase(buildings.begin() + itpb);
  211. obecny->second = st->ID;
  212. buildings.push_back(new CBuildingRect(st));
  213. }
  214. }
  215. }
  216. }
  217. else
  218. {
  219. buildings.push_back(new CBuildingRect(st));
  220. s.insert(std::pair<int,int>(st->group,st->ID));
  221. }
  222. }
  223. }
  224. else continue;
  225. }
  226. else
  227. break;
  228. }
  229. //garrison
  230. std::sort(buildings.begin(),buildings.end(),srthlp);
  231. garr = new CGarrisonInt(305,387,4,32,townInt,243,13,town,town->visitingHero);
  232. if(Activate)
  233. {
  234. LOCPLINT->objsToBlit.push_back(this);
  235. activate();
  236. showAll();
  237. }
  238. //blit buildings on bg
  239. //for(int i=0;i<buildings.size();i++)
  240. //{
  241. // blitAt(buildings[i]->def->ourImages[0].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,cityBg);
  242. //}
  243. }
  244. CCastleInterface::~CCastleInterface()
  245. {
  246. SDL_FreeSurface(townInt);
  247. SDL_FreeSurface(cityBg);
  248. delete exit;
  249. delete split;
  250. delete hall;
  251. delete fort;
  252. delete flag;
  253. delete garr;
  254. delete townlist;
  255. delete statusbar;
  256. for(int i=0;i<buildings.size();i++)
  257. {
  258. delete buildings[i];
  259. }
  260. }
  261. void CCastleInterface::close()
  262. {
  263. LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),this));
  264. deactivate();
  265. LOCPLINT->castleInt = NULL;
  266. LOCPLINT->adventureInt->activate();
  267. delete this;
  268. }
  269. void CCastleInterface::splitF()
  270. {
  271. }
  272. void CCastleInterface::showAll(SDL_Surface * to)
  273. {
  274. if (!to)
  275. to=ekran;
  276. statusbar->show();
  277. blitAt(cityBg,0,0,to);
  278. blitAt(townInt,0,374,to);
  279. LOCPLINT->adventureInt->resdatabar.draw();
  280. townlist->draw();
  281. garr->show();
  282. int pom;
  283. //draw fort icon
  284. if(town->builtBuildings.find(9)!=town->builtBuildings.end())
  285. pom = 2;
  286. else if(town->builtBuildings.find(8)!=town->builtBuildings.end())
  287. pom = 1;
  288. else if(town->builtBuildings.find(7)!=town->builtBuildings.end())
  289. pom = 0;
  290. else pom = 3;
  291. blitAt(fort->ourImages[pom].bitmap,122,413,to);
  292. //draw ((village/town/city) hall)/capitol icon
  293. if(town->builtBuildings.find(13)!=town->builtBuildings.end())
  294. pom = 3;
  295. else if(town->builtBuildings.find(12)!=town->builtBuildings.end())
  296. pom = 2;
  297. else if(town->builtBuildings.find(11)!=town->builtBuildings.end())
  298. pom = 1;
  299. else pom = 0;
  300. blitAt(hall->ourImages[pom].bitmap,80,413,to);
  301. //draw creatures icons and their growths
  302. for(int i=0;i<CREATURES_PER_TOWN;i++)
  303. {
  304. int cid = -1;
  305. if (town->builtBuildings.find(30+i)!=town->builtBuildings.end())
  306. {
  307. cid = (14*town->subID)+(i*2);
  308. if (town->builtBuildings.find(30+CREATURES_PER_TOWN+i)!=town->builtBuildings.end())
  309. {
  310. cid++;
  311. }
  312. }
  313. if (cid>=0)
  314. {
  315. int pomx, pomy;
  316. pomx = 22 + (55*((i>3)?(i-4):i));
  317. pomy = (i>3)?(507):(459);
  318. blitAt(CGI->creh->smallImgs[cid],pomx,pomy,to);
  319. std::ostringstream oss;
  320. oss << '+' << (CGI->creh->creatures[cid].growth + town->creatureIncome[i]);
  321. CSDL_Ext::printAtMiddle(oss.str(),pomx+16,pomy+37,GEOR13,zwykly,to);
  322. }
  323. }
  324. //print name and income
  325. CSDL_Ext::printAt(town->name,85,389,GEOR13,zwykly,to);
  326. char temp[10];
  327. itoa(town->dailyIncome(),temp,10);
  328. CSDL_Ext::printAtMiddle(temp,195,442,GEOR13,zwykly,to);
  329. //blit town icon
  330. pom = town->subID*2;
  331. if (!town->hasFort())
  332. pom += F_NUMBER*2;
  333. if(town->builded >= MAX_BUILDING_PER_TURN)
  334. pom++;
  335. blitAt(LOCPLINT->bigTownPic->ourImages[pom].bitmap,15,387,to);
  336. //flag
  337. if(town->getOwner()<PLAYER_LIMIT)
  338. blitAt(flag->ourImages[town->getOwner()].bitmap,241,387,to);
  339. //print garrison
  340. //for(
  341. // std::map<int,std::pair<CCreature*,int> >::const_iterator i=town->garrison.slots.begin();
  342. // i!=town->garrison.slots.end();
  343. // i++
  344. // )
  345. //{
  346. // blitAt(CGI->creh->bigImgs[i->second.first->idNumber],305+(62*(i->first)),387,to);
  347. // itoa(i->second.second,temp,10);
  348. // CSDL_Ext::printTo(temp,305+(62*(i->first))+57,387+61,GEOR13,zwykly,to);
  349. //}
  350. show();
  351. }
  352. void CCastleInterface::townChange()
  353. {
  354. const CGTownInstance * nt = townlist->items[townlist->selected];
  355. deactivate();
  356. LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),this));
  357. delete this;
  358. LOCPLINT->castleInt = new CCastleInterface(nt,true);
  359. }
  360. void CCastleInterface::show(SDL_Surface * to)
  361. {
  362. if (!to)
  363. to=ekran;
  364. count++;
  365. if(count==4)
  366. {
  367. count=0;
  368. animval++;
  369. }
  370. blitAt(cityBg,0,0,to);
  371. //blit buildings
  372. for(int i=0;i<buildings.size();i++)
  373. {
  374. if((animval)%(buildings[i]->def->ourImages.size()))
  375. {
  376. blitAt(buildings[i]->def->ourImages[0].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to);
  377. blitAt(buildings[i]->def->ourImages[(animval)%(buildings[i]->def->ourImages.size())].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to);
  378. }
  379. else
  380. blitAt(buildings[i]->def->ourImages[(animval)%(buildings[i]->def->ourImages.size())].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to);
  381. //if(buildings[i]->hovered && buildings[i]->border)
  382. // blitAt(buildings[i]->border,buildings[i]->pos.x,buildings[i]->pos.y);
  383. if(hBuild==buildings[i] && hBuild->border)
  384. blitAt(hBuild->border,hBuild->pos,to);
  385. }
  386. //for(int i=0;i<buildings.size();i++)
  387. //{
  388. // if((animval)%(buildings[i]->def->ourImages.size())==0)
  389. // blitAt(buildings[i]->def->ourImages[(animval)%(buildings[i]->def->ourImages.size())].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to);
  390. // else continue;
  391. //}
  392. }
  393. void CCastleInterface::activate()
  394. {
  395. townlist->activate();
  396. garr->activate();
  397. LOCPLINT->curint = this;
  398. LOCPLINT->statusbar = statusbar;
  399. exit->activate();
  400. split->activate();
  401. for(int i=0;i<buildings.size();i++)
  402. buildings[i]->activate();
  403. }
  404. void CCastleInterface::deactivate()
  405. {
  406. townlist->deactivate();
  407. garr->deactivate();
  408. exit->deactivate();
  409. split->deactivate();
  410. for(int i=0;i<buildings.size();i++)
  411. buildings[i]->deactivate();
  412. }