mapHandler.cpp 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373
  1. #include "stdafx.h"
  2. #include "mapHandler.h"
  3. #include "client/SDL_Extensions.h"
  4. #include "client/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 "client/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 "client/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. // printing terrain
  444. srx = srx_init;
  445. for (int bx = 0; bx < dx; bx++, srx+=32)
  446. {
  447. // Skip column if not in map
  448. if (top_tile.x+bx < 0 || top_tile.x+bx >= map->width)
  449. continue;
  450. sry = sry_init;
  451. for (int by=0; by < dy; by++, sry+=32)
  452. {
  453. int3 pos(top_tile.x+bx, top_tile.y+by, top_tile.z); //blitted tile position
  454. // Skip tile if not in map
  455. if (pos.y < 0 || pos.y >= map->height)
  456. continue;
  457. const TerrainTile2 & tile = ttiles[pos.x][pos.y][pos.z];
  458. const TerrainTile &tinfo = *tile.tileInfo;
  459. SDL_Rect sr;
  460. sr.x=srx;
  461. sr.y=sry;
  462. sr.h=sr.w=32;
  463. //blit terrain with river/road
  464. if(tile.terbitmap) //if custom terrain graphic - use it
  465. SDL_BlitSurface(tile.terbitmap, &genRect(sr.h, sr.w, 0, 0), extSurf, &sr);
  466. else //use default terrain graphic
  467. CSDL_Ext::blitWithRotateClipVal(terrainGraphics[tinfo.tertype][tinfo.terview],rtile, extSurf, sr, tinfo.siodmyTajemniczyBajt%4);
  468. if(tinfo.nuine) //print river if present
  469. CSDL_Ext::blitWithRotateClipValWithAlpha(staticRiverDefs[tinfo.nuine-1]->ourImages[tinfo.rivDir].bitmap,rtile, extSurf, sr, (tinfo.siodmyTajemniczyBajt>>2)%4);
  470. if(tinfo.malle) //print road if present
  471. CSDL_Ext::blitWithRotateClipValWithAlpha(roadDefs[tinfo.malle-1]->ourImages[tinfo.roadDir].bitmap,rtile, extSurf, sr, (tinfo.siodmyTajemniczyBajt>>4)%4);
  472. //blit objects
  473. const std::vector < std::pair<const CGObjectInstance*,SDL_Rect> > &objects = tile.objects;
  474. for(int h=0; h < objects.size(); ++h)
  475. {
  476. const CGObjectInstance *obj = objects[h].first;
  477. ui8 color = obj->tempOwner;
  478. //checking if object has non-empty graphic on this tile
  479. if(obj->ID != HEROI_TYPE && !obj->coveringAt(obj->pos.x - (top_tile.x + bx), top_tile.y + by - obj->pos.y + 5))
  480. continue;
  481. //don't print flaggable objects in puzzle mode
  482. if(puzzleMode && obj->tempOwner != 254)
  483. continue;
  484. SDL_Rect sr2(sr);
  485. SDL_Rect pp = objects[h].second;
  486. pp.h = sr.h;
  487. pp.w = sr.w;
  488. const CGHeroInstance * themp = (obj->ID != HEROI_TYPE
  489. ? NULL
  490. : static_cast<const CGHeroInstance*>(obj));
  491. //print hero / boat and flag
  492. if(themp && themp->moveDir && themp->type || obj->ID == 8) //it's hero or boat
  493. {
  494. const int IMGVAL = 8; //frames per group of movement animation
  495. ui8 dir;
  496. std::vector<Cimage> * iv = NULL;
  497. std::vector<CDefEssential *> Graphics::*flg = NULL;
  498. SDL_Surface * tb; //surface to blitted
  499. if(themp) //hero
  500. {
  501. dir = themp->moveDir;
  502. //pick graphics of hero (or boat if hero is sailing)
  503. iv = (themp->boat)
  504. ? &graphics->boatAnims[themp->boat->subID]->ourImages
  505. : &graphics->heroAnims[themp->type->heroType]->ourImages;
  506. //pick appropriate flag set
  507. if(themp->boat)
  508. {
  509. switch (themp->boat->subID)
  510. {
  511. case 0: flg = &Graphics::flags1; break;
  512. case 1: flg = &Graphics::flags2; break;
  513. case 2: flg = &Graphics::flags3; break;
  514. default: tlog1 << "Not supported boat subtype: " << themp->boat->subID << std::endl;
  515. }
  516. }
  517. else
  518. {
  519. flg = &Graphics::flags4;
  520. }
  521. }
  522. else //boat
  523. {
  524. const CGBoat *boat = static_cast<const CGBoat*>(obj);
  525. dir = boat->direction;
  526. iv = &graphics->boatAnims[boat->subID]->ourImages;
  527. }
  528. if(themp && !themp->isStanding) //hero is moving
  529. {
  530. size_t gg;
  531. for(gg=0; gg<iv->size(); ++gg)
  532. {
  533. if((*iv)[gg].groupNumber==getHeroFrameNum(dir, true))
  534. {
  535. tb = (*iv)[gg+heroAnim%IMGVAL].bitmap;
  536. break;
  537. }
  538. }
  539. CSDL_Ext::blit8bppAlphaTo24bpp(tb,&pp,extSurf,&sr2);
  540. //printing flag
  541. pp.y+=IMGVAL*2-32;
  542. sr2.y-=16;
  543. SDL_BlitSurface((graphics->*flg)[color]->ourImages[gg+heroAnim%IMGVAL+35].bitmap, &pp, extSurf, &sr2);
  544. }
  545. else //hero / boat stands still
  546. {
  547. size_t gg;
  548. for(gg=0; gg < iv->size(); ++gg)
  549. {
  550. if((*iv)[gg].groupNumber==getHeroFrameNum(dir, false))
  551. {
  552. tb = (*iv)[gg].bitmap;
  553. break;
  554. }
  555. }
  556. CSDL_Ext::blit8bppAlphaTo24bpp(tb,&pp,extSurf,&sr2);
  557. //printing flag
  558. if(flg
  559. && obj->pos.x == top_tile.x + bx
  560. && obj->pos.y == top_tile.y + by)
  561. {
  562. SDL_Rect bufr = sr2;
  563. bufr.x-=2*32;
  564. bufr.y-=1*32;
  565. bufr.h = 64;
  566. bufr.w = 96;
  567. if(bufr.x-extRect->x>-64)
  568. SDL_BlitSurface((graphics->*flg)[color]->ourImages[getHeroFrameNum(dir, false) *8+(heroAnim/4)%IMGVAL].bitmap, NULL, extSurf, &bufr);
  569. }
  570. }
  571. }
  572. else //blit normal object
  573. {
  574. const std::vector<Cimage> &ourImages = obj->defInfo->handler->ourImages;
  575. SDL_Surface *bitmap = ourImages[(anim+obj->animPhaseShift)%ourImages.size()].bitmap;
  576. //setting appropriate flag color
  577. if(color < 8 || color==255)
  578. CSDL_Ext::setPlayerColor(bitmap, color);
  579. if( obj->hasShadowAt(obj->pos.x - (top_tile.x + bx), top_tile.y + by - obj->pos.y + 5) )
  580. CSDL_Ext::blit8bppAlphaTo24bpp(bitmap,&pp,extSurf,&sr2);
  581. else
  582. SDL_BlitSurface(bitmap,&pp,extSurf,&sr2);
  583. }
  584. }
  585. //objects blitted
  586. }
  587. }
  588. // terrain printed
  589. // printing borders
  590. srx = srx_init;
  591. for (int bx = 0; bx < dx; bx++, srx+=32)
  592. {
  593. sry = sry_init;
  594. for (int by = 0; by<dy; by++, sry+=32)
  595. {
  596. int3 pos(top_tile.x+bx, top_tile.y+by, top_tile.z); //blitted tile position
  597. SDL_Rect sr;
  598. sr.x=srx;
  599. sr.y=sry;
  600. sr.h=sr.w=32;
  601. if (pos.x < 0 || pos.x >= map->width ||
  602. pos.y < 0 || pos.y >= map->height)
  603. {
  604. SDL_BlitSurface(ttiles[pos.x][pos.y][top_tile.z].terbitmap,
  605. &genRect(sr.h, sr.w, 0, 0),extSurf,&sr);
  606. }
  607. else
  608. {
  609. //blitting Fog of War
  610. if (!puzzleMode)
  611. {
  612. if (pos.x >= 0 &&
  613. pos.y >= 0 &&
  614. pos.x < CGI->mh->map->width &&
  615. pos.y < CGI->mh->map->height &&
  616. !(*visibilityMap)[pos.x][pos.y][top_tile.z])
  617. {
  618. SDL_Surface * hide = getVisBitmap(pos.x, pos.y, *visibilityMap, top_tile.z);
  619. CSDL_Ext::blit8bppAlphaTo24bpp(hide, &rtile, extSurf, &sr);
  620. }
  621. }
  622. //FoW blitted
  623. // TODO: these should be activable by the console
  624. #ifdef MARK_BLOCKED_POSITIONS
  625. if(ttiles[pos.x][pos.y][top_tile.z].tileInfo->blocked) //temporary hiding blocked positions
  626. {
  627. SDL_Rect sr;
  628. sr.x=srx;
  629. sr.y=sry;
  630. sr.h=sr.w=32;
  631. memset(rSurf->pixels, 128, rSurf->pitch * rSurf->h);
  632. SDL_BlitSurface(rSurf,&genRect(sr.h, sr.w, 0, 0),extSurf,&sr);
  633. }
  634. #endif
  635. #ifdef MARK_VISITABLE_POSITIONS
  636. if(ttiles[pos.x][pos.y][top_tile.z].tileInfo->visitable) //temporary hiding visitable positions
  637. {
  638. SDL_Rect sr;
  639. sr.x=srx;
  640. sr.y=sry;
  641. sr.h=sr.w=32;
  642. memset(rSurf->pixels, 128, rSurf->pitch * rSurf->h);
  643. SDL_BlitSurface(rSurf,&genRect(sr.h, sr.w, 0, 0),extSurf,&sr);
  644. }
  645. #endif
  646. }
  647. }
  648. }
  649. // borders printed
  650. #ifdef MARK_GRID_POSITIONS
  651. // print grid
  652. // TODO: This option should be activated by the console.
  653. srx = srx_init;
  654. for (int bx = 0; bx < dx; bx++, srx+=32)
  655. {
  656. sry = sry_init;
  657. for (int by = 0; by<dy; by++, sry+=32)
  658. {
  659. SDL_Rect sr;
  660. sr.x=srx;
  661. sr.y=sry;
  662. sr.h=sr.w=32;
  663. const int3 color(0x555555, 0x555555, 0x555555);
  664. if (sr.y >= extRect->y &&
  665. sr.y < extRect->y+extRect->h)
  666. for(int i=0;i<sr.w;i++)
  667. if (sr.x+i >= extRect->x &&
  668. sr.x+i < extRect->x+extRect->w)
  669. CSDL_Ext::SDL_PutPixelWithoutRefresh(extSurf,sr.x+i,sr.y,color.x,color.y,color.z);
  670. if (sr.x >= extRect->x &&
  671. sr.x < extRect->x+extRect->w)
  672. for(int i=0; i<sr.h;i++)
  673. if (sr.y+i >= extRect->y &&
  674. sr.y+i < extRect->y+extRect->h)
  675. CSDL_Ext::SDL_PutPixelWithoutRefresh(extSurf,sr.x,sr.y+i,color.x,color.y,color.z);
  676. }
  677. }
  678. // grid
  679. #endif
  680. //applying sepia / gray effect
  681. if(puzzleMode)
  682. {
  683. if(ADVOPT.puzzleSepia)
  684. {
  685. const int sepiaDepth = 20;
  686. const int sepiaIntensity = 30;
  687. for(int xp = extRect->x; xp < extRect->x + extRect->w; ++xp)
  688. {
  689. for(int yp = extRect->y; yp < extRect->y + extRect->h; ++yp)
  690. {
  691. unsigned char * pixels = (unsigned char*)extSurf->pixels + yp * extSurf->pitch + xp * extSurf->format->BytesPerPixel;
  692. int b = pixels[0];
  693. int g = pixels[1];
  694. int r = pixels[2];
  695. int gry = (r + g + b) / 3;
  696. r = g = b = gry;
  697. r = r + (sepiaDepth * 2);
  698. g = g + sepiaDepth;
  699. if (r>255) r=255;
  700. if (g>255) g=255;
  701. if (b>255) b=255;
  702. // Darken blue color to increase sepia effect
  703. b -= sepiaIntensity;
  704. // normalize if out of bounds
  705. if (b<0) b=0;
  706. if (b>255) b=255;
  707. pixels[0] = b;
  708. pixels[1] = g;
  709. pixels[2] = r;
  710. }
  711. }
  712. }
  713. else
  714. {
  715. for(int xp = extRect->x; xp < extRect->x + extRect->w; ++xp)
  716. {
  717. for(int yp = extRect->y; yp < extRect->y + extRect->h; ++yp)
  718. {
  719. unsigned char * pixels = (unsigned char*)extSurf->pixels + yp * extSurf->pitch + xp * extSurf->format->BytesPerPixel;
  720. int b = pixels[0];
  721. int g = pixels[1];
  722. int r = pixels[2];
  723. int gry = (r + g + b) / 3;
  724. pixels[0] = pixels[1] = pixels[2] = gry;
  725. }
  726. }
  727. }
  728. }
  729. //sepia / gray effect applied
  730. SDL_SetClipRect(extSurf, &prevClip); //restoring clip_rect
  731. }
  732. SDL_Surface * CMapHandler::getVisBitmap(int x, int y, const std::vector< std::vector< std::vector<unsigned char> > > & visibilityMap, int lvl)
  733. {
  734. int size = visibilityMap.size()-1; //is tile visible. arrangement: (like num keyboard)
  735. bool d7 = (x>0 && y>0) ? visibilityMap[x-1][y-1][lvl] : 0, //789
  736. d8 = (y>0) ? visibilityMap[x][y-1][lvl] : 0, //456
  737. d9 = (y>0 && x<size) ? visibilityMap[x+1][y-1][lvl] : 0,//123
  738. d4 = (x>0) ? visibilityMap[x-1][y][lvl] : 0,
  739. d5 = visibilityMap[x][y][lvl], //TODO use me - OMFG
  740. d6 = (x<size) ? visibilityMap[x+1][y][lvl] : 0,
  741. d1 = (x>0 && y<size) ? visibilityMap[x-1][y+1][lvl] : 0,
  742. d2 = (y<size) ? visibilityMap[x][y+1][lvl] : 0,
  743. d3 = (x<size && y<size) ? visibilityMap[x+1][y+1][lvl] : 0;
  744. if(!d2 && !d6 && !d4 && !d8 && !d7 && !d3 && !d9 && !d1)
  745. {
  746. return fullHide->ourImages[hideBitmap[x][y][lvl]].bitmap; //fully hidden
  747. }
  748. else if(!d2 && !d6 && !d4 && !d8 && !d7 && d3 && !d9 && !d1)
  749. {
  750. return partialHide->ourImages[22].bitmap; //visible right bottom corner
  751. }
  752. else if(!d2 && !d6 && !d4 && !d8 && !d7 && !d3 && d9 && !d1)
  753. {
  754. return partialHide->ourImages[15].bitmap; //visible right top corner
  755. }
  756. else if(!d2 && !d6 && !d4 && !d8 && !d7 && !d3 && !d9 && d1)
  757. {
  758. return partialHide->ourImages[34].bitmap; //visible left bottom corner
  759. }
  760. else if(!d2 && !d6 && !d4 && !d8 && d7 && !d3 && !d9 && !d1)
  761. {
  762. return partialHide->ourImages[35].bitmap; //visible left top corner
  763. }
  764. else if(!d2 && !d6 && !d4 && d8 && d7 && !d3 && d9 && !d1)
  765. {
  766. return partialHide->ourImages[0].bitmap; //visible top
  767. }
  768. else if(d2 && !d6 && !d4 && !d8 && !d7 && d3 && !d9 && d1)
  769. {
  770. return partialHide->ourImages[4].bitmap; //visble bottom
  771. }
  772. else if(!d2 && !d6 && d4 && !d8 && d7 && !d3 && !d9 && d1)
  773. {
  774. return partialHide->ourImages[36].bitmap; //visible left
  775. }
  776. else if(!d2 && d6 && !d4 && !d8 && !d7 && d3 && d9 && !d1)
  777. {
  778. return partialHide->ourImages[2].bitmap; //visible right
  779. }
  780. else if(d2 && d6 && !d4 && !d8 && !d7)
  781. {
  782. return partialHide->ourImages[12].bitmap; //visible bottom, right - bottom, right; left top corner hidden
  783. }
  784. else if(!d2 && d6 && !d4 && d8 && !d1)
  785. {
  786. return partialHide->ourImages[13].bitmap; //visible right, right - top; left bottom corner hidden
  787. }
  788. else if(!d2 && !d6 && d4 && d8 && !d3)
  789. {
  790. return partialHide->ourImages[37].bitmap; //visible top, top - left, left; right bottom corner hidden
  791. }
  792. else if(d2 && !d6 && d4 && !d8 && !d9)
  793. {
  794. return partialHide->ourImages[38].bitmap; //visible left, left - bottom, bottom; right top corner hidden
  795. }
  796. else if(d2 && d6 && d4 && d8)
  797. {
  798. return partialHide->ourImages[10].bitmap; //visible left, right, bottom and top
  799. }
  800. if(!d2 && !d6 && !d4 && !d8 && !d7 && d3 && d9 && !d1)
  801. {
  802. return partialHide->ourImages[16].bitmap; //visible right corners
  803. }
  804. if(!d2 && !d6 && !d4 && !d8 && d7 && !d3 && d9 && !d1)
  805. {
  806. return partialHide->ourImages[18].bitmap; //visible top corners
  807. }
  808. if(!d2 && !d6 && !d4 && !d8 && d7 && !d3 && !d9 && d1)
  809. {
  810. return partialHide->ourImages[39].bitmap; //visible left corners
  811. }
  812. if(!d2 && !d6 && !d4 && !d8 && !d7 && d3 && !d9 && d1)
  813. {
  814. return partialHide->ourImages[40].bitmap; //visible bottom corners
  815. }
  816. if(!d2 && !d6 && !d4 && !d8 && !d7 && !d3 && d9 && d1)
  817. {
  818. return partialHide->ourImages[17].bitmap; //visible right - top and bottom - left corners
  819. }
  820. if(!d2 && !d6 && !d4 && !d8 && d7 && d3 && !d9 && !d1)
  821. {
  822. return partialHide->ourImages[41].bitmap; //visible top - left and bottom - right corners
  823. }
  824. if(!d2 && !d6 && !d4 && !d8 && !d7 && d3 && d9 && d1)
  825. {
  826. return partialHide->ourImages[19].bitmap; //visible corners without left top
  827. }
  828. if(!d2 && !d6 && !d4 && !d8 && d7 && d3 && d9 && !d1)
  829. {
  830. return partialHide->ourImages[20].bitmap; //visible corners without left bottom
  831. }
  832. if(!d2 && !d6 && !d4 && !d8 && d7 && !d3 && d9 && d1)
  833. {
  834. return partialHide->ourImages[42].bitmap; //visible corners without right bottom
  835. }
  836. if(!d2 && !d6 && !d4 && !d8 && d7 && d3 && !d9 && d1)
  837. {
  838. return partialHide->ourImages[43].bitmap; //visible corners without right top
  839. }
  840. if(!d2 && !d6 && !d4 && !d8 && d7 && d3 && d9 && d1)
  841. {
  842. return partialHide->ourImages[21].bitmap; //visible all corners only
  843. }
  844. if(d2 && d6 && d4 && !d8)
  845. {
  846. return partialHide->ourImages[6].bitmap; //hidden top
  847. }
  848. if(d2 && !d6 && d4 && d8)
  849. {
  850. return partialHide->ourImages[7].bitmap; //hidden right
  851. }
  852. if(!d2 && d6 && d4 && d8)
  853. {
  854. return partialHide->ourImages[8].bitmap; //hidden bottom
  855. }
  856. if(d2 && d6 && !d4 && d8)
  857. {
  858. return partialHide->ourImages[44].bitmap; //hidden left
  859. }
  860. if(!d2 && d6 && d4 && !d8)
  861. {
  862. return partialHide->ourImages[9].bitmap; //hidden top and bottom
  863. }
  864. if(d2 && !d6 && !d4 && d8)
  865. {
  866. return partialHide->ourImages[29].bitmap; //hidden left and right
  867. }
  868. if(!d2 && !d6 && !d4 && d8 && d3 && !d1)
  869. {
  870. return partialHide->ourImages[24].bitmap; //visible top and right bottom corner
  871. }
  872. if(!d2 && !d6 && !d4 && d8 && !d3 && d1)
  873. {
  874. return partialHide->ourImages[45].bitmap; //visible top and left bottom corner
  875. }
  876. if(!d2 && !d6 && !d4 && d8 && d3 && d1)
  877. {
  878. return partialHide->ourImages[33].bitmap; //visible top and bottom corners
  879. }
  880. if(!d2 && !d6 && d4 && !d8 && !d3 && d9)
  881. {
  882. return partialHide->ourImages[46].bitmap; //visible left and right top corner
  883. }
  884. if(!d2 && !d6 && d4 && !d8 && d3 && !d9)
  885. {
  886. return partialHide->ourImages[47].bitmap; //visible left and right bottom corner
  887. }
  888. if(!d2 && !d6 && d4 && !d8 && d3 && d9)
  889. {
  890. return partialHide->ourImages[32].bitmap; //visible left and right corners
  891. }
  892. if(d2 && !d6 && !d4 && !d8 && d7 && !d9)
  893. {
  894. return partialHide->ourImages[48].bitmap; //visible bottom and left top corner
  895. }
  896. if(d2 && !d6 && !d4 && !d8 && !d7 && d9)
  897. {
  898. return partialHide->ourImages[30].bitmap; //visible bottom and right top corner
  899. }
  900. if(d2 && !d6 && !d4 && !d8 && d7 && d9)
  901. {
  902. return partialHide->ourImages[31].bitmap; //visible bottom and top corners
  903. }
  904. if(!d2 && d6 && !d4 && !d8 && !d7 && d1)
  905. {
  906. return partialHide->ourImages[25].bitmap; //visible right and left bottom corner
  907. }
  908. if(!d2 && d6 && !d4 && !d8 && d7 && !d1)
  909. {
  910. return partialHide->ourImages[26].bitmap; //visible right and left top corner
  911. }
  912. if(!d2 && d6 && !d4 && !d8 && d7 && d1)
  913. {
  914. return partialHide->ourImages[49].bitmap; //visible right and left cornres
  915. }
  916. if(d2 && d6 && !d4 && !d8 && d7)
  917. {
  918. return partialHide->ourImages[28].bitmap; //visible bottom, right - bottom, right; left top corner visible
  919. }
  920. else if(!d2 && d6 && !d4 && d8 && d1)
  921. {
  922. return partialHide->ourImages[27].bitmap; //visible right, right - top; left bottom corner visible
  923. }
  924. else if(!d2 && !d6 && d4 && d8 && d3)
  925. {
  926. return partialHide->ourImages[50].bitmap; //visible top, top - left, left; right bottom corner visible
  927. }
  928. else if(d2 && !d6 && d4 && !d8 && d9)
  929. {
  930. return partialHide->ourImages[51].bitmap; //visible left, left - bottom, bottom; right top corner visible
  931. }
  932. //newly added
  933. else if(!d2 && !d6 && !d4 && d8 && !d7 && !d3 && d9 && !d1) //visible t and tr
  934. {
  935. return partialHide->ourImages[0].bitmap;
  936. }
  937. else if(!d2 && !d6 && !d4 && d8 && d7 && !d3 && !d9 && !d1) //visible t and tl
  938. {
  939. return partialHide->ourImages[1].bitmap;
  940. }
  941. else if(d2 && !d6 && !d4 && !d8 && !d7 && d3 && !d9 && !d1) //visible b and br
  942. {
  943. return partialHide->ourImages[4].bitmap;
  944. }
  945. else if(d2 && !d6 && !d4 && !d8 && !d7 && !d3 && !d9 && d1) //visible b and bl
  946. {
  947. return partialHide->ourImages[5].bitmap;
  948. }
  949. else if(!d2 && !d6 && d4 && !d8 && d7 && !d3 && !d9 && !d1) //visible l and tl
  950. {
  951. return partialHide->ourImages[36].bitmap;
  952. }
  953. else if(!d2 && !d6 && d4 && !d8 && !d7 && !d3 && !d9 && d1) //visible l and bl
  954. {
  955. return partialHide->ourImages[36].bitmap;
  956. }
  957. else if(!d2 && d6 && !d4 && !d8 && !d7 && !d3 && d9 && !d1) //visible r and tr
  958. {
  959. return partialHide->ourImages[2].bitmap;
  960. }
  961. else if(!d2 && d6 && !d4 && !d8 && !d7 && d3 && !d9 && !d1) //visible r and br
  962. {
  963. return partialHide->ourImages[3].bitmap;
  964. }
  965. return fullHide->ourImages[0].bitmap; //this case should never happen, but it is better to hide too much than reveal it....
  966. }
  967. bool CMapHandler::printObject(const CGObjectInstance *obj)
  968. {
  969. if(!obj->defInfo->handler)
  970. processDef(obj->defInfo);
  971. const SDL_Surface *bitmap = obj->defInfo->handler->ourImages[0].bitmap;
  972. int tilesW = bitmap->w/32,
  973. tilesH = bitmap->h/32;
  974. for(int fx=0; fx<bitmap->w/32; ++fx)
  975. {
  976. for(int fy=0; fy<bitmap->h/32; ++fy)
  977. {
  978. SDL_Rect cr;
  979. cr.w = 32;
  980. cr.h = 32;
  981. cr.x = fx*32;
  982. cr.y = fy*32;
  983. std::pair<const CGObjectInstance*,SDL_Rect> toAdd = std::make_pair(obj, cr);
  984. 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)
  985. {
  986. TerrainTile2 & curt = ttiles[obj->pos.x + fx - bitmap->w/32+1][obj->pos.y + fy - bitmap->h/32+1][obj->pos.z];
  987. std::vector< std::pair<const CGObjectInstance*,SDL_Rect> >::iterator i = curt.objects.begin();
  988. for(; i != curt.objects.end(); i++)
  989. {
  990. OCM_HLP cmp;
  991. if(cmp(toAdd, *i))
  992. {
  993. curt.objects.insert(i, toAdd);
  994. i = curt.objects.begin(); //to validate and avoid adding it second time
  995. break;
  996. }
  997. }
  998. if(i == curt.objects.end())
  999. curt.objects.insert(i, toAdd);
  1000. }
  1001. } // for(int fy=0; fy<bitmap->h/32; ++fy)
  1002. } //for(int fx=0; fx<bitmap->w/32; ++fx)
  1003. return true;
  1004. }
  1005. bool CMapHandler::hideObject(const CGObjectInstance *obj)
  1006. {
  1007. CDefEssential * curd = obj->defInfo->handler;
  1008. if(!curd) return false;
  1009. const SDL_Surface *bitmap = curd->ourImages[0].bitmap;
  1010. for(int fx=0; fx<bitmap->w/32; ++fx)
  1011. {
  1012. for(int fy=0; fy<bitmap->h/32; ++fy)
  1013. {
  1014. 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)
  1015. {
  1016. 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;
  1017. for(size_t dd=0; dd < ctile.size(); ++dd)
  1018. {
  1019. if(ctile[dd].first->id==obj->id)
  1020. ctile.erase(ctile.begin() + dd);
  1021. }
  1022. }
  1023. } // for(int fy=0; fy<bitmap->h/32; ++fy)
  1024. } //for(int fx=0; fx<bitmap->w/32; ++fx)
  1025. return true;
  1026. }
  1027. bool CMapHandler::removeObject(CGObjectInstance *obj)
  1028. {
  1029. hideObject(obj);
  1030. return true;
  1031. }
  1032. unsigned char CMapHandler::getHeroFrameNum(unsigned char dir, bool isMoving) const
  1033. {
  1034. if(isMoving)
  1035. {
  1036. static const unsigned char frame [] = {-1, 10, 5, 6, 7, 8, 9, 12, 11};
  1037. return frame[dir];
  1038. /*switch(dir)
  1039. {
  1040. case 1:
  1041. return 10;
  1042. case 2:
  1043. return 5;
  1044. case 3:
  1045. return 6;
  1046. case 4:
  1047. return 7;
  1048. case 5:
  1049. return 8;
  1050. case 6:
  1051. return 9;
  1052. case 7:
  1053. return 12;
  1054. case 8:
  1055. return 11;
  1056. default:
  1057. throw std::string("Something very wrong1.");
  1058. }*/
  1059. }
  1060. else //if(isMoving)
  1061. {
  1062. static const unsigned char frame [] = {-1, 13, 0, 1, 2, 3, 4, 15, 14};
  1063. return frame[dir];
  1064. /*switch(dir)
  1065. {
  1066. case 1:
  1067. return 13;
  1068. case 2:
  1069. return 0;
  1070. case 3:
  1071. return 1;
  1072. case 4:
  1073. return 2;
  1074. case 5:
  1075. return 3;
  1076. case 6:
  1077. return 4;
  1078. case 7:
  1079. return 15;
  1080. case 8:
  1081. return 14;
  1082. default:
  1083. throw std::string("Something very wrong2.");
  1084. }*/
  1085. }
  1086. }
  1087. void CMapHandler::validateRectTerr(SDL_Rect * val, const SDL_Rect * ext)
  1088. {
  1089. if(ext)
  1090. {
  1091. if(val->x<0)
  1092. {
  1093. val->w += val->x;
  1094. val->x = ext->x;
  1095. }
  1096. else
  1097. {
  1098. val->x += ext->x;
  1099. }
  1100. if(val->y<0)
  1101. {
  1102. val->h += val->y;
  1103. val->y = ext->y;
  1104. }
  1105. else
  1106. {
  1107. val->y += ext->y;
  1108. }
  1109. if(val->x+val->w > ext->x+ext->w)
  1110. {
  1111. val->w = ext->x+ext->w-val->x;
  1112. }
  1113. if(val->y+val->h > ext->y+ext->h)
  1114. {
  1115. val->h = ext->y+ext->h-val->y;
  1116. }
  1117. //for sign problems
  1118. if(val->h > 20000 || val->w > 20000)
  1119. {
  1120. val->h = val->w = 0;
  1121. }
  1122. }
  1123. }
  1124. unsigned char CMapHandler::getDir(const int3 &a, const int3 &b)
  1125. {
  1126. if(a.z!=b.z)
  1127. return -1; //error!
  1128. if(a.x==b.x+1 && a.y==b.y+1) //lt
  1129. return 0;
  1130. else if(a.x==b.x && a.y==b.y+1) //t
  1131. return 1;
  1132. else if(a.x==b.x-1 && a.y==b.y+1) //rt
  1133. return 2;
  1134. else if(a.x==b.x-1 && a.y==b.y) //r
  1135. return 3;
  1136. else if(a.x==b.x-1 && a.y==b.y-1) //rb
  1137. return 4;
  1138. else if(a.x==b.x && a.y==b.y-1) //b
  1139. return 5;
  1140. else if(a.x==b.x+1 && a.y==b.y-1) //lb
  1141. return 6;
  1142. else if(a.x==b.x+1 && a.y==b.y) //l
  1143. return 7;
  1144. return -2; //shouldn't happen
  1145. }
  1146. void shiftColors(SDL_Surface *img, int from, int howMany) //shifts colors in palette
  1147. {
  1148. //works with at most 16 colors, if needed more -> increase values
  1149. assert(howMany < 16);
  1150. SDL_Color palette[16];
  1151. for(int i=0; i<howMany; ++i)
  1152. {
  1153. palette[(i+1)%howMany] =img->format->palette->colors[from + i];
  1154. }
  1155. SDL_SetColors(img,palette,from,howMany);
  1156. }
  1157. void CMapHandler::updateWater() //shift colors in palettes of water tiles
  1158. {
  1159. for(size_t j=0; j < terrainGraphics[7].size(); ++j)
  1160. {
  1161. shiftColors(terrainGraphics[7][j],246, 9);
  1162. }
  1163. for(size_t j=0; j < terrainGraphics[8].size(); ++j)
  1164. {
  1165. shiftColors(terrainGraphics[8][j],229, 12);
  1166. shiftColors(terrainGraphics[8][j],242, 14);
  1167. }
  1168. for(size_t j=0; j < staticRiverDefs[0]->ourImages.size(); ++j)
  1169. {
  1170. shiftColors(staticRiverDefs[0]->ourImages[j].bitmap,183, 12);
  1171. shiftColors(staticRiverDefs[0]->ourImages[j].bitmap,195, 6);
  1172. }
  1173. for(size_t j=0; j < staticRiverDefs[2]->ourImages.size(); ++j)
  1174. {
  1175. shiftColors(staticRiverDefs[2]->ourImages[j].bitmap,228, 12);
  1176. shiftColors(staticRiverDefs[2]->ourImages[j].bitmap,183, 6);
  1177. shiftColors(staticRiverDefs[2]->ourImages[j].bitmap,240, 6);
  1178. }
  1179. for(size_t j=0; j < staticRiverDefs[3]->ourImages.size(); ++j)
  1180. {
  1181. shiftColors(staticRiverDefs[3]->ourImages[j].bitmap,240, 9);
  1182. }
  1183. }
  1184. CMapHandler::~CMapHandler()
  1185. {
  1186. delete fullHide;
  1187. delete partialHide;
  1188. for(int i=0; i < roadDefs.size(); i++)
  1189. delete roadDefs[i];
  1190. for(int i=0; i < staticRiverDefs.size(); i++)
  1191. delete staticRiverDefs[i];
  1192. //TODO: why this code makes VCMI crash?
  1193. /*for(int i=0; i < terrainGraphics.size(); ++i)
  1194. {
  1195. for(int j=0; j < terrainGraphics[i].size(); ++j)
  1196. SDL_FreeSurface(terrainGraphics[i][j]);
  1197. }
  1198. terrainGraphics.clear();*/
  1199. }
  1200. CMapHandler::CMapHandler()
  1201. {
  1202. mapW = mapH = 0;
  1203. frameW = frameH = 0;
  1204. fullHide = NULL;
  1205. partialHide = NULL;
  1206. }
  1207. void CMapHandler::getTerrainDescr( const int3 &pos, std::string & out, bool terName )
  1208. {
  1209. out.clear();
  1210. TerrainTile2 &t = ttiles[pos.x][pos.y][pos.z];
  1211. for(std::vector < std::pair<const CGObjectInstance*,SDL_Rect> >::const_iterator i = t.objects.begin(); i != t.objects.end(); i++)
  1212. {
  1213. if(i->first->ID == 124)
  1214. {
  1215. out = i->first->hoverName;
  1216. return;
  1217. }
  1218. }
  1219. if(terName)
  1220. out = CGI->generaltexth->terrainNames[t.tileInfo->tertype];
  1221. }
  1222. TerrainTile2::TerrainTile2()
  1223. :tileInfo(0),terbitmap(0)
  1224. {}