27 #pragma warning(disable:4127)
38 template <
bool MetasVal
id, CombinatorFunc Combinator>
42 int a_SizeX,
int a_SizeY,
int a_SizeZ,
43 int a_SrcOffX,
int a_SrcOffY,
int a_SrcOffZ,
44 int a_DstOffX,
int a_DstOffY,
int a_DstOffZ,
45 int a_SrcSizeX,
int a_SrcSizeY,
int a_SrcSizeZ,
46 int a_DstSizeX,
int a_DstSizeY,
int a_DstSizeZ
51 for (
int y = 0; y < a_SizeY; y++)
53 int SrcBaseY = (y + a_SrcOffY) * a_SrcSizeX * a_SrcSizeZ;
54 int DstBaseY = (y + a_DstOffY) * a_DstSizeX * a_DstSizeZ;
55 for (
int z = 0; z < a_SizeZ; z++)
57 int SrcBaseZ = SrcBaseY + (z + a_SrcOffZ) * a_SrcSizeX;
58 int DstBaseZ = DstBaseY + (z + a_DstOffZ) * a_DstSizeX;
59 int SrcIdx = SrcBaseZ + a_SrcOffX;
60 int DstIdx = DstBaseZ + a_DstOffX;
61 for (
int x = 0; x < a_SizeX; x++)
65 Combinator(a_DstTypes[DstIdx], a_SrcTypes[SrcIdx], a_DstMetas[DstIdx], a_SrcMetas[SrcIdx]);
70 Combinator(a_DstTypes[DstIdx], a_SrcTypes[SrcIdx], FakeDestMeta,
static_cast<NIBBLETYPE>(0));
84 template <
bool MetaVal
id>
87 a_DstType = a_SrcType;
90 a_DstMeta = a_SrcMeta;
99 template <
bool MetaVal
id>
104 a_DstType = a_SrcType;
107 a_DstMeta = a_SrcMeta;
118 template <
bool MetaVal
id>
123 a_DstType = a_SrcType;
126 a_DstMeta = a_SrcMeta;
137 template <
bool MetaVal
id>
177 a_DstType = a_SrcType;
180 a_DstMeta = a_SrcMeta;
211 template <
bool MetaVal
id>
217 a_DstType = a_SrcType;
220 a_DstMeta = a_SrcMeta;
230 template <
bool MetaVal
id>
233 if ((a_DstType == a_SrcType) && (!MetaValid || (a_DstMeta == a_SrcMeta)))
243 a_DstType = a_SrcType;
246 a_DstMeta = a_SrcMeta;
256 template <
bool MetaVal
id>
259 if ((a_DstType == a_SrcType) && (!MetaValid || (a_DstMeta == a_SrcMeta)))
276 template <
bool MetaVal
id>
280 if ((a_SrcType != a_DstType) || !MetaValid || (a_SrcMeta != a_DstMeta))
309 if ((a_DataTypes &
baTypes) == 0)
348 LOGWARNING(
"Creating a cBlockArea with height larger than world height (%d). Continuing, but the area may misbehave.", a_SizeY);
352 SetSize(a_SizeX, a_SizeY, a_SizeZ, a_DataTypes);
362 Create(a_Size.
x, a_Size.
y, a_Size.
z, a_DataTypes);
408 (a_RelX >= 0) && (a_RelX <
m_Size.
x) &&
409 (a_RelY >= 0) && (a_RelY <
m_Size.
y) &&
410 (a_RelZ >= 0) && (a_RelZ <
m_Size.
z)
450 ASSERT(a_MinBlockX <= a_MaxBlockX);
451 ASSERT(a_MinBlockY <= a_MaxBlockY);
452 ASSERT(a_MinBlockZ <= a_MaxBlockZ);
461 if (!
SetSize(a_MaxBlockX - a_MinBlockX, a_MaxBlockY - a_MinBlockY, a_MaxBlockZ - a_MinBlockZ, a_DataTypes))
465 m_Origin.
Set(a_MinBlockX, a_MinBlockY, a_MinBlockZ);
469 int MinChunkX, MaxChunkX;
470 int MinChunkZ, MaxChunkZ;
475 if (!a_ForEachChunkProvider.
ForEachChunkInRect(MinChunkX, MaxChunkX, MinChunkZ, MaxChunkZ, Reader))
491 a_ForEachChunkProvider,
492 a_Bounds.
p1.
x, a_Bounds.
p2.
x,
493 a_Bounds.
p1.
y, a_Bounds.
p2.
y,
494 a_Bounds.
p1.
z, a_Bounds.
p2.
z,
506 a_ForEachChunkProvider,
507 a_Point1.
x, a_Point2.
x,
508 a_Point1.
y, a_Point2.
y,
509 a_Point1.
z, a_Point2.
z,
524 return a_ForEachChunkProvider.
WriteBlockArea(*
this, a_MinBlockX, a_MinBlockY, a_MinBlockZ, a_DataTypes);
534 a_ForEachChunkProvider,
535 a_MinCoords.
x, a_MinCoords.
y, a_MinCoords.
z,
548 LOGWARNING(
"Trying to copy a cBlockArea into self, ignoring.");
577 const auto & pos = keyPair.second->GetPos();
578 a_Into.
m_BlockEntities->emplace(keyPair.first, keyPair.second->Clone(pos));
601 LOGWARNING(
"cBlockArea: Cannot open file \"%s\" for raw dump", a_FileName.c_str());
610 unsigned char DataTypes =
static_cast<unsigned char>(
GetDataTypes());
611 f.
Write(&DataTypes, 1);
635 void cBlockArea::Crop(
int a_AddMinX,
int a_SubMaxX,
int a_AddMinY,
int a_SubMaxY,
int a_AddMinZ,
int a_SubMaxZ)
638 (a_AddMinX + a_SubMaxX >=
m_Size.
x) ||
639 (a_AddMinY + a_SubMaxY >=
m_Size.
y) ||
640 (a_AddMinZ + a_SubMaxZ >=
m_Size.
z)
643 LOGWARNING(
"cBlockArea:Crop called with more croping than the dimensions: %d x %d x %d with cropping %d, %d and %d",
645 a_AddMinX + a_SubMaxX, a_AddMinY + a_SubMaxY, a_AddMinZ + a_SubMaxZ
652 CropBlockTypes(a_AddMinX, a_SubMaxX, a_AddMinY, a_SubMaxY, a_AddMinZ, a_SubMaxZ);
668 const Vector3i AddMin{ a_AddMinX, a_AddMinY, a_AddMinZ };
674 for (
auto & keyPair: oldBE)
676 auto & be = keyPair.second;
677 auto Pos = be->GetPos();
678 if (CropBox.IsInside(Pos))
689 m_Size.
x -= a_AddMinX + a_SubMaxX;
690 m_Size.
y -= a_AddMinY + a_SubMaxY;
691 m_Size.
z -= a_AddMinZ + a_SubMaxZ;
698 void cBlockArea::Expand(
int a_SubMinX,
int a_AddMaxX,
int a_SubMinY,
int a_AddMaxY,
int a_SubMinZ,
int a_AddMaxZ)
702 ExpandBlockTypes(a_SubMinX, a_AddMaxX, a_SubMinY, a_AddMaxY, a_SubMinZ, a_AddMaxZ);
721 for (
auto & keyPair: oldBE)
723 auto & be = keyPair.second;
724 auto posX = be->GetPosX() + a_SubMinX;
725 auto posY = be->GetPosY() + a_SubMinY;
726 auto posZ = be->GetPosZ() + a_SubMinZ;
727 be->SetPos({posX, posY, posZ});
733 m_Size.
x += a_SubMinX + a_AddMaxX;
734 m_Size.
y += a_SubMinY + a_AddMaxY;
735 m_Size.
z += a_SubMinZ + a_AddMaxZ;
748 bool IsDummyMetas = ((SrcMetas ==
nullptr) || (DstMetas ==
nullptr));
752 MergeByStrategy<false>(a_Src, a_RelX, a_RelY, a_RelZ, a_Strategy, SrcMetas, DstMetas);
756 MergeByStrategy<true>(a_Src, a_RelX, a_RelY, a_RelZ, a_Strategy, SrcMetas, DstMetas);
766 Merge(a_Src, a_RelMinCoords.
x, a_RelMinCoords.
y, a_RelMinCoords.
z, a_Strategy);
777 LOGWARNING(
"%s: requested datatypes that are not present in the BlockArea object, trimming those away (req 0x%x, stor 0x%x)",
784 if ((a_DataTypes &
baTypes) != 0)
786 for (
size_t i = 0; i < BlockCount; i++)
791 if ((a_DataTypes &
baMetas) != 0)
793 for (
size_t i = 0; i < BlockCount; i++)
798 if ((a_DataTypes &
baLight) != 0)
800 for (
size_t i = 0; i < BlockCount; i++)
807 for (
size_t i = 0; i < BlockCount; i++)
838 LOGWARNING(
"%s: requested datatypes that are not present in the BlockArea object, trimming those away (req 0x%x, stor 0x%x)",
844 if ((a_DataTypes &
baTypes) != 0)
846 for (
int y = a_MinRelY; y <= a_MaxRelY; y++)
for (
int z = a_MinRelZ; z <= a_MaxRelZ; z++)
for (
int x = a_MinRelX; x <= a_MaxRelX; x++)
851 if ((a_DataTypes &
baMetas) != 0)
853 for (
int y = a_MinRelY; y <= a_MaxRelY; y++)
for (
int z = a_MinRelZ; z <= a_MaxRelZ; z++)
for (
int x = a_MinRelX; x <= a_MaxRelX; x++)
858 if ((a_DataTypes &
baLight) != 0)
860 for (
int y = a_MinRelY; y <= a_MaxRelY; y++)
for (
int z = a_MinRelZ; z <= a_MaxRelZ; z++)
for (
int x = a_MinRelX; x <= a_MaxRelX; x++)
867 for (
int y = a_MinRelY; y <= a_MaxRelY; y++)
for (
int z = a_MinRelZ; z <= a_MaxRelZ; z++)
for (
int x = a_MinRelX; x <= a_MaxRelX; x++)
897 a_RelCuboid.
p1.
x, a_RelCuboid.
p2.
x,
898 a_RelCuboid.
p1.
y, a_RelCuboid.
p2.
y,
899 a_RelCuboid.
p1.
z, a_RelCuboid.
p2.
z,
900 a_DataTypes, a_BlockType, a_BlockMeta, a_BlockLight, a_BlockSkyLight
914 int dx = abs(a_RelX2 - a_RelX1);
915 int dy = abs(a_RelY2 - a_RelY1);
916 int dz = abs(a_RelZ2 - a_RelZ1);
917 int sx = (a_RelX1 < a_RelX2) ? 1 : -1;
918 int sy = (a_RelY1 < a_RelY2) ? 1 : -1;
919 int sz = (a_RelZ1 < a_RelZ2) ? 1 : -1;
921 if (dx >= std::max(dy, dz))
923 int yd = dy - dx / 2;
924 int zd = dz - dx / 2;
928 RelSetData(a_RelX1, a_RelY1, a_RelZ1, a_DataTypes, a_BlockType, a_BlockMeta, a_BlockLight, a_BlockSkyLight);
930 if (a_RelX1 == a_RelX2)
953 else if (dy >= std::max(dx, dz))
955 int xd = dx - dy / 2;
956 int zd = dz - dy / 2;
960 RelSetData(a_RelX1, a_RelY1, a_RelZ1, a_DataTypes, a_BlockType, a_BlockMeta, a_BlockLight, a_BlockSkyLight);
962 if (a_RelY1 == a_RelY2)
988 ASSERT(dz >= std::max(dx, dy));
989 int xd = dx - dz / 2;
990 int yd = dy - dz / 2;
994 RelSetData(a_RelX1, a_RelY1, a_RelZ1, a_DataTypes, a_BlockType, a_BlockMeta, a_BlockLight, a_BlockSkyLight);
996 if (a_RelZ1 == a_RelZ2)
1031 a_Point1.
x, a_Point1.
y, a_Point1.
z,
1032 a_Point2.
x, a_Point2.
y, a_Point2.
z,
1033 a_DataTypes, a_BlockType, a_BlockMeta, a_BlockLight, a_BlockSkyLight
1045 LOGWARNING(
"cBlockArea: Cannot rotate blockmeta without blocktypes!");
1059 for (
int x = 0; x <
m_Size.
x; x++)
1062 for (
int z = 0; z <
m_Size.
z; z++)
1065 for (
int y = 0; y <
m_Size.
y; y++)
1082 for (
auto & keyPair: oldBE)
1084 auto & be = keyPair.second;
1085 auto newX = be->GetPosZ();
1086 auto newY = be->GetPosY();
1087 auto newZ =
m_Size.
x - be->GetPosX() - 1;
1089 be->SetPos({newX, newY, newZ});
1105 LOGWARNING(
"cBlockArea: Cannot rotate blockmeta without blocktypes!");
1119 for (
int x = 0; x <
m_Size.
x; x++)
1122 for (
int z = 0; z <
m_Size.
z; z++)
1125 for (
int y = 0; y <
m_Size.
y; y++)
1142 for (
auto & keyPair: oldBE)
1144 auto & be = keyPair.second;
1145 auto newX =
m_Size.
z - be->GetPosZ() - 1;
1146 auto newY = be->GetPosY();
1147 auto newZ = be->GetPosX();
1149 be->SetPos({newX, newY, newZ});
1165 LOGWARNING(
"cBlockArea: Cannot mirror meta without blocktypes!");
1179 for (
int y = 0; y <
m_Size.
y; y++)
1181 for (
int z = 0; z < HalfZ; z++)
1183 for (
int x = 0; x <
m_Size.
x; x++)
1201 for (
auto & keyPair: oldBE)
1203 auto & be = keyPair.second;
1204 auto newX = be->GetPosX();
1205 auto newY = be->GetPosY();
1206 auto newZ = MaxZ - be->GetPosZ();
1207 auto newIdx =
MakeIndex(newX, newY, newZ);
1208 be->SetPos({newX, newY, newZ});
1222 LOGWARNING(
"cBlockArea: Cannot mirror meta without blocktypes!");
1236 for (
int y = 0; y < HalfY; y++)
1238 for (
int z = 0; z <
m_Size.
z; z++)
1240 for (
int x = 0; x <
m_Size.
x; x++)
1258 for (
auto & keyPair: oldBE)
1260 auto & be = keyPair.second;
1261 auto newX = be->GetPosX();
1262 auto newY = MaxY - be->GetPosY();
1263 auto newZ = be->GetPosZ();
1264 auto newIdx =
MakeIndex(newX, newY, newZ);
1265 be->SetPos({newX, newY, newZ});
1279 LOGWARNING(
"cBlockArea: Cannot mirror meta without blocktypes!");
1293 for (
int y = 0; y <
m_Size.
y; y++)
1295 for (
int z = 0; z <
m_Size.
z; z++)
1297 for (
int x = 0; x < HalfX; x++)
1315 for (
auto & keyPair: oldBE)
1317 auto & be = keyPair.second;
1318 auto newX = MaxX - be->GetPosX();
1319 auto newY = be->GetPosY();
1320 auto newZ = be->GetPosZ();
1321 auto newIdx =
MakeIndex(newX, newY, newZ);
1322 be->SetPos({newX, newY, newZ});
1337 for (
int x = 0; x <
m_Size.
x; x++)
1340 for (
int z = 0; z <
m_Size.
z; z++)
1343 for (
int y = 0; y <
m_Size.
y; y++)
1354 for (
int x = 0; x <
m_Size.
x; x++)
1357 for (
int z = 0; z <
m_Size.
z; z++)
1360 for (
int y = 0; y <
m_Size.
y; y++)
1374 for (
auto & keyPair: oldBE)
1376 auto & be = keyPair.second;
1377 auto newX = be->GetPosZ();
1378 auto newY = be->GetPosY();
1379 auto newZ =
m_Size.
x - be->GetPosX() - 1;
1381 be->SetPos({newX, newY, newZ});
1398 for (
int z = 0; z <
m_Size.
z; z++)
1401 for (
int x = 0; x <
m_Size.
x; x++)
1404 for (
int y = 0; y <
m_Size.
y; y++)
1415 for (
int z = 0; z <
m_Size.
z; z++)
1418 for (
int x = 0; x <
m_Size.
x; x++)
1421 for (
int y = 0; y <
m_Size.
y; y++)
1435 for (
auto & keyPair: oldBE)
1437 auto & be = keyPair.second;
1438 auto newX =
m_Size.
z - be->GetPosZ() - 1;
1439 auto newY = be->GetPosY();
1440 auto newZ = be->GetPosX();
1442 be->SetPos({newX, newY, newZ});
1460 for (
int y = 0; y <
m_Size.
y; y++)
1462 for (
int z = 0; z < HalfZ; z++)
1464 for (
int x = 0; x <
m_Size.
x; x++)
1474 for (
int y = 0; y <
m_Size.
y; y++)
1476 for (
int z = 0; z < HalfZ; z++)
1478 for (
int x = 0; x <
m_Size.
x; x++)
1491 for (
auto & keyPair: oldBE)
1493 auto & be = keyPair.second;
1494 auto newX = be->GetPosX();
1495 auto newY = be->GetPosY();
1496 auto newZ = MaxZ - be->GetPosZ();
1497 auto newIdx =
MakeIndex(newX, newY, newZ);
1498 be->SetPos({newX, newY, newZ});
1514 for (
int y = 0; y < HalfY; y++)
1516 for (
int z = 0; z <
m_Size.
z; z++)
1518 for (
int x = 0; x <
m_Size.
x; x++)
1528 for (
int y = 0; y < HalfY; y++)
1530 for (
int z = 0; z <
m_Size.
z; z++)
1532 for (
int x = 0; x <
m_Size.
x; x++)
1545 for (
auto & keyPair: oldBE)
1547 auto & be = keyPair.second;
1548 auto newX = be->GetPosX();
1549 auto newY = MaxY - be->GetPosY();
1550 auto newZ = be->GetPosZ();
1551 auto newIdx =
MakeIndex(newX, newY, newZ);
1552 be->SetPos({newX, newY, newZ});
1568 for (
int y = 0; y <
m_Size.
y; y++)
1570 for (
int z = 0; z <
m_Size.
z; z++)
1572 for (
int x = 0; x < HalfX; x++)
1582 for (
int y = 0; y <
m_Size.
y; y++)
1584 for (
int z = 0; z <
m_Size.
z; z++)
1586 for (
int x = 0; x < HalfX; x++)
1599 for (
auto & keyPair: oldBE)
1601 auto & be = keyPair.second;
1602 auto newX = MaxX - be->GetPosX();
1603 auto newY = be->GetPosY();
1604 auto newZ = be->GetPosZ();
1605 auto newIdx =
MakeIndex(newX, newY, newZ);
1606 be->SetPos({newX, newY, newZ});
1619 auto idx =
MakeIndex(a_RelX, a_RelY, a_RelZ);
1628 if (itr->second->GetBlockType() == a_BlockType)
1714 LOGWARNING(
"cBlockArea: BlockTypes have not been read!");
1798 auto idx =
MakeIndex(a_RelX, a_RelY, a_RelZ);
1801 LOGWARNING(
"%s: BlockTypes not available but requested to be written to.", __FUNCTION__);
1809 LOGWARNING(
"%s: BlockMetas not available but requested to be written to.", __FUNCTION__);
1822 if (itr->second->GetBlockType() == a_BlockType)
1851 auto idx =
MakeIndex(a_RelX, a_RelY, a_RelZ);
1854 LOGWARNING(
"cBlockArea: BlockTypes have not been read!");
1864 LOGWARNING(
"cBlockArea: BlockMetas have not been read!");
1894 LOGWARNING(
"%s: BlockTypes have not been read!", __FUNCTION__);
1900 for (
int y = 0; y <
m_Size.
y; y++)
1902 for (
int z = 0; z <
m_Size.
z; z++)
1904 for (
int x = 0; x <
m_Size.
x; x++)
1925 LOGWARNING(
"%s: BlockTypes not available!", __FUNCTION__);
1932 for (
size_t i = 0; i < num; i++)
1951 LOGWARNING(
"%s: BlockTypes not available!", __FUNCTION__);
1958 LOGWARNING(
"%s: BlockMetas not available, comparing blocktypes only!", __FUNCTION__);
1965 for (
size_t i = 0; i < num; i++)
1984 LOGWARNING(
"%s: BlockTypes have not been read!", __FUNCTION__);
1991 int MaxX = 0, MinX =
m_Size.
x - 1;
1992 int MaxY = 0, MinY =
m_Size.
y - 1;
1993 int MaxZ = 0, MinZ =
m_Size.
z - 1;
1994 for (
int y = 0; y <
m_Size.
y; y++)
1996 for (
int z = 0; z <
m_Size.
z; z++)
1998 for (
int x = 0; x <
m_Size.
x; x++)
2087 if ((a_DataTypes &
baTypes) != 0)
2090 if (NewBlocks ==
nullptr)
2095 if ((a_DataTypes &
baMetas) != 0)
2098 if (NewMetas ==
nullptr)
2103 if ((a_DataTypes &
baLight) != 0)
2106 if (NewLight ==
nullptr)
2114 if (NewSkyLight ==
nullptr)
2122 if (NewBlockEntities ==
nullptr)
2151 return static_cast<size_t>(a_RelPos.
x + a_RelPos.
z * a_Size.
x + a_RelPos.
y * a_Size.
x * a_Size.
z);
2165 auto idx =
MakeIndex(a_RelX, a_RelY, a_RelZ);
2171 return a_Callback(*itr->second);
2195 if (a_Callback(*keyPair.second))
2209 if (a_Array ==
nullptr)
2211 LOGWARNING(
"cBlockArea: datatype has not been read!");
2214 a_Array[
MakeIndex(a_RelX, a_RelY, a_RelZ)] = a_Value;
2232 if (a_Array ==
nullptr)
2234 LOGWARNING(
"cBlockArea: datatype has not been read!");
2237 return a_Array[
MakeIndex(a_RelX, a_RelY, a_RelZ)];
2255 int NewSizeX =
GetSizeX() - a_AddMinX - a_SubMaxX;
2256 int NewSizeY =
GetSizeY() - a_AddMinY - a_SubMaxY;
2257 int NewSizeZ =
GetSizeZ() - a_AddMinZ - a_SubMaxZ;
2260 for (
int y = 0; y < NewSizeY; y++)
2262 for (
int z = 0; z < NewSizeZ; z++)
2264 for (
int x = 0; x < NewSizeX; x++)
2266 auto OldIndex =
MakeIndex(x + a_AddMinX, y + a_AddMinY, z + a_AddMinZ);
2280 int NewSizeX =
GetSizeX() - a_AddMinX - a_SubMaxX;
2281 int NewSizeY =
GetSizeY() - a_AddMinY - a_SubMaxY;
2282 int NewSizeZ =
GetSizeZ() - a_AddMinZ - a_SubMaxZ;
2285 for (
int y = 0; y < NewSizeY; y++)
2287 for (
int z = 0; z < NewSizeZ; z++)
2289 for (
int x = 0; x < NewSizeX; x++)
2291 NewNibbles[idx++] = a_Array[
MakeIndex(x + a_AddMinX, y + a_AddMinY, z + a_AddMinZ)];
2295 a_Array = std::move(NewNibbles);
2304 int NewSizeX =
m_Size.
x + a_SubMinX + a_AddMaxX;
2305 int NewSizeY =
m_Size.
y + a_SubMinY + a_AddMaxY;
2306 int NewSizeZ =
m_Size.
z + a_SubMinZ + a_AddMaxZ;
2307 size_t BlockCount =
static_cast<size_t>(NewSizeX * NewSizeY * NewSizeZ);
2309 memset(NewBlockTypes.get(), 0, BlockCount *
sizeof(
BLOCKTYPE));
2310 size_t OldIndex = 0;
2311 for (
int y = 0; y <
m_Size.
y; y++)
2314 for (
int z = 0; z <
m_Size.
z; z++)
2316 int IndexBaseZ = IndexBaseY + (z + a_SubMinZ) *
m_Size.
x;
2317 auto idx =
static_cast<size_t>(IndexBaseZ + a_SubMinX);
2318 for (
int x = 0; x <
m_Size.
x; x++)
2333 int NewSizeX =
m_Size.
x + a_SubMinX + a_AddMaxX;
2334 int NewSizeY =
m_Size.
y + a_SubMinY + a_AddMaxY;
2335 int NewSizeZ =
m_Size.
z + a_SubMinZ + a_AddMaxZ;
2336 size_t BlockCount =
static_cast<size_t>(NewSizeX * NewSizeY * NewSizeZ);
2338 memset(NewNibbles.get(), 0, BlockCount *
sizeof(
NIBBLETYPE));
2339 size_t OldIndex = 0;
2340 for (
int y = 0; y <
m_Size.
y; y++)
2343 for (
int z = 0; z <
m_Size.
z; z++)
2345 int IndexBaseZ = IndexBaseY + (z + a_SubMinZ) *
m_Size.
x;
2346 auto idx =
static_cast<size_t>(IndexBaseZ + a_SubMinX);
2347 for (
int x = 0; x <
m_Size.
x; x++)
2349 NewNibbles[idx++] = a_Array[OldIndex++];
2353 a_Array = std::move(NewNibbles);
2361 int a_RelX,
int a_RelY,
int a_RelZ,
2371 auto Index =
MakeIndex(a_RelX, a_RelY, a_RelZ);
2372 if ((a_DataTypes &
baTypes) != 0)
2376 if ((a_DataTypes &
baMetas) != 0)
2380 if ((a_DataTypes &
baLight) != 0)
2395 if (itr->second->GetBlockType() == a_BlockType)
2415 template <
bool MetasVal
id>
2421 LOGWARNING(
"%s: cannot merge because one of the areas doesn't have blocktypes.", __FUNCTION__);
2426 int SrcOffX = std::max(0, -a_RelX);
2427 int DstOffX = std::max(0, a_RelX);
2430 int SrcOffY = std::max(0, -a_RelY);
2431 int DstOffY = std::max(0, a_RelY);
2434 int SrcOffZ = std::max(0, -a_RelZ);
2435 int DstOffZ = std::max(0, a_RelZ);
2444 InternalMergeBlocks<MetasValid, MergeCombinatorOverwrite<MetasValid> >(
2447 SizeX, SizeY, SizeZ,
2448 SrcOffX, SrcOffY, SrcOffZ,
2449 DstOffX, DstOffY, DstOffZ,
2458 InternalMergeBlocks<MetasValid, MergeCombinatorFillAir<MetasValid> >(
2461 SizeX, SizeY, SizeZ,
2462 SrcOffX, SrcOffY, SrcOffZ,
2463 DstOffX, DstOffY, DstOffZ,
2472 InternalMergeBlocks<MetasValid, MergeCombinatorImprint<MetasValid> >(
2475 SizeX, SizeY, SizeZ,
2476 SrcOffX, SrcOffY, SrcOffZ,
2477 DstOffX, DstOffY, DstOffZ,
2486 InternalMergeBlocks<MetasValid, MergeCombinatorLake<MetasValid> >(
2489 SizeX, SizeY, SizeZ,
2490 SrcOffX, SrcOffY, SrcOffZ,
2491 DstOffX, DstOffY, DstOffZ,
2500 InternalMergeBlocks<MetasValid, MergeCombinatorSpongePrint<MetasValid> >(
2503 SizeX, SizeY, SizeZ,
2504 SrcOffX, SrcOffY, SrcOffZ,
2505 DstOffX, DstOffY, DstOffZ,
2514 InternalMergeBlocks<MetasValid, MergeCombinatorDifference<MetasValid> >(
2517 SizeX, SizeY, SizeZ,
2518 SrcOffX, SrcOffY, SrcOffZ,
2519 DstOffX, DstOffY, DstOffZ,
2528 InternalMergeBlocks<MetasValid, MergeCombinatorSimpleCompare<MetasValid> >(
2531 SizeX, SizeY, SizeZ,
2532 SrcOffX, SrcOffY, SrcOffZ,
2533 DstOffX, DstOffY, DstOffZ,
2542 InternalMergeBlocks<MetasValid, MergeCombinatorMask<MetasValid> >(
2545 SizeX, SizeY, SizeZ,
2546 SrcOffX, SrcOffY, SrcOffZ,
2547 DstOffX, DstOffY, DstOffZ,
2554 UNREACHABLE(
"Unsupported block area merge strategy");
2586 for (
int y = 0; y <
m_Size.
y; ++y)
for (
int z = 0; z <
m_Size.
z; ++z)
for (
int x = 0; x <
m_Size.
x; ++x)
2604 auto srcX = x + a_RelX;
2605 auto srcY = y + a_RelY;
2606 auto srcZ = z + a_RelZ;
2609 auto srcIdx = a_Src.
MakeIndex(srcX, srcY, srcZ);
2639 for (
int y = 0; y <
m_Size.
y; ++y)
for (
int z = 0; z <
m_Size.
z; ++z)
for (
int x = 0; x <
m_Size.
x; ++x)
2671 for (
auto & keyPair: oldBE)
2673 auto type =
m_BlockTypes[
static_cast<size_t>(keyPair.first)];
2674 if (type == keyPair.second->GetBlockType())
2704 m_AreaBounds(
cCuboid(a_Area.GetOrigin(), a_Area.GetOrigin() + a_Area.GetSize() -
Vector3i(1, 1, 1))),
2705 m_Origin(a_Area.m_Origin.x, a_Area.m_Origin.y, a_Area.m_Origin.z),
2717 int SizeY = m_Area.m_Size.y;
2759 for (
int y = 0; y < SizeY; y++)
2761 int ChunkY = MinY + y;
2763 for (
int z = 0; z < SizeZ; z++)
2765 int ChunkZ = BaseZ + z;
2766 int AreaZ = OffZ + z;
2767 for (
int x = 0; x < SizeX; x++)
2769 int ChunkX = BaseX + x;
2770 int AreaX = OffX + x;
2771 a_AreaDst[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] =
cChunkDef::GetNibble(a_ChunkSrc, ChunkX, ChunkY, ChunkZ);
2783 m_CurrentChunkX = a_ChunkX;
2784 m_CurrentChunkZ = a_ChunkZ;
2794 int SizeY = m_Area.m_Size.y;
2837 if (m_Area.m_BlockTypes !=
nullptr)
2839 for (
int y = 0; y < SizeY; y++)
2841 int InChunkY = MinY + y;
2843 for (
int z = 0; z < SizeZ; z++)
2845 int InChunkZ = BaseZ + z;
2846 int AreaZ = OffZ + z;
2847 for (
int x = 0; x < SizeX; x++)
2849 int InChunkX = BaseX + x;
2850 int AreaX = OffX + x;
2851 m_Area.m_BlockTypes[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = a_BlockData.
GetBlock({ InChunkX, InChunkY, InChunkZ });
2858 if (m_Area.m_BlockMetas !=
nullptr)
2860 for (
int y = 0; y < SizeY; y++)
2862 int InChunkY = MinY + y;
2864 for (
int z = 0; z < SizeZ; z++)
2866 int InChunkZ = BaseZ + z;
2867 int AreaZ = OffZ + z;
2868 for (
int x = 0; x < SizeX; x++)
2870 int InChunkX = BaseX + x;
2871 int AreaX = OffX + x;
2872 m_Area.m_BlockMetas[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = a_BlockData.
GetMeta({ InChunkX, InChunkY, InChunkZ });
2879 if (m_Area.m_BlockLight !=
nullptr)
2881 for (
int y = 0; y < SizeY; y++)
2883 int InChunkY = MinY + y;
2885 for (
int z = 0; z < SizeZ; z++)
2887 int InChunkZ = BaseZ + z;
2888 int AreaZ = OffZ + z;
2889 for (
int x = 0; x < SizeX; x++)
2891 int InChunkX = BaseX + x;
2892 int AreaX = OffX + x;
2893 m_Area.m_BlockLight[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = a_LightData.
GetBlockLight({ InChunkX, InChunkY, InChunkZ });
2900 if (m_Area.m_BlockSkyLight !=
nullptr)
2902 for (
int y = 0; y < SizeY; y++)
2904 int InChunkY = MinY + y;
2906 for (
int z = 0; z < SizeZ; z++)
2908 int InChunkZ = BaseZ + z;
2909 int AreaZ = OffZ + z;
2910 for (
int x = 0; x < SizeX; x++)
2912 int InChunkX = BaseX + x;
2913 int AreaX = OffX + x;
2914 m_Area.m_BlockSkyLight[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = a_LightData.
GetSkyLight({ InChunkX, InChunkY, InChunkZ });
2927 if (!m_Area.HasBlockEntities())
2931 if (!m_AreaBounds.IsInside(a_BlockEntity->
GetPos()))
2935 auto areaPos = a_BlockEntity->
GetPos() - m_Area.m_Origin;
2936 auto Idx = m_Area.MakeIndex(areaPos);
2937 m_Area.m_BlockEntities->emplace(Idx, a_BlockEntity->
Clone(areaPos));
void MergeCombinatorSimpleCompare(BLOCKTYPE &a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE &a_DstMeta, NIBBLETYPE a_SrcMeta)
Combinator used for cBlockArea::msSimpleCompare merging.
void() CombinatorFunc(BLOCKTYPE &a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE &a_DstMeta, NIBBLETYPE a_SrcMeta)
void MergeCombinatorDifference(BLOCKTYPE &a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE &a_DstMeta, NIBBLETYPE a_SrcMeta)
Combinator used for cBlockArea::msDifference merging.
void MergeCombinatorSpongePrint(BLOCKTYPE &a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE &a_DstMeta, NIBBLETYPE a_SrcMeta)
Combinator used for cBlockArea::msSpongePrint merging.
void InternalMergeBlocks(BLOCKTYPE *a_DstTypes, const BLOCKTYPE *a_SrcTypes, NIBBLETYPE *a_DstMetas, const NIBBLETYPE *a_SrcMetas, int a_SizeX, int a_SizeY, int a_SizeZ, int a_SrcOffX, int a_SrcOffY, int a_SrcOffZ, int a_DstOffX, int a_DstOffY, int a_DstOffZ, int a_SrcSizeX, int a_SrcSizeY, int a_SrcSizeZ, int a_DstSizeX, int a_DstSizeY, int a_DstSizeZ)
Merges two blocktypes and blockmetas of the specified sizes and offsets using the specified combinato...
void MergeCombinatorMask(BLOCKTYPE &a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE &a_DstMeta, NIBBLETYPE a_SrcMeta)
Combinator used for cBlockArea::msMask merging.
void MergeCombinatorLake(BLOCKTYPE &a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE &a_DstMeta, NIBBLETYPE a_SrcMeta)
Combinator used for cBlockArea::msLake merging.
void MergeCombinatorOverwrite(BLOCKTYPE &a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE &a_DstMeta, NIBBLETYPE a_SrcMeta)
Combinator used for cBlockArea::msOverwrite merging.
void MergeCombinatorFillAir(BLOCKTYPE &a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE &a_DstMeta, NIBBLETYPE a_SrcMeta)
Combinator used for cBlockArea::msFillAir merging.
void MergeCombinatorImprint(BLOCKTYPE &a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE &a_DstMeta, NIBBLETYPE a_SrcMeta)
Combinator used for cBlockArea::msImprint merging.
@ E_BLOCK_STATIONARY_LAVA
@ E_BLOCK_STATIONARY_WATER
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
unsigned char BLOCKTYPE
The datatype used by blockdata.
void LOGWARNING(std::string_view a_Format, const Args &... args)
void Create(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes=baTypes|baMetas|baBlockEntities)
Creates a new area of the specified size and contents.
void GetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) const
NIBBLETYPE GetBlockSkyLight(int a_BlockX, int a_BlockY, int a_BlockZ) const
void SetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
void SetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
void MergeByStrategy(const cBlockArea &a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy, const NIBBLETYPE *SrcMetas, NIBBLETYPE *DstMetas)
size_t MakeIndex(Vector3i a_RelPos) const
Returns the index into the internal arrays for the specified coords.
cBlockEntitiesPtr m_BlockEntities
The block entities contained within the area.
void Expand(int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMaxY, int a_SubMinZ, int a_AddMaxZ)
Expands the internal contents by the specified amount of blocks from each border.
void SetOrigin(int a_OriginX, int a_OriginY, int a_OriginZ)
Resets the origin.
static bool IsValidDataTypeCombination(int a_DataTypes)
Returns true if the datatype combination is valid.
void MirrorYZ(void)
Mirrors the entire area around the YZ plane.
NIBBLETYPE GetNibble(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE *a_Array) const
NIBBLETYPE GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ) const
bool DoWithBlockEntityRelAt(int a_RelX, int a_RelY, int a_RelZ, cBlockEntityCallback a_Callback)
Calls the callback for the block entity at the specified coords.
bool Write(cForEachChunkProvider &a_ForEachChunkProvider, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes)
Writes the area back into cWorld at the coords specified.
NIBBLETYPE * GetBlockMetas(void) const
void FillRelCuboid(int a_MinRelX, int a_MaxRelX, int a_MinRelY, int a_MaxRelY, int a_MinRelZ, int a_MaxRelZ, int a_DataTypes, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta=0, NIBBLETYPE a_BlockLight=0, NIBBLETYPE a_BlockSkyLight=0x0f)
Fills a cuboid inside the block area with the specified data.
bool ForEachBlockEntity(cBlockEntityCallback a_Callback)
Calls the callback for all the block entities.
void SetBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockLight)
Vector3i m_WEOffset
An extra data value sometimes stored in the .schematic file.
void SetWEOffset(int a_OffsetX, int a_OffsetY, int a_OffsetZ)
std::unique_ptr< BLOCKTYPE[]> BLOCKARRAY
bool HasBlockSkyLights(void) const
void MirrorXY(void)
Mirrors the entire area around the XY plane.
void RescanBlockEntities(void)
Updates m_BlockEntities to remove BEs that no longer match the blocktype at their coords,...
size_t CountSpecificBlocks(BLOCKTYPE a_BlockType) const
Returns how many times the specified block is contained in the area.
void MirrorYZNoMeta(void)
Mirrors the entire area around the YZ plane, doesn't use blockhandlers for block meta.
void Crop(int a_AddMinX, int a_SubMaxX, int a_AddMinY, int a_SubMaxY, int a_AddMinZ, int a_SubMaxZ)
Crops the internal contents by the specified amount of blocks from each border.
void RotateCCWNoMeta(void)
Rotates the entire area counter-clockwise around the Y axis, doesn't use blockhandlers for block meta...
void SetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockSkyLight)
void CropBlockTypes(int a_AddMinX, int a_SubMaxX, int a_AddMinY, int a_SubMaxY, int a_AddMinZ, int a_SubMaxZ)
void ExpandBlockTypes(int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMaxY, int a_SubMinZ, int a_AddMaxZ)
cBlockEntity * GetBlockEntityRel(Vector3i a_RelPos)
Returns the cBlockEntity at the specified coords, or nullptr if none.
void GetNonAirCropRelCoords(int &a_MinRelX, int &a_MinRelY, int &a_MinRelZ, int &a_MaxRelX, int &a_MaxRelY, int &a_MaxRelZ, BLOCKTYPE a_IgnoreBlockType=E_BLOCK_AIR)
Returns the minimum and maximum coords in each direction for the first non-ignored block in each dire...
void MirrorXYNoMeta(void)
Mirrors the entire area around the XY plane, doesn't use blockhandlers for block meta.
void GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) const
NIBBLETYPE GetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE *a_Array) const
size_t CountNonAirBlocks(void) const
Returns the count of blocks that are not air.
void SetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType)
void SetBlockSkyLight(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockSkyLight)
bool SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes)
Clears the data stored and prepares a fresh new block area with the specified dimensions.
NIBBLETYPE GetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ) const
void SetRelBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType)
bool HasBlockLights(void) const
bool HasBlockEntities(void) const
size_t GetBlockCount(void) const
bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback a_Callback)
Calls the callback for the block entity at the specified coords.
void CopyFrom(const cBlockArea &a_From)
Copies the contents from the specified BlockArea into this object.
NIBBLETYPE GetRelBlockLight(int a_RelX, int a_RelY, int a_RelZ) const
bool HasBlockTypes(void) const
void RotateCW(void)
Rotates the entire area clockwise around the Y axis.
int GetDataTypes(void) const
Returns the datatypes that are stored in the object (bitmask of baXXX values)
void SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockMeta)
void CropNibbles(NIBBLEARRAY &a_Array, int a_AddMinX, int a_SubMaxX, int a_AddMinY, int a_SubMaxY, int a_AddMinZ, int a_SubMaxZ)
void MirrorXZ(void)
Mirrors the entire area around the XZ plane.
BLOCKTYPE * GetBlockTypes(void) const
Returns the internal pointer to the block types.
void Fill(int a_DataTypes, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta=0, NIBBLETYPE a_BlockLight=0, NIBBLETYPE a_BlockSkyLight=0x0f)
Fills the entire block area with the specified data.
void RotateCCW(void)
Rotates the entire area counter-clockwise around the Y axis.
NIBBLETYPE GetBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ) const
BLOCKTYPE GetRelBlockType(int a_RelX, int a_RelY, int a_RelZ) const
void RelSetData(int a_RelX, int a_RelY, int a_RelZ, int a_DataTypes, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, NIBBLETYPE a_BlockLight, NIBBLETYPE a_BlockSkyLight)
Sets the specified datatypes at the specified location.
void SetRelBlockLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockLight)
void RelLine(int a_RelX1, int a_RelY1, int a_RelZ1, int a_RelX2, int a_RelY2, int a_RelZ2, int a_DataTypes, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta=0, NIBBLETYPE a_BlockLight=0, NIBBLETYPE a_BlockSkyLight=0x0f)
Draws a line between two points with the specified data.
void MirrorXZNoMeta(void)
Mirrors the entire area around the XZ plane, doesn't use blockhandlers for block meta.
cCuboid GetBounds(void) const
NIBBLETYPE * GetBlockSkyLight(void) const
NIBBLETYPE GetRelBlockMeta(int a_RelX, int a_RelY, int a_RelZ) const
NIBBLETYPE * GetBlockLight(void) const
eMergeStrategy
The per-block strategy to use when merging another block area into this object.
bool Read(cForEachChunkProvider &a_ForEachChunkProvider, int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ, int a_DataTypes=baTypes|baMetas|baBlockEntities)
Reads an area of blocks specified.
void DumpToRawFile(const AString &a_FileName)
For testing purposes only, dumps the area into a file.
void SetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Value, NIBBLETYPE *a_Array)
bool IsValidRelCoords(int a_RelX, int a_RelY, int a_RelZ) const
Returns true if the specified relative coords are within this area's coord range (0 - m_Size).
void CopyTo(cBlockArea &a_Into) const
Copies this object's contents into the specified BlockArea.
std::unique_ptr< NIBBLETYPE[]> NIBBLEARRAY
static size_t MakeIndexForSize(Vector3i a_RelPos, Vector3i a_Size)
std::unique_ptr< cBlockEntities > cBlockEntitiesPtr
bool HasBlockMetas(void) const
void Merge(const cBlockArea &a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy)
Merges another block area into this one, using the specified block combinating strategy This function...
void MergeBlockEntities(int a_RelX, int a_RelY, int a_RelZ, const cBlockArea &a_Src)
Updates m_BlockEntities to remove BEs that no longer match the blocktype at their coords,...
void RotateCWNoMeta(void)
Rotates the entire area clockwise around the Y axis, doesn't use blockhandlers for block meta.
void SetNibble(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Value, NIBBLETYPE *a_Array)
bool IsValidCoords(int a_BlockX, int a_BlockY, int a_BlockZ) const
Returns true if the specified coords are within this area's coord range (as indicated by m_Origin).
void ExpandNibbles(NIBBLEARRAY &a_Array, int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMaxY, int a_SubMinZ, int a_AddMaxZ)
void SetRelBlockMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockMeta)
void Clear(void)
Clears the data stored to reclaim memory.
NIBBLEARRAY m_BlockSkyLight
void RemoveNonMatchingBlockEntities(void)
Removes from m_BlockEntities those BEs that no longer match the blocktype at their coords.
BLOCKTYPE GetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ) const
virtual bool Coords(int a_ChunkX, int a_ChunkZ) override
virtual void BlockEntity(cBlockEntity *a_BlockEntity) override
cChunkReader(cBlockArea &a_Area)
void CopyNibbles(NIBBLETYPE *a_AreaDst, const NIBBLETYPE *a_ChunkSrc)
virtual void ChunkData(const ChunkBlockData &a_BlockData, const ChunkLightData &a_LightData) override
static OwnedBlockEntity CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld *a_World=nullptr)
Creates a new block entity for the specified block type at the specified absolute pos.
static bool IsBlockEntityBlockType(BLOCKTYPE a_BlockType)
Returns true if the specified blocktype is supposed to have an associated block entity.
OwnedBlockEntity Clone(Vector3i a_Pos)
Makes an exact copy of this block entity, except for its m_World (set to nullptr),...
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) const
Rotates a given block meta clockwise.
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) const
Rotates a given block meta counter-clockwise.
virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) const
Mirros a given block meta around the XZ plane.
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) const
Mirros a given block meta around the YZ plane.
static const cBlockHandler & For(BLOCKTYPE a_BlockType)
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) const
Mirrors a given block meta around the XY plane.
NIBBLETYPE GetMeta(Vector3i a_Position) const
BLOCKTYPE GetBlock(Vector3i a_Position) const
NIBBLETYPE GetSkyLight(Vector3i a_Position) const
NIBBLETYPE GetBlockLight(Vector3i a_Position) const
static bool IsValidHeight(Vector3i a_BlockPosition)
Validates a height-coordinate.
static void AbsoluteToRelative(int &a_X, int &a_Y, int &a_Z, int &a_ChunkX, int &a_ChunkZ)
Converts absolute block coords into relative (chunk + block) coords:
static NIBBLETYPE GetNibble(const NIBBLETYPE *a_Buffer, int x, int y, int z)
virtual bool WriteBlockArea(cBlockArea &a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes)=0
Writes the block area into the specified coords.
virtual bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback &a_Callback)=0
Calls the callback for each chunk in the specified range.
bool Open(const AString &iFileName, eMode iMode)
int Write(const void *a_Buffer, size_t a_NumBytes)
Writes up to a_NumBytes bytes from a_Buffer, returns the number of bytes actually written,...
void Move(T a_X, T a_Y, T a_Z)
void Set(T a_x, T a_y, T a_z)
std::unordered_map< size_t, OwnedBlockEntity > cBlockEntities