map.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776
  1. #include "map.h"
  2. #include "raycast_mesh.h"
  3. #include "../../common/Log.h"
  4. #ifdef WIN32
  5. #define _snprintf snprintf
  6. #include <WinSock2.h>
  7. #include <windows.h>
  8. #endif
  9. #include <algorithm>
  10. #include <map>
  11. #include <memory>
  12. #include <tuple>
  13. #include <vector>
  14. #include <fstream>
  15. #include <iostream>
  16. #include <boost/regex.hpp>
  17. #include <boost/filesystem.hpp>
  18. #include <boost/foreach.hpp>
  19. #include <boost/asio.hpp>
  20. #include <boost/iostreams/filtering_streambuf.hpp>
  21. #include <boost/iostreams/copy.hpp>
  22. #include <boost/iostreams/filter/gzip.hpp>
  23. struct Map::impl
  24. {
  25. RaycastMesh *rm;
  26. };
  27. inline bool file_exists(const std::string& name) {
  28. std::ifstream f(name.c_str());
  29. return f.good();
  30. }
  31. ThreadReturnType LoadMapAsync(void* mapToLoad)
  32. {
  33. Map* map = (Map*)mapToLoad;
  34. map->SetMapLoaded(false);
  35. std::string filename = "Maps/";
  36. filename += map->GetFileName();
  37. std::string deflatedFileName = filename + ".EQ2MapDeflated";
  38. filename += ".EQ2Map";
  39. if(file_exists(deflatedFileName))
  40. filename = deflatedFileName;
  41. map->SetFileName(filename);
  42. if (map->Load(filename))
  43. map->SetMapLoaded(true);
  44. map->SetMapLoading(false);
  45. THREAD_RETURN(NULL);
  46. }
  47. Map::Map(string zonename, string file, SPGrid* grid) {
  48. CheckMapMutex.SetName(file + "MapMutex");
  49. SetMapLoaded(false);
  50. m_ZoneName = zonename;
  51. m_ZoneFile = file;
  52. imp = nullptr;
  53. mGrid = grid;
  54. m_CellSize = CELLSIZEDEFAULT;
  55. }
  56. Map::~Map() {
  57. SetMapLoaded(false);
  58. if(imp) {
  59. imp->rm->release();
  60. safe_delete(imp);
  61. }
  62. safe_delete(mGrid);
  63. }
  64. float Map::FindBestZ(glm::vec3 &start, glm::vec3 *result)
  65. {
  66. if (!IsMapLoaded())
  67. return BEST_Z_INVALID;
  68. if (!imp)
  69. return BEST_Z_INVALID;
  70. glm::vec3 tmp;
  71. if(!result)
  72. result = &tmp;
  73. start.z += 1.0f;//RuleI(Map, FindBestZHeightAdjust);
  74. glm::vec3 from(start.x, start.y, start.z);
  75. glm::vec3 to(start.x, start.y, BEST_Z_INVALID);
  76. float hit_distance;
  77. bool hit = false;
  78. hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
  79. if(hit) {
  80. return result->z;
  81. }
  82. // Find nearest Z above us
  83. to.z = -BEST_Z_INVALID;
  84. hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
  85. if (hit)
  86. {
  87. return result->z;
  88. }
  89. return BEST_Z_INVALID;
  90. }
  91. float Map::FindClosestZ(glm::vec3 &start, glm::vec3 *result) {
  92. if (!IsMapLoaded())
  93. return false;
  94. // Unlike FindBestZ, this method finds the closest Z value above or below the specified point.
  95. //
  96. if (!imp)
  97. return false;
  98. float ClosestZ = BEST_Z_INVALID;
  99. glm::vec3 tmp;
  100. if (!result)
  101. result = &tmp;
  102. glm::vec3 from(start.x, start.y, start.z);
  103. glm::vec3 to(start.x, start.y, BEST_Z_INVALID);
  104. float hit_distance;
  105. bool hit = false;
  106. // first check is below us
  107. hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
  108. if (hit) {
  109. ClosestZ = result->z;
  110. }
  111. // Find nearest Z above us
  112. to.z = -BEST_Z_INVALID;
  113. hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
  114. if (hit) {
  115. if (std::abs(from.z - result->z) < std::abs(ClosestZ - from.z))
  116. return result->z;
  117. }
  118. return ClosestZ;
  119. }
  120. bool Map::LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::vec3 *result) {
  121. if (!IsMapLoaded())
  122. return false;
  123. if(!imp)
  124. return false;
  125. return imp->rm->raycast((const RmReal*)&start, (const RmReal*)&end, (RmReal*)result, nullptr, nullptr);
  126. }
  127. bool Map::LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_mag, glm::vec3 *result) {
  128. if (!IsMapLoaded())
  129. return false;
  130. if (!imp)
  131. return false;
  132. float z = BEST_Z_INVALID;
  133. glm::vec3 step;
  134. glm::vec3 cur;
  135. cur.x = start.x;
  136. cur.y = start.y;
  137. cur.z = start.z;
  138. step.x = end.x - start.x;
  139. step.y = end.y - start.y;
  140. step.z = end.z - start.z;
  141. float factor = step_mag / sqrt(step.x*step.x + step.y*step.y + step.z*step.z);
  142. step.x *= factor;
  143. step.y *= factor;
  144. step.z *= factor;
  145. int steps = 0;
  146. if (step.x > 0 && step.x < 0.001f)
  147. step.x = 0.001f;
  148. if (step.y > 0 && step.y < 0.001f)
  149. step.y = 0.001f;
  150. if (step.z > 0 && step.z < 0.001f)
  151. step.z = 0.001f;
  152. if (step.x < 0 && step.x > -0.001f)
  153. step.x = -0.001f;
  154. if (step.y < 0 && step.y > -0.001f)
  155. step.y = -0.001f;
  156. if (step.z < 0 && step.z > -0.001f)
  157. step.z = -0.001f;
  158. //while we are not past end
  159. //always do this once, even if start == end.
  160. while(cur.x != end.x || cur.y != end.y || cur.z != end.z)
  161. {
  162. steps++;
  163. glm::vec3 me;
  164. me.x = cur.x;
  165. me.y = cur.y;
  166. me.z = cur.z;
  167. glm::vec3 hit;
  168. float best_z = FindBestZ(me, &hit);
  169. float diff = best_z - z;
  170. diff = diff < 0 ? -diff : diff;
  171. if (z <= BEST_Z_INVALID || best_z <= BEST_Z_INVALID || diff < 12.0)
  172. z = best_z;
  173. else
  174. return true;
  175. //look at current location
  176. if(LineIntersectsZone(start, end, step_mag, result))
  177. {
  178. return true;
  179. }
  180. //move 1 step
  181. if (cur.x != end.x)
  182. cur.x += step.x;
  183. if (cur.y != end.y)
  184. cur.y += step.y;
  185. if (cur.z != end.z)
  186. cur.z += step.z;
  187. //watch for end conditions
  188. if ( (cur.x > end.x && end.x >= start.x) || (cur.x < end.x && end.x <= start.x) || (step.x == 0) ) {
  189. cur.x = end.x;
  190. }
  191. if ( (cur.y > end.y && end.y >= start.y) || (cur.y < end.y && end.y <= start.y) || (step.y == 0) ) {
  192. cur.y = end.y;
  193. }
  194. if ( (cur.z > end.z && end.z >= start.z) || (cur.z < end.z && end.z < start.z) || (step.z == 0) ) {
  195. cur.z = end.z;
  196. }
  197. }
  198. //walked entire line and didnt run into anything...
  199. return false;
  200. }
  201. bool Map::CheckLoS(glm::vec3 myloc, glm::vec3 oloc)
  202. {
  203. if (!IsMapLoaded())
  204. return false;
  205. if(!imp)
  206. return false;
  207. return !imp->rm->raycast((const RmReal*)&myloc, (const RmReal*)&oloc, nullptr, nullptr, nullptr);
  208. }
  209. // returns true if a collision happens
  210. bool Map::DoCollisionCheck(glm::vec3 myloc, glm::vec3 oloc, glm::vec3 &outnorm, float &distance) {
  211. if (!IsMapLoaded())
  212. return false;
  213. if(!imp)
  214. return false;
  215. return imp->rm->raycast((const RmReal*)&myloc, (const RmReal*)&oloc, nullptr, (RmReal *)&outnorm, (RmReal *)&distance);
  216. }
  217. Map *Map::LoadMapFile(std::string zonename, std::string file, SPGrid* grid) {
  218. std::string filename = "Maps/";
  219. filename += file;
  220. std::string deflatedFileName = filename + ".EQ2MapDeflated";
  221. filename += ".EQ2Map";
  222. if(file_exists(deflatedFileName))
  223. filename = deflatedFileName;
  224. LogWrite(MAP__INFO, 7, "Map", "Attempting to load Map File [{%s}]", filename.c_str());
  225. auto m = new Map(zonename, file, grid);
  226. m->SetMapLoading(true);
  227. m->SetFileName(filename);
  228. #ifdef WIN32
  229. _beginthread(LoadMapAsync, 0, (void*)m);
  230. #else
  231. pthread_t t1;
  232. pthread_create(&t1, NULL, LoadMapAsync, (void*)m);
  233. pthread_detach(t1);
  234. #endif
  235. return m;
  236. }
  237. /**
  238. * @param filename
  239. * @return
  240. */
  241. bool Map::Load(const std::string &filename)
  242. {
  243. FILE *map_file = fopen(filename.c_str(), "rb");
  244. if (map_file) {
  245. LogWrite(MAP__INFO, 7, "Map", "Loading Map File [{%s}]", filename.c_str());
  246. bool loaded_map_file = LoadV2(map_file);
  247. fclose(map_file);
  248. if (loaded_map_file) {
  249. LogWrite(MAP__INFO, 7, "Map", "Loaded Map File [{%s}]", filename.c_str());
  250. }
  251. else {
  252. LogWrite(MAP__ERROR, 7, "Map", "FAILED Loading Map File [{%s}]", filename.c_str());
  253. }
  254. return loaded_map_file;
  255. }
  256. else {
  257. return false;
  258. }
  259. return false;
  260. }
  261. struct ModelEntry
  262. {
  263. struct Poly
  264. {
  265. uint32 v1, v2, v3;
  266. uint8 vis;
  267. };
  268. std::vector<glm::vec3> verts;
  269. std::vector<Poly> polys;
  270. };
  271. bool Map::LoadV2(FILE* f) {
  272. std::size_t foundDeflated = m_FileName.find(".EQ2MapDeflated");
  273. if(foundDeflated != std::string::npos)
  274. return LoadV2Deflated(f);
  275. // Read the string for the zone file name this was created for
  276. int8 strSize;
  277. char name[256];
  278. fread(&strSize, sizeof(int8), 1, f);
  279. LogWrite(MAP__DEBUG, 0, "Map", "strSize = %u", strSize);
  280. size_t len = fread(&name, sizeof(char), strSize, f);
  281. name[len] = '\0';
  282. LogWrite(MAP__DEBUG, 0, "Map", "name = %s", name);
  283. string fileName(name);
  284. std::size_t found = fileName.find(m_ZoneName);
  285. // Make sure file contents are for the correct zone
  286. if (found == std::string::npos) {
  287. fclose(f);
  288. LogWrite(MAP__ERROR, 0, "Map", "Map::LoadV2() map contents (%s) do not match its name (%s).", &name, m_ZoneName.c_str());
  289. return false;
  290. }
  291. // Read the min bounds
  292. fread(&m_MinX, sizeof(float), 1, f);
  293. fread(&m_MinZ, sizeof(float), 1, f);
  294. // Read the max bounds
  295. fread(&m_MaxX, sizeof(float), 1, f);
  296. fread(&m_MaxZ, sizeof(float), 1, f);
  297. // Calculate how many cells we need
  298. // in both the X and Z direction
  299. float width = m_MaxX - m_MinX;
  300. float height = m_MaxZ - m_MinZ;
  301. m_NumCellsX = ceil(width / m_CellSize);
  302. m_NumCellsZ = ceil(height / m_CellSize);
  303. if (mGrid != nullptr)
  304. mGrid->InitValues(m_MinX, m_MaxX, m_MinZ, m_MaxZ, m_NumCellsX, m_NumCellsZ);
  305. // Read the number of grids
  306. int32 NumGrids;
  307. fread(&NumGrids, sizeof(int32), 1, f);
  308. std::vector<glm::vec3> verts;
  309. std::vector<uint32> indices;
  310. uint32 face_count = 0;
  311. // Loop through the grids loading the face list
  312. for (int32 i = 0; i < NumGrids; i++) {
  313. // Read the grid id
  314. int32 GridID;
  315. fread(&GridID, sizeof(int32), 1, f);
  316. // Read the number of vertices
  317. int32 NumFaces;
  318. fread(&NumFaces, sizeof(int32), 1, f);
  319. face_count += NumFaces;
  320. // Loop through the vertices list reading
  321. // 3 at a time to creat a triangle (face)
  322. for (int32 y = 0; y < NumFaces; ) {
  323. // Each vertex need an x,y,z coordinate and
  324. // we will be reading 3 to create the face
  325. float x1, x2, x3;
  326. float y1, y2, y3;
  327. float z1, z2, z3;
  328. // Read the first vertex
  329. fread(&x1, sizeof(float), 1, f);
  330. fread(&y1, sizeof(float), 1, f);
  331. fread(&z1, sizeof(float), 1, f);
  332. y++;
  333. // Read the second vertex
  334. fread(&x2, sizeof(float), 1, f);
  335. fread(&y2, sizeof(float), 1, f);
  336. fread(&z2, sizeof(float), 1, f);
  337. y++;
  338. // Read the third (final) vertex
  339. fread(&x3, sizeof(float), 1, f);
  340. fread(&y3, sizeof(float), 1, f);
  341. fread(&z3, sizeof(float), 1, f);
  342. y++;
  343. glm::vec3 a(x1, z1, y1);
  344. glm::vec3 b(x2, z2, y2);
  345. glm::vec3 c(x3, z3, y3);
  346. size_t sz = verts.size();
  347. verts.push_back(a);
  348. indices.push_back((uint32)sz);
  349. verts.push_back(b);
  350. indices.push_back((uint32)sz + 1);
  351. verts.push_back(c);
  352. indices.push_back((uint32)sz + 2);
  353. if (mGrid != nullptr)
  354. {
  355. Face* face = new Face;
  356. face->Vertex1[0] = x1;
  357. face->Vertex1[1] = y1;
  358. face->Vertex1[2] = z1;
  359. face->Vertex2[0] = x2;
  360. face->Vertex2[1] = y2;
  361. face->Vertex2[2] = z2;
  362. face->Vertex3[0] = x3;
  363. face->Vertex3[1] = y3;
  364. face->Vertex3[2] = z3;
  365. mGrid->AddFace(face, GridID);
  366. }
  367. }
  368. }
  369. face_count = face_count / 3;
  370. if (imp) {
  371. imp->rm->release();
  372. imp->rm = nullptr;
  373. }
  374. else {
  375. imp = new impl;
  376. }
  377. imp->rm = createRaycastMesh((RmUint32)verts.size(), (const RmReal*)&verts[0], face_count, &indices[0]);
  378. if (!imp->rm) {
  379. delete imp;
  380. imp = nullptr;
  381. return false;
  382. }
  383. return true;
  384. }
  385. bool Map::LoadV2Deflated(FILE* f) {
  386. std::ifstream file(m_FileName.c_str(), ios_base::in | ios_base::binary);
  387. boost::iostreams::filtering_streambuf<boost::iostreams::input> inbuf;
  388. inbuf.push(boost::iostreams::gzip_decompressor());
  389. inbuf.push(file);
  390. ostream out(&inbuf);
  391. std::streambuf * const srcbuf = out.rdbuf();
  392. std::streamsize size = srcbuf->in_avail();
  393. if(size == -1)
  394. {
  395. file.close();
  396. LogWrite(MAP__ERROR, 0, "Map", "Map::LoadV2Deflated() unable to deflate (%s).", m_ZoneFile.c_str());
  397. return false;
  398. }
  399. // Read the string for the zone file name this was created for
  400. int8 strSize;
  401. char* buf = new char[1024];
  402. srcbuf->sgetn(buf,sizeof(int8));
  403. memcpy(&strSize,&buf[0],sizeof(int8));
  404. LogWrite(MAP__DEBUG, 0, "Map", "strSize = %u", strSize);
  405. char name[256];
  406. srcbuf->sgetn(&name[0],strSize);
  407. name[strSize] = '\0';
  408. LogWrite(MAP__DEBUG, 0, "Map", "name = %s", name);
  409. string fileName(name);
  410. std::size_t found = fileName.find(m_ZoneName);
  411. // Make sure file contents are for the correct zone
  412. if (found == std::string::npos) {
  413. file.close();
  414. safe_delete_array(buf);
  415. LogWrite(MAP__ERROR, 0, "Map", "Map::LoadV2Deflated() map contents (%s) do not match its name (%s).", &name, m_ZoneFile.c_str());
  416. return false;
  417. }
  418. // Read the min bounds
  419. srcbuf->sgetn(buf,sizeof(float));
  420. memcpy(&m_MinX,&buf[0],sizeof(float));
  421. srcbuf->sgetn(buf,sizeof(float));
  422. memcpy(&m_MinZ,&buf[0],sizeof(float));
  423. srcbuf->sgetn(buf,sizeof(float));
  424. memcpy(&m_MaxX,&buf[0],sizeof(float));
  425. srcbuf->sgetn(buf,sizeof(float));
  426. memcpy(&m_MaxZ,&buf[0],sizeof(float));
  427. // Calculate how many cells we need
  428. // in both the X and Z direction
  429. float width = m_MaxX - m_MinX;
  430. float height = m_MaxZ - m_MinZ;
  431. m_NumCellsX = ceil(width / m_CellSize);
  432. m_NumCellsZ = ceil(height / m_CellSize);
  433. if (mGrid != nullptr)
  434. mGrid->InitValues(m_MinX, m_MaxX, m_MinZ, m_MaxZ, m_NumCellsX, m_NumCellsZ);
  435. // Read the number of grids
  436. int32 NumGrids;
  437. srcbuf->sgetn(buf,sizeof(int32));
  438. memcpy(&NumGrids,&buf[0],sizeof(int32));
  439. std::vector<glm::vec3> verts;
  440. std::vector<uint32> indices;
  441. uint32 face_count = 0;
  442. // Loop through the grids loading the face list
  443. for (int32 i = 0; i < NumGrids; i++) {
  444. // Read the grid id
  445. int32 GridID;
  446. srcbuf->sgetn(buf,sizeof(int32));
  447. memcpy(&GridID,&buf[0],sizeof(int32));
  448. // Read the number of vertices
  449. int32 NumFaces;
  450. srcbuf->sgetn(buf,sizeof(int32));
  451. memcpy(&NumFaces,&buf[0],sizeof(int32));
  452. face_count += NumFaces;
  453. // Loop through the vertices list reading
  454. // 3 at a time to creat a triangle (face)
  455. for (int32 y = 0; y < NumFaces; ) {
  456. // Each vertex need an x,y,z coordinate and
  457. // we will be reading 3 to create the face
  458. float x1, x2, x3;
  459. float y1, y2, y3;
  460. float z1, z2, z3;
  461. // Read the first vertex
  462. srcbuf->sgetn(buf,sizeof(float)*3);
  463. memcpy(&x1,&buf[0],sizeof(float));
  464. memcpy(&y1,&buf[4],sizeof(float));
  465. memcpy(&z1,&buf[8],sizeof(float));
  466. y++;
  467. // Read the second vertex
  468. srcbuf->sgetn(buf,sizeof(float)*3);
  469. memcpy(&x2,&buf[0],sizeof(float));
  470. memcpy(&y2,&buf[4],sizeof(float));
  471. memcpy(&z2,&buf[8],sizeof(float));
  472. y++;
  473. // Read the third (final) vertex
  474. srcbuf->sgetn(buf,sizeof(float)*3);
  475. memcpy(&x3,&buf[0],sizeof(float));
  476. memcpy(&y3,&buf[4],sizeof(float));
  477. memcpy(&z3,&buf[8],sizeof(float));
  478. y++;
  479. glm::vec3 a(x1, z1, y1);
  480. glm::vec3 b(x2, z2, y2);
  481. glm::vec3 c(x3, z3, y3);
  482. size_t sz = verts.size();
  483. verts.push_back(a);
  484. indices.push_back((uint32)sz);
  485. verts.push_back(b);
  486. indices.push_back((uint32)sz + 1);
  487. verts.push_back(c);
  488. indices.push_back((uint32)sz + 2);
  489. if (mGrid != nullptr)
  490. {
  491. Face* face = new Face;
  492. face->Vertex1[0] = x1;
  493. face->Vertex1[1] = y1;
  494. face->Vertex1[2] = z1;
  495. face->Vertex2[0] = x2;
  496. face->Vertex2[1] = y2;
  497. face->Vertex2[2] = z2;
  498. face->Vertex3[0] = x3;
  499. face->Vertex3[1] = y3;
  500. face->Vertex3[2] = z3;
  501. mGrid->AddFace(face, GridID);
  502. }
  503. }
  504. }
  505. face_count = face_count / 3;
  506. if (imp) {
  507. imp->rm->release();
  508. imp->rm = nullptr;
  509. }
  510. else {
  511. imp = new impl;
  512. }
  513. imp->rm = createRaycastMesh((RmUint32)verts.size(), (const RmReal*)&verts[0], face_count, &indices[0]);
  514. file.close();
  515. safe_delete_array(buf);
  516. if (!imp->rm) {
  517. delete imp;
  518. imp = nullptr;
  519. return false;
  520. }
  521. return true;
  522. }
  523. void Map::RotateVertex(glm::vec3 &v, float rx, float ry, float rz) {
  524. glm::vec3 nv = v;
  525. nv.y = (std::cos(rx) * v.y) - (std::sin(rx) * v.z);
  526. nv.z = (std::sin(rx) * v.y) + (std::cos(rx) * v.z);
  527. v = nv;
  528. nv.x = (std::cos(ry) * v.x) + (std::sin(ry) * v.z);
  529. nv.z = -(std::sin(ry) * v.x) + (std::cos(ry) * v.z);
  530. v = nv;
  531. nv.x = (std::cos(rz) * v.x) - (std::sin(rz) * v.y);
  532. nv.y = (std::sin(rz) * v.x) + (std::cos(rz) * v.y);
  533. v = nv;
  534. }
  535. void Map::ScaleVertex(glm::vec3 &v, float sx, float sy, float sz) {
  536. v.x = v.x * sx;
  537. v.y = v.y * sy;
  538. v.z = v.z * sz;
  539. }
  540. void Map::TranslateVertex(glm::vec3 &v, float tx, float ty, float tz) {
  541. v.x = v.x + tx;
  542. v.y = v.y + ty;
  543. v.z = v.z + tz;
  544. }
  545. void MapRange::AddVersionRange(std::string zoneName) {
  546. boost::filesystem::path targetDir("Maps/");
  547. // crash fix since the dir isn't present
  548. if(!boost::filesystem::is_directory(targetDir))
  549. {
  550. LogWrite(MAP__ERROR, 7, "Map", "Unable to find directory %s", targetDir.c_str());
  551. return;
  552. }
  553. boost::filesystem::recursive_directory_iterator iter(targetDir), eod;
  554. boost::smatch base_match;
  555. std::string formula = "(.*\\/|.*\\\\)((" + zoneName + ")(\\-([0-9]+)\\-([0-9]+))?)(\\.EQ2Map|\\.EQ2MapDeflated)$";
  556. boost::regex re(formula.c_str());
  557. LogWrite(MAP__INFO, 0, "Map", "Map Formula to match: %s", formula.c_str());
  558. BOOST_FOREACH(boost::filesystem::path
  559. const & i, make_pair(iter, eod)) {
  560. if (is_regular_file(i)) {
  561. std::string fileName(i.string());
  562. if (boost::regex_match(fileName, base_match, re)) {
  563. boost::ssub_match base_sub_match = base_match[2];
  564. boost::ssub_match base_sub_match2 = base_match[5];
  565. boost::ssub_match base_sub_match3 = base_match[6];
  566. std::string baseMatch(base_sub_match.str().c_str());
  567. std::string baseMatch2(base_sub_match2.str().c_str());
  568. std::string baseMatch3(base_sub_match3.str().c_str());
  569. LogWrite(MAP__INFO, 0, "Map", "Map To Load: %s, size: %i, string: %s, min: %s, max: %s\n", i.string().c_str(), base_match.size(), baseMatch.c_str(), baseMatch2.c_str(), baseMatch3.c_str());
  570. SPGrid * Grid = new SPGrid(base_sub_match.str().c_str(), 0);
  571. Map * zonemap = Map::LoadMapFile(zoneName, base_sub_match.str().c_str(), Grid);
  572. int32 min_version = 0, max_version = 0;
  573. if (strlen(base_sub_match2.str().c_str()) > 0)
  574. min_version = atoul(base_sub_match2.str().c_str());
  575. if (strlen(base_sub_match2.str().c_str()) > 0)
  576. max_version = atoul(base_sub_match3.str().c_str());
  577. version_map.insert(std::make_pair(new VersionRange(min_version, max_version), zonemap));
  578. }
  579. }
  580. }
  581. }
  582. MapRange::MapRange()
  583. {
  584. }
  585. MapRange::~MapRange()
  586. {
  587. Clear();
  588. }
  589. void MapRange::Clear()
  590. {
  591. map<VersionRange*, Map*>::iterator itr;
  592. for (itr = version_map.begin(); itr != version_map.end(); itr++)
  593. {
  594. VersionRange* range = itr->first;
  595. Map* map = itr->second;
  596. delete range;
  597. delete map;
  598. }
  599. version_map.clear();
  600. }
  601. map<VersionRange*, Map*>::iterator MapRange::FindVersionRange(int32 min_version, int32 max_version)
  602. {
  603. map<VersionRange*, Map*>::iterator itr;
  604. for (itr = version_map.begin(); itr != version_map.end(); itr++)
  605. {
  606. VersionRange* range = itr->first;
  607. // if min and max version are both in range
  608. if (range->GetMinVersion() <= min_version && max_version <= range->GetMaxVersion())
  609. return itr;
  610. // if the min version is in range, but max range is 0
  611. else if (range->GetMinVersion() <= min_version && range->GetMaxVersion() == 0)
  612. return itr;
  613. // if min version is 0 and max_version has a cap
  614. else if (range->GetMinVersion() == 0 && max_version <= range->GetMaxVersion())
  615. return itr;
  616. }
  617. return version_map.end();
  618. }
  619. map<VersionRange*, Map*>::iterator MapRange::FindMapByVersion(int32 version)
  620. {
  621. map<VersionRange*, Map*>::iterator enditr = version_map.end();
  622. map<VersionRange*, Map*>::iterator itr;
  623. for (itr = version_map.begin(); itr != version_map.end(); itr++)
  624. {
  625. VersionRange* range = itr->first;
  626. // if min and max version are both in range
  627. if(range->GetMinVersion() == 0 && range->GetMaxVersion() == 0)
  628. enditr = itr;
  629. else if (version >= range->GetMinVersion() && version <= range->GetMaxVersion())
  630. return itr;
  631. }
  632. return enditr;
  633. }