CCastleInterface.cpp 10 KB

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