mapHandler.cpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371
  1. #include "../stdafx.h"
  2. #include "mapHandler.h"
  3. #include "SDL_Extensions.h"
  4. #include "CGameInfo.h"
  5. #include <cstdlib>
  6. #include "../hch/CLodHandler.h"
  7. #include "../hch/CDefObjInfoHandler.h"
  8. #include <algorithm>
  9. #include "../lib/CGameState.h"
  10. #include "../hch/CHeroHandler.h"
  11. #include "../hch/CTownHandler.h"
  12. #include "Graphics.h"
  13. #include <iomanip>
  14. #include <sstream>
  15. #include "../hch/CObjectHandler.h"
  16. #include "../lib/map.h"
  17. #include "../hch/CDefHandler.h"
  18. #include "CConfigHandler.h"
  19. #include <boost/assign/list_of.hpp>
  20. #include "../hch/CGeneralTextHandler.h"
  21. /*
  22. * mapHandler.cpp, part of VCMI engine
  23. *
  24. * Authors: listed in file AUTHORS in main folder
  25. *
  26. * License: GNU General Public License v2.0 or later
  27. * Full text of license available in license.txt file, in main folder
  28. *
  29. */
  30. extern SDL_Surface * screen;
  31. #define ADVOPT (conf.go()->ac)
  32. std::string nameFromType (int typ)
  33. {
  34. switch(static_cast<TerrainTile::EterrainType>(typ))
  35. {
  36. case TerrainTile::dirt:
  37. return std::string("DIRTTL.DEF");
  38. case TerrainTile::sand:
  39. return std::string("SANDTL.DEF");
  40. case TerrainTile::grass:
  41. return std::string("GRASTL.DEF");
  42. case TerrainTile::snow:
  43. return std::string("SNOWTL.DEF");
  44. case TerrainTile::swamp:
  45. return std::string("SWMPTL.DEF");
  46. case TerrainTile::rough:
  47. return std::string("ROUGTL.DEF");
  48. case TerrainTile::subterranean:
  49. return std::string("SUBBTL.DEF");
  50. case TerrainTile::lava:
  51. return std::string("LAVATL.DEF");
  52. case TerrainTile::water:
  53. return std::string("WATRTL.DEF");
  54. case TerrainTile::rock:
  55. return std::string("ROCKTL.DEF");
  56. case TerrainTile::border:
  57. //TODO use me
  58. break;
  59. default:
  60. //TODO do something here
  61. break;
  62. }
  63. return std::string();
  64. }
  65. struct OCM_HLP
  66. {
  67. bool operator ()(const std::pair<const CGObjectInstance*, SDL_Rect> & a, const std::pair<const CGObjectInstance*, SDL_Rect> & b)
  68. {
  69. return (*a.first)<(*b.first);
  70. }
  71. } ocmptwo ;
  72. void alphaTransformDef(CGDefInfo * defInfo)
  73. {
  74. for(int yy=0; yy<defInfo->handler->ourImages.size(); ++yy)
  75. {
  76. CSDL_Ext::alphaTransform(defInfo->handler->ourImages[yy].bitmap);
  77. }
  78. }
  79. void CMapHandler::prepareFOWDefs()
  80. {
  81. fullHide = CDefHandler::giveDef("TSHRC.DEF");
  82. partialHide = CDefHandler::giveDef("TSHRE.DEF");
  83. //adding necessary rotations
  84. int missRot [] = {22, 15, 2, 13, 12, 16, 18, 17, 20, 19, 7, 24, 26, 25, 30, 32, 27, 28};
  85. Cimage nw;
  86. for(int g=0; g<ARRAY_COUNT(missRot); ++g)
  87. {
  88. nw = partialHide->ourImages[missRot[g]];
  89. nw.bitmap = CSDL_Ext::rotate01(nw.bitmap);
  90. partialHide->ourImages.push_back(nw);
  91. }
  92. //necessaary rotations added
  93. //alpha - transformation
  94. for(size_t i=0; i<partialHide->ourImages.size(); ++i)
  95. {
  96. CSDL_Ext::alphaTransform(partialHide->ourImages[i].bitmap);
  97. }
  98. //initialization of type of full-hide image
  99. hideBitmap.resize(CGI->mh->map->width);
  100. for (size_t i=0;i<hideBitmap.size();i++)
  101. {
  102. hideBitmap[i].resize(CGI->mh->map->height);
  103. }
  104. for (size_t i=0; i<hideBitmap.size(); ++i)
  105. {
  106. for (int j=0; j < CGI->mh->map->height; ++j)
  107. {
  108. hideBitmap[i][j].resize(CGI->mh->map->twoLevel+1);
  109. for(int k=0; k<CGI->mh->map->twoLevel+1; ++k)
  110. {
  111. hideBitmap[i][j][k] = rand()%fullHide->ourImages.size();
  112. }
  113. }
  114. }
  115. }
  116. void CMapHandler::roadsRiverTerrainInit()
  117. {
  118. //initializing road's and river's DefHandlers
  119. roadDefs.push_back(CDefHandler::giveDefEss("dirtrd.def"));
  120. roadDefs.push_back(CDefHandler::giveDefEss("gravrd.def"));
  121. roadDefs.push_back(CDefHandler::giveDefEss("cobbrd.def"));
  122. staticRiverDefs.push_back(CDefHandler::giveDefEss("clrrvr.def"));
  123. staticRiverDefs.push_back(CDefHandler::giveDefEss("icyrvr.def"));
  124. staticRiverDefs.push_back(CDefHandler::giveDefEss("mudrvr.def"));
  125. staticRiverDefs.push_back(CDefHandler::giveDefEss("lavrvr.def"));
  126. for(size_t g=0; g<staticRiverDefs.size(); ++g)
  127. {
  128. for(size_t h=0; h < staticRiverDefs[g]->ourImages.size(); ++h)
  129. {
  130. CSDL_Ext::alphaTransform(staticRiverDefs[g]->ourImages[h].bitmap);
  131. }
  132. }
  133. for(size_t g=0; g<roadDefs.size(); ++g)
  134. {
  135. for(size_t h=0; h < roadDefs[g]->ourImages.size(); ++h)
  136. {
  137. CSDL_Ext::alphaTransform(roadDefs[g]->ourImages[h].bitmap);
  138. }
  139. }
  140. sizes.x = CGI->mh->map->width;
  141. sizes.y = CGI->mh->map->height;
  142. sizes.z = CGI->mh->map->twoLevel+1;
  143. // Create enough room for the whole map and its frame
  144. ttiles.resize(CGI->mh->map->width, frameW, frameW);
  145. for (int i=0-frameW;i<ttiles.size()-frameW;i++)
  146. {
  147. ttiles[i].resize(CGI->mh->map->height, frameH, frameH);
  148. }
  149. for (int i=0-frameW;i<ttiles.size()-frameW;i++)
  150. {
  151. for (int j=0-frameH;j<(int)CGI->mh->map->height+frameH;j++)
  152. ttiles[i][j].resize(CGI->mh->map->twoLevel+1, 0, 0);
  153. }
  154. // prepare the map
  155. for (int i=0; i<map->width; i++) //by width
  156. {
  157. for (int j=0; j<map->height;j++) //by height
  158. {
  159. for (int k=0; k<=map->twoLevel; ++k) //by levels
  160. {
  161. TerrainTile2 &pom(ttiles[i][j][k]);
  162. pom.pos = int3(i, j, k);
  163. pom.tileInfo = &(map->terrain[i][j][k]);
  164. }
  165. }
  166. }
  167. }
  168. void CMapHandler::borderAndTerrainBitmapInit()
  169. {
  170. CDefHandler * bord = CDefHandler::giveDef("EDG.DEF");
  171. bord->notFreeImgs = true;
  172. terrainGraphics.resize(10);
  173. for (int i = 0; i < 10 ; i++)
  174. {
  175. CDefHandler *hlp = CDefHandler::giveDef(nameFromType(i));
  176. terrainGraphics[i].resize(hlp->ourImages.size());
  177. hlp->notFreeImgs = true;
  178. for(size_t j=0; j < hlp->ourImages.size(); ++j)
  179. terrainGraphics[i][j] = hlp->ourImages[j].bitmap;
  180. delete hlp;
  181. }
  182. for (int i=0-frameW; i<map->width+frameW; i++) //by width
  183. {
  184. for (int j=0-frameH; j<map->height+frameH;j++) //by height
  185. {
  186. for(int k=0; k<=map->twoLevel; ++k) //by levles
  187. {
  188. if(i < 0 || i > (map->width-1) || j < 0 || j > (map->height-1))
  189. {
  190. int terBitmapNum = -1;
  191. if(i==-1 && j==-1)
  192. terBitmapNum = 16;
  193. else if(i==-1 && j==(map->height))
  194. terBitmapNum = 19;
  195. else if(i==(map->width) && j==-1)
  196. terBitmapNum = 17;
  197. else if(i==(map->width) && j==(map->height))
  198. terBitmapNum = 18;
  199. else if(j == -1 && i > -1 && i < map->height)
  200. terBitmapNum = 22+rand()%2;
  201. else if(i == -1 && j > -1 && j < map->height)
  202. terBitmapNum = 33+rand()%2;
  203. else if(j == map->height && i >-1 && i < map->width)
  204. terBitmapNum = 29+rand()%2;
  205. else if(i == map->width && j > -1 && j < map->height)
  206. terBitmapNum = 25+rand()%2;
  207. else
  208. terBitmapNum = rand()%16;
  209. if(terBitmapNum != -1)
  210. {
  211. ttiles[i][j][k].terbitmap = bord->ourImages[terBitmapNum].bitmap;
  212. continue;
  213. }
  214. }
  215. }
  216. }
  217. }
  218. delete bord;
  219. }
  220. void CMapHandler::initObjectRects()
  221. {
  222. //initializing objects / rects
  223. for(size_t f=0; f < map->objects.size(); ++f)
  224. {
  225. const CGObjectInstance *obj = map->objects[f];
  226. if( !obj
  227. || obj->ID==HEROI_TYPE && static_cast<const CGHeroInstance*>(obj)->inTownGarrison //garrisoned hero
  228. || obj->ID==8 && static_cast<const CGBoat*>(obj)->hero //boat wih hero (hero graphics is used)
  229. || !obj->defInfo
  230. || !obj->defInfo->handler) //no graphic...
  231. {
  232. continue;
  233. }
  234. const SDL_Surface *bitmap = obj->defInfo->handler->ourImages[0].bitmap;
  235. for(int fx=0; fx<bitmap->w>>5; ++fx) //bitmap->w/32
  236. {
  237. for(int fy=0; fy<bitmap->h>>5; ++fy) //bitmap->h/32
  238. {
  239. SDL_Rect cr;
  240. cr.w = 32;
  241. cr.h = 32;
  242. cr.x = fx<<5; //fx*32
  243. cr.y = fy<<5; //fy*32
  244. std::pair<const CGObjectInstance*,SDL_Rect> toAdd = std::make_pair(obj,cr);
  245. if( (obj->pos.x + fx - bitmap->w/32+1) >= 0
  246. && (obj->pos.x + fx - bitmap->w/32+1) < ttiles.size() - frameW
  247. && (obj->pos.y + fy - bitmap->h/32+1) >= 0
  248. && (obj->pos.y + fy - bitmap->h/32+1) < ttiles[0].size() - frameH
  249. )
  250. {
  251. //TerrainTile2 & curt =
  252. // ttiles
  253. // [obj->pos.x + fx - bitmap->w/32]
  254. //[obj->pos.y + fy - bitmap->h/32]
  255. //[obj->pos.z];
  256. ttiles[obj->pos.x + fx - bitmap->w/32+1][obj->pos.y + fy - bitmap->h/32+1][obj->pos.z].objects.push_back(toAdd);
  257. }
  258. } // for(int fy=0; fy<bitmap->h/32; ++fy)
  259. } //for(int fx=0; fx<bitmap->w/32; ++fx)
  260. } // for(int f=0; f<map->objects.size(); ++f)
  261. for(int ix=0; ix<ttiles.size()-frameW; ++ix)
  262. {
  263. for(int iy=0; iy<ttiles[0].size()-frameH; ++iy)
  264. {
  265. for(int iz=0; iz<ttiles[0][0].size(); ++iz)
  266. {
  267. stable_sort(ttiles[ix][iy][iz].objects.begin(), ttiles[ix][iy][iz].objects.end(), ocmptwo);
  268. }
  269. }
  270. }
  271. }
  272. static void processDef (CGDefInfo* def)
  273. {
  274. if(def->id == EVENTI_TYPE)
  275. return;
  276. if(!def->handler) //if object has already set handler (eg. heroes) it should not be overwritten
  277. {
  278. if(def->name.size())
  279. {
  280. if(vstd::contains(CGI->mh->loadedDefs, def->name))
  281. {
  282. def->handler = CGI->mh->loadedDefs[def->name];
  283. }
  284. else
  285. {
  286. CGI->mh->loadedDefs[def->name] = def->handler = CDefHandler::giveDefEss(def->name);
  287. }
  288. }
  289. else
  290. {
  291. tlog2 << "No def name for " << def->id << " " << def->subid << std::endl;
  292. def->handler = NULL;
  293. return;
  294. }
  295. // def->width = def->handler->ourImages[0].bitmap->w/32;
  296. // def->height = def->handler->ourImages[0].bitmap->h/32;
  297. }
  298. CGDefInfo* pom = CGI->dobjinfo->gobjs[def->id][def->subid];
  299. if(pom && def->id!=TOWNI_TYPE)
  300. {
  301. pom->handler = def->handler;
  302. pom->width = pom->handler->ourImages[0].bitmap->w/32;
  303. pom->height = pom->handler->ourImages[0].bitmap->h/32;
  304. }
  305. else if(def->id != HEROI_TYPE && def->id != TOWNI_TYPE)
  306. tlog3 << "\t\tMinor warning: lacking def info for " << def->id << " " << def->subid <<" " << def->name << std::endl;
  307. //alpha transformation
  308. for(size_t yy=0; yy < def->handler->ourImages.size(); ++yy)
  309. {
  310. CSDL_Ext::alphaTransform(def->handler->ourImages[yy].bitmap);
  311. }
  312. }
  313. void CMapHandler::initHeroDef(CGHeroInstance * h)
  314. {
  315. h->defInfo->handler = graphics->flags1[0];
  316. h->defInfo->width = h->defInfo->handler->ourImages[0].bitmap->w/32;
  317. h->defInfo->height = h->defInfo->handler->ourImages[0].bitmap->h/32;
  318. }
  319. void CMapHandler::init()
  320. {
  321. timeHandler th;
  322. th.getDif();
  323. CGI->dobjinfo->gobjs[8][0]->handler = graphics->boatAnims[0];
  324. CGI->dobjinfo->gobjs[8][1]->handler = graphics->boatAnims[1];
  325. CGI->dobjinfo->gobjs[8][2]->handler = graphics->boatAnims[2];
  326. // Size of visible terrain.
  327. mapW = conf.go()->ac.advmapW;
  328. mapH = conf.go()->ac.advmapH;
  329. // Total number of visible tiles. Substract the center tile, then
  330. // compute the number of tiles on each side, and reassemble.
  331. int t1, t2;
  332. t1 = (mapW-32)/2;
  333. t2 = mapW - 32 - t1;
  334. tilesW = 1 + (t1+31)/32 + (t2+31)/32;
  335. t1 = (mapH-32)/2;
  336. t2 = mapH - 32 - t1;
  337. tilesH = 1 + (t1+31)/32 + (t2+31)/32;
  338. // Size of the frame around the map. In extremes positions, the
  339. // frame must not be on the center of the map, but right on the
  340. // edge of the center tile.
  341. frameW = (mapW+31) /32 / 2;
  342. frameH = (mapH+31) /32 / 2;
  343. offsetX = (mapW - (2*frameW+1)*32)/2;
  344. offsetY = (mapH - (2*frameH+1)*32)/2;
  345. std::ifstream ifs(DATA_DIR "/config/townsDefs.txt");
  346. int ccc;
  347. ifs>>ccc;
  348. for(int i=0;i<ccc*2;i++)
  349. {
  350. CGDefInfo *n;
  351. if(i<ccc)
  352. {
  353. n = CGI->state->villages[i];
  354. map->defy.push_back(CGI->state->forts[i]);
  355. }
  356. else
  357. n = CGI->state->capitols[i%ccc];
  358. ifs >> n->name;
  359. if(!n)
  360. tlog1 << "*HUGE* Warning - missing town def for " << i << std::endl;
  361. else
  362. map->defy.push_back(n);
  363. }
  364. tlog0<<"\tLoading town def info: "<<th.getDif()<<std::endl;
  365. for(int i=0;i<map->heroes.size();i++)
  366. {
  367. if(!map->heroes[i]->defInfo->handler)
  368. {
  369. initHeroDef(map->heroes[i]);
  370. }
  371. }
  372. std::for_each(map->defy.begin(),map->defy.end(),processDef); //load h3m defs
  373. tlog0<<"\tUnpacking and handling defs: "<<th.getDif()<<std::endl;
  374. for(int i=0;i<PLAYER_LIMIT;i++)
  375. {
  376. for(size_t j=0; j < map->players[i].heroesNames.size(); ++j)
  377. {
  378. usedHeroes.insert(map->players[i].heroesNames[j].heroID);
  379. }
  380. }
  381. tlog0<<"\tChecking used heroes: "<<th.getDif()<<std::endl;
  382. prepareFOWDefs();
  383. roadsRiverTerrainInit(); //road's and river's DefHandlers; and simple values initialization
  384. borderAndTerrainBitmapInit();
  385. tlog0<<"\tPreparing FoW, roads, rivers,borders: "<<th.getDif()<<std::endl;
  386. initObjectRects();
  387. tlog0<<"\tMaking object rects: "<<th.getDif()<<std::endl;
  388. }
  389. // Update map window screen
  390. // top_tile top left tile to draw. Not necessarily visible.
  391. // extRect, extRect = map window on screen
  392. // moveX, moveY: when a hero is in movement indicates how to shift the map. Range is -31 to + 31.
  393. void CMapHandler::terrainRect(int3 top_tile, unsigned char anim, const std::vector< std::vector< std::vector<unsigned char> > > * visibilityMap, bool otherHeroAnim, unsigned char heroAnim, SDL_Surface * extSurf, const SDL_Rect * extRect, int moveX, int moveY, bool puzzleMode)
  394. {
  395. // Width and height of the portion of the map to process. Units in tiles.
  396. unsigned int dx = tilesW;
  397. unsigned int dy = tilesH;
  398. // Basic rectangle for a tile. Should be a const but conflicts with SDL headers
  399. SDL_Rect rtile = { 0, 0, 32, 32 };
  400. // Absolute coords of the first pixel in the top left corner
  401. int srx_init = offsetX + extRect->x;
  402. int sry_init = offsetY + extRect->y;
  403. int srx, sry; // absolute screen coordinates in pixels
  404. // If moving, we need to add an extra column/line
  405. if (moveX != 0)
  406. {
  407. dx++;
  408. srx_init += moveX;
  409. if (moveX > 0)
  410. {
  411. // Moving right. We still need to draw the old tile on the
  412. // left, so adjust our referential
  413. top_tile.x --;
  414. srx_init -= 32;
  415. }
  416. }
  417. if (moveY != 0)
  418. {
  419. dy++;
  420. sry_init += moveY;
  421. if (moveY > 0)
  422. {
  423. // Moving down. We still need to draw the tile on the top,
  424. // so adjust our referential.
  425. top_tile.y --;
  426. sry_init -= 32;
  427. }
  428. }
  429. // Reduce sizes if we go out of the full map.
  430. if (top_tile.x < -frameW)
  431. top_tile.x = -frameW;
  432. if (top_tile.y < -frameH)
  433. top_tile.y = -frameH;
  434. if (top_tile.x + dx > map->width + frameW)
  435. dx = map->width + frameW - top_tile.x;
  436. if (top_tile.y + dy > map->height + frameH)
  437. dy = map->height + frameH - top_tile.y;
  438. if(!otherHeroAnim)
  439. heroAnim = anim; //the same, as it should be
  440. SDL_Rect prevClip;
  441. SDL_GetClipRect(extSurf, &prevClip);
  442. SDL_SetClipRect(extSurf, extRect); //preventing blitting outside of that rect
  443. const BlitterWithRotationVal blitterWithRotation = CSDL_Ext::getBlitterWithRotation(extSurf);
  444. const BlitterWithRotationVal blitterWithRotationAndAlpha = CSDL_Ext::getBlitterWithRotationAndAlpha(extSurf);
  445. //const BlitterWithRotationAndAlphaVal blitterWithRotation = CSDL_Ext::getBlitterWithRotation(extSurf);
  446. // printing terrain
  447. srx = srx_init;
  448. for (int bx = 0; bx < dx; bx++, srx+=32)
  449. {
  450. // Skip column if not in map
  451. if (top_tile.x+bx < 0 || top_tile.x+bx >= map->width)
  452. continue;
  453. sry = sry_init;
  454. for (int by=0; by < dy; by++, sry+=32)
  455. {
  456. int3 pos(top_tile.x+bx, top_tile.y+by, top_tile.z); //blitted tile position
  457. // Skip tile if not in map
  458. if (pos.y < 0 || pos.y >= map->height)
  459. continue;
  460. const TerrainTile2 & tile = ttiles[pos.x][pos.y][pos.z];
  461. const TerrainTile &tinfo = *tile.tileInfo;
  462. SDL_Rect sr;
  463. sr.x=srx;
  464. sr.y=sry;
  465. sr.h=sr.w=32;
  466. //blit terrain with river/road
  467. if(tile.terbitmap) //if custom terrain graphic - use it
  468. SDL_BlitSurface(tile.terbitmap, &genRect(sr.h, sr.w, 0, 0), extSurf, &sr);
  469. else //use default terrain graphic
  470. blitterWithRotation(terrainGraphics[tinfo.tertype][tinfo.terview],rtile, extSurf, sr, tinfo.siodmyTajemniczyBajt%4);
  471. if(tinfo.nuine) //print river if present
  472. blitterWithRotationAndAlpha(staticRiverDefs[tinfo.nuine-1]->ourImages[tinfo.rivDir].bitmap,rtile, extSurf, sr, (tinfo.siodmyTajemniczyBajt>>2)%4);
  473. if(tinfo.malle) //print road if present
  474. blitterWithRotationAndAlpha(roadDefs[tinfo.malle-1]->ourImages[tinfo.roadDir].bitmap,rtile, extSurf, sr, (tinfo.siodmyTajemniczyBajt>>4)%4);
  475. //blit objects
  476. const std::vector < std::pair<const CGObjectInstance*,SDL_Rect> > &objects = tile.objects;
  477. for(int h=0; h < objects.size(); ++h)
  478. {
  479. const CGObjectInstance *obj = objects[h].first;
  480. ui8 color = obj->tempOwner;
  481. //checking if object has non-empty graphic on this tile
  482. if(obj->ID != HEROI_TYPE && !obj->coveringAt(obj->pos.x - (top_tile.x + bx), top_tile.y + by - obj->pos.y + 5))
  483. continue;
  484. //don't print flaggable objects in puzzle mode
  485. if(puzzleMode && obj->tempOwner != 254)
  486. continue;
  487. SDL_Rect sr2(sr);
  488. SDL_Rect pp = objects[h].second;
  489. pp.h = sr.h;
  490. pp.w = sr.w;
  491. const CGHeroInstance * themp = (obj->ID != HEROI_TYPE
  492. ? NULL
  493. : static_cast<const CGHeroInstance*>(obj));
  494. //print hero / boat and flag
  495. if(themp && themp->moveDir && themp->type || obj->ID == 8) //it's hero or boat
  496. {
  497. const int IMGVAL = 8; //frames per group of movement animation
  498. ui8 dir;
  499. std::vector<Cimage> * iv = NULL;
  500. std::vector<CDefEssential *> Graphics::*flg = NULL;
  501. SDL_Surface * tb; //surface to blitted
  502. if(themp) //hero
  503. {
  504. dir = themp->moveDir;
  505. //pick graphics of hero (or boat if hero is sailing)
  506. iv = (themp->boat)
  507. ? &graphics->boatAnims[themp->boat->subID]->ourImages
  508. : &graphics->heroAnims[themp->type->heroType]->ourImages;
  509. //pick appropriate flag set
  510. if(themp->boat)
  511. {
  512. switch (themp->boat->subID)
  513. {
  514. case 0: flg = &Graphics::flags1; break;
  515. case 1: flg = &Graphics::flags2; break;
  516. case 2: flg = &Graphics::flags3; break;
  517. default: tlog1 << "Not supported boat subtype: " << themp->boat->subID << std::endl;
  518. }
  519. }
  520. else
  521. {
  522. flg = &Graphics::flags4;
  523. }
  524. }
  525. else //boat
  526. {
  527. const CGBoat *boat = static_cast<const CGBoat*>(obj);
  528. dir = boat->direction;
  529. iv = &graphics->boatAnims[boat->subID]->ourImages;
  530. }
  531. if(themp && !themp->isStanding) //hero is moving
  532. {
  533. size_t gg;
  534. for(gg=0; gg<iv->size(); ++gg)
  535. {
  536. if((*iv)[gg].groupNumber==getHeroFrameNum(dir, true))
  537. {
  538. tb = (*iv)[gg+heroAnim%IMGVAL].bitmap;
  539. break;
  540. }
  541. }
  542. CSDL_Ext::blit8bppAlphaTo24bpp(tb,&pp,extSurf,&sr2);
  543. //printing flag
  544. pp.y+=IMGVAL*2-32;
  545. sr2.y-=16;
  546. SDL_BlitSurface((graphics->*flg)[color]->ourImages[gg+heroAnim%IMGVAL+35].bitmap, &pp, extSurf, &sr2);
  547. }
  548. else //hero / boat stands still
  549. {
  550. size_t gg;
  551. for(gg=0; gg < iv->size(); ++gg)
  552. {
  553. if((*iv)[gg].groupNumber==getHeroFrameNum(dir, false))
  554. {
  555. tb = (*iv)[gg].bitmap;
  556. break;
  557. }
  558. }
  559. CSDL_Ext::blit8bppAlphaTo24bpp(tb,&pp,extSurf,&sr2);
  560. //printing flag
  561. if(flg
  562. && obj->pos.x == top_tile.x + bx
  563. && obj->pos.y == top_tile.y + by)
  564. {
  565. SDL_Rect bufr = sr2;
  566. bufr.x-=2*32;
  567. bufr.y-=1*32;
  568. bufr.h = 64;
  569. bufr.w = 96;
  570. if(bufr.x-extRect->x>-64)
  571. SDL_BlitSurface((graphics->*flg)[color]->ourImages[getHeroFrameNum(dir, false) *8+(heroAnim/4)%IMGVAL].bitmap, NULL, extSurf, &bufr);
  572. }
  573. }
  574. }
  575. else //blit normal object
  576. {
  577. const std::vector<Cimage> &ourImages = obj->defInfo->handler->ourImages;
  578. SDL_Surface *bitmap = ourImages[(anim+obj->animPhaseShift)%ourImages.size()].bitmap;
  579. //setting appropriate flag color
  580. if(color < 8 || color==255)
  581. CSDL_Ext::setPlayerColor(bitmap, color);
  582. if( obj->hasShadowAt(obj->pos.x - (top_tile.x + bx), top_tile.y + by - obj->pos.y + 5) )
  583. CSDL_Ext::blit8bppAlphaTo24bpp(bitmap,&pp,extSurf,&sr2);
  584. else
  585. SDL_BlitSurface(bitmap,&pp,extSurf,&sr2);
  586. }
  587. }
  588. //objects blitted
  589. }
  590. }
  591. // terrain printed
  592. // printing borders
  593. srx = srx_init;
  594. for (int bx = 0; bx < dx; bx++, srx+=32)
  595. {
  596. sry = sry_init;
  597. for (int by = 0; by<dy; by++, sry+=32)
  598. {
  599. int3 pos(top_tile.x+bx, top_tile.y+by, top_tile.z); //blitted tile position
  600. SDL_Rect sr;
  601. sr.x=srx;
  602. sr.y=sry;
  603. sr.h=sr.w=32;
  604. if (pos.x < 0 || pos.x >= map->width ||
  605. pos.y < 0 || pos.y >= map->height)
  606. {
  607. SDL_BlitSurface(ttiles[pos.x][pos.y][top_tile.z].terbitmap,
  608. &genRect(sr.h, sr.w, 0, 0),extSurf,&sr);
  609. }
  610. else
  611. {
  612. //blitting Fog of War
  613. if (!puzzleMode)
  614. {
  615. if (pos.x >= 0 &&
  616. pos.y >= 0 &&
  617. pos.x < CGI->mh->map->width &&
  618. pos.y < CGI->mh->map->height &&
  619. !(*visibilityMap)[pos.x][pos.y][top_tile.z])
  620. {
  621. SDL_Surface * hide = getVisBitmap(pos.x, pos.y, *visibilityMap, top_tile.z);
  622. CSDL_Ext::blit8bppAlphaTo24bpp(hide, &rtile, extSurf, &sr);
  623. }
  624. }
  625. //FoW blitted
  626. // TODO: these should be activable by the console
  627. #ifdef MARK_BLOCKED_POSITIONS
  628. if(ttiles[pos.x][pos.y][top_tile.z].tileInfo->blocked) //temporary hiding blocked positions
  629. {
  630. SDL_Rect sr;
  631. sr.x=srx;
  632. sr.y=sry;
  633. sr.h=sr.w=32;
  634. memset(rSurf->pixels, 128, rSurf->pitch * rSurf->h);
  635. SDL_BlitSurface(rSurf,&genRect(sr.h, sr.w, 0, 0),extSurf,&sr);
  636. }
  637. #endif
  638. #ifdef MARK_VISITABLE_POSITIONS
  639. if(ttiles[pos.x][pos.y][top_tile.z].tileInfo->visitable) //temporary hiding visitable positions
  640. {
  641. SDL_Rect sr;
  642. sr.x=srx;
  643. sr.y=sry;
  644. sr.h=sr.w=32;
  645. memset(rSurf->pixels, 128, rSurf->pitch * rSurf->h);
  646. SDL_BlitSurface(rSurf,&genRect(sr.h, sr.w, 0, 0),extSurf,&sr);
  647. }
  648. #endif
  649. }
  650. }
  651. }
  652. // borders printed
  653. #ifdef MARK_GRID_POSITIONS
  654. // print grid
  655. // TODO: This option should be activated by the console.
  656. srx = srx_init;
  657. for (int bx = 0; bx < dx; bx++, srx+=32)
  658. {
  659. sry = sry_init;
  660. for (int by = 0; by<dy; by++, sry+=32)
  661. {
  662. SDL_Rect sr;
  663. sr.x=srx;
  664. sr.y=sry;
  665. sr.h=sr.w=32;
  666. const int3 color(0x555555, 0x555555, 0x555555);
  667. if (sr.y >= extRect->y &&
  668. sr.y < extRect->y+extRect->h)
  669. for(int i=0;i<sr.w;i++)
  670. if (sr.x+i >= extRect->x &&
  671. sr.x+i < extRect->x+extRect->w)
  672. CSDL_Ext::SDL_PutPixelWithoutRefresh(extSurf,sr.x+i,sr.y,color.x,color.y,color.z);
  673. if (sr.x >= extRect->x &&
  674. sr.x < extRect->x+extRect->w)
  675. for(int i=0; i<sr.h;i++)
  676. if (sr.y+i >= extRect->y &&
  677. sr.y+i < extRect->y+extRect->h)
  678. CSDL_Ext::SDL_PutPixelWithoutRefresh(extSurf,sr.x,sr.y+i,color.x,color.y,color.z);
  679. }
  680. }
  681. // grid
  682. #endif
  683. //applying sepia / gray effect
  684. if(puzzleMode)
  685. {
  686. if(ADVOPT.puzzleSepia)
  687. {
  688. const int sepiaDepth = 20;
  689. const int sepiaIntensity = 30;
  690. for(int xp = extRect->x; xp < extRect->x + extRect->w; ++xp)
  691. {
  692. for(int yp = extRect->y; yp < extRect->y + extRect->h; ++yp)
  693. {
  694. unsigned char * pixels = (unsigned char*)extSurf->pixels + yp * extSurf->pitch + xp * extSurf->format->BytesPerPixel;
  695. int b = pixels[0];
  696. int g = pixels[1];
  697. int r = pixels[2];
  698. int gry = (r + g + b) / 3;
  699. r = g = b = gry;
  700. r = r + (sepiaDepth * 2);
  701. g = g + sepiaDepth;
  702. if (r>255) r=255;
  703. if (g>255) g=255;
  704. if (b>255) b=255;
  705. // Darken blue color to increase sepia effect
  706. b -= sepiaIntensity;
  707. // normalize if out of bounds
  708. if (b<0) b=0;
  709. if (b>255) b=255;
  710. pixels[0] = b;
  711. pixels[1] = g;
  712. pixels[2] = r;
  713. }
  714. }
  715. }
  716. else
  717. {
  718. for(int xp = extRect->x; xp < extRect->x + extRect->w; ++xp)
  719. {
  720. for(int yp = extRect->y; yp < extRect->y + extRect->h; ++yp)
  721. {
  722. unsigned char * pixels = (unsigned char*)extSurf->pixels + yp * extSurf->pitch + xp * extSurf->format->BytesPerPixel;
  723. int b = pixels[0];
  724. int g = pixels[1];
  725. int r = pixels[2];
  726. int gry = (r + g + b) / 3;
  727. pixels[0] = pixels[1] = pixels[2] = gry;
  728. }
  729. }
  730. }
  731. }
  732. //sepia / gray effect applied
  733. SDL_SetClipRect(extSurf, &prevClip); //restoring clip_rect
  734. }
  735. SDL_Surface * CMapHandler::getVisBitmap(int x, int y, const std::vector< std::vector< std::vector<unsigned char> > > & visibilityMap, int lvl)
  736. {
  737. int size = visibilityMap.size()-1; //is tile visible. arrangement: (like num keyboard)
  738. bool d7 = (x>0 && y>0) ? visibilityMap[x-1][y-1][lvl] : 0, //789
  739. d8 = (y>0) ? visibilityMap[x][y-1][lvl] : 0, //456
  740. d9 = (y>0 && x<size) ? visibilityMap[x+1][y-1][lvl] : 0,//123
  741. d4 = (x>0) ? visibilityMap[x-1][y][lvl] : 0,
  742. d5 = visibilityMap[x][y][lvl], //TODO use me - OMFG
  743. d6 = (x<size) ? visibilityMap[x+1][y][lvl] : 0,
  744. d1 = (x>0 && y<size) ? visibilityMap[x-1][y+1][lvl] : 0,
  745. d2 = (y<size) ? visibilityMap[x][y+1][lvl] : 0,
  746. d3 = (x<size && y<size) ? visibilityMap[x+1][y+1][lvl] : 0;
  747. if (!d6 && !d4)
  748. {
  749. if (!d3 && !d9 && !d1 && !d7)
  750. return fullHide->ourImages[hideBitmap[x][y][lvl]].bitmap; //fully hidden
  751. if(d2)
  752. return partialHide->ourImages[4].bitmap; //visble bottom
  753. else if (d8)
  754. return partialHide->ourImages[0].bitmap; //visible top
  755. else if (d3)
  756. return partialHide->ourImages[22].bitmap; //visible right bottom corner
  757. else if (d9)
  758. return partialHide->ourImages[15].bitmap; //visible right top corner
  759. else if (d1)
  760. return partialHide->ourImages[34].bitmap; //visible left bottom corner
  761. else if (d7)
  762. return partialHide->ourImages[35].bitmap; //visible left top corner
  763. if (!d2 && !d8)
  764. {
  765. if (d1)
  766. {
  767. if (d3)
  768. {
  769. if (d7)
  770. {
  771. if (d9)
  772. return partialHide->ourImages[21].bitmap;
  773. else
  774. return partialHide->ourImages[43].bitmap;
  775. }
  776. else
  777. {
  778. if (d9)
  779. return partialHide->ourImages[19].bitmap;
  780. else
  781. return partialHide->ourImages[40].bitmap;
  782. }
  783. }
  784. else
  785. {
  786. if (d7)
  787. {
  788. if (d9)
  789. return partialHide->ourImages[42].bitmap;
  790. else
  791. return partialHide->ourImages[39].bitmap;
  792. }
  793. else
  794. return partialHide->ourImages[17].bitmap;
  795. }
  796. }
  797. else
  798. {
  799. if(!d3)
  800. return partialHide->ourImages[18].bitmap;
  801. else if(!d7)
  802. return partialHide->ourImages[16].bitmap; //visible right corner
  803. else if(!d9)
  804. return partialHide->ourImages[41].bitmap;
  805. else
  806. return partialHide->ourImages[20].bitmap;
  807. }
  808. }
  809. if (d2)
  810. {
  811. if(d8)
  812. return partialHide->ourImages[29].bitmap;
  813. else if(d3)
  814. return partialHide->ourImages[1].bitmap;
  815. else
  816. return partialHide->ourImages[5].bitmap;
  817. }
  818. else if (d7)
  819. return partialHide->ourImages[4].bitmap;
  820. else
  821. return partialHide->ourImages[9].bitmap;
  822. }
  823. else //(d4 && d6 != 0)
  824. {
  825. if (d2)
  826. {
  827. if (d4)
  828. {
  829. if (d6)
  830. {
  831. if (d8)
  832. return partialHide->ourImages[10].bitmap;
  833. else
  834. return partialHide->ourImages[6].bitmap;
  835. }
  836. else
  837. {
  838. if (d8)
  839. return partialHide->ourImages[7].bitmap;
  840. else if (d9)
  841. return partialHide->ourImages[51].bitmap;
  842. else
  843. return partialHide->ourImages[38].bitmap;
  844. }
  845. }
  846. else
  847. {
  848. if (d6)
  849. {
  850. if (d8)
  851. return partialHide->ourImages[44].bitmap;
  852. else if (d7)
  853. return partialHide->ourImages[28].bitmap;
  854. else
  855. return partialHide->ourImages[12].bitmap;
  856. }
  857. else
  858. {
  859. if (d7)
  860. {
  861. if (d9)
  862. return partialHide->ourImages[31].bitmap;
  863. else
  864. return partialHide->ourImages[48].bitmap;
  865. }
  866. else
  867. return partialHide->ourImages[30].bitmap;
  868. }
  869. }
  870. }
  871. else
  872. {
  873. if (d4)
  874. {
  875. if (d6)
  876. {
  877. if (d8)
  878. return partialHide->ourImages[8].bitmap;
  879. else
  880. return partialHide->ourImages[9].bitmap;
  881. }
  882. else
  883. {
  884. if (d8)
  885. {
  886. if (d3)
  887. return partialHide->ourImages[50].bitmap;
  888. else
  889. return partialHide->ourImages[37].bitmap;
  890. }
  891. else
  892. {
  893. if (d3)
  894. {
  895. if (d9)
  896. return partialHide->ourImages[32].bitmap;
  897. else
  898. return partialHide->ourImages[47].bitmap;
  899. }
  900. else
  901. {
  902. if (d9)
  903. return partialHide->ourImages[46].bitmap;
  904. else
  905. return partialHide->ourImages[36].bitmap;
  906. }
  907. }
  908. }
  909. }
  910. else
  911. {
  912. if (d6)
  913. {
  914. if (d8)
  915. {
  916. if (d1)
  917. return partialHide->ourImages[27].bitmap;
  918. else
  919. return partialHide->ourImages[13].bitmap;
  920. }
  921. else
  922. {
  923. if (d7)
  924. {
  925. if (d1)
  926. return partialHide->ourImages[49].bitmap;
  927. else
  928. return partialHide->ourImages[26].bitmap;
  929. }
  930. else
  931. {
  932. if (d1)
  933. return partialHide->ourImages[25].bitmap;
  934. else
  935. {
  936. if (d9)
  937. return partialHide->ourImages[2].bitmap;
  938. else
  939. return partialHide->ourImages[3].bitmap;
  940. }
  941. }
  942. }
  943. }
  944. else
  945. {
  946. if (d1)
  947. {
  948. if (d3)
  949. return partialHide->ourImages[33].bitmap;
  950. else
  951. return partialHide->ourImages[45].bitmap;
  952. }
  953. else
  954. return partialHide->ourImages[24].bitmap;
  955. }
  956. }
  957. }
  958. }
  959. return fullHide->ourImages[0].bitmap; //this case should never happen, but it is better to hide too much than reveal it....
  960. }
  961. bool CMapHandler::printObject(const CGObjectInstance *obj)
  962. {
  963. if(!obj->defInfo->handler)
  964. processDef(obj->defInfo);
  965. const SDL_Surface *bitmap = obj->defInfo->handler->ourImages[0].bitmap;
  966. int tilesW = bitmap->w/32,
  967. tilesH = bitmap->h/32;
  968. for(int fx=0; fx<bitmap->w/32; ++fx)
  969. {
  970. for(int fy=0; fy<bitmap->h/32; ++fy)
  971. {
  972. SDL_Rect cr;
  973. cr.w = 32;
  974. cr.h = 32;
  975. cr.x = fx*32;
  976. cr.y = fy*32;
  977. std::pair<const CGObjectInstance*,SDL_Rect> toAdd = std::make_pair(obj, cr);
  978. if((obj->pos.x + fx - bitmap->w/32+1)>=0 && (obj->pos.x + fx - bitmap->w/32+1)<ttiles.size()-frameW && (obj->pos.y + fy - bitmap->h/32+1)>=0 && (obj->pos.y + fy - bitmap->h/32+1)<ttiles[0].size()-frameH)
  979. {
  980. TerrainTile2 & curt = ttiles[obj->pos.x + fx - bitmap->w/32+1][obj->pos.y + fy - bitmap->h/32+1][obj->pos.z];
  981. std::vector< std::pair<const CGObjectInstance*,SDL_Rect> >::iterator i = curt.objects.begin();
  982. for(; i != curt.objects.end(); i++)
  983. {
  984. OCM_HLP cmp;
  985. if(cmp(toAdd, *i))
  986. {
  987. curt.objects.insert(i, toAdd);
  988. i = curt.objects.begin(); //to validate and avoid adding it second time
  989. break;
  990. }
  991. }
  992. if(i == curt.objects.end())
  993. curt.objects.insert(i, toAdd);
  994. }
  995. } // for(int fy=0; fy<bitmap->h/32; ++fy)
  996. } //for(int fx=0; fx<bitmap->w/32; ++fx)
  997. return true;
  998. }
  999. bool CMapHandler::hideObject(const CGObjectInstance *obj)
  1000. {
  1001. CDefEssential * curd = obj->defInfo->handler;
  1002. if(!curd) return false;
  1003. const SDL_Surface *bitmap = curd->ourImages[0].bitmap;
  1004. for(int fx=0; fx<bitmap->w/32; ++fx)
  1005. {
  1006. for(int fy=0; fy<bitmap->h/32; ++fy)
  1007. {
  1008. if((obj->pos.x + fx - bitmap->w/32+1)>=0 && (obj->pos.x + fx - bitmap->w/32+1)<ttiles.size()-frameW && (obj->pos.y + fy - bitmap->h/32+1)>=0 && (obj->pos.y + fy - bitmap->h/32+1)<ttiles[0].size()-frameH)
  1009. {
  1010. std::vector < std::pair<const CGObjectInstance*,SDL_Rect> > & ctile = ttiles[obj->pos.x + fx - bitmap->w/32+1][obj->pos.y + fy - bitmap->h/32+1][obj->pos.z].objects;
  1011. for(size_t dd=0; dd < ctile.size(); ++dd)
  1012. {
  1013. if(ctile[dd].first->id==obj->id)
  1014. ctile.erase(ctile.begin() + dd);
  1015. }
  1016. }
  1017. } // for(int fy=0; fy<bitmap->h/32; ++fy)
  1018. } //for(int fx=0; fx<bitmap->w/32; ++fx)
  1019. return true;
  1020. }
  1021. bool CMapHandler::removeObject(CGObjectInstance *obj)
  1022. {
  1023. hideObject(obj);
  1024. return true;
  1025. }
  1026. unsigned char CMapHandler::getHeroFrameNum(unsigned char dir, bool isMoving) const
  1027. {
  1028. if(isMoving)
  1029. {
  1030. static const unsigned char frame [] = {-1, 10, 5, 6, 7, 8, 9, 12, 11};
  1031. return frame[dir];
  1032. /*switch(dir)
  1033. {
  1034. case 1:
  1035. return 10;
  1036. case 2:
  1037. return 5;
  1038. case 3:
  1039. return 6;
  1040. case 4:
  1041. return 7;
  1042. case 5:
  1043. return 8;
  1044. case 6:
  1045. return 9;
  1046. case 7:
  1047. return 12;
  1048. case 8:
  1049. return 11;
  1050. default:
  1051. throw std::string("Something very wrong1.");
  1052. }*/
  1053. }
  1054. else //if(isMoving)
  1055. {
  1056. static const unsigned char frame [] = {-1, 13, 0, 1, 2, 3, 4, 15, 14};
  1057. return frame[dir];
  1058. /*switch(dir)
  1059. {
  1060. case 1:
  1061. return 13;
  1062. case 2:
  1063. return 0;
  1064. case 3:
  1065. return 1;
  1066. case 4:
  1067. return 2;
  1068. case 5:
  1069. return 3;
  1070. case 6:
  1071. return 4;
  1072. case 7:
  1073. return 15;
  1074. case 8:
  1075. return 14;
  1076. default:
  1077. throw std::string("Something very wrong2.");
  1078. }*/
  1079. }
  1080. }
  1081. void CMapHandler::validateRectTerr(SDL_Rect * val, const SDL_Rect * ext)
  1082. {
  1083. if(ext)
  1084. {
  1085. if(val->x<0)
  1086. {
  1087. val->w += val->x;
  1088. val->x = ext->x;
  1089. }
  1090. else
  1091. {
  1092. val->x += ext->x;
  1093. }
  1094. if(val->y<0)
  1095. {
  1096. val->h += val->y;
  1097. val->y = ext->y;
  1098. }
  1099. else
  1100. {
  1101. val->y += ext->y;
  1102. }
  1103. if(val->x+val->w > ext->x+ext->w)
  1104. {
  1105. val->w = ext->x+ext->w-val->x;
  1106. }
  1107. if(val->y+val->h > ext->y+ext->h)
  1108. {
  1109. val->h = ext->y+ext->h-val->y;
  1110. }
  1111. //for sign problems
  1112. if(val->h > 20000 || val->w > 20000)
  1113. {
  1114. val->h = val->w = 0;
  1115. }
  1116. }
  1117. }
  1118. unsigned char CMapHandler::getDir(const int3 &a, const int3 &b)
  1119. {
  1120. if(a.z!=b.z)
  1121. return -1; //error!
  1122. if(a.x==b.x+1 && a.y==b.y+1) //lt
  1123. return 0;
  1124. else if(a.x==b.x && a.y==b.y+1) //t
  1125. return 1;
  1126. else if(a.x==b.x-1 && a.y==b.y+1) //rt
  1127. return 2;
  1128. else if(a.x==b.x-1 && a.y==b.y) //r
  1129. return 3;
  1130. else if(a.x==b.x-1 && a.y==b.y-1) //rb
  1131. return 4;
  1132. else if(a.x==b.x && a.y==b.y-1) //b
  1133. return 5;
  1134. else if(a.x==b.x+1 && a.y==b.y-1) //lb
  1135. return 6;
  1136. else if(a.x==b.x+1 && a.y==b.y) //l
  1137. return 7;
  1138. return -2; //shouldn't happen
  1139. }
  1140. void shiftColors(SDL_Surface *img, int from, int howMany) //shifts colors in palette
  1141. {
  1142. //works with at most 16 colors, if needed more -> increase values
  1143. assert(howMany < 16);
  1144. SDL_Color palette[16];
  1145. for(int i=0; i<howMany; ++i)
  1146. {
  1147. palette[(i+1)%howMany] =img->format->palette->colors[from + i];
  1148. }
  1149. SDL_SetColors(img,palette,from,howMany);
  1150. }
  1151. void CMapHandler::updateWater() //shift colors in palettes of water tiles
  1152. {
  1153. for(size_t j=0; j < terrainGraphics[7].size(); ++j)
  1154. {
  1155. shiftColors(terrainGraphics[7][j],246, 9);
  1156. }
  1157. for(size_t j=0; j < terrainGraphics[8].size(); ++j)
  1158. {
  1159. shiftColors(terrainGraphics[8][j],229, 12);
  1160. shiftColors(terrainGraphics[8][j],242, 14);
  1161. }
  1162. for(size_t j=0; j < staticRiverDefs[0]->ourImages.size(); ++j)
  1163. {
  1164. shiftColors(staticRiverDefs[0]->ourImages[j].bitmap,183, 12);
  1165. shiftColors(staticRiverDefs[0]->ourImages[j].bitmap,195, 6);
  1166. }
  1167. for(size_t j=0; j < staticRiverDefs[2]->ourImages.size(); ++j)
  1168. {
  1169. shiftColors(staticRiverDefs[2]->ourImages[j].bitmap,228, 12);
  1170. shiftColors(staticRiverDefs[2]->ourImages[j].bitmap,183, 6);
  1171. shiftColors(staticRiverDefs[2]->ourImages[j].bitmap,240, 6);
  1172. }
  1173. for(size_t j=0; j < staticRiverDefs[3]->ourImages.size(); ++j)
  1174. {
  1175. shiftColors(staticRiverDefs[3]->ourImages[j].bitmap,240, 9);
  1176. }
  1177. }
  1178. CMapHandler::~CMapHandler()
  1179. {
  1180. delete fullHide;
  1181. delete partialHide;
  1182. for(int i=0; i < roadDefs.size(); i++)
  1183. delete roadDefs[i];
  1184. for(int i=0; i < staticRiverDefs.size(); i++)
  1185. delete staticRiverDefs[i];
  1186. //TODO: why this code makes VCMI crash?
  1187. /*for(int i=0; i < terrainGraphics.size(); ++i)
  1188. {
  1189. for(int j=0; j < terrainGraphics[i].size(); ++j)
  1190. SDL_FreeSurface(terrainGraphics[i][j]);
  1191. }
  1192. terrainGraphics.clear();*/
  1193. }
  1194. CMapHandler::CMapHandler()
  1195. {
  1196. mapW = mapH = 0;
  1197. frameW = frameH = 0;
  1198. fullHide = NULL;
  1199. partialHide = NULL;
  1200. }
  1201. void CMapHandler::getTerrainDescr( const int3 &pos, std::string & out, bool terName )
  1202. {
  1203. out.clear();
  1204. TerrainTile2 &t = ttiles[pos.x][pos.y][pos.z];
  1205. for(std::vector < std::pair<const CGObjectInstance*,SDL_Rect> >::const_iterator i = t.objects.begin(); i != t.objects.end(); i++)
  1206. {
  1207. if(i->first->ID == 124) //Hole
  1208. {
  1209. out = i->first->hoverName;
  1210. return;
  1211. }
  1212. }
  1213. if(t.tileInfo->siodmyTajemniczyBajt & 128)
  1214. out = CGI->generaltexth->names[225]; //Favourable Winds
  1215. else if(terName)
  1216. out = CGI->generaltexth->terrainNames[t.tileInfo->tertype];
  1217. }
  1218. TerrainTile2::TerrainTile2()
  1219. :tileInfo(0),terbitmap(0)
  1220. {}