67 FILE* in = fopen(filename,
"rb");
71 if (fread(&header,
sizeof(header), 1, in) != 1)
96 TC_LOG_ERROR(
"maps",
"Error loading map liquids data\n");
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.",
141 fseek(in, offset, SEEK_SET);
159 fseek(in, offset, SEEK_SET);
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)
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())
208 static uint32 constexpr indices[8][3] =
220 static float constexpr boundGridCoords[9][2] =
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 }
234 for (
uint32 quarterIndex = 0; quarterIndex < 8; ++quarterIndex)
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]])
248 fseek(in, offset, SEEK_SET);
282 if (fseek(in, offset, SEEK_SET) != 0)
286 if (fread(
_holes,
sizeof(
uint8), 16 * 16 * 8, in) != 16 * 16 * 8)
299 int lx = (int)x & 15;
300 int ly = (int)y & 15;
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];
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];
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];
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];
391 return a * x + b * y + c;
419 int32 h1 = V9_h1_ptr[ 0];
420 int32 h2 = V9_h1_ptr[129];
429 int32 h1 = V9_h1_ptr[0];
430 int32 h3 = V9_h1_ptr[1];
442 int32 h2 = V9_h1_ptr[129];
443 int32 h4 = V9_h1_ptr[130];
452 int32 h3 = V9_h1_ptr[ 1];
453 int32 h4 = V9_h1_ptr[130];
489 int32 h1 = V9_h1_ptr[ 0];
490 int32 h2 = V9_h1_ptr[129];
499 int32 h1 = V9_h1_ptr[0];
500 int32 h3 = V9_h1_ptr[1];
512 int32 h2 = V9_h1_ptr[129];
513 int32 h4 = V9_h1_ptr[130];
522 int32 h3 = V9_h1_ptr[ 1];
523 int32 h4 = V9_h1_ptr[130];
539 int cellRow = row / 8;
540 int cellCol = col / 8;
541 int holeRow = row % 8;
542 int holeCol = col % 8;
544 return (
_holes[cellRow * 16 * 8 + cellCol * 8 + holeRow] & (1 << holeCol)) != 0;
564 quarterIndex = 4 + (gx <= gy);
568 else if (doubleGridX & 1)
571 quarterIndex = gx > gy;
573 G3D::Ray ray = G3D::Ray::fromOriginAndDirection(G3D::Vector3(gx, gy, 0.0f), G3D::Vector3::unitZ());
613 int idx=(x_int>>3)*16 + (y_int>>3);
619 uint32 liqTypeIdx = liquidEntry->SoundBank;
624 uint32 overrideLiquid = area->LiquidTypeID[liquidEntry->SoundBank];
625 if (!overrideLiquid && area->ParentAreaID)
629 overrideLiquid = area->LiquidTypeID[liquidEntry->SoundBank];
634 entry = overrideLiquid;
635 liqTypeIdx = liq->SoundBank;
673 data->
level = liquid_level;
678 float delta = liquid_level - z;
682 if (delta > collisionHeight)
684 else if (delta > 0.0f)
686 else if (delta > -0.1f)
DB2Storage< LiquidTypeEntry > sLiquidTypeStore("LiquidType.db2", &LiquidTypeLoadInfo::Instance)
DB2Storage< AreaTableEntry > sAreaTableStore("AreaTable.db2", &AreaTableLoadInfo::Instance)
#define CENTER_GRID_OFFSET
constexpr float GROUND_LEVEL_OFFSET_HACK
#define TC_LOG_ERROR(filterType__,...)
uint32 const MapVersionMagic
u_map_magic const MapAreaMagic
u_map_magic const MapLiquidMagic
u_map_magic const MapHeightMagic
u_map_magic const MapMagic
map_liquidHeaderTypeFlags
std::optional< T > Optional
Optional helper class to wrap optional values within.
float const GROUND_HEIGHT_TOLERANCE
constexpr bool HasFlag(T flag) const
LoadResult loadData(char const *filename)
bool loadAreaData(FILE *in, uint32 offset, uint32 size)
float getHeightFromFlat(float x, float y) const
float getMinHeight(float x, float y) const
bool isHole(int row, int col) const
uint16 getArea(float x, float y) const
float getHeightFromFloat(float x, float y) const
float getHeightFromUint16(float x, float y) const
map_liquidHeaderTypeFlags * _liquidFlags
uint16 _liquidGlobalEntry
map_liquidHeaderTypeFlags _liquidGlobalFlags
bool loadHolesData(FILE *in, uint32 offset, uint32 size)
float _gridIntHeightMultiplier
float getLiquidLevel(float x, float y) const
G3D::Plane * _minHeightPlanes
float getHeightFromUint8(float x, float y) const
float getHeight(float x, float y) const
bool loadHeightData(FILE *in, uint32 offset, uint32 size)
GetHeightPtr _gridGetHeight
ZLiquidStatus GetLiquidStatus(float x, float y, float z, Optional< map_liquidHeaderTypeFlags > ReqLiquidType, LiquidData *data=nullptr, float collisionHeight=2.03128f) const
bool loadLiquidData(FILE *in, uint32 offset, uint32 size)
GridCoord ComputeGridCoordSimple(float x, float y)
EnumFlag< map_liquidHeaderTypeFlags > type_flags