map.cpp 62 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468
  1. #define VCMI_DLL
  2. #include "stdafx.h"
  3. #include "map.h"
  4. #include "hch/CObjectHandler.h"
  5. #include "hch/CDefObjInfoHandler.h"
  6. #include "lib/VCMI_Lib.h"
  7. #include <zlib.h>
  8. #include <boost/crc.hpp>
  9. std::set<si32> convertBuildings(const std::set<si32> h3m, int castleID)
  10. {
  11. std::map<int,int> mapa;
  12. std::set<si32> ret;
  13. std::ifstream b5("config/buildings5.txt");
  14. while(!b5.eof())
  15. {
  16. int a, b;
  17. b5 >> a >> b;
  18. if(castleID==8 && b==17) //magic university ID 17 (h3m) => 21 (vcmi)
  19. b=21;
  20. mapa[a]=b;
  21. }
  22. for(std::set<si32>::const_iterator i=h3m.begin();i!=h3m.end();i++)
  23. {
  24. if(mapa[*i]>=0)
  25. ret.insert(mapa[*i]);
  26. else if(mapa[*i] >= (-CREATURES_PER_TOWN)) // horde buildings
  27. {
  28. int level = (-mapa[*i]);
  29. if(h3m.find(20+(level*3)) != h3m.end()) //upgraded creature horde building
  30. {
  31. if(((castleID==1) || (castleID==3)) && ((level==3) || (level==5)))
  32. ret.insert(25);
  33. else
  34. ret.insert(19);
  35. }
  36. else
  37. {
  38. if(((castleID==1) || (castleID==3)) && ((level==3) || (level==5)))
  39. ret.insert(24);
  40. else
  41. ret.insert(18);
  42. }
  43. }
  44. else
  45. {
  46. std::cout<<"Conversion warning: unknown building "<<*i<<" in castle "<<castleID<<std::endl;
  47. }
  48. }
  49. ret.insert(10); //village hall is always present
  50. ret.insert(-1); //houses near v.hall / eyecandies
  51. ret.insert(-2); //terrain eyecandy, if -1 is used
  52. if(ret.find(11)!=ret.end())
  53. ret.insert(27);
  54. if(ret.find(12)!=ret.end())
  55. ret.insert(28);
  56. if(ret.find(13)!=ret.end())
  57. ret.insert(29);
  58. return ret;
  59. }
  60. unsigned int intPow(unsigned int a, unsigned int b)
  61. {
  62. unsigned int ret=1;
  63. for(int i=0; i<b; ++i)
  64. ret*=a;
  65. return ret;
  66. }
  67. unsigned char reverse(unsigned char arg)
  68. {
  69. unsigned char ret = 0;
  70. for (int i=0; i<8;i++)
  71. {
  72. if(((arg)&(1<<i))>>i)
  73. {
  74. ret |= (128>>i);
  75. }
  76. }
  77. return ret;
  78. }
  79. EDefType getDefType(CGDefInfo * a)
  80. {
  81. switch(a->id)
  82. {
  83. case 5: case 65: case 66: case 67: case 68: case 69:
  84. return ARTIFACT_DEF; //handled
  85. case 6:
  86. return PANDORA_DEF; //hanled
  87. case 26:
  88. return EVENTOBJ_DEF; //handled
  89. case 33:
  90. return GARRISON_DEF; //handled
  91. case 34: case 70: case 62: //70 - random hero //62 - prison
  92. return HERO_DEF; //handled
  93. case 36:
  94. return GRAIL_DEF; //hanled
  95. case 53: case 17: case 18: case 19: case 20: case 42: case 87: case 220://cases 17 - 20 and 42 - tests
  96. return PLAYERONLY_DEF; //handled
  97. case 54: case 71: case 72: case 73: case 74: case 75: case 162: case 163: case 164:
  98. return CREATURES_DEF; //handled
  99. case 59:
  100. return SIGN_DEF; //handled
  101. case 77:
  102. return TOWN_DEF; //can be problematic, but handled
  103. case 79: case 76:
  104. return RESOURCE_DEF; //handled
  105. case 81:
  106. return SCHOLAR_DEF; //handled
  107. case 83:
  108. return SEERHUT_DEF; //handled
  109. case 91:
  110. return SIGN_DEF; //handled
  111. case 88: case 89: case 90:
  112. return SHRINE_DEF; //handled
  113. case 93:
  114. return SPELLSCROLL_DEF; //handled
  115. case 98:
  116. return TOWN_DEF; //handled
  117. case 113:
  118. return WITCHHUT_DEF; //handled
  119. case 214:
  120. return HEROPLACEHOLDER_DEF; //partially handled
  121. case 215:
  122. return BORDERGUARD_DEF; //handled by analogy to seer huts ;]
  123. case 216:
  124. return CREGEN2_DEF; //handled
  125. case 217:
  126. return CREGEN_DEF; //handled
  127. case 218:
  128. return CREGEN3_DEF; //handled
  129. case 219:
  130. return GARRISON_DEF; //handled
  131. default:
  132. return TERRAINOBJ_DEF; // nothing to be handled
  133. }
  134. }
  135. int readNormalNr (unsigned char * bufor, int pos, int bytCon = 4, bool cyclic = false)
  136. {
  137. int ret=0;
  138. int amp=1;
  139. for (int ir=0; ir<bytCon; ir++)
  140. {
  141. ret+=bufor[pos+ir]*amp;
  142. amp*=256;
  143. }
  144. if(cyclic && bytCon<4 && ret>=amp/2)
  145. {
  146. ret = ret-amp;
  147. }
  148. return ret;
  149. }
  150. char readChar(unsigned char * bufor, int &i)
  151. {
  152. return bufor[i++];
  153. }
  154. std::string readString(unsigned char * bufor, int &i)
  155. {
  156. int len = readNormalNr(bufor,i); i+=4;
  157. std::string ret; ret.reserve(len);
  158. for(int gg=0; gg<len; ++gg)
  159. {
  160. ret += bufor[i++];
  161. }
  162. return ret;
  163. }
  164. CCreatureSet readCreatureSet(unsigned char * bufor, int &i, int number, bool version) //version==true for >RoE maps
  165. {
  166. if(version)
  167. {
  168. CCreatureSet ret;
  169. std::pair<ui32,si32> ins;
  170. for(int ir=0;ir<number;ir++)
  171. {
  172. int rettt = readNormalNr(bufor,i+ir*4, 2);
  173. if(rettt==0xffff) continue;
  174. if(rettt>32768)
  175. rettt = 65536-rettt+VLC->creh->creatures.size()-16;
  176. ins.first = rettt;
  177. ins.second = readNormalNr(bufor,i+ir*4+2, 2);
  178. std::pair<si32,std::pair<ui32,si32> > tt(ir,ins);
  179. ret.slots.insert(tt);
  180. }
  181. i+=number*4;
  182. return ret;
  183. }
  184. else
  185. {
  186. CCreatureSet ret;
  187. std::pair<ui32,si32> ins;
  188. for(int ir=0;ir<number;ir++)
  189. {
  190. int rettt = readNormalNr(bufor,i+ir*3, 1);
  191. if(rettt==0xff) continue;
  192. if(rettt>220)
  193. rettt = 256-rettt+VLC->creh->creatures.size()-16;
  194. ins.first = rettt;
  195. ins.second = readNormalNr(bufor,i+ir*3+1, 2);
  196. std::pair<si32,std::pair<ui32,si32> > tt(ir,ins);
  197. ret.slots.insert(tt);
  198. }
  199. i+=number*3;
  200. return ret;
  201. }
  202. }
  203. CMapHeader::CMapHeader(unsigned char *map)
  204. {
  205. this->version = (Eformat)map[0]; //wersja mapy
  206. this->areAnyPLayers = map[4]; //seems to be invalid
  207. this->height = this->width = map[5]; // wymiary mapy
  208. this->twoLevel = map[9]; //czy sa lochy
  209. int length = map[10]; //name length
  210. int i=14, pom;
  211. while (i-14<length) //read name
  212. this->name+=map[i++];
  213. length = map[i] + map[i+1]*256; //description length
  214. i+=4;
  215. for (pom=0;pom<length;pom++)
  216. this->description+=map[i++];
  217. this->difficulty = map[i++]; // reading map difficulty
  218. if(version!=RoE)
  219. {
  220. this->levelLimit = map[i++]; // hero level limit
  221. }
  222. else
  223. {
  224. levelLimit = 0;
  225. }
  226. for (pom=0;pom<8;pom++)
  227. {
  228. this->players[pom].canHumanPlay = map[i++];
  229. this->players[pom].canComputerPlay = map[i++];
  230. if ((!(this->players[pom].canHumanPlay || this->players[pom].canComputerPlay)))
  231. {
  232. switch(version)
  233. {
  234. case SoD: case WoG:
  235. i+=13;
  236. break;
  237. case AB:
  238. i+=12;
  239. break;
  240. case RoE:
  241. i+=6;
  242. break;
  243. }
  244. continue;
  245. }
  246. this->players[pom].AITactic = map[i++];
  247. if(version == SoD || version == WoG)
  248. i++;
  249. this->players[pom].allowedFactions = 0;
  250. this->players[pom].allowedFactions += map[i++];
  251. if(version != RoE)
  252. this->players[pom].allowedFactions += (map[i++])*256;
  253. this->players[pom].isFactionRandom = map[i++];
  254. this->players[pom].hasMainTown = map[i++];
  255. if (this->players[pom].hasMainTown)
  256. {
  257. if(version != RoE)
  258. {
  259. this->players[pom].generateHeroAtMainTown = map[i++];
  260. this->players[pom].generateHero = map[i++];
  261. }
  262. this->players[pom].posOfMainTown.x = map[i++];
  263. this->players[pom].posOfMainTown.y = map[i++];
  264. this->players[pom].posOfMainTown.z = map[i++];
  265. }
  266. players[pom].p8= map[i++];
  267. players[pom].p9= map[i++];
  268. if(players[pom].p9!=0xff)
  269. {
  270. players[pom].mainHeroPortrait = map[i++];
  271. int nameLength = map[i++];
  272. i+=3;
  273. for (int pp=0;pp<nameLength;pp++)
  274. players[pom].mainHeroName+=map[i++];
  275. }
  276. if(version!=RoE)
  277. {
  278. i++; ////heroes placeholders //domostwa
  279. int heroCount = map[i++];
  280. i+=3;
  281. for (int pp=0;pp<heroCount;pp++)
  282. {
  283. SheroName vv;
  284. vv.heroID=map[i++];
  285. int hnl = map[i++];
  286. i+=3;
  287. for (int zz=0;zz<hnl;zz++)
  288. {
  289. vv.heroName+=map[i++];
  290. }
  291. this->players[pom].heroesNames.push_back(vv);
  292. }
  293. }
  294. }
  295. this->victoryCondition = (EvictoryConditions)map[i++];
  296. if (this->victoryCondition != winStandard) //specific victory conditions
  297. {
  298. int nr;
  299. switch (this->victoryCondition) //read victory conditions
  300. {
  301. case artifact:
  302. {
  303. this->vicConDetails = new VicCon0();
  304. ((VicCon0*)this->vicConDetails)->ArtifactID = map[i+2];
  305. nr=(version==RoE ? 1 : 2);
  306. break;
  307. }
  308. case gatherTroop:
  309. {
  310. this->vicConDetails = new VicCon1();
  311. int temp1 = map[i+2];
  312. int temp2 = map[i+3];
  313. ((VicCon1*)this->vicConDetails)->monsterID = map[i+2];
  314. ((VicCon1*)this->vicConDetails)->neededQuantity=readNormalNr(map, i+(version==RoE ? 3 : 4));
  315. nr=(version==RoE ? 5 : 6);
  316. break;
  317. }
  318. case gatherResource:
  319. {
  320. this->vicConDetails = new VicCon2();
  321. ((VicCon2*)this->vicConDetails)->resourceID = map[i+2];
  322. ((VicCon2*)this->vicConDetails)->neededQuantity=readNormalNr(map, i+3);
  323. nr=5;
  324. break;
  325. }
  326. case buildCity:
  327. {
  328. this->vicConDetails = new VicCon3();
  329. ((VicCon3*)this->vicConDetails)->posOfCity.x = map[i+2];
  330. ((VicCon3*)this->vicConDetails)->posOfCity.y = map[i+3];
  331. ((VicCon3*)this->vicConDetails)->posOfCity.z = map[i+4];
  332. ((VicCon3*)this->vicConDetails)->councilNeededLevel = map[i+5];
  333. ((VicCon3*)this->vicConDetails)->fortNeededLevel = map[i+6];
  334. nr=5;
  335. break;
  336. }
  337. case buildGrail:
  338. {
  339. this->vicConDetails = new VicCon4();
  340. if (map[i+4]>2)
  341. ((VicCon4*)this->vicConDetails)->anyLocation = true;
  342. else
  343. {
  344. ((VicCon4*)this->vicConDetails)->whereBuildGrail.x = map[i+2];
  345. ((VicCon4*)this->vicConDetails)->whereBuildGrail.y = map[i+3];
  346. ((VicCon4*)this->vicConDetails)->whereBuildGrail.z = map[i+4];
  347. }
  348. nr=3;
  349. break;
  350. }
  351. case beatHero:
  352. {
  353. this->vicConDetails = new VicCon5();
  354. ((VicCon5*)this->vicConDetails)->locationOfHero.x = map[i+2];
  355. ((VicCon5*)this->vicConDetails)->locationOfHero.y = map[i+3];
  356. ((VicCon5*)this->vicConDetails)->locationOfHero.z = map[i+4];
  357. nr=3;
  358. break;
  359. }
  360. case captureCity:
  361. {
  362. this->vicConDetails = new VicCon6();
  363. ((VicCon6*)this->vicConDetails)->locationOfTown.x = map[i+2];
  364. ((VicCon6*)this->vicConDetails)->locationOfTown.y = map[i+3];
  365. ((VicCon6*)this->vicConDetails)->locationOfTown.z = map[i+4];
  366. nr=3;
  367. break;
  368. }
  369. case beatMonster:
  370. {
  371. this->vicConDetails = new VicCon7();
  372. ((VicCon7*)this->vicConDetails)->locationOfMonster.x = map[i+2];
  373. ((VicCon7*)this->vicConDetails)->locationOfMonster.y = map[i+3];
  374. ((VicCon7*)this->vicConDetails)->locationOfMonster.z = map[i+4];
  375. nr=3;
  376. break;
  377. }
  378. case takeDwellings:
  379. {
  380. this->vicConDetails = new CspecificVictoryConidtions();
  381. nr=3;
  382. break;
  383. }
  384. case takeMines:
  385. {
  386. this->vicConDetails = new CspecificVictoryConidtions();
  387. nr=3;
  388. break;
  389. }
  390. case transportItem:
  391. {
  392. this->vicConDetails = new VicCona();
  393. ((VicCona*)this->vicConDetails)->artifactID = map[i+2];
  394. ((VicCona*)this->vicConDetails)->destinationPlace.x = map[i+3];
  395. ((VicCona*)this->vicConDetails)->destinationPlace.y = map[i+4];
  396. ((VicCona*)this->vicConDetails)->destinationPlace.z = map[i+5];
  397. nr=4;
  398. break;
  399. }
  400. }
  401. this->vicConDetails->allowNormalVictory = map[i++];
  402. this->vicConDetails->appliesToAI = map[i++];
  403. i+=nr;
  404. }
  405. this->lossCondition.typeOfLossCon = (ElossCon)map[i++];
  406. switch (this->lossCondition.typeOfLossCon) //read loss conditions
  407. {
  408. case lossCastle:
  409. {
  410. this->lossCondition.castlePos.x=map[i++];
  411. this->lossCondition.castlePos.y=map[i++];
  412. this->lossCondition.castlePos.z=map[i++];
  413. }
  414. case lossHero:
  415. {
  416. this->lossCondition.heroPos.x=map[i++];
  417. this->lossCondition.heroPos.y=map[i++];
  418. this->lossCondition.heroPos.z=map[i++];
  419. }
  420. case timeExpires:
  421. {
  422. this->lossCondition.timeLimit = readNormalNr(map, i++,2);
  423. i++;
  424. }
  425. }
  426. this->howManyTeams=map[i++]; //read number of teams
  427. if(this->howManyTeams>0) //read team numbers
  428. {
  429. for(int rr=0; rr<8; ++rr)
  430. {
  431. this->players[rr].team=map[i++];
  432. }
  433. }
  434. }
  435. void Mapa::initFromBytes(unsigned char * bufor)
  436. {
  437. timeHandler th;
  438. th.getDif();
  439. int i=0;
  440. readHeader(bufor, i);
  441. _log0<<"\tReading header: "<<th.getDif()<<std::endl;
  442. readRumors(bufor, i);
  443. _log0<<"\tReading rumors: "<<th.getDif()<<std::endl;
  444. readPredefinedHeroes(bufor, i);
  445. _log0<<"\tReading predefined heroes: "<<th.getDif()<<std::endl;
  446. readTerrain(bufor, i);
  447. _log0<<"\tReading terrain: "<<th.getDif()<<std::endl;
  448. readDefInfo(bufor, i);
  449. _log0<<"\tReading defs info: "<<th.getDif()<<std::endl;
  450. readObjects(bufor, i);
  451. _log0<<"\tReading objects: "<<th.getDif()<<std::endl;
  452. readEvents(bufor, i);
  453. _log0<<"\tReading events: "<<th.getDif()<<std::endl;
  454. //map readed, bufor no longer needed
  455. delete[] bufor; bufor=NULL;
  456. for(int f=0; f<objects.size(); ++f) //calculationg blocked / visitable positions
  457. {
  458. if(!objects[f]->defInfo)
  459. continue;
  460. addBlockVisTiles(objects[f]);
  461. }
  462. _log0<<"\tCalculating blocked/visitable tiles: "<<th.getDif()<<std::endl;
  463. }
  464. void Mapa::removeBlockVisTiles(CGObjectInstance * obj)
  465. {
  466. for(int fx=0; fx<8; ++fx)
  467. {
  468. for(int fy=0; fy<6; ++fy)
  469. {
  470. int xVal = obj->pos.x + fx - 7;
  471. int yVal = obj->pos.y + fy - 5;
  472. int zVal = obj->pos.z;
  473. if(xVal>=0 && xVal<width && yVal>=0 && yVal<height)
  474. {
  475. TerrainTile & curt = terrain[xVal][yVal][zVal];
  476. if(((obj->defInfo->visitMap[fy] >> (7 - fx)) & 1))
  477. {
  478. curt.visitableObjects -= obj;
  479. curt.visitable = curt.visitableObjects.size();
  480. }
  481. if(!((obj->defInfo->blockMap[fy] >> (7 - fx)) & 1))
  482. {
  483. curt.blockingObjects -= obj;
  484. curt.blocked = curt.visitableObjects.size();
  485. }
  486. }
  487. }
  488. }
  489. }
  490. void Mapa::addBlockVisTiles(CGObjectInstance * obj)
  491. {
  492. for(int fx=0; fx<8; ++fx)
  493. {
  494. for(int fy=0; fy<6; ++fy)
  495. {
  496. int xVal = obj->pos.x + fx - 7;
  497. int yVal = obj->pos.y + fy - 5;
  498. int zVal = obj->pos.z;
  499. if(xVal>=0 && xVal<width && yVal>=0 && yVal<height)
  500. {
  501. TerrainTile & curt = terrain[xVal][yVal][zVal];
  502. if(((obj->defInfo->visitMap[fy] >> (7 - fx)) & 1))
  503. {
  504. curt.visitableObjects.push_back(obj);
  505. curt.visitable = true;
  506. }
  507. if(!((obj->defInfo->blockMap[fy] >> (7 - fx)) & 1))
  508. {
  509. curt.blockingObjects.push_back(obj);
  510. curt.blocked = true;
  511. }
  512. }
  513. }
  514. }
  515. }
  516. Mapa::Mapa(std::string filename)
  517. {
  518. _log0<<"Opening map file: "<<filename<<"\t "<<std::flush;
  519. gzFile map = gzopen(filename.c_str(),"rb");
  520. std::vector<unsigned char> mapstr; int pom;
  521. while((pom=gzgetc(map))>=0)
  522. {
  523. mapstr.push_back(pom);
  524. }
  525. gzclose(map);
  526. unsigned char *initTable = new unsigned char[mapstr.size()];
  527. for(int ss=0; ss<mapstr.size(); ++ss)
  528. {
  529. initTable[ss] = mapstr[ss];
  530. }
  531. _log0<<"done."<<std::endl;
  532. boost::crc_32_type result;
  533. result.process_bytes(initTable,mapstr.size());
  534. checksum = result.checksum();
  535. _log0 << "\tOur map checksum: "<<result.checksum() << std::endl;
  536. initFromBytes(initTable);
  537. }
  538. CGHeroInstance * Mapa::getHero(int ID, int mode)
  539. {
  540. if (mode != 0)
  541. #ifndef __GNUC__
  542. throw new std::exception("gs->getHero: This mode is not supported!");
  543. #else
  544. throw new std::exception();
  545. #endif
  546. for(int i=0; i<heroes.size();i++)
  547. if(heroes[i]->subID == ID)
  548. return heroes[i];
  549. return NULL;
  550. }
  551. int Mapa::loadSeerHut( unsigned char * bufor, int i, CGObjectInstance * nobj )
  552. {
  553. CSeerHutObjInfo * spec = new CSeerHutObjInfo;
  554. if(version>RoE)
  555. {
  556. spec->missionType = bufor[i]; ++i;
  557. switch(spec->missionType)
  558. {
  559. case 0:
  560. i+=3;
  561. return i;
  562. case 1:
  563. {
  564. spec->m1level = readNormalNr(bufor,i); i+=4;
  565. int limit = readNormalNr(bufor,i); i+=4;
  566. if(limit == ((int)0xffffffff))
  567. {
  568. spec->isDayLimit = false;
  569. spec->lastDay = -1;
  570. }
  571. else
  572. {
  573. spec->isDayLimit = true;
  574. spec->lastDay = limit;
  575. }
  576. break;
  577. }
  578. case 2:
  579. {
  580. spec->m2attack = bufor[i]; ++i;
  581. spec->m2defence = bufor[i]; ++i;
  582. spec->m2power = bufor[i]; ++i;
  583. spec->m2knowledge = bufor[i]; ++i;
  584. int limit = readNormalNr(bufor,i); i+=4;
  585. if(limit == ((int)0xffffffff))
  586. {
  587. spec->isDayLimit = false;
  588. spec->lastDay = -1;
  589. }
  590. else
  591. {
  592. spec->isDayLimit = true;
  593. spec->lastDay = limit;
  594. }
  595. break;
  596. }
  597. case 3:
  598. {
  599. spec->m3bytes[0] = bufor[i]; ++i;
  600. spec->m3bytes[1] = bufor[i]; ++i;
  601. spec->m3bytes[2] = bufor[i]; ++i;
  602. spec->m3bytes[3] = bufor[i]; ++i;
  603. int limit = readNormalNr(bufor,i); i+=4;
  604. if(limit == ((int)0xffffffff))
  605. {
  606. spec->isDayLimit = false;
  607. spec->lastDay = -1;
  608. }
  609. else
  610. {
  611. spec->isDayLimit = true;
  612. spec->lastDay = limit;
  613. }
  614. break;
  615. }
  616. case 4:
  617. {
  618. spec->m4bytes[0] = bufor[i]; ++i;
  619. spec->m4bytes[1] = bufor[i]; ++i;
  620. spec->m4bytes[2] = bufor[i]; ++i;
  621. spec->m4bytes[3] = bufor[i]; ++i;
  622. int limit = readNormalNr(bufor,i); i+=4;
  623. if(limit == ((int)0xffffffff))
  624. {
  625. spec->isDayLimit = false;
  626. spec->lastDay = -1;
  627. }
  628. else
  629. {
  630. spec->isDayLimit = true;
  631. spec->lastDay = limit;
  632. }
  633. break;
  634. }
  635. case 5:
  636. {
  637. int artNumber = bufor[i]; ++i;
  638. for(int yy=0; yy<artNumber; ++yy)
  639. {
  640. int artid = readNormalNr(bufor,i, 2); i+=2;
  641. spec->m5arts.push_back(artid);
  642. }
  643. int limit = readNormalNr(bufor,i); i+=4;
  644. if(limit == ((int)0xffffffff))
  645. {
  646. spec->isDayLimit = false;
  647. spec->lastDay = -1;
  648. }
  649. else
  650. {
  651. spec->isDayLimit = true;
  652. spec->lastDay = limit;
  653. }
  654. break;
  655. }
  656. case 6:
  657. {
  658. int typeNumber = bufor[i]; ++i;
  659. for(int hh=0; hh<typeNumber; ++hh)
  660. {
  661. int creType = readNormalNr(bufor,i, 2); i+=2;
  662. int creNumb = readNormalNr(bufor,i, 2); i+=2;
  663. spec->m6cre.push_back(&(VLC->creh->creatures[creType]));
  664. spec->m6number.push_back(creNumb);
  665. }
  666. int limit = readNormalNr(bufor,i); i+=4;
  667. if(limit == ((int)0xffffffff))
  668. {
  669. spec->isDayLimit = false;
  670. spec->lastDay = -1;
  671. }
  672. else
  673. {
  674. spec->isDayLimit = true;
  675. spec->lastDay = limit;
  676. }
  677. break;
  678. }
  679. case 7:
  680. {
  681. spec->m7wood = readNormalNr(bufor,i); i+=4;
  682. spec->m7mercury = readNormalNr(bufor,i); i+=4;
  683. spec->m7ore = readNormalNr(bufor,i); i+=4;
  684. spec->m7sulfur = readNormalNr(bufor,i); i+=4;
  685. spec->m7crystal = readNormalNr(bufor,i); i+=4;
  686. spec->m7gems = readNormalNr(bufor,i); i+=4;
  687. spec->m7gold = readNormalNr(bufor,i); i+=4;
  688. int limit = readNormalNr(bufor,i); i+=4;
  689. if(limit == ((int)0xffffffff))
  690. {
  691. spec->isDayLimit = false;
  692. spec->lastDay = -1;
  693. }
  694. else
  695. {
  696. spec->isDayLimit = true;
  697. spec->lastDay = limit;
  698. }
  699. break;
  700. }
  701. case 8:
  702. {
  703. int heroType = bufor[i]; ++i;
  704. spec->m8hero = heroType;
  705. int limit = readNormalNr(bufor,i); i+=4;
  706. if(limit == ((int)0xffffffff))
  707. {
  708. spec->isDayLimit = false;
  709. spec->lastDay = -1;
  710. }
  711. else
  712. {
  713. spec->isDayLimit = true;
  714. spec->lastDay = limit;
  715. }
  716. break;
  717. }
  718. case 9:
  719. {
  720. spec->m9player = bufor[i]; ++i;
  721. int limit = readNormalNr(bufor,i); i+=4;
  722. if(limit == ((int)0xffffffff))
  723. {
  724. spec->isDayLimit = false;
  725. spec->lastDay = -1;
  726. }
  727. else
  728. {
  729. spec->isDayLimit = true;
  730. spec->lastDay = limit;
  731. }
  732. break;
  733. }
  734. }//internal switch end (seer huts)
  735. int len1 = readNormalNr(bufor,i); i+=4;
  736. for(int ee=0; ee<len1; ++ee)
  737. {
  738. spec->firstVisitText += bufor[i]; ++i;
  739. }
  740. int len2 = readNormalNr(bufor,i); i+=4;
  741. for(int ee=0; ee<len2; ++ee)
  742. {
  743. spec->nextVisitText += bufor[i]; ++i;
  744. }
  745. int len3 = readNormalNr(bufor,i); i+=4;
  746. for(int ee=0; ee<len3; ++ee)
  747. {
  748. spec->completedText += bufor[i]; ++i;
  749. }
  750. }
  751. else //RoE
  752. {
  753. int artID = bufor[i]; ++i;
  754. if(artID!=255) //not none quest
  755. {
  756. spec->m5arts.push_back(artID);
  757. spec->missionType = 5;
  758. }
  759. else
  760. {
  761. spec->missionType = 255;
  762. }
  763. }
  764. if(spec->missionType!=255)
  765. {
  766. unsigned char rewardType = bufor[i]; ++i;
  767. spec->rewardType = rewardType;
  768. switch(rewardType)
  769. {
  770. case 1:
  771. {
  772. spec->r1exp = readNormalNr(bufor,i); i+=4;
  773. break;
  774. }
  775. case 2:
  776. {
  777. spec->r2mana = readNormalNr(bufor,i); i+=4;
  778. break;
  779. }
  780. case 3:
  781. {
  782. spec->r3morale = bufor[i]; ++i;
  783. break;
  784. }
  785. case 4:
  786. {
  787. spec->r4luck = bufor[i]; ++i;
  788. break;
  789. }
  790. case 5:
  791. {
  792. spec->r5type = bufor[i]; ++i;
  793. spec->r5amount = readNormalNr(bufor,i, 3); i+=3;
  794. i+=1;
  795. break;
  796. }
  797. case 6:
  798. {
  799. spec->r6type = bufor[i]; ++i;
  800. spec->r6amount = bufor[i]; ++i;
  801. break;
  802. }
  803. case 7:
  804. {
  805. spec->r7ability = bufor[i]; ++i;
  806. spec->r7level = bufor[i]; ++i;
  807. break;
  808. }
  809. case 8:
  810. {
  811. spec->r8art = readNormalNr(bufor,i, (version == RoE ? 1 : 2)); i+=(version == RoE ? 1 : 2);
  812. break;
  813. }
  814. case 9:
  815. {
  816. spec->r9spell = bufor[i]; ++i;
  817. break;
  818. }
  819. case 10:
  820. {
  821. if(version>RoE)
  822. {
  823. spec->r10creature = readNormalNr(bufor,i, 2); i+=2;
  824. spec->r10amount = readNormalNr(bufor,i, 2); i+=2;
  825. }
  826. else
  827. {
  828. spec->r10creature = bufor[i]; ++i;
  829. spec->r10amount = readNormalNr(bufor,i, 2); i+=2;
  830. }
  831. break;
  832. }
  833. }// end of internal switch
  834. i+=2;
  835. }
  836. else //missionType==255
  837. {
  838. i+=3;
  839. }
  840. nobj->info = spec;
  841. return i;
  842. }
  843. void Mapa::loadTown( CGObjectInstance * &nobj, unsigned char * bufor, int &i )
  844. {
  845. CGTownInstance * nt = new CGTownInstance();
  846. (*(static_cast<CGObjectInstance*>(nt))) = *nobj;
  847. delete nobj;
  848. nobj = nt;
  849. nt->identifier = 0;
  850. if(version>RoE)
  851. {
  852. readNormalNr(bufor,i); i+=4;
  853. }
  854. nt->tempOwner = bufor[i]; ++i;
  855. if(readChar(bufor,i)) //has name
  856. nt->name = readString(bufor,i);
  857. if(readChar(bufor,i))//true if garrison isn't empty
  858. nt->army = readCreatureSet(bufor,i,7,(version>RoE));
  859. nt->army.formation = bufor[i]; ++i;
  860. if(readChar(bufor,i)) //unusualBuildings
  861. {
  862. //built buildings
  863. for(int byte=0;byte<6;byte++)
  864. {
  865. for(int bit=0;bit<8;bit++)
  866. if(bufor[i] & (1<<bit))
  867. nt->builtBuildings.insert(byte*8+bit);
  868. i++;
  869. }
  870. //forbidden buildings
  871. for(int byte=6;byte<12;byte++)
  872. {
  873. for(int bit=0;bit<8;bit++)
  874. if(bufor[i] & (1<<bit))
  875. nt->forbiddenBuildings.insert((byte-6)*8+bit);
  876. i++;
  877. }
  878. nt->builtBuildings = convertBuildings(nt->builtBuildings,nt->subID);
  879. nt->forbiddenBuildings = convertBuildings(nt->forbiddenBuildings,nt->subID);
  880. }
  881. else //standard buildings
  882. {
  883. if(readChar(bufor,i)) //has fort
  884. nt->builtBuildings.insert(7);
  885. nt->builtBuildings.insert(-50); //means that set of standard building should be included
  886. }
  887. int ist = i;
  888. if(version>RoE)
  889. {
  890. for(i; i<ist+9; ++i)
  891. {
  892. unsigned char c = bufor[i];
  893. for(int yy=0; yy<8; ++yy)
  894. {
  895. if((i-ist)*8+yy < SPELLS_QUANTITY)
  896. {
  897. if(c == (c|((unsigned char)intPow(2, yy))))
  898. nt->obligatorySpells.push_back((i-ist)*8+yy);
  899. }
  900. }
  901. }
  902. }
  903. ist = i;
  904. for(i; i<ist+9; ++i)
  905. {
  906. unsigned char c = bufor[i];
  907. for(int yy=0; yy<8; ++yy)
  908. {
  909. if((i-ist)*8+yy < SPELLS_QUANTITY)
  910. {
  911. if(c != (c|((unsigned char)intPow(2, yy))))
  912. nt->possibleSpells.push_back((i-ist)*8+yy);
  913. }
  914. }
  915. }
  916. /////// reading castle events //////////////////////////////////
  917. int numberOfEvent = readNormalNr(bufor,i); i+=4;
  918. for(int gh = 0; gh<numberOfEvent; ++gh)
  919. {
  920. CCastleEvent nce;
  921. int nameLen = readNormalNr(bufor,i); i+=4;
  922. for(int ll=0; ll<nameLen; ++ll)
  923. {
  924. nce.name += bufor[i]; ++i;
  925. }
  926. int messLen = readNormalNr(bufor,i); i+=4;
  927. for(int ll=0; ll<messLen; ++ll)
  928. {
  929. nce.message += bufor[i]; ++i;
  930. }
  931. nce.wood = readNormalNr(bufor,i); i+=4;
  932. nce.mercury = readNormalNr(bufor,i); i+=4;
  933. nce.ore = readNormalNr(bufor,i); i+=4;
  934. nce.sulfur = readNormalNr(bufor,i); i+=4;
  935. nce.crystal = readNormalNr(bufor,i); i+=4;
  936. nce.gems = readNormalNr(bufor,i); i+=4;
  937. nce.gold = readNormalNr(bufor,i); i+=4;
  938. nce.players = bufor[i]; ++i;
  939. if(version > AB)
  940. {
  941. nce.forHuman = bufor[i]; ++i;
  942. }
  943. else
  944. nce.forHuman = true;
  945. nce.forComputer = bufor[i]; ++i;
  946. nce.firstShow = readNormalNr(bufor,i, 2); i+=2;
  947. nce.forEvery = bufor[i]; ++i;
  948. i+=17;
  949. for(int kk=0; kk<6; ++kk)
  950. {
  951. nce.bytes[kk] = bufor[i]; ++i;
  952. }
  953. for(int vv=0; vv<7; ++vv)
  954. {
  955. nce.gen[vv] = readNormalNr(bufor,i, 2); i+=2;
  956. }
  957. i+=4;
  958. nt->events.insert(nce);
  959. }//castle events have been read
  960. if(version > AB)
  961. {
  962. nt->alignment = bufor[i]; ++i;
  963. }
  964. else
  965. nt->alignment = 0xff;
  966. i+=3;
  967. nt->builded = 0;
  968. nt->destroyed = 0;
  969. nt->garrisonHero = NULL;
  970. if(nt->ID==98)
  971. towns.push_back(nt);
  972. }
  973. void Mapa::loadHero( CGObjectInstance * &nobj, unsigned char * bufor, int &i )
  974. {
  975. CGHeroInstance * nhi = new CGHeroInstance;
  976. (*(static_cast<CGObjectInstance*>(nhi))) = *nobj;
  977. delete nobj;
  978. nobj=nhi;
  979. if(version>RoE)
  980. {
  981. nhi->identifier = readNormalNr(bufor,i, 4); i+=4;
  982. }
  983. nhi->setOwner(bufor[i]); ++i;
  984. nhi->subID = readNormalNr(bufor,i, 1); ++i;
  985. if(readChar(bufor,i))//true if hero has nonstandard name
  986. nhi->name = readString(bufor,i);
  987. if(version>AB)
  988. {
  989. if(readChar(bufor,i))//true if hore's experience is greater than 0
  990. { nhi->exp = readNormalNr(bufor,i); i+=4; }
  991. else
  992. nhi->exp = -1;
  993. }
  994. else
  995. { nhi->exp = readNormalNr(bufor,i); i+=4; }
  996. bool portrait=bufor[i]; ++i;
  997. if (portrait)
  998. i++; //TODO read portrait nr, save, open
  999. else
  1000. nhi->portrait = nhi->subID;
  1001. if(readChar(bufor,i))//true if hero has specified abilities
  1002. {
  1003. int howMany = readNormalNr(bufor,i); i+=4;
  1004. nhi->secSkills.resize(howMany);
  1005. for(int yy=0; yy<howMany; ++yy)
  1006. {
  1007. nhi->secSkills[yy].first = readNormalNr(bufor,i, 1); ++i;
  1008. nhi->secSkills[yy].second = readNormalNr(bufor,i, 1); ++i;
  1009. }
  1010. }
  1011. if(readChar(bufor,i))//true if hero has nonstandard garrison
  1012. nhi->army = readCreatureSet(bufor,i,7,(version>RoE));
  1013. nhi->army.formation =bufor[i]; ++i; //formation
  1014. bool artSet = bufor[i]; ++i; //true if artifact set is not default (hero has some artifacts)
  1015. int artmask = version == RoE ? 0xff : 0xffff;
  1016. int artidlen = version == RoE ? 1 : 2;
  1017. if(artSet)
  1018. {
  1019. for(int pom=0;pom<16;pom++)
  1020. {
  1021. int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
  1022. if(id!=artmask)
  1023. nhi->artifWorn[pom] = id;
  1024. }
  1025. //misc5 art //17
  1026. if(version>=SoD)
  1027. {
  1028. int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
  1029. if(id!=artmask)
  1030. nhi->artifWorn[16] = id;
  1031. }
  1032. //spellbook
  1033. int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
  1034. if(id!=artmask)
  1035. nhi->artifWorn[17] = id;
  1036. //19 //???what is that? gap in file or what? - it's probably fifth slot..
  1037. if(version>RoE)
  1038. {
  1039. id = readNormalNr(bufor,i, artidlen); i+=artidlen;
  1040. if(id!=artmask)
  1041. nhi->artifWorn[18] = id;
  1042. }
  1043. else
  1044. i+=1;
  1045. //bag artifacts //20
  1046. int amount = readNormalNr(bufor,i, 2); i+=2; //number of artifacts in hero's bag
  1047. if(amount>0)
  1048. {
  1049. for(int ss=0; ss<amount; ++ss)
  1050. {
  1051. id = readNormalNr(bufor,i, artidlen); i+=artidlen;
  1052. if(id!=artmask)
  1053. nhi->artifacts.push_back(id);
  1054. }
  1055. }
  1056. } //artifacts
  1057. nhi->patrol.patrolRadious = readNormalNr(bufor,i, 1); ++i;
  1058. if(nhi->patrol.patrolRadious == 0xff)
  1059. nhi->patrol.patrolling = false;
  1060. else
  1061. nhi->patrol.patrolling = true;
  1062. if(version>RoE)
  1063. {
  1064. if(readChar(bufor,i))//true if hero has nonstandard (mapmaker defined) biography
  1065. nhi->biography = readString(bufor,i);
  1066. nhi->sex = !(bufor[i]); ++i;
  1067. }
  1068. //spells
  1069. if(version>AB)
  1070. {
  1071. bool areSpells = bufor[i]; ++i;
  1072. if(areSpells) //TODO: sprawdziæ //seems to be ok - tow
  1073. {
  1074. int ist = i;
  1075. for(i; i<ist+9; ++i)
  1076. {
  1077. unsigned char c = bufor[i];
  1078. for(int yy=0; yy<8; ++yy)
  1079. {
  1080. if((i-ist)*8+yy < SPELLS_QUANTITY)
  1081. {
  1082. if(c == (c|((unsigned char)intPow(2, yy))))
  1083. nhi->spells.insert((i-ist)*8+yy);
  1084. }
  1085. }
  1086. }
  1087. }
  1088. }
  1089. else if(version==AB) //we can read one spell
  1090. {
  1091. unsigned char buff = bufor[i]; ++i;
  1092. if(buff!=254)
  1093. {
  1094. nhi->spells.insert(buff);
  1095. }
  1096. }
  1097. //spells loaded
  1098. if(version>AB)
  1099. {
  1100. if(readChar(bufor,i))//customPrimSkills
  1101. {
  1102. nhi->primSkills.resize(4);
  1103. for(int xx=0;xx<4;xx++)
  1104. nhi->primSkills[xx] = bufor[i++];
  1105. }
  1106. }
  1107. i+=16;
  1108. nhi->moveDir = 4;
  1109. nhi->isStanding = true;
  1110. nhi->level = -1;
  1111. nhi->mana = -1;
  1112. nhi->movement = -1;
  1113. if(nhi->ID==34)
  1114. heroes.push_back(nhi);
  1115. }
  1116. void Mapa::loadPlayerInfo( int &pom, unsigned char * bufor, int &i )
  1117. {
  1118. for (pom=0;pom<8;pom++)
  1119. {
  1120. players[pom].canHumanPlay = bufor[i++];
  1121. players[pom].canComputerPlay = bufor[i++];
  1122. if ((!(players[pom].canHumanPlay || players[pom].canComputerPlay)))
  1123. {
  1124. memset(&players[pom],0,sizeof(PlayerInfo));
  1125. switch(version)
  1126. {
  1127. case SoD: case WoG:
  1128. i+=13;
  1129. break;
  1130. case AB:
  1131. i+=12;
  1132. break;
  1133. case RoE:
  1134. i+=6;
  1135. break;
  1136. }
  1137. continue;
  1138. }
  1139. players[pom].AITactic = bufor[i++];
  1140. if(version == SoD || version == WoG)
  1141. players[pom].p7= bufor[i++];
  1142. else
  1143. players[pom].p7= -1;
  1144. players[pom].allowedFactions = 0;
  1145. players[pom].allowedFactions += bufor[i++];
  1146. if(version != RoE)
  1147. players[pom].allowedFactions += (bufor[i++])*256;
  1148. players[pom].isFactionRandom = bufor[i++];
  1149. players[pom].hasMainTown = bufor[i++];
  1150. if (players[pom].hasMainTown)
  1151. {
  1152. if(version != RoE)
  1153. {
  1154. players[pom].generateHeroAtMainTown = bufor[i++];
  1155. players[pom].generateHero = bufor[i++];
  1156. }
  1157. else
  1158. {
  1159. players[pom].generateHeroAtMainTown = false;
  1160. players[pom].generateHero = false;
  1161. }
  1162. players[pom].posOfMainTown.x = bufor[i++];
  1163. players[pom].posOfMainTown.y = bufor[i++];
  1164. players[pom].posOfMainTown.z = bufor[i++];
  1165. }
  1166. players[pom].p8= bufor[i++];
  1167. players[pom].p9= bufor[i++];
  1168. if(players[pom].p9!=0xff)
  1169. {
  1170. players[pom].mainHeroPortrait = bufor[i++];
  1171. int nameLength = bufor[i++];
  1172. i+=3;
  1173. for (int pp=0;pp<nameLength;pp++)
  1174. players[pom].mainHeroName+=bufor[i++];
  1175. }
  1176. if(version != RoE)
  1177. {
  1178. i++; ////unknown byte
  1179. int heroCount = bufor[i++];
  1180. i+=3;
  1181. for (int pp=0;pp<heroCount;pp++)
  1182. {
  1183. SheroName vv;
  1184. vv.heroID=bufor[i++];
  1185. int hnl = bufor[i++];
  1186. i+=3;
  1187. for (int zz=0;zz<hnl;zz++)
  1188. {
  1189. vv.heroName+=bufor[i++];
  1190. }
  1191. players[pom].heroesNames.push_back(vv);
  1192. }
  1193. }
  1194. }
  1195. }
  1196. void Mapa::loadViCLossConditions( unsigned char * bufor, int &i)
  1197. {
  1198. victoryCondition = (EvictoryConditions)bufor[i++];
  1199. if (victoryCondition != winStandard) //specific victory conditions
  1200. {
  1201. int nr;
  1202. switch (victoryCondition) //read victory conditions
  1203. {
  1204. case artifact:
  1205. {
  1206. vicConDetails = new VicCon0();
  1207. ((VicCon0*)vicConDetails)->ArtifactID = bufor[i+2];
  1208. nr=(version==RoE ? 1 : 2);
  1209. break;
  1210. }
  1211. case gatherTroop:
  1212. {
  1213. vicConDetails = new VicCon1();
  1214. int temp1 = bufor[i+2];
  1215. int temp2 = bufor[i+3];
  1216. ((VicCon1*)vicConDetails)->monsterID = bufor[i+2];
  1217. ((VicCon1*)vicConDetails)->neededQuantity=readNormalNr(bufor,i+(version==RoE ? 3 : 4));
  1218. nr=(version==RoE ? 5 : 6);
  1219. break;
  1220. }
  1221. case gatherResource:
  1222. {
  1223. vicConDetails = new VicCon2();
  1224. ((VicCon2*)vicConDetails)->resourceID = bufor[i+2];
  1225. ((VicCon2*)vicConDetails)->neededQuantity=readNormalNr(bufor,i+3);
  1226. nr=5;
  1227. break;
  1228. }
  1229. case buildCity:
  1230. {
  1231. vicConDetails = new VicCon3();
  1232. ((VicCon3*)vicConDetails)->posOfCity.x = bufor[i+2];
  1233. ((VicCon3*)vicConDetails)->posOfCity.y = bufor[i+3];
  1234. ((VicCon3*)vicConDetails)->posOfCity.z = bufor[i+4];
  1235. ((VicCon3*)vicConDetails)->councilNeededLevel = bufor[i+5];
  1236. ((VicCon3*)vicConDetails)->fortNeededLevel = bufor[i+6];
  1237. nr=5;
  1238. break;
  1239. }
  1240. case buildGrail:
  1241. {
  1242. vicConDetails = new VicCon4();
  1243. if (bufor[i+4]>2)
  1244. ((VicCon4*)vicConDetails)->anyLocation = true;
  1245. else
  1246. {
  1247. ((VicCon4*)vicConDetails)->whereBuildGrail.x = bufor[i+2];
  1248. ((VicCon4*)vicConDetails)->whereBuildGrail.y = bufor[i+3];
  1249. ((VicCon4*)vicConDetails)->whereBuildGrail.z = bufor[i+4];
  1250. }
  1251. nr=3;
  1252. break;
  1253. }
  1254. case beatHero:
  1255. {
  1256. vicConDetails = new VicCon5();
  1257. ((VicCon5*)vicConDetails)->locationOfHero.x = bufor[i+2];
  1258. ((VicCon5*)vicConDetails)->locationOfHero.y = bufor[i+3];
  1259. ((VicCon5*)vicConDetails)->locationOfHero.z = bufor[i+4];
  1260. nr=3;
  1261. break;
  1262. }
  1263. case captureCity:
  1264. {
  1265. vicConDetails = new VicCon6();
  1266. ((VicCon6*)vicConDetails)->locationOfTown.x = bufor[i+2];
  1267. ((VicCon6*)vicConDetails)->locationOfTown.y = bufor[i+3];
  1268. ((VicCon6*)vicConDetails)->locationOfTown.z = bufor[i+4];
  1269. nr=3;
  1270. break;
  1271. }
  1272. case beatMonster:
  1273. {
  1274. vicConDetails = new VicCon7();
  1275. ((VicCon7*)vicConDetails)->locationOfMonster.x = bufor[i+2];
  1276. ((VicCon7*)vicConDetails)->locationOfMonster.y = bufor[i+3];
  1277. ((VicCon7*)vicConDetails)->locationOfMonster.z = bufor[i+4];
  1278. nr=3;
  1279. break;
  1280. }
  1281. case takeDwellings:
  1282. {
  1283. vicConDetails = new CspecificVictoryConidtions();
  1284. nr=0;
  1285. break;
  1286. }
  1287. case takeMines:
  1288. {
  1289. vicConDetails = new CspecificVictoryConidtions();
  1290. nr=0;
  1291. break;
  1292. }
  1293. case transportItem:
  1294. {
  1295. vicConDetails = new VicCona();
  1296. ((VicCona*)vicConDetails)->artifactID = bufor[i+2];
  1297. ((VicCona*)vicConDetails)->destinationPlace.x = bufor[i+3];
  1298. ((VicCona*)vicConDetails)->destinationPlace.y = bufor[i+4];
  1299. ((VicCona*)vicConDetails)->destinationPlace.z = bufor[i+5];
  1300. nr=4;
  1301. break;
  1302. }
  1303. }
  1304. vicConDetails->allowNormalVictory = bufor[i++];
  1305. vicConDetails->appliesToAI = bufor[i++];
  1306. i+=nr;
  1307. }
  1308. lossCondition.typeOfLossCon = (ElossCon)bufor[i++];
  1309. switch (lossCondition.typeOfLossCon) //read loss conditions
  1310. {
  1311. case lossCastle:
  1312. {
  1313. lossCondition.castlePos.x=bufor[i++];
  1314. lossCondition.castlePos.y=bufor[i++];
  1315. lossCondition.castlePos.z=bufor[i++];
  1316. break;
  1317. }
  1318. case lossHero:
  1319. {
  1320. lossCondition.heroPos.x=bufor[i++];
  1321. lossCondition.heroPos.y=bufor[i++];
  1322. lossCondition.heroPos.z=bufor[i++];
  1323. break;
  1324. }
  1325. case timeExpires:
  1326. {
  1327. lossCondition.timeLimit = readNormalNr(bufor,i++,2);
  1328. i++;
  1329. break;
  1330. }
  1331. }
  1332. }
  1333. void Mapa::readRumors( unsigned char * bufor, int &i)
  1334. {
  1335. int rumNr = readNormalNr(bufor,i,4);i+=4;
  1336. for (int it=0;it<rumNr;it++)
  1337. {
  1338. Rumor ourRumor;
  1339. int nameL = readNormalNr(bufor,i,4);i+=4; //read length of name of rumor
  1340. for (int zz=0; zz<nameL; zz++)
  1341. ourRumor.name+=bufor[i++];
  1342. nameL = readNormalNr(bufor,i,4);i+=4; //read length of rumor
  1343. for (int zz=0; zz<nameL; zz++)
  1344. ourRumor.text+=bufor[i++];
  1345. rumors.push_back(ourRumor); //add to our list
  1346. }
  1347. }
  1348. void Mapa::readHeader( unsigned char * bufor, int &i)
  1349. {
  1350. version = (Eformat)(readNormalNr(bufor,i)); i+=4; //map version
  1351. areAnyPLayers = readChar(bufor,i); //invalid on some maps
  1352. height = width = (readNormalNr(bufor,i)); i+=4; // wymiary mapy
  1353. twoLevel = readChar(bufor,i); //czy sa lochy
  1354. terrain = new TerrainTile**[width]; // allocate memory
  1355. for (int ii=0;ii<width;ii++)
  1356. {
  1357. terrain[ii] = new TerrainTile*[height]; // allocate memory
  1358. for(int jj=0;jj<height;jj++)
  1359. terrain[ii][jj] = new TerrainTile[twoLevel+1];
  1360. }
  1361. int pom;
  1362. name = readString(bufor,i);
  1363. description= readString(bufor,i);
  1364. difficulty = readChar(bufor,i); // reading map difficulty
  1365. if(version != RoE)
  1366. levelLimit = readChar(bufor,i); // hero level limit
  1367. else
  1368. levelLimit = 0;
  1369. loadPlayerInfo(pom, bufor, i);
  1370. loadViCLossConditions(bufor, i);
  1371. howManyTeams=bufor[i++]; //read number of teams
  1372. if(howManyTeams>0) //read team numbers
  1373. {
  1374. for(int rr=0; rr<8; ++rr)
  1375. {
  1376. players[rr].team=bufor[i++];
  1377. }
  1378. }
  1379. //reading allowed heroes (20 bytes)
  1380. int ist;
  1381. ist=i; //starting i for loop
  1382. allowedHeroes.resize(HEROES_QUANTITY);
  1383. for(int xx=0;xx<HEROES_QUANTITY;xx++)
  1384. allowedHeroes[xx] = true;
  1385. for(i; i<ist+ (version == RoE ? 16 : 20) ; ++i)
  1386. {
  1387. unsigned char c = bufor[i];
  1388. for(int yy=0; yy<8; ++yy)
  1389. if((i-ist)*8+yy < HEROES_QUANTITY)
  1390. if(c != (c|((unsigned char)intPow(2, yy))))
  1391. allowedHeroes[(i-ist)*8+yy] = false;
  1392. }
  1393. if(version>RoE) //probably reserved for further heroes
  1394. i+=4;
  1395. unsigned char disp = 0;
  1396. if(version>=SoD)
  1397. {
  1398. disp = bufor[i++];
  1399. disposedHeroes.resize(disp);
  1400. for(int g=0; g<disp; ++g)
  1401. {
  1402. disposedHeroes[g].ID = bufor[i++];
  1403. disposedHeroes[g].portrait = bufor[i++];
  1404. int lenbuf = readNormalNr(bufor,i); i+=4;
  1405. for (int zz=0; zz<lenbuf; zz++)
  1406. disposedHeroes[g].name+=bufor[i++];
  1407. int players = bufor[i++];
  1408. for(int zz=0;zz<8;zz++)
  1409. {
  1410. int por = (1<<zz);
  1411. if(players & por)
  1412. disposedHeroes[g].players[zz] = true;
  1413. else
  1414. disposedHeroes[g].players[zz] = false;
  1415. }
  1416. }
  1417. }
  1418. i+=31; //omitting NULLS
  1419. allowedArtifact.resize(ARTIFACTS_QUANTITY);
  1420. for(int x=0;x<allowedArtifact.size();x++)
  1421. allowedArtifact[x] = true;
  1422. //reading allowed artifacts: 17 or 18 bytes
  1423. if(version!=RoE)
  1424. {
  1425. ist=i; //starting i for loop
  1426. for(i; i<ist+(version==AB ? 17 : 18); ++i)
  1427. {
  1428. unsigned char c = bufor[i];
  1429. for(int yy=0; yy<8; ++yy)
  1430. {
  1431. if((i-ist)*8+yy < ARTIFACTS_QUANTITY)
  1432. {
  1433. if(c == (c|((unsigned char)intPow(2, yy))))
  1434. allowedArtifact[(i-ist)*8+yy] = false;
  1435. }
  1436. }
  1437. }//allowed artifacts have been read
  1438. }
  1439. allowedSpell.resize(SPELLS_QUANTITY);
  1440. for(int x=0;x<allowedSpell.size();x++)
  1441. allowedSpell[x] = true;
  1442. allowedAbilities.resize(SKILL_QUANTITY);
  1443. for(int x=0;x<allowedAbilities.size();x++)
  1444. allowedAbilities[x] = true;
  1445. if(version>=SoD)
  1446. {
  1447. //reading allowed spells (9 bytes)
  1448. ist=i; //starting i for loop
  1449. for(i; i<ist+9; ++i)
  1450. {
  1451. unsigned char c = bufor[i];
  1452. for(int yy=0; yy<8; ++yy)
  1453. if((i-ist)*8+yy < SPELLS_QUANTITY)
  1454. if(c == (c|((unsigned char)intPow(2, yy))))
  1455. allowedSpell[(i-ist)*8+yy] = false;
  1456. }
  1457. //allowed hero's abilities (4 bytes)
  1458. ist=i; //starting i for loop
  1459. for(i; i<ist+4; ++i)
  1460. {
  1461. unsigned char c = bufor[i];
  1462. for(int yy=0; yy<8; ++yy)
  1463. {
  1464. if((i-ist)*8+yy < SKILL_QUANTITY)
  1465. {
  1466. if(c == (c|((unsigned char)intPow(2, yy))))
  1467. allowedAbilities[(i-ist)*8+yy] = false;
  1468. }
  1469. }
  1470. }
  1471. }
  1472. }
  1473. void Mapa::readPredefinedHeroes( unsigned char * bufor, int &i)
  1474. {
  1475. switch(version)
  1476. {
  1477. case WoG: case SoD:
  1478. {
  1479. for(int z=0;z<HEROES_QUANTITY;z++) //disposed heroes
  1480. {
  1481. int custom = bufor[i++];
  1482. if(!custom)
  1483. continue;
  1484. CGHeroInstance * cgh = new CGHeroInstance;
  1485. cgh->ID = 34;
  1486. cgh->subID = z;
  1487. if(readChar(bufor,i))//true if hore's experience is greater than 0
  1488. { cgh->exp = readNormalNr(bufor,i); i+=4; }
  1489. else
  1490. cgh->exp = 0;
  1491. if(readChar(bufor,i))//true if hero has specified abilities
  1492. {
  1493. int howMany = readNormalNr(bufor,i); i+=4;
  1494. cgh->secSkills.resize(howMany);
  1495. for(int yy=0; yy<howMany; ++yy)
  1496. {
  1497. cgh->secSkills[yy].first = readNormalNr(bufor,i, 1); ++i;
  1498. cgh->secSkills[yy].second = readNormalNr(bufor,i, 1); ++i;
  1499. }
  1500. }
  1501. bool artSet = bufor[i]; ++i; //true if artifact set is not default (hero has some artifacts)
  1502. int artmask = version == RoE ? 0xff : 0xffff;
  1503. int artidlen = version == RoE ? 1 : 2;
  1504. if(artSet)
  1505. {
  1506. for(int pom=0;pom<16;pom++)
  1507. {
  1508. int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
  1509. if(id!=artmask)
  1510. cgh->artifWorn[pom] = id;
  1511. }
  1512. //misc5 art //17
  1513. if(version>=SoD)
  1514. {
  1515. i+=2;
  1516. //int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
  1517. //if(id!=artmask)
  1518. // spec->artifWorn[16] = id;
  1519. }
  1520. //spellbook
  1521. int id = readNormalNr(bufor,i, artidlen); i+=artidlen;
  1522. if(id!=artmask)
  1523. cgh->artifWorn[17] = id;
  1524. //19 //???what is that? gap in file or what? - it's probably fifth slot..
  1525. if(version>RoE)
  1526. {
  1527. id = readNormalNr(bufor,i, artidlen); i+=artidlen;
  1528. if(id!=artmask)
  1529. cgh->artifWorn[18] = id;
  1530. }
  1531. else
  1532. i+=1;
  1533. //bag artifacts //20
  1534. int amount = readNormalNr(bufor,i, 2); i+=2; //number of artifacts in hero's bag
  1535. if(amount>0)
  1536. {
  1537. for(int ss=0; ss<amount; ++ss)
  1538. {
  1539. id = readNormalNr(bufor,i, artidlen); i+=artidlen;
  1540. if(id!=artmask)
  1541. cgh->artifacts.push_back(id);
  1542. }
  1543. }
  1544. } //artifacts
  1545. if(readChar(bufor,i))//customBio
  1546. cgh->biography = readString(bufor,i);
  1547. int sex = bufor[i++]; // 0xFF is default, 00 male, 01 female
  1548. if(readChar(bufor,i))//are spells
  1549. {
  1550. int ist = i;
  1551. for(i; i<ist+9; ++i)
  1552. {
  1553. unsigned char c = bufor[i];
  1554. for(int yy=0; yy<8; ++yy)
  1555. {
  1556. if((i-ist)*8+yy < SPELLS_QUANTITY)
  1557. {
  1558. if(c == (c|((unsigned char)intPow(2, yy))))
  1559. cgh->spells.insert((i-ist)*8+yy);
  1560. }
  1561. }
  1562. }
  1563. }
  1564. if(readChar(bufor,i))//customPrimSkills
  1565. {
  1566. cgh->primSkills.resize(4);
  1567. for(int xx=0;xx<4;xx++)
  1568. cgh->primSkills[xx] = bufor[i++];
  1569. }
  1570. predefinedHeroes.push_back(cgh);
  1571. }
  1572. break;
  1573. }
  1574. case RoE:
  1575. i+=0;
  1576. break;
  1577. }
  1578. }
  1579. void Mapa::readTerrain( unsigned char * bufor, int &i)
  1580. {
  1581. for (int c=0; c<width; c++) // reading terrain
  1582. {
  1583. for (int z=0; z<height; z++)
  1584. {
  1585. terrain[z][c][0].tertype = (EterrainType)(bufor[i++]);
  1586. terrain[z][c][0].terview = bufor[i++];
  1587. terrain[z][c][0].nuine = (Eriver)bufor[i++];
  1588. terrain[z][c][0].rivDir = bufor[i++];
  1589. terrain[z][c][0].malle = (Eroad)bufor[i++];
  1590. terrain[z][c][0].roadDir = bufor[i++];
  1591. terrain[z][c][0].siodmyTajemniczyBajt = bufor[i++];
  1592. terrain[z][c][0].blocked = 0;
  1593. terrain[z][c][0].visitable = 0;
  1594. }
  1595. }
  1596. if (twoLevel) // read underground terrain
  1597. {
  1598. for (int c=0; c<width; c++) // reading terrain
  1599. {
  1600. for (int z=0; z<height; z++)
  1601. {
  1602. terrain[z][c][1].tertype = (EterrainType)(bufor[i++]);
  1603. terrain[z][c][1].terview = bufor[i++];
  1604. terrain[z][c][1].nuine = (Eriver)bufor[i++];
  1605. terrain[z][c][1].rivDir = bufor[i++];
  1606. terrain[z][c][1].malle = (Eroad)bufor[i++];
  1607. terrain[z][c][1].roadDir = bufor[i++];
  1608. terrain[z][c][1].siodmyTajemniczyBajt = bufor[i++];
  1609. terrain[z][c][1].blocked = 0;
  1610. terrain[z][c][1].visitable = 0;
  1611. }
  1612. }
  1613. }
  1614. }
  1615. void Mapa::readDefInfo( unsigned char * bufor, int &i)
  1616. {
  1617. int defAmount = readNormalNr(bufor,i); i+=4;
  1618. defy.reserve(defAmount);
  1619. for (int idd = 0 ; idd<defAmount; idd++) // reading defs
  1620. {
  1621. CGDefInfo * vinya = new CGDefInfo(); // info about new def
  1622. //reading name
  1623. int nameLength = readNormalNr(bufor,i,4);i+=4;
  1624. vinya->name.reserve(nameLength);
  1625. for (int cd=0;cd<nameLength;cd++)
  1626. {
  1627. vinya->name += bufor[i++];
  1628. }
  1629. std::transform(vinya->name.begin(),vinya->name.end(),vinya->name.begin(),(int(*)(int))toupper);
  1630. unsigned char bytes[12];
  1631. for (int v=0; v<12; v++) // read info
  1632. {
  1633. bytes[v] = bufor[i++];
  1634. }
  1635. vinya->terrainAllowed = readNormalNr(bufor,i,2);i+=2;
  1636. vinya->terrainMenu = readNormalNr(bufor,i,2);i+=2;
  1637. vinya->id = readNormalNr(bufor,i,4);i+=4;
  1638. vinya->subid = readNormalNr(bufor,i,4);i+=4;
  1639. vinya->type = bufor[i++];
  1640. vinya->printPriority = bufor[i++];
  1641. for (int zi=0; zi<6; zi++)
  1642. {
  1643. vinya->blockMap[zi] = reverse(bytes[zi]);
  1644. }
  1645. for (int zi=0; zi<6; zi++)
  1646. {
  1647. vinya->visitMap[zi] = reverse(bytes[6+zi]);
  1648. }
  1649. i+=16;
  1650. if(vinya->id!=34)
  1651. vinya->visitDir = VLC->dobjinfo->gobjs[vinya->id][vinya->subid]->visitDir;
  1652. else
  1653. vinya->visitDir = 0xff;
  1654. defy.push_back(vinya); // add this def to the vector
  1655. }
  1656. }
  1657. void Mapa::readObjects( unsigned char * bufor, int &i)
  1658. {
  1659. int howManyObjs = readNormalNr(bufor,i, 4); i+=4;
  1660. for(int ww=0; ww<howManyObjs; ++ww) //comment this line to turn loading objects off
  1661. {
  1662. //std::cout << "object nr "<<ww<<"\ti= "<<i<<std::endl;
  1663. CGObjectInstance * nobj = new CGObjectInstance(); //we will read this object
  1664. nobj->id = objects.size();
  1665. nobj->pos.x = bufor[i++];
  1666. nobj->pos.y = bufor[i++];
  1667. nobj->pos.z = bufor[i++];
  1668. int tempd = readNormalNr(bufor,i, 4); i+=4;
  1669. nobj->defInfo = defy[tempd];
  1670. nobj->ID = nobj->defInfo->id;
  1671. nobj->subID = nobj->defInfo->subid;
  1672. //if (((nobj.x==0)&&(nobj.y==0)) || nobj.x>width || nobj.y>height || nobj.z>1 || nobj.defNumber>defy.size()) std::cout << "Alarm!!! Obiekt "<<ww<<" jest kopniety (lub wystaje poza mape)\n";
  1673. i+=5;
  1674. unsigned char buff [30];
  1675. for(int ccc=0; ccc<30; ++ccc)
  1676. {
  1677. buff[ccc] = bufor[i+ccc];
  1678. }
  1679. int j = nobj->defInfo->id;
  1680. int p = 99;
  1681. switch(getDefType(nobj->defInfo))
  1682. {
  1683. case EVENTOBJ_DEF: //for event - objects
  1684. {
  1685. CEventObjInfo * spec = new CEventObjInfo;
  1686. bool guardMess;
  1687. guardMess = bufor[i]; ++i;
  1688. if(guardMess)
  1689. {
  1690. int messLong = readNormalNr(bufor,i, 4); i+=4;
  1691. if(messLong>0)
  1692. {
  1693. spec->isMessage = true;
  1694. for(int yy=0; yy<messLong; ++yy)
  1695. {
  1696. spec->message +=bufor[i+yy];
  1697. }
  1698. i+=messLong;
  1699. }
  1700. spec->areGuarders = bufor[i]; ++i;
  1701. if(spec->areGuarders)
  1702. {
  1703. spec->guarders = readCreatureSet(bufor,i,7,(version>RoE));
  1704. }
  1705. i+=4;
  1706. }
  1707. else
  1708. {
  1709. spec->isMessage = false;
  1710. spec->areGuarders = false;
  1711. spec->message = std::string("");
  1712. }
  1713. spec->gainedExp = readNormalNr(bufor,i, 4); i+=4;
  1714. spec->manaDiff = readNormalNr(bufor,i, 4); i+=4;
  1715. spec->moraleDiff = readNormalNr(bufor,i, 1, true); ++i;
  1716. spec->luckDiff = readNormalNr(bufor,i, 1, true); ++i;
  1717. spec->wood = readNormalNr(bufor,i); i+=4;
  1718. spec->mercury = readNormalNr(bufor,i); i+=4;
  1719. spec->ore = readNormalNr(bufor,i); i+=4;
  1720. spec->sulfur = readNormalNr(bufor,i); i+=4;
  1721. spec->crystal = readNormalNr(bufor,i); i+=4;
  1722. spec->gems = readNormalNr(bufor,i); i+=4;
  1723. spec->gold = readNormalNr(bufor,i); i+=4;
  1724. spec->attack = readNormalNr(bufor,i, 1); ++i;
  1725. spec->defence = readNormalNr(bufor,i, 1); ++i;
  1726. spec->power = readNormalNr(bufor,i, 1); ++i;
  1727. spec->knowledge = readNormalNr(bufor,i, 1); ++i;
  1728. int gabn; //number of gained abilities
  1729. gabn = readNormalNr(bufor,i, 1); ++i;
  1730. for(int oo = 0; oo<gabn; ++oo)
  1731. {
  1732. spec->abilities.push_back(readNormalNr(bufor,i, 1)); ++i;
  1733. spec->abilityLevels.push_back(readNormalNr(bufor,i, 1)); ++i;
  1734. }
  1735. int gart = readNormalNr(bufor,i, 1); ++i; //number of gained artifacts
  1736. for(int oo = 0; oo<gart; ++oo)
  1737. {
  1738. spec->artifacts.push_back(readNormalNr(bufor,i, (version == RoE ? 1 : 2))); i+=(version == RoE ? 1 : 2);
  1739. }
  1740. int gspel = readNormalNr(bufor,i, 1); ++i; //number of gained spells
  1741. for(int oo = 0; oo<gspel; ++oo)
  1742. {
  1743. spec->spells.push_back(readNormalNr(bufor,i, 1)); ++i;
  1744. }
  1745. int gcre = readNormalNr(bufor,i, 1); ++i; //number of gained creatures
  1746. spec->creatures = readCreatureSet(bufor,i,gcre,(version>RoE));
  1747. i+=8;
  1748. spec->availableFor = readNormalNr(bufor,i, 1); ++i;
  1749. spec->computerActivate = readNormalNr(bufor,i, 1); ++i;
  1750. spec->humanActivate = readNormalNr(bufor,i, 1); ++i;
  1751. i+=4;
  1752. nobj->info = spec;
  1753. break;
  1754. }
  1755. case HERO_DEF:
  1756. {
  1757. loadHero(nobj, bufor, i);
  1758. break;
  1759. }
  1760. case CREATURES_DEF:
  1761. {
  1762. CCreatureObjInfo * spec = new CCreatureObjInfo;
  1763. if(version>RoE)
  1764. {
  1765. spec->bytes[0] = bufor[i]; ++i;
  1766. spec->bytes[1] = bufor[i]; ++i;
  1767. spec->bytes[2] = bufor[i]; ++i;
  1768. spec->bytes[3] = bufor[i]; ++i;
  1769. }
  1770. spec->number = readNormalNr(bufor,i, 2); i+=2;
  1771. spec->character = bufor[i]; ++i;
  1772. bool isMesTre = bufor[i]; ++i; //true if there is message or treasury
  1773. if(isMesTre)
  1774. {
  1775. int messLength = readNormalNr(bufor,i); i+=4;
  1776. if(messLength>0)
  1777. {
  1778. for(int tt=0; tt<messLength; ++tt)
  1779. {
  1780. spec->message += bufor[i]; ++i;
  1781. }
  1782. }
  1783. spec->wood = readNormalNr(bufor,i); i+=4;
  1784. spec->mercury = readNormalNr(bufor,i); i+=4;
  1785. spec->ore = readNormalNr(bufor,i); i+=4;
  1786. spec->sulfur = readNormalNr(bufor,i); i+=4;
  1787. spec->crytal = readNormalNr(bufor,i); i+=4;
  1788. spec->gems = readNormalNr(bufor,i); i+=4;
  1789. spec->gold = readNormalNr(bufor,i); i+=4;
  1790. int artID = readNormalNr(bufor,i, (version == RoE ? 1 : 2)); i+=(version == RoE ? 1 : 2);
  1791. if(version==RoE)
  1792. {
  1793. if(artID!=0xff)
  1794. spec->gainedArtifact = artID;
  1795. else
  1796. spec->gainedArtifact = -1;
  1797. }
  1798. else
  1799. {
  1800. if(artID!=0xffff)
  1801. spec->gainedArtifact = artID;
  1802. else
  1803. spec->gainedArtifact = -1;
  1804. }
  1805. }
  1806. spec->neverFlees = bufor[i]; ++i;
  1807. spec->notGrowingTeam = bufor[i]; ++i;
  1808. i+=2;
  1809. nobj->info = spec;
  1810. break;
  1811. }
  1812. case SIGN_DEF:
  1813. {
  1814. CSignObjInfo * spec = new CSignObjInfo;
  1815. int length = readNormalNr(bufor,i); i+=4;
  1816. for(int rr=0; rr<length; ++rr)
  1817. {
  1818. spec->message += bufor[i]; ++i;
  1819. }
  1820. i+=4;
  1821. nobj->info = spec;
  1822. break;
  1823. }
  1824. case SEERHUT_DEF:
  1825. {
  1826. i = loadSeerHut(bufor, i, nobj);
  1827. break;
  1828. }
  1829. case WITCHHUT_DEF:
  1830. {
  1831. CWitchHutObjInfo * spec = new CWitchHutObjInfo;
  1832. if(version>RoE) //in reo we cannot specify it - all are allowed (I hope)
  1833. {
  1834. int ist=i; //starting i for loop
  1835. for(i; i<ist+4; ++i)
  1836. {
  1837. unsigned char c = bufor[i];
  1838. for(int yy=0; yy<8; ++yy)
  1839. {
  1840. if((i-ist)*8+yy < SKILL_QUANTITY)
  1841. {
  1842. if(c == (c|((unsigned char)intPow(2, yy))))
  1843. spec->allowedAbilities.push_back((i-ist)*8+yy);
  1844. }
  1845. }
  1846. }
  1847. }
  1848. else //(RoE map)
  1849. {
  1850. for(int gg=0; gg<SKILL_QUANTITY; ++gg)
  1851. {
  1852. spec->allowedAbilities.push_back(gg);
  1853. }
  1854. }
  1855. nobj->info = spec;
  1856. break;
  1857. }
  1858. case SCHOLAR_DEF:
  1859. {
  1860. CScholarObjInfo * spec = new CScholarObjInfo;
  1861. spec->bonusType = bufor[i]; ++i;
  1862. switch(spec->bonusType)
  1863. {
  1864. case 0xff:
  1865. ++i;
  1866. break;
  1867. case 0:
  1868. spec->r0type = bufor[i]; ++i;
  1869. break;
  1870. case 1:
  1871. spec->r1 = bufor[i]; ++i;
  1872. break;
  1873. case 2:
  1874. spec->r2 = bufor[i]; ++i;
  1875. break;
  1876. }
  1877. i+=6;
  1878. nobj->info = spec;
  1879. break;
  1880. }
  1881. case GARRISON_DEF:
  1882. {
  1883. CGarrisonObjInfo * spec = new CGarrisonObjInfo;
  1884. spec->player = bufor[i]; ++i;
  1885. i+=3;
  1886. spec->units = readCreatureSet(bufor,i,7,(version>RoE));
  1887. if(version > RoE)
  1888. {
  1889. spec->movableUnits = bufor[i]; ++i;
  1890. }
  1891. else
  1892. spec->movableUnits = true;
  1893. i+=8;
  1894. nobj->setOwner(spec->player);
  1895. nobj->info = spec;
  1896. break;
  1897. }
  1898. case ARTIFACT_DEF:
  1899. {
  1900. CArtifactObjInfo * spec = new CArtifactObjInfo;
  1901. bool areSettings = bufor[i]; ++i;
  1902. if(areSettings)
  1903. {
  1904. int messLength = readNormalNr(bufor,i, 4); i+=4;
  1905. for(int hh=0; hh<messLength; ++hh)
  1906. {
  1907. spec->message += bufor[i]; ++i;
  1908. }
  1909. bool areGuards = bufor[i]; ++i;
  1910. if(areGuards)
  1911. {
  1912. spec->areGuards = true;
  1913. spec->guards = readCreatureSet(bufor,i,7,(version>RoE));
  1914. }
  1915. else
  1916. spec->areGuards = false;
  1917. i+=4;
  1918. }
  1919. nobj->info = spec;
  1920. break;
  1921. }
  1922. case RESOURCE_DEF:
  1923. {
  1924. CResourceObjInfo * spec = new CResourceObjInfo;
  1925. bool isMessGuard = bufor[i]; ++i;
  1926. if(isMessGuard)
  1927. {
  1928. int messLength = readNormalNr(bufor,i); i+=4;
  1929. for(int mm=0; mm<messLength; ++mm)
  1930. {
  1931. spec->message+=bufor[i]; ++i;
  1932. }
  1933. spec->areGuards = bufor[i]; ++i;
  1934. if(spec->areGuards)
  1935. {
  1936. spec->guards = readCreatureSet(bufor,i,7,(version>RoE));
  1937. }
  1938. i+=4;
  1939. }
  1940. else
  1941. {
  1942. spec->areGuards = false;
  1943. }
  1944. spec->amount = readNormalNr(bufor,i); i+=4;
  1945. i+=4;
  1946. nobj->info = spec;
  1947. break;
  1948. }
  1949. case TOWN_DEF:
  1950. {
  1951. loadTown(nobj, bufor, i);
  1952. break;
  1953. }
  1954. case PLAYERONLY_DEF:
  1955. {
  1956. CPlayerOnlyObjInfo * spec = new CPlayerOnlyObjInfo;
  1957. spec->player = bufor[i]; ++i;
  1958. i+=3;
  1959. nobj->setOwner(spec->player);
  1960. nobj->info = spec;
  1961. break;
  1962. }
  1963. case SHRINE_DEF:
  1964. {
  1965. CShrineObjInfo * spec = new CShrineObjInfo;
  1966. spec->spell = bufor[i]; i+=4;
  1967. nobj->info = spec;
  1968. break;
  1969. }
  1970. case SPELLSCROLL_DEF:
  1971. {
  1972. CSpellScrollObjinfo * spec = new CSpellScrollObjinfo;
  1973. bool messg = bufor[i]; ++i;
  1974. if(messg)
  1975. {
  1976. int mLength = readNormalNr(bufor,i); i+=4;
  1977. for(int vv=0; vv<mLength; ++vv)
  1978. {
  1979. spec->message += bufor[i]; ++i;
  1980. }
  1981. spec->areGuarders = bufor[i]; ++i;
  1982. if(spec->areGuarders)
  1983. {
  1984. spec->guarders = readCreatureSet(bufor,i,7,(version>RoE));
  1985. }
  1986. i+=4;
  1987. }
  1988. spec->spell = bufor[i]; ++i;
  1989. i+=3;
  1990. nobj->info = spec;
  1991. break;
  1992. }
  1993. case PANDORA_DEF:
  1994. {
  1995. CPandorasBoxObjInfo * spec = new CPandorasBoxObjInfo;
  1996. bool messg = bufor[i]; ++i;
  1997. if(messg)
  1998. {
  1999. int mLength = readNormalNr(bufor,i); i+=4;
  2000. for(int vv=0; vv<mLength; ++vv)
  2001. {
  2002. spec->message += bufor[i]; ++i;
  2003. }
  2004. spec->areGuarders = bufor[i]; ++i;
  2005. if(spec->areGuarders)
  2006. {
  2007. spec->guarders = readCreatureSet(bufor,i,7,(version>RoE));
  2008. }
  2009. i+=4;
  2010. }
  2011. ////// copied form event handling (seems to be similar)
  2012. spec->gainedExp = readNormalNr(bufor,i, 4); i+=4;
  2013. spec->manaDiff = readNormalNr(bufor,i, 4); i+=4;
  2014. spec->moraleDiff = readNormalNr(bufor,i, 1, true); ++i;
  2015. spec->luckDiff = readNormalNr(bufor,i, 1, true); ++i;
  2016. spec->wood = readNormalNr(bufor,i); i+=4;
  2017. spec->mercury = readNormalNr(bufor,i); i+=4;
  2018. spec->ore = readNormalNr(bufor,i); i+=4;
  2019. spec->sulfur = readNormalNr(bufor,i); i+=4;
  2020. spec->crystal = readNormalNr(bufor,i); i+=4;
  2021. spec->gems = readNormalNr(bufor,i); i+=4;
  2022. spec->gold = readNormalNr(bufor,i); i+=4;
  2023. spec->attack = readNormalNr(bufor,i, 1); ++i;
  2024. spec->defence = readNormalNr(bufor,i, 1); ++i;
  2025. spec->power = readNormalNr(bufor,i, 1); ++i;
  2026. spec->knowledge = readNormalNr(bufor,i, 1); ++i;
  2027. int gabn; //number of gained abilities
  2028. gabn = readNormalNr(bufor,i, 1); ++i;
  2029. for(int oo = 0; oo<gabn; ++oo)
  2030. {
  2031. spec->abilities.push_back(readNormalNr(bufor,i, 1)); ++i;
  2032. spec->abilityLevels.push_back(readNormalNr(bufor,i, 1)); ++i;
  2033. }
  2034. int gart = readNormalNr(bufor,i, 1); ++i; //number of gained artifacts
  2035. for(int oo = 0; oo<gart; ++oo)
  2036. {
  2037. if(version > RoE)
  2038. {
  2039. spec->artifacts.push_back(readNormalNr(bufor,i, 2)); i+=2;
  2040. }
  2041. else
  2042. {
  2043. spec->artifacts.push_back(readNormalNr(bufor,i, 1)); i+=1;
  2044. }
  2045. }
  2046. int gspel = readNormalNr(bufor,i, 1); ++i; //number of gained spells
  2047. for(int oo = 0; oo<gspel; ++oo)
  2048. {
  2049. spec->spells.push_back(readNormalNr(bufor,i, 1)); ++i;
  2050. }
  2051. int gcre = readNormalNr(bufor,i, 1); ++i; //number of gained creatures
  2052. spec->creatures = readCreatureSet(bufor,i,gcre,(version>RoE));
  2053. i+=8;
  2054. nobj->info = spec;
  2055. ///////end of copied fragment
  2056. break;
  2057. }
  2058. case GRAIL_DEF:
  2059. {
  2060. CGrailObjInfo * spec = new CGrailObjInfo;
  2061. spec->radius = readNormalNr(bufor,i); i+=4;
  2062. nobj->info = spec;
  2063. break;
  2064. }
  2065. case CREGEN_DEF:
  2066. {
  2067. CCreGenObjInfo * spec = new CCreGenObjInfo;
  2068. spec->player = readNormalNr(bufor,i); i+=4;
  2069. spec->identifier = readNormalNr(bufor,i); i+=4;
  2070. if(!spec->identifier)
  2071. {
  2072. spec->asCastle = false;
  2073. spec->castles[0] = bufor[i]; ++i;
  2074. spec->castles[1] = bufor[i]; ++i;
  2075. }
  2076. else
  2077. {
  2078. spec->asCastle = true;
  2079. }
  2080. nobj->setOwner(spec->player);
  2081. nobj->info = spec;
  2082. break;
  2083. }
  2084. case CREGEN2_DEF:
  2085. {
  2086. CCreGen2ObjInfo * spec = new CCreGen2ObjInfo;
  2087. spec->player = readNormalNr(bufor,i); i+=4;
  2088. spec->identifier = readNormalNr(bufor,i); i+=4;
  2089. if(!spec->identifier)
  2090. {
  2091. spec->asCastle = false;
  2092. spec->castles[0] = bufor[i]; ++i;
  2093. spec->castles[1] = bufor[i]; ++i;
  2094. }
  2095. else
  2096. {
  2097. spec->asCastle = true;
  2098. }
  2099. spec->minLevel = bufor[i]; ++i;
  2100. spec->maxLevel = bufor[i]; ++i;
  2101. //if(spec->maxLevel>7)
  2102. // spec->maxLevel = 7;
  2103. //if(spec->minLevel<1)
  2104. // spec->minLevel = 1;
  2105. nobj->setOwner(spec->player);
  2106. nobj->info = spec;
  2107. break;
  2108. }
  2109. case CREGEN3_DEF:
  2110. {
  2111. CCreGen3ObjInfo * spec = new CCreGen3ObjInfo;
  2112. spec->player = bufor[i]; ++i;
  2113. i+=3;
  2114. spec->minLevel = bufor[i]; ++i;
  2115. spec->maxLevel = bufor[i]; ++i;
  2116. if(spec->maxLevel>7)
  2117. spec->maxLevel = 7;
  2118. if(spec->minLevel<1)
  2119. spec->minLevel = 1;
  2120. nobj->setOwner(spec->player);
  2121. nobj->info = spec;
  2122. break;
  2123. }
  2124. case BORDERGUARD_DEF:
  2125. {
  2126. CBorderGuardObjInfo * spec = new CBorderGuardObjInfo;
  2127. spec->missionType = bufor[i]; ++i;
  2128. int len1, len2, len3;
  2129. switch(spec->missionType)
  2130. {
  2131. case 0:
  2132. {
  2133. goto borderguardend;
  2134. break;
  2135. }
  2136. case 1:
  2137. {
  2138. spec->m1level = readNormalNr(bufor,i); i+=4;
  2139. int limit = readNormalNr(bufor,i); i+=4;
  2140. if(limit == ((int)0xffffffff))
  2141. {
  2142. spec->isDayLimit = false;
  2143. spec->lastDay = -1;
  2144. }
  2145. else
  2146. {
  2147. spec->isDayLimit = true;
  2148. spec->lastDay = limit;
  2149. }
  2150. break;
  2151. }
  2152. case 2:
  2153. {
  2154. spec->m2attack = bufor[i]; ++i;
  2155. spec->m2defence = bufor[i]; ++i;
  2156. spec->m2power = bufor[i]; ++i;
  2157. spec->m2knowledge = bufor[i]; ++i;
  2158. int limit = readNormalNr(bufor,i); i+=4;
  2159. if(limit == ((int)0xffffffff))
  2160. {
  2161. spec->isDayLimit = false;
  2162. spec->lastDay = -1;
  2163. }
  2164. else
  2165. {
  2166. spec->isDayLimit = true;
  2167. spec->lastDay = limit;
  2168. }
  2169. break;
  2170. }
  2171. case 3:
  2172. {
  2173. spec->m3bytes[0] = bufor[i]; ++i;
  2174. spec->m3bytes[1] = bufor[i]; ++i;
  2175. spec->m3bytes[2] = bufor[i]; ++i;
  2176. spec->m3bytes[3] = bufor[i]; ++i;
  2177. int limit = readNormalNr(bufor,i); i+=4;
  2178. if(limit == ((int)0xffffffff))
  2179. {
  2180. spec->isDayLimit = false;
  2181. spec->lastDay = -1;
  2182. }
  2183. else
  2184. {
  2185. spec->isDayLimit = true;
  2186. spec->lastDay = limit;
  2187. }
  2188. break;
  2189. }
  2190. case 4:
  2191. {
  2192. spec->m4bytes[0] = bufor[i]; ++i;
  2193. spec->m4bytes[1] = bufor[i]; ++i;
  2194. spec->m4bytes[2] = bufor[i]; ++i;
  2195. spec->m4bytes[3] = bufor[i]; ++i;
  2196. int limit = readNormalNr(bufor,i); i+=4;
  2197. if(limit == ((int)0xffffffff))
  2198. {
  2199. spec->isDayLimit = false;
  2200. spec->lastDay = -1;
  2201. }
  2202. else
  2203. {
  2204. spec->isDayLimit = true;
  2205. spec->lastDay = limit;
  2206. }
  2207. break;
  2208. }
  2209. case 5:
  2210. {
  2211. int artNumber = bufor[i]; ++i;
  2212. for(int yy=0; yy<artNumber; ++yy)
  2213. {
  2214. spec->m5arts.push_back(readNormalNr(bufor,i, 2)); i+=2;
  2215. }
  2216. int limit = readNormalNr(bufor,i); i+=4;
  2217. if(limit == ((int)0xffffffff))
  2218. {
  2219. spec->isDayLimit = false;
  2220. spec->lastDay = -1;
  2221. }
  2222. else
  2223. {
  2224. spec->isDayLimit = true;
  2225. spec->lastDay = limit;
  2226. }
  2227. break;
  2228. }
  2229. case 6:
  2230. {
  2231. int typeNumber = bufor[i]; ++i;
  2232. for(int hh=0; hh<typeNumber; ++hh)
  2233. {
  2234. int creType = readNormalNr(bufor,i, 2); i+=2;
  2235. int creNumb = readNormalNr(bufor,i, 2); i+=2;
  2236. spec->m6cre.push_back(&(VLC->creh->creatures[creType]));
  2237. spec->m6number.push_back(creNumb);
  2238. }
  2239. int limit = readNormalNr(bufor,i); i+=4;
  2240. if(limit == ((int)0xffffffff))
  2241. {
  2242. spec->isDayLimit = false;
  2243. spec->lastDay = -1;
  2244. }
  2245. else
  2246. {
  2247. spec->isDayLimit = true;
  2248. spec->lastDay = limit;
  2249. }
  2250. break;
  2251. }
  2252. case 7:
  2253. {
  2254. spec->m7wood = readNormalNr(bufor,i); i+=4;
  2255. spec->m7mercury = readNormalNr(bufor,i); i+=4;
  2256. spec->m7ore = readNormalNr(bufor,i); i+=4;
  2257. spec->m7sulfur = readNormalNr(bufor,i); i+=4;
  2258. spec->m7crystal = readNormalNr(bufor,i); i+=4;
  2259. spec->m7gems = readNormalNr(bufor,i); i+=4;
  2260. spec->m7gold = readNormalNr(bufor,i); i+=4;
  2261. int limit = readNormalNr(bufor,i); i+=4;
  2262. if(limit == ((int)0xffffffff))
  2263. {
  2264. spec->isDayLimit = false;
  2265. spec->lastDay = -1;
  2266. }
  2267. else
  2268. {
  2269. spec->isDayLimit = true;
  2270. spec->lastDay = limit;
  2271. }
  2272. break;
  2273. }
  2274. case 8:
  2275. {
  2276. int heroType = bufor[i]; ++i;
  2277. spec->m8hero = heroType;
  2278. int limit = readNormalNr(bufor,i); i+=4;
  2279. if(limit == ((int)0xffffffff))
  2280. {
  2281. spec->isDayLimit = false;
  2282. spec->lastDay = -1;
  2283. }
  2284. else
  2285. {
  2286. spec->isDayLimit = true;
  2287. spec->lastDay = limit;
  2288. }
  2289. break;
  2290. }
  2291. case 9:
  2292. {
  2293. spec->m9player = bufor[i]; ++i;
  2294. int limit = readNormalNr(bufor,i); i+=4;
  2295. if(limit == ((int)0xffffffff))
  2296. {
  2297. spec->isDayLimit = false;
  2298. spec->lastDay = -1;
  2299. }
  2300. else
  2301. {
  2302. spec->isDayLimit = true;
  2303. spec->lastDay = limit;
  2304. }
  2305. break;
  2306. }
  2307. }//internal switch end (seer huts)
  2308. len1 = readNormalNr(bufor,i); i+=4;
  2309. for(int ee=0; ee<len1; ++ee)
  2310. {
  2311. spec->firstVisitText += bufor[i]; ++i;
  2312. }
  2313. len2 = readNormalNr(bufor,i); i+=4;
  2314. for(int ee=0; ee<len2; ++ee)
  2315. {
  2316. spec->nextVisitText += bufor[i]; ++i;
  2317. }
  2318. len3 = readNormalNr(bufor,i); i+=4;
  2319. for(int ee=0; ee<len3; ++ee)
  2320. {
  2321. spec->completedText += bufor[i]; ++i;
  2322. }
  2323. nobj->info = spec;
  2324. borderguardend:
  2325. break;
  2326. }
  2327. case HEROPLACEHOLDER_DEF:
  2328. {
  2329. i+=3; //TODO: handle it more properly
  2330. break;
  2331. }
  2332. } //end of main switch
  2333. objects.push_back(nobj);
  2334. }
  2335. }
  2336. void Mapa::readEvents( unsigned char * bufor, int &i )
  2337. {
  2338. int numberOfEvents = readNormalNr(bufor,i); i+=4;
  2339. for(int yyoo=0; yyoo<numberOfEvents; ++yyoo)
  2340. {
  2341. CMapEvent ne;
  2342. ne.name = std::string();
  2343. ne.message = std::string();
  2344. int nameLen = readNormalNr(bufor,i); i+=4;
  2345. for(int qq=0; qq<nameLen; ++qq)
  2346. {
  2347. ne.name += bufor[i]; ++i;
  2348. }
  2349. int messLen = readNormalNr(bufor,i); i+=4;
  2350. for(int qq=0; qq<messLen; ++qq)
  2351. {
  2352. ne.message +=bufor[i]; ++i;
  2353. }
  2354. ne.wood = readNormalNr(bufor,i); i+=4;
  2355. ne.mercury = readNormalNr(bufor,i); i+=4;
  2356. ne.ore = readNormalNr(bufor,i); i+=4;
  2357. ne.sulfur = readNormalNr(bufor,i); i+=4;
  2358. ne.crystal = readNormalNr(bufor,i); i+=4;
  2359. ne.gems = readNormalNr(bufor,i); i+=4;
  2360. ne.gold = readNormalNr(bufor,i); i+=4;
  2361. ne.players = bufor[i]; ++i;
  2362. if(version>AB)
  2363. {
  2364. ne.humanAffected = bufor[i]; ++i;
  2365. }
  2366. else
  2367. ne.humanAffected = true;
  2368. ne.computerAffected = bufor[i]; ++i;
  2369. ne.firstOccurence = bufor[i]; ++i;
  2370. ne.nextOccurence = bufor[i]; ++i;
  2371. i+=18;
  2372. events.push_back(ne);
  2373. }
  2374. }
  2375. bool Mapa::isInTheMap( int3 pos )
  2376. {
  2377. if(pos.x<0 || pos.y<0 || pos.z<0 || pos.x >= width || pos.y >= height || pos.z > twoLevel)
  2378. return false;
  2379. else return true;
  2380. }