TrinityCore
GridMap.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "GridMap.h"
19#include "DB2Stores.h"
20#include "GridDefines.h"
21#include "Log.h"
22#include <G3D/Plane.h>
23#include <G3D/Ray.h>
24
25// *****************************
26// Grid function
27// *****************************
29{
30 _flags = 0;
31 // Area data
32 _gridArea = 0;
33 _areaMap = nullptr;
34 // Height level data
38 m_V9 = nullptr;
39 m_V8 = nullptr;
40 _minHeightPlanes = nullptr;
41 // Liquid data
44 _liquidOffX = 0;
45 _liquidOffY = 0;
46 _liquidWidth = 0;
47 _liquidHeight = 0;
49 _liquidEntry = nullptr;
50 _liquidFlags = nullptr;
51 _liquidMap = nullptr;
52 _holes = nullptr;
53}
54
56{
57 unloadData();
58}
59
61{
62 // Unload old data if exist
63 unloadData();
64
65 map_fileheader header;
66 // Not return error if file not found
67 FILE* in = fopen(filename, "rb");
68 if (!in)
70
71 if (fread(&header, sizeof(header), 1, in) != 1)
72 {
73 fclose(in);
75 }
76
77 if (header.mapMagic == MapMagic && header.versionMagic == MapVersionMagic)
78 {
79 // load up area data
80 if (header.areaMapOffset && !loadAreaData(in, header.areaMapOffset, header.areaMapSize))
81 {
82 TC_LOG_ERROR("maps", "Error loading map area data\n");
83 fclose(in);
85 }
86 // load up height data
87 if (header.heightMapOffset && !loadHeightData(in, header.heightMapOffset, header.heightMapSize))
88 {
89 TC_LOG_ERROR("maps", "Error loading map height data\n");
90 fclose(in);
92 }
93 // load up liquid data
94 if (header.liquidMapOffset && !loadLiquidData(in, header.liquidMapOffset, header.liquidMapSize))
95 {
96 TC_LOG_ERROR("maps", "Error loading map liquids data\n");
97 fclose(in);
99 }
100 // loadup holes data (if any. check header.holesOffset)
101 if (header.holesSize && !loadHolesData(in, header.holesOffset, header.holesSize))
102 {
103 TC_LOG_ERROR("maps", "Error loading map holes data\n");
104 fclose(in);
106 }
107 fclose(in);
108 return LoadResult::Ok;
109 }
110
111 TC_LOG_ERROR("maps", "Map file '{}' is from an incompatible map version (%.*s v{}), %.*s v{} is expected. Please pull your source, recompile tools and recreate maps using the updated mapextractor, then replace your old map files with new files. If you still have problems search on forum for error TCE00018.",
112 filename, 4, header.mapMagic.data(), header.versionMagic, 4, MapMagic.data(), MapVersionMagic);
113 fclose(in);
115}
116
118{
119 delete[] _areaMap;
120 delete[] m_V9;
121 delete[] m_V8;
122 delete[] _minHeightPlanes;
123 delete[] _liquidEntry;
124 delete[] _liquidFlags;
125 delete[] _liquidMap;
126 delete[] _holes;
127 _areaMap = nullptr;
128 m_V9 = nullptr;
129 m_V8 = nullptr;
130 _minHeightPlanes = nullptr;
131 _liquidEntry = nullptr;
132 _liquidFlags = nullptr;
133 _liquidMap = nullptr;
134 _holes = nullptr;
136}
137
138bool GridMap::loadAreaData(FILE* in, uint32 offset, uint32 /*size*/)
139{
140 map_areaHeader header;
141 fseek(in, offset, SEEK_SET);
142
143 if (fread(&header, sizeof(header), 1, in) != 1 || header.areaMagic != MapAreaMagic)
144 return false;
145
146 _gridArea = header.gridArea;
148 {
149 _areaMap = new uint16[16 * 16];
150 if (fread(_areaMap, sizeof(uint16), 16*16, in) != 16*16)
151 return false;
152 }
153 return true;
154}
155
156bool GridMap::loadHeightData(FILE* in, uint32 offset, uint32 /*size*/)
157{
158 map_heightHeader header;
159 fseek(in, offset, SEEK_SET);
160
161 if (fread(&header, sizeof(header), 1, in) != 1 || header.heightMagic != MapHeightMagic)
162 return false;
163
164 _gridHeight = header.gridHeight;
166 {
168 {
169 m_uint16_V9 = new uint16 [129*129];
170 m_uint16_V8 = new uint16 [128*128];
171 if (fread(m_uint16_V9, sizeof(uint16), 129*129, in) != 129*129 ||
172 fread(m_uint16_V8, sizeof(uint16), 128*128, in) != 128*128)
173 return false;
174 _gridIntHeightMultiplier = (header.gridMaxHeight - header.gridHeight) / 65535;
176 }
178 {
179 m_uint8_V9 = new uint8 [129*129];
180 m_uint8_V8 = new uint8 [128*128];
181 if (fread(m_uint8_V9, sizeof(uint8), 129*129, in) != 129*129 ||
182 fread(m_uint8_V8, sizeof(uint8), 128*128, in) != 128*128)
183 return false;
184 _gridIntHeightMultiplier = (header.gridMaxHeight - header.gridHeight) / 255;
186 }
187 else
188 {
189 m_V9 = new float [129*129];
190 m_V8 = new float [128*128];
191 if (fread(m_V9, sizeof(float), 129*129, in) != 129*129 ||
192 fread(m_V8, sizeof(float), 128*128, in) != 128*128)
193 return false;
195 }
196 }
197 else
199
201 {
202 std::array<int16, 9> maxHeights;
203 std::array<int16, 9> minHeights;
204 if (fread(maxHeights.data(), sizeof(int16), maxHeights.size(), in) != maxHeights.size() ||
205 fread(minHeights.data(), sizeof(int16), minHeights.size(), in) != minHeights.size())
206 return false;
207
208 static uint32 constexpr indices[8][3] =
209 {
210 { 3, 0, 4 },
211 { 0, 1, 4 },
212 { 1, 2, 4 },
213 { 2, 5, 4 },
214 { 5, 8, 4 },
215 { 8, 7, 4 },
216 { 7, 6, 4 },
217 { 6, 3, 4 }
218 };
219
220 static float constexpr boundGridCoords[9][2] =
221 {
222 { 0.0f, 0.0f },
223 { 0.0f, -266.66666f },
224 { 0.0f, -533.33331f },
225 { -266.66666f, 0.0f },
226 { -266.66666f, -266.66666f },
227 { -266.66666f, -533.33331f },
228 { -533.33331f, 0.0f },
229 { -533.33331f, -266.66666f },
230 { -533.33331f, -533.33331f }
231 };
232
233 _minHeightPlanes = new G3D::Plane[8];
234 for (uint32 quarterIndex = 0; quarterIndex < 8; ++quarterIndex)
235 _minHeightPlanes[quarterIndex] = G3D::Plane(
236 G3D::Vector3(boundGridCoords[indices[quarterIndex][0]][0], boundGridCoords[indices[quarterIndex][0]][1], minHeights[indices[quarterIndex][0]]),
237 G3D::Vector3(boundGridCoords[indices[quarterIndex][1]][0], boundGridCoords[indices[quarterIndex][1]][1], minHeights[indices[quarterIndex][1]]),
238 G3D::Vector3(boundGridCoords[indices[quarterIndex][2]][0], boundGridCoords[indices[quarterIndex][2]][1], minHeights[indices[quarterIndex][2]])
239 );
240 }
241
242 return true;
243}
244
245bool GridMap::loadLiquidData(FILE* in, uint32 offset, uint32 /*size*/)
246{
247 map_liquidHeader header;
248 fseek(in, offset, SEEK_SET);
249
250 if (fread(&header, sizeof(header), 1, in) != 1 || header.liquidMagic != MapLiquidMagic)
251 return false;
252
255 _liquidOffX = header.offsetX;
256 _liquidOffY = header.offsetY;
257 _liquidWidth = header.width;
258 _liquidHeight = header.height;
259 _liquidLevel = header.liquidLevel;
260
262 {
263 _liquidEntry = new uint16[16*16];
264 if (fread(_liquidEntry, sizeof(uint16), 16*16, in) != 16*16)
265 return false;
266
268 if (fread(_liquidFlags, sizeof(map_liquidHeaderTypeFlags), 16*16, in) != 16*16)
269 return false;
270 }
272 {
274 if (fread(_liquidMap, sizeof(float), _liquidWidth*_liquidHeight, in) != (uint32(_liquidWidth) * uint32(_liquidHeight)))
275 return false;
276 }
277 return true;
278}
279
280bool GridMap::loadHolesData(FILE* in, uint32 offset, uint32 /*size*/)
281{
282 if (fseek(in, offset, SEEK_SET) != 0)
283 return false;
284
285 _holes = new uint8[16 * 16 * 8];
286 if (fread(_holes, sizeof(uint8), 16 * 16 * 8, in) != 16 * 16 * 8)
287 return false;
288
289 return true;
290}
291
292uint16 GridMap::getArea(float x, float y) const
293{
294 if (!_areaMap)
295 return _gridArea;
296
297 x = 16 * (CENTER_GRID_ID - x/SIZE_OF_GRIDS);
298 y = 16 * (CENTER_GRID_ID - y/SIZE_OF_GRIDS);
299 int lx = (int)x & 15;
300 int ly = (int)y & 15;
301 return _areaMap[lx*16 + ly];
302}
303
304float GridMap::getHeightFromFlat(float /*x*/, float /*y*/) const
305{
306 return _gridHeight;
307}
308
309float GridMap::getHeightFromFloat(float x, float y) const
310{
311 if (!m_V8 || !m_V9)
312 return _gridHeight;
313
316
317 int x_int = (int)x;
318 int y_int = (int)y;
319 x -= x_int;
320 y -= y_int;
321 x_int&=(MAP_RESOLUTION - 1);
322 y_int&=(MAP_RESOLUTION - 1);
323
324 if (isHole(x_int, y_int))
325 return INVALID_HEIGHT;
326
327 // Height stored as: h5 - its v8 grid, h1-h4 - its v9 grid
328 // +--------------> X
329 // | h1-------h2 Coordinates is:
330 // | | \ 1 / | h1 0, 0
331 // | | \ / | h2 0, 1
332 // | | 2 h5 3 | h3 1, 0
333 // | | / \ | h4 1, 1
334 // | | / 4 \ | h5 1/2, 1/2
335 // | h3-------h4
336 // V Y
337 // For find height need
338 // 1 - detect triangle
339 // 2 - solve linear equation from triangle points
340 // Calculate coefficients for solve h = a*x + b*y + c
341
342 float a, b, c;
343 // Select triangle:
344 if (x+y < 1)
345 {
346 if (x > y)
347 {
348 // 1 triangle (h1, h2, h5 points)
349 float h1 = m_V9[(x_int)*129 + y_int];
350 float h2 = m_V9[(x_int+1)*129 + y_int];
351 float h5 = 2 * m_V8[x_int*128 + y_int];
352 a = h2-h1;
353 b = h5-h1-h2;
354 c = h1;
355 }
356 else
357 {
358 // 2 triangle (h1, h3, h5 points)
359 float h1 = m_V9[x_int*129 + y_int ];
360 float h3 = m_V9[x_int*129 + y_int+1];
361 float h5 = 2 * m_V8[x_int*128 + y_int];
362 a = h5 - h1 - h3;
363 b = h3 - h1;
364 c = h1;
365 }
366 }
367 else
368 {
369 if (x > y)
370 {
371 // 3 triangle (h2, h4, h5 points)
372 float h2 = m_V9[(x_int+1)*129 + y_int ];
373 float h4 = m_V9[(x_int+1)*129 + y_int+1];
374 float h5 = 2 * m_V8[x_int*128 + y_int];
375 a = h2 + h4 - h5;
376 b = h4 - h2;
377 c = h5 - h4;
378 }
379 else
380 {
381 // 4 triangle (h3, h4, h5 points)
382 float h3 = m_V9[(x_int)*129 + y_int+1];
383 float h4 = m_V9[(x_int+1)*129 + y_int+1];
384 float h5 = 2 * m_V8[x_int*128 + y_int];
385 a = h4 - h3;
386 b = h3 + h4 - h5;
387 c = h5 - h4;
388 }
389 }
390 // Calculate height
391 return a * x + b * y + c;
392}
393
394float GridMap::getHeightFromUint8(float x, float y) const
395{
396 if (!m_uint8_V8 || !m_uint8_V9)
397 return _gridHeight;
398
401
402 int x_int = (int)x;
403 int y_int = (int)y;
404 x -= x_int;
405 y -= y_int;
406 x_int&=(MAP_RESOLUTION - 1);
407 y_int&=(MAP_RESOLUTION - 1);
408
409 if (isHole(x_int, y_int))
410 return INVALID_HEIGHT;
411
412 int32 a, b, c;
413 uint8 *V9_h1_ptr = &m_uint8_V9[x_int*128 + x_int + y_int];
414 if (x+y < 1)
415 {
416 if (x > y)
417 {
418 // 1 triangle (h1, h2, h5 points)
419 int32 h1 = V9_h1_ptr[ 0];
420 int32 h2 = V9_h1_ptr[129];
421 int32 h5 = 2 * m_uint8_V8[x_int*128 + y_int];
422 a = h2-h1;
423 b = h5-h1-h2;
424 c = h1;
425 }
426 else
427 {
428 // 2 triangle (h1, h3, h5 points)
429 int32 h1 = V9_h1_ptr[0];
430 int32 h3 = V9_h1_ptr[1];
431 int32 h5 = 2 * m_uint8_V8[x_int*128 + y_int];
432 a = h5 - h1 - h3;
433 b = h3 - h1;
434 c = h1;
435 }
436 }
437 else
438 {
439 if (x > y)
440 {
441 // 3 triangle (h2, h4, h5 points)
442 int32 h2 = V9_h1_ptr[129];
443 int32 h4 = V9_h1_ptr[130];
444 int32 h5 = 2 * m_uint8_V8[x_int*128 + y_int];
445 a = h2 + h4 - h5;
446 b = h4 - h2;
447 c = h5 - h4;
448 }
449 else
450 {
451 // 4 triangle (h3, h4, h5 points)
452 int32 h3 = V9_h1_ptr[ 1];
453 int32 h4 = V9_h1_ptr[130];
454 int32 h5 = 2 * m_uint8_V8[x_int*128 + y_int];
455 a = h4 - h3;
456 b = h3 + h4 - h5;
457 c = h5 - h4;
458 }
459 }
460 // Calculate height
461 return (float)((a * x) + (b * y) + c)*_gridIntHeightMultiplier + _gridHeight;
462}
463
464float GridMap::getHeightFromUint16(float x, float y) const
465{
466 if (!m_uint16_V8 || !m_uint16_V9)
467 return _gridHeight;
468
471
472 int x_int = (int)x;
473 int y_int = (int)y;
474 x -= x_int;
475 y -= y_int;
476 x_int&=(MAP_RESOLUTION - 1);
477 y_int&=(MAP_RESOLUTION - 1);
478
479 if (isHole(x_int, y_int))
480 return INVALID_HEIGHT;
481
482 int32 a, b, c;
483 uint16 *V9_h1_ptr = &m_uint16_V9[x_int*128 + x_int + y_int];
484 if (x+y < 1)
485 {
486 if (x > y)
487 {
488 // 1 triangle (h1, h2, h5 points)
489 int32 h1 = V9_h1_ptr[ 0];
490 int32 h2 = V9_h1_ptr[129];
491 int32 h5 = 2 * m_uint16_V8[x_int*128 + y_int];
492 a = h2-h1;
493 b = h5-h1-h2;
494 c = h1;
495 }
496 else
497 {
498 // 2 triangle (h1, h3, h5 points)
499 int32 h1 = V9_h1_ptr[0];
500 int32 h3 = V9_h1_ptr[1];
501 int32 h5 = 2 * m_uint16_V8[x_int*128 + y_int];
502 a = h5 - h1 - h3;
503 b = h3 - h1;
504 c = h1;
505 }
506 }
507 else
508 {
509 if (x > y)
510 {
511 // 3 triangle (h2, h4, h5 points)
512 int32 h2 = V9_h1_ptr[129];
513 int32 h4 = V9_h1_ptr[130];
514 int32 h5 = 2 * m_uint16_V8[x_int*128 + y_int];
515 a = h2 + h4 - h5;
516 b = h4 - h2;
517 c = h5 - h4;
518 }
519 else
520 {
521 // 4 triangle (h3, h4, h5 points)
522 int32 h3 = V9_h1_ptr[ 1];
523 int32 h4 = V9_h1_ptr[130];
524 int32 h5 = 2 * m_uint16_V8[x_int*128 + y_int];
525 a = h4 - h3;
526 b = h3 + h4 - h5;
527 c = h5 - h4;
528 }
529 }
530 // Calculate height
531 return (float)((a * x) + (b * y) + c)*_gridIntHeightMultiplier + _gridHeight;
532}
533
534bool GridMap::isHole(int row, int col) const
535{
536 if (!_holes)
537 return false;
538
539 int cellRow = row / 8; // 8 squares per cell
540 int cellCol = col / 8;
541 int holeRow = row % 8;
542 int holeCol = col % 8;
543
544 return (_holes[cellRow * 16 * 8 + cellCol * 8 + holeRow] & (1 << holeCol)) != 0;
545}
546
547float GridMap::getMinHeight(float x, float y) const
548{
549 if (!_minHeightPlanes)
550 return -500.0f;
551
553
554 int32 doubleGridX = int32(std::floor(-(x - MAP_HALFSIZE) / CENTER_GRID_OFFSET));
555 int32 doubleGridY = int32(std::floor(-(y - MAP_HALFSIZE) / CENTER_GRID_OFFSET));
556
557 float gx = x - (int32(gridCoord.x_coord) - CENTER_GRID_ID + 1) * SIZE_OF_GRIDS;
558 float gy = y - (int32(gridCoord.y_coord) - CENTER_GRID_ID + 1) * SIZE_OF_GRIDS;
559
560 uint32 quarterIndex = 0;
561 if (doubleGridY & 1)
562 {
563 if (doubleGridX & 1)
564 quarterIndex = 4 + (gx <= gy);
565 else
566 quarterIndex = 2 + ((-SIZE_OF_GRIDS - gx) > gy);
567 }
568 else if (doubleGridX & 1)
569 quarterIndex = 6 + ((-SIZE_OF_GRIDS - gx) <= gy);
570 else
571 quarterIndex = gx > gy;
572
573 G3D::Ray ray = G3D::Ray::fromOriginAndDirection(G3D::Vector3(gx, gy, 0.0f), G3D::Vector3::unitZ());
574 return ray.intersection(_minHeightPlanes[quarterIndex]).z;
575}
576
577float GridMap::getLiquidLevel(float x, float y) const
578{
579 if (!_liquidMap)
580 return _liquidLevel;
581
584
585 int cx_int = ((int)x & (MAP_RESOLUTION-1)) - _liquidOffY;
586 int cy_int = ((int)y & (MAP_RESOLUTION-1)) - _liquidOffX;
587
588 if (cx_int < 0 || cx_int >=_liquidHeight)
589 return INVALID_HEIGHT;
590 if (cy_int < 0 || cy_int >=_liquidWidth)
591 return INVALID_HEIGHT;
592
593 return _liquidMap[cx_int*_liquidWidth + cy_int];
594}
595
596constexpr float GROUND_LEVEL_OFFSET_HACK = 0.02f; // due to floating point precision issues, we have to resort to a small hack to fix inconsistencies in liquids
597
598// Get water state on map
599ZLiquidStatus GridMap::GetLiquidStatus(float x, float y, float z, Optional<map_liquidHeaderTypeFlags> ReqLiquidType, LiquidData* data, float collisionHeight) const
600{
601 // Check water type (if no water return)
603 return LIQUID_MAP_NO_WATER;
604
605 // Get cell
608
609 int x_int = (int)cx & (MAP_RESOLUTION-1);
610 int y_int = (int)cy & (MAP_RESOLUTION-1);
611
612 // Check water type in cell
613 int idx=(x_int>>3)*16 + (y_int>>3);
616 if (LiquidTypeEntry const* liquidEntry = sLiquidTypeStore.LookupEntry(entry))
617 {
619 uint32 liqTypeIdx = liquidEntry->SoundBank;
620 if (entry < 21)
621 {
622 if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(getArea(x, y)))
623 {
624 uint32 overrideLiquid = area->LiquidTypeID[liquidEntry->SoundBank];
625 if (!overrideLiquid && area->ParentAreaID)
626 {
627 area = sAreaTableStore.LookupEntry(area->ParentAreaID);
628 if (area)
629 overrideLiquid = area->LiquidTypeID[liquidEntry->SoundBank];
630 }
631
632 if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(overrideLiquid))
633 {
634 entry = overrideLiquid;
635 liqTypeIdx = liq->SoundBank;
636 }
637 }
638 }
639
640 type |= map_liquidHeaderTypeFlags(1 << liqTypeIdx);
641 }
642
644 return LIQUID_MAP_NO_WATER;
645
646 // Check req liquid type mask
647 if (ReqLiquidType && (*ReqLiquidType & type) == map_liquidHeaderTypeFlags::NoWater)
648 return LIQUID_MAP_NO_WATER;
649
650 // Check water level:
651 // Check water height map
652 int lx_int = x_int - _liquidOffY;
653 int ly_int = y_int - _liquidOffX;
654 if (lx_int < 0 || lx_int >=_liquidHeight)
655 return LIQUID_MAP_NO_WATER;
656 if (ly_int < 0 || ly_int >=_liquidWidth)
657 return LIQUID_MAP_NO_WATER;
658
659 // Get water level
660 float liquid_level = _liquidMap ? _liquidMap[lx_int*_liquidWidth + ly_int] : _liquidLevel;
661 // Get ground level (sub 0.02 for fix some errors)
662 float ground_level = getHeight(x, y);
663
664 // Check water level and ground level
665 if (liquid_level < (ground_level - GROUND_LEVEL_OFFSET_HACK) || z < (ground_level - GROUND_LEVEL_OFFSET_HACK))
666 return LIQUID_MAP_NO_WATER;
667
668 // All ok in water -> store data
669 if (data)
670 {
671 data->entry = entry;
672 data->type_flags = type;
673 data->level = liquid_level;
674 data->depth_level = ground_level;
675 }
676
677 // For speed check as int values
678 float delta = liquid_level - z;
679
680 uint32 status = LIQUID_MAP_ABOVE_WATER; // Above water
681
682 if (delta > collisionHeight) // Under water
683 status = LIQUID_MAP_UNDER_WATER;
684 else if (delta > 0.0f) // In water
685 status = LIQUID_MAP_IN_WATER;
686 else if (delta > -0.1f) // Walk on water
687 status = LIQUID_MAP_WATER_WALK;
688
689 if (status != LIQUID_MAP_ABOVE_WATER)
690 if (std::fabs(ground_level - z) <= GROUND_HEIGHT_TOLERANCE)
691 status |= LIQUID_MAP_OCEAN_FLOOR;
692
693 return static_cast<ZLiquidStatus>(status);
694}
DB2Storage< LiquidTypeEntry > sLiquidTypeStore("LiquidType.db2", &LiquidTypeLoadInfo::Instance)
DB2Storage< AreaTableEntry > sAreaTableStore("AreaTable.db2", &AreaTableLoadInfo::Instance)
uint8_t uint8
Definition: Define.h:144
int16_t int16
Definition: Define.h:139
int32_t int32
Definition: Define.h:138
uint16_t uint16
Definition: Define.h:143
uint32_t uint32
Definition: Define.h:142
#define MAP_RESOLUTION
Definition: GridDefines.h:55
#define SIZE_OF_GRIDS
Definition: GridDefines.h:40
#define CENTER_GRID_ID
Definition: GridDefines.h:41
#define CENTER_GRID_OFFSET
Definition: GridDefines.h:43
#define MAP_HALFSIZE
Definition: GridDefines.h:58
#define INVALID_HEIGHT
Definition: GridDefines.h:61
constexpr float GROUND_LEVEL_OFFSET_HACK
Definition: GridMap.cpp:596
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:165
uint32 const MapVersionMagic
Definition: MapDefines.cpp:21
u_map_magic const MapAreaMagic
Definition: MapDefines.cpp:22
u_map_magic const MapLiquidMagic
Definition: MapDefines.cpp:24
u_map_magic const MapHeightMagic
Definition: MapDefines.cpp:23
u_map_magic const MapMagic
Definition: MapDefines.cpp:20
ZLiquidStatus
Definition: MapDefines.h:125
@ LIQUID_MAP_UNDER_WATER
Definition: MapDefines.h:130
@ LIQUID_MAP_OCEAN_FLOOR
Definition: MapDefines.h:131
@ LIQUID_MAP_NO_WATER
Definition: MapDefines.h:126
@ LIQUID_MAP_IN_WATER
Definition: MapDefines.h:129
@ LIQUID_MAP_ABOVE_WATER
Definition: MapDefines.h:127
@ LIQUID_MAP_WATER_WALK
Definition: MapDefines.h:128
map_liquidHeaderTypeFlags
Definition: MapDefines.h:97
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition: Optional.h:25
float const GROUND_HEIGHT_TOLERANCE
Definition: SharedDefines.h:25
constexpr bool HasFlag(T flag) const
Definition: EnumFlag.h:106
LoadResult
Definition: GridMap.h:87
LoadResult loadData(char const *filename)
Definition: GridMap.cpp:60
bool loadAreaData(FILE *in, uint32 offset, uint32 size)
Definition: GridMap.cpp:138
float getHeightFromFlat(float x, float y) const
Definition: GridMap.cpp:304
void unloadData()
Definition: GridMap.cpp:117
float getMinHeight(float x, float y) const
Definition: GridMap.cpp:547
bool isHole(int row, int col) const
Definition: GridMap.cpp:534
uint8 * m_uint8_V8
Definition: GridMap.h:43
GridMap()
Definition: GridMap.cpp:28
float _liquidLevel
Definition: GridMap.h:54
uint16 * m_uint16_V8
Definition: GridMap.h:42
~GridMap()
Definition: GridMap.cpp:55
uint16 getArea(float x, float y) const
Definition: GridMap.cpp:292
uint16 * _liquidEntry
Definition: GridMap.h:55
float getHeightFromFloat(float x, float y) const
Definition: GridMap.cpp:309
float getHeightFromUint16(float x, float y) const
Definition: GridMap.cpp:464
uint8 _liquidOffY
Definition: GridMap.h:62
map_liquidHeaderTypeFlags * _liquidFlags
Definition: GridMap.h:56
uint16 _liquidGlobalEntry
Definition: GridMap.h:59
map_liquidHeaderTypeFlags _liquidGlobalFlags
Definition: GridMap.h:60
uint8 _liquidOffX
Definition: GridMap.h:61
uint8 * m_uint8_V9
Definition: GridMap.h:37
float * _liquidMap
Definition: GridMap.h:57
uint32 _flags
Definition: GridMap.h:32
bool loadHolesData(FILE *in, uint32 offset, uint32 size)
Definition: GridMap.cpp:280
uint8 _liquidHeight
Definition: GridMap.h:64
uint16 * _areaMap
Definition: GridMap.h:51
float _gridIntHeightMultiplier
Definition: GridMap.h:48
uint8 _liquidWidth
Definition: GridMap.h:63
float getLiquidLevel(float x, float y) const
Definition: GridMap.cpp:577
float * m_V9
Definition: GridMap.h:35
G3D::Plane * _minHeightPlanes
Definition: GridMap.h:45
uint16 _gridArea
Definition: GridMap.h:58
uint16 * m_uint16_V9
Definition: GridMap.h:36
float getHeightFromUint8(float x, float y) const
Definition: GridMap.cpp:394
float getHeight(float x, float y) const
Definition: GridMap.h:97
bool loadHeightData(FILE *in, uint32 offset, uint32 size)
Definition: GridMap.cpp:156
uint8 * _holes
Definition: GridMap.h:66
float _gridHeight
Definition: GridMap.h:47
GetHeightPtr _gridGetHeight
Definition: GridMap.h:76
ZLiquidStatus GetLiquidStatus(float x, float y, float z, Optional< map_liquidHeaderTypeFlags > ReqLiquidType, LiquidData *data=nullptr, float collisionHeight=2.03128f) const
Definition: GridMap.cpp:599
bool loadLiquidData(FILE *in, uint32 offset, uint32 size)
Definition: GridMap.cpp:245
float * m_V8
Definition: GridMap.h:41
GridCoord ComputeGridCoordSimple(float x, float y)
Definition: GridDefines.h:199
uint32 x_coord
Definition: GridDefines.h:173
uint32 y_coord
Definition: GridDefines.h:174
uint32 entry
Definition: MapDefines.h:140
EnumFlag< map_liquidHeaderTypeFlags > type_flags
Definition: MapDefines.h:139
float depth_level
Definition: MapDefines.h:142
float level
Definition: MapDefines.h:141
EnumFlag< map_areaHeaderFlags > flags
Definition: MapDefines.h:64
uint16 gridArea
Definition: MapDefines.h:65
u_map_magic areaMagic
Definition: MapDefines.h:63
u_map_magic mapMagic
Definition: MapDefines.h:40
uint32 holesSize
Definition: MapDefines.h:50
uint32 liquidMapSize
Definition: MapDefines.h:48
uint32 areaMapOffset
Definition: MapDefines.h:43
uint32 heightMapSize
Definition: MapDefines.h:46
uint32 heightMapOffset
Definition: MapDefines.h:45
uint32 holesOffset
Definition: MapDefines.h:49
uint32 versionMagic
Definition: MapDefines.h:41
uint32 liquidMapOffset
Definition: MapDefines.h:47
uint32 areaMapSize
Definition: MapDefines.h:44
float gridMaxHeight
Definition: MapDefines.h:84
EnumFlag< map_heightHeaderFlags > flags
Definition: MapDefines.h:82
u_map_magic heightMagic
Definition: MapDefines.h:81
u_map_magic liquidMagic
Definition: MapDefines.h:113
EnumFlag< map_liquidHeaderFlags > flags
Definition: MapDefines.h:114
EnumFlag< map_liquidHeaderTypeFlags > liquidFlags
Definition: MapDefines.h:115