25 #pragma warning(disable:4127) 36 template <
bool MetasVal
id, CombinatorFunc Combinator>
40 int a_SizeX,
int a_SizeY,
int a_SizeZ,
41 int a_SrcOffX,
int a_SrcOffY,
int a_SrcOffZ,
42 int a_DstOffX,
int a_DstOffY,
int a_DstOffZ,
43 int a_SrcSizeX,
int a_SrcSizeY,
int a_SrcSizeZ,
44 int a_DstSizeX,
int a_DstSizeY,
int a_DstSizeZ
49 for (
int y = 0; y < a_SizeY; y++)
51 int SrcBaseY = (y + a_SrcOffY) * a_SrcSizeX * a_SrcSizeZ;
52 int DstBaseY = (y + a_DstOffY) * a_DstSizeX * a_DstSizeZ;
53 for (
int z = 0; z < a_SizeZ; z++)
55 int SrcBaseZ = SrcBaseY + (z + a_SrcOffZ) * a_SrcSizeX;
56 int DstBaseZ = DstBaseY + (z + a_DstOffZ) * a_DstSizeX;
57 int SrcIdx = SrcBaseZ + a_SrcOffX;
58 int DstIdx = DstBaseZ + a_DstOffX;
59 for (
int x = 0; x < a_SizeX; x++)
63 Combinator(a_DstTypes[DstIdx], a_SrcTypes[SrcIdx], a_DstMetas[DstIdx], a_SrcMetas[SrcIdx]);
68 Combinator(a_DstTypes[DstIdx], a_SrcTypes[SrcIdx], FakeDestMeta, static_cast<NIBBLETYPE>(0));
82 template <
bool MetaVal
id>
85 a_DstType = a_SrcType;
88 a_DstMeta = a_SrcMeta;
97 template <
bool MetaVal
id>
102 a_DstType = a_SrcType;
105 a_DstMeta = a_SrcMeta;
116 template <
bool MetaVal
id>
121 a_DstType = a_SrcType;
124 a_DstMeta = a_SrcMeta;
135 template <
bool MetaVal
id>
175 a_DstType = a_SrcType;
178 a_DstMeta = a_SrcMeta;
209 template <
bool MetaVal
id>
215 a_DstType = a_SrcType;
218 a_DstMeta = a_SrcMeta;
228 template <
bool MetaVal
id>
231 if ((a_DstType == a_SrcType) && (!MetaValid || (a_DstMeta == a_SrcMeta)))
241 a_DstType = a_SrcType;
244 a_DstMeta = a_SrcMeta;
254 template <
bool MetaVal
id>
257 if ((a_DstType == a_SrcType) && (!MetaValid || (a_DstMeta == a_SrcMeta)))
274 template <
bool MetaVal
id>
278 if ((a_SrcType != a_DstType) || !MetaValid || (a_SrcMeta != a_DstMeta))
307 if ((a_DataTypes &
baTypes) == 0)
346 LOGWARNING(
"Creating a cBlockArea with height larger than world height (%d). Continuing, but the area may misbehave.", a_SizeY);
350 SetSize(a_SizeX, a_SizeY, a_SizeZ, a_DataTypes);
360 Create(a_Size.
x, a_Size.
y, a_Size.
z, a_DataTypes);
406 (a_RelX >= 0) && (a_RelX <
m_Size.
x) &&
407 (a_RelY >= 0) && (a_RelY <
m_Size.
y) &&
408 (a_RelZ >= 0) && (a_RelZ <
m_Size.
z)
448 ASSERT(a_MinBlockX <= a_MaxBlockX);
449 ASSERT(a_MinBlockY <= a_MaxBlockY);
450 ASSERT(a_MinBlockZ <= a_MaxBlockZ);
459 if (!
SetSize(a_MaxBlockX - a_MinBlockX, a_MaxBlockY - a_MinBlockY, a_MaxBlockZ - a_MinBlockZ, a_DataTypes))
463 m_Origin.
Set(a_MinBlockX, a_MinBlockY, a_MinBlockZ);
467 int MinChunkX, MaxChunkX;
468 int MinChunkZ, MaxChunkZ;
473 if (!a_ForEachChunkProvider.
ForEachChunkInRect(MinChunkX, MaxChunkX, MinChunkZ, MaxChunkZ, Reader))
489 a_ForEachChunkProvider,
490 a_Bounds.
p1.
x, a_Bounds.
p2.
x,
491 a_Bounds.
p1.
y, a_Bounds.
p2.
y,
492 a_Bounds.
p1.
z, a_Bounds.
p2.
z,
504 a_ForEachChunkProvider,
505 a_Point1.
x, a_Point2.
x,
506 a_Point1.
y, a_Point2.
y,
507 a_Point1.
z, a_Point2.
z,
522 return a_ForEachChunkProvider.
WriteBlockArea(*
this, a_MinBlockX, a_MinBlockY, a_MinBlockZ, a_DataTypes);
532 a_ForEachChunkProvider,
533 a_MinCoords.
x, a_MinCoords.
y, a_MinCoords.
z,
546 LOGWARNING(
"Trying to copy a cBlockArea into self, ignoring.");
575 const auto & pos = keyPair.second->GetPos();
576 a_Into.
m_BlockEntities->insert({keyPair.first, keyPair.second->Clone(pos)});
599 LOGWARNING(
"cBlockArea: Cannot open file \"%s\" for raw dump", a_FileName.c_str());
608 unsigned char DataTypes =
static_cast<unsigned char>(
GetDataTypes());
609 f.
Write(&DataTypes, 1);
633 void cBlockArea::Crop(
int a_AddMinX,
int a_SubMaxX,
int a_AddMinY,
int a_SubMaxY,
int a_AddMinZ,
int a_SubMaxZ)
636 (a_AddMinX + a_SubMaxX >=
m_Size.
x) ||
637 (a_AddMinY + a_SubMaxY >=
m_Size.
y) ||
638 (a_AddMinZ + a_SubMaxZ >=
m_Size.
z)
641 LOGWARNING(
"cBlockArea:Crop called with more croping than the dimensions: %d x %d x %d with cropping %d, %d and %d",
643 a_AddMinX + a_SubMaxX, a_AddMinY + a_SubMaxY, a_AddMinZ + a_SubMaxZ
650 CropBlockTypes(a_AddMinX, a_SubMaxX, a_AddMinY, a_SubMaxY, a_AddMinZ, a_SubMaxZ);
666 auto maxX =
m_Size.
x - a_SubMaxX;
667 auto maxY =
m_Size.
y - a_SubMaxY;
668 auto maxZ =
m_Size.
z - a_SubMaxZ;
673 for (
const auto & keyPair: oldBE)
675 auto & be = keyPair.second;
676 auto posX = be->GetPosX();
677 auto posY = be->GetPosY();
678 auto posZ = be->GetPosZ();
680 (posX < a_AddMinX) || (posX >= maxX) ||
681 (posY < a_AddMinY) || (posY >= maxY) ||
682 (posZ < a_AddMinZ) || (posZ >= maxZ)
694 be->SetPos({posX, posY, posZ});
701 m_Size.
x -= a_AddMinX + a_SubMaxX;
702 m_Size.
y -= a_AddMinY + a_SubMaxY;
703 m_Size.
z -= a_AddMinZ + a_SubMaxZ;
710 void cBlockArea::Expand(
int a_SubMinX,
int a_AddMaxX,
int a_SubMinY,
int a_AddMaxY,
int a_SubMinZ,
int a_AddMaxZ)
714 ExpandBlockTypes(a_SubMinX, a_AddMaxX, a_SubMinY, a_AddMaxY, a_SubMinZ, a_AddMaxZ);
733 for (
const auto & keyPair: oldBE)
735 auto & be = keyPair.second;
736 auto posX = be->GetPosX() + a_SubMinX;
737 auto posY = be->GetPosY() + a_SubMinY;
738 auto posZ = be->GetPosZ() + a_SubMinZ;
739 be->SetPos({posX, posY, posZ});
745 m_Size.
x += a_SubMinX + a_AddMaxX;
746 m_Size.
y += a_SubMinY + a_AddMaxY;
747 m_Size.
z += a_SubMinZ + a_AddMaxZ;
760 bool IsDummyMetas = ((SrcMetas ==
nullptr) || (DstMetas ==
nullptr));
764 MergeByStrategy<false>(a_Src, a_RelX, a_RelY, a_RelZ, a_Strategy, SrcMetas, DstMetas);
768 MergeByStrategy<true>(a_Src, a_RelX, a_RelY, a_RelZ, a_Strategy, SrcMetas, DstMetas);
778 Merge(a_Src, a_RelMinCoords.
x, a_RelMinCoords.
y, a_RelMinCoords.
z, a_Strategy);
789 LOGWARNING(
"%s: requested datatypes that are not present in the BlockArea object, trimming those away (req 0x%x, stor 0x%x)",
796 if ((a_DataTypes &
baTypes) != 0)
798 for (
size_t i = 0; i < BlockCount; i++)
803 if ((a_DataTypes &
baMetas) != 0)
805 for (
size_t i = 0; i < BlockCount; i++)
810 if ((a_DataTypes &
baLight) != 0)
812 for (
size_t i = 0; i < BlockCount; i++)
819 for (
size_t i = 0; i < BlockCount; i++)
850 LOGWARNING(
"%s: requested datatypes that are not present in the BlockArea object, trimming those away (req 0x%x, stor 0x%x)",
856 if ((a_DataTypes &
baTypes) != 0)
858 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++)
863 if ((a_DataTypes &
baMetas) != 0)
865 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++)
870 if ((a_DataTypes &
baLight) != 0)
872 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++)
879 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++)
909 a_RelCuboid.
p1.
x, a_RelCuboid.
p2.
x,
910 a_RelCuboid.
p1.
y, a_RelCuboid.
p2.
y,
911 a_RelCuboid.
p1.
z, a_RelCuboid.
p2.
z,
912 a_DataTypes, a_BlockType, a_BlockMeta, a_BlockLight, a_BlockSkyLight
926 int dx = abs(a_RelX2 - a_RelX1);
927 int dy = abs(a_RelY2 - a_RelY1);
928 int dz = abs(a_RelZ2 - a_RelZ1);
929 int sx = (a_RelX1 < a_RelX2) ? 1 : -1;
930 int sy = (a_RelY1 < a_RelY2) ? 1 : -1;
931 int sz = (a_RelZ1 < a_RelZ2) ? 1 : -1;
933 if (dx >= std::max(dy, dz))
935 int yd = dy - dx / 2;
936 int zd = dz - dx / 2;
940 RelSetData(a_RelX1, a_RelY1, a_RelZ1, a_DataTypes, a_BlockType, a_BlockMeta, a_BlockLight, a_BlockSkyLight);
942 if (a_RelX1 == a_RelX2)
965 else if (dy >= std::max(dx, dz))
967 int xd = dx - dy / 2;
968 int zd = dz - dy / 2;
972 RelSetData(a_RelX1, a_RelY1, a_RelZ1, a_DataTypes, a_BlockType, a_BlockMeta, a_BlockLight, a_BlockSkyLight);
974 if (a_RelY1 == a_RelY2)
1000 ASSERT(dz >= std::max(dx, dy));
1001 int xd = dx - dz / 2;
1002 int yd = dy - dz / 2;
1006 RelSetData(a_RelX1, a_RelY1, a_RelZ1, a_DataTypes, a_BlockType, a_BlockMeta, a_BlockLight, a_BlockSkyLight);
1008 if (a_RelZ1 == a_RelZ2)
1043 a_Point1.
x, a_Point1.
y, a_Point1.
z,
1044 a_Point2.
x, a_Point2.
y, a_Point2.
z,
1045 a_DataTypes, a_BlockType, a_BlockMeta, a_BlockLight, a_BlockSkyLight
1057 LOGWARNING(
"cBlockArea: Cannot rotate blockmeta without blocktypes!");
1071 for (
int x = 0; x <
m_Size.
x; x++)
1074 for (
int z = 0; z <
m_Size.
z; z++)
1077 for (
int y = 0; y <
m_Size.
y; y++)
1094 for (
const auto & keyPair: oldBE)
1096 auto & be = keyPair.second;
1097 auto newX = be->GetPosZ();
1098 auto newY = be->GetPosY();
1099 auto newZ =
m_Size.
x - be->GetPosX() - 1;
1101 be->SetPos({newX, newY, newZ});
1117 LOGWARNING(
"cBlockArea: Cannot rotate blockmeta without blocktypes!");
1131 for (
int x = 0; x <
m_Size.
x; x++)
1134 for (
int z = 0; z <
m_Size.
z; z++)
1137 for (
int y = 0; y <
m_Size.
y; y++)
1154 for (
const auto & keyPair: oldBE)
1156 auto & be = keyPair.second;
1157 auto newX =
m_Size.
z - be->GetPosZ() - 1;
1158 auto newY = be->GetPosY();
1159 auto newZ = be->GetPosX();
1161 be->SetPos({newX, newY, newZ});
1177 LOGWARNING(
"cBlockArea: Cannot mirror meta without blocktypes!");
1191 for (
int y = 0; y <
m_Size.
y; y++)
1193 for (
int z = 0; z < HalfZ; z++)
1195 for (
int x = 0; x <
m_Size.
x; x++)
1213 for (
const auto & keyPair: oldBE)
1215 auto & be = keyPair.second;
1216 auto newX = be->GetPosX();
1217 auto newY = be->GetPosY();
1218 auto newZ = MaxZ - be->GetPosZ();
1219 auto newIdx =
MakeIndex(newX, newY, newZ);
1220 be->SetPos({newX, newY, newZ});
1234 LOGWARNING(
"cBlockArea: Cannot mirror meta without blocktypes!");
1248 for (
int y = 0; y < HalfY; y++)
1250 for (
int z = 0; z <
m_Size.
z; z++)
1252 for (
int x = 0; x <
m_Size.
x; x++)
1270 for (
const auto & keyPair: oldBE)
1272 auto & be = keyPair.second;
1273 auto newX = be->GetPosX();
1274 auto newY = MaxY - be->GetPosY();
1275 auto newZ = be->GetPosZ();
1276 auto newIdx =
MakeIndex(newX, newY, newZ);
1277 be->SetPos({newX, newY, newZ});
1291 LOGWARNING(
"cBlockArea: Cannot mirror meta without blocktypes!");
1305 for (
int y = 0; y <
m_Size.
y; y++)
1307 for (
int z = 0; z <
m_Size.
z; z++)
1309 for (
int x = 0; x < HalfX; x++)
1327 for (
const auto & keyPair: oldBE)
1329 auto & be = keyPair.second;
1330 auto newX = MaxX - be->GetPosX();
1331 auto newY = be->GetPosY();
1332 auto newZ = be->GetPosZ();
1333 auto newIdx =
MakeIndex(newX, newY, newZ);
1334 be->SetPos({newX, newY, newZ});
1349 for (
int x = 0; x <
m_Size.
x; x++)
1352 for (
int z = 0; z <
m_Size.
z; z++)
1355 for (
int y = 0; y <
m_Size.
y; y++)
1366 for (
int x = 0; x <
m_Size.
x; x++)
1369 for (
int z = 0; z <
m_Size.
z; z++)
1372 for (
int y = 0; y <
m_Size.
y; y++)
1386 for (
const auto & keyPair: oldBE)
1388 auto & be = keyPair.second;
1389 auto newX = be->GetPosZ();
1390 auto newY = be->GetPosY();
1391 auto newZ =
m_Size.
x - be->GetPosX() - 1;
1393 be->SetPos({newX, newY, newZ});
1410 for (
int z = 0; z <
m_Size.
z; z++)
1413 for (
int x = 0; x <
m_Size.
x; x++)
1416 for (
int y = 0; y <
m_Size.
y; y++)
1427 for (
int z = 0; z <
m_Size.
z; z++)
1430 for (
int x = 0; x <
m_Size.
x; x++)
1433 for (
int y = 0; y <
m_Size.
y; y++)
1447 for (
const auto & keyPair: oldBE)
1449 auto & be = keyPair.second;
1450 auto newX =
m_Size.
z - be->GetPosZ() - 1;
1451 auto newY = be->GetPosY();
1452 auto newZ = be->GetPosX();
1454 be->SetPos({newX, newY, newZ});
1472 for (
int y = 0; y <
m_Size.
y; y++)
1474 for (
int z = 0; z < HalfZ; z++)
1476 for (
int x = 0; x <
m_Size.
x; x++)
1486 for (
int y = 0; y <
m_Size.
y; y++)
1488 for (
int z = 0; z < HalfZ; z++)
1490 for (
int x = 0; x <
m_Size.
x; x++)
1503 for (
const auto & keyPair: oldBE)
1505 auto & be = keyPair.second;
1506 auto newX = be->GetPosX();
1507 auto newY = be->GetPosY();
1508 auto newZ = MaxZ - be->GetPosZ();
1509 auto newIdx =
MakeIndex(newX, newY, newZ);
1510 be->SetPos({newX, newY, newZ});
1526 for (
int y = 0; y < HalfY; y++)
1528 for (
int z = 0; z <
m_Size.
z; z++)
1530 for (
int x = 0; x <
m_Size.
x; x++)
1540 for (
int y = 0; y < HalfY; y++)
1542 for (
int z = 0; z <
m_Size.
z; z++)
1544 for (
int x = 0; x <
m_Size.
x; x++)
1557 for (
const auto & keyPair: oldBE)
1559 auto & be = keyPair.second;
1560 auto newX = be->GetPosX();
1561 auto newY = MaxY - be->GetPosY();
1562 auto newZ = be->GetPosZ();
1563 auto newIdx =
MakeIndex(newX, newY, newZ);
1564 be->SetPos({newX, newY, newZ});
1580 for (
int y = 0; y <
m_Size.
y; y++)
1582 for (
int z = 0; z <
m_Size.
z; z++)
1584 for (
int x = 0; x < HalfX; x++)
1594 for (
int y = 0; y <
m_Size.
y; y++)
1596 for (
int z = 0; z <
m_Size.
z; z++)
1598 for (
int x = 0; x < HalfX; x++)
1611 for (
const auto & keyPair: oldBE)
1613 auto & be = keyPair.second;
1614 auto newX = MaxX - be->GetPosX();
1615 auto newY = be->GetPosY();
1616 auto newZ = be->GetPosZ();
1617 auto newIdx =
MakeIndex(newX, newY, newZ);
1618 be->SetPos({newX, newY, newZ});
1631 auto idx =
MakeIndex(a_RelX, a_RelY, a_RelZ);
1640 if (itr->second->GetBlockType() == a_BlockType)
1726 LOGWARNING(
"cBlockArea: BlockTypes have not been read!");
1810 auto idx =
MakeIndex(a_RelX, a_RelY, a_RelZ);
1813 LOGWARNING(
"%s: BlockTypes not available but requested to be written to.", __FUNCTION__);
1821 LOGWARNING(
"%s: BlockMetas not available but requested to be written to.", __FUNCTION__);
1834 if (itr->second->GetBlockType() == a_BlockType)
1863 auto idx =
MakeIndex(a_RelX, a_RelY, a_RelZ);
1866 LOGWARNING(
"cBlockArea: BlockTypes have not been read!");
1876 LOGWARNING(
"cBlockArea: BlockMetas have not been read!");
1906 LOGWARNING(
"%s: BlockTypes have not been read!", __FUNCTION__);
1912 for (
int y = 0; y <
m_Size.
y; y++)
1914 for (
int z = 0; z <
m_Size.
z; z++)
1916 for (
int x = 0; x <
m_Size.
x; x++)
1937 LOGWARNING(
"%s: BlockTypes not available!", __FUNCTION__);
1944 for (
size_t i = 0; i < num; i++)
1963 LOGWARNING(
"%s: BlockTypes not available!", __FUNCTION__);
1970 LOGWARNING(
"%s: BlockMetas not available, comparing blocktypes only!", __FUNCTION__);
1977 for (
size_t i = 0; i < num; i++)
1996 LOGWARNING(
"%s: BlockTypes have not been read!", __FUNCTION__);
2003 int MaxX = 0, MinX =
m_Size.
x - 1;
2004 int MaxY = 0, MinY =
m_Size.
y - 1;
2005 int MaxZ = 0, MinZ =
m_Size.
z - 1;
2006 for (
int y = 0; y <
m_Size.
y; y++)
2008 for (
int z = 0; z <
m_Size.
z; z++)
2010 for (
int x = 0; x <
m_Size.
x; x++)
2099 if ((a_DataTypes &
baTypes) != 0)
2101 NewBlocks.reset(
new BLOCKTYPE[a_SizeX * a_SizeY * a_SizeZ]);
2102 if (NewBlocks ==
nullptr)
2107 if ((a_DataTypes &
baMetas) != 0)
2109 NewMetas.reset(
new NIBBLETYPE[a_SizeX * a_SizeY * a_SizeZ]);
2110 if (NewMetas ==
nullptr)
2115 if ((a_DataTypes &
baLight) != 0)
2117 NewLight.reset(
new NIBBLETYPE[a_SizeX * a_SizeY * a_SizeZ]);
2118 if (NewLight ==
nullptr)
2125 NewSkyLight.reset(
new NIBBLETYPE[a_SizeX * a_SizeY * a_SizeZ]);
2126 if (NewSkyLight ==
nullptr)
2134 if (NewBlockEntities ==
nullptr)
2163 return static_cast<size_t>(a_RelPos.
x + a_RelPos.
z * a_Size.
x + a_RelPos.
y * a_Size.
x * a_Size.
z);
2177 auto idx =
MakeIndex(a_RelX, a_RelY, a_RelZ);
2183 return a_Callback(*itr->second);
2207 if (a_Callback(*keyPair.second))
2227 return handler->ConvertToPickups(blockMeta, blockEntity, a_Digger, a_Tool);
2236 if (a_Array ==
nullptr)
2238 LOGWARNING(
"cBlockArea: datatype has not been read!");
2241 a_Array[
MakeIndex(a_RelX, a_RelY, a_RelZ)] = a_Value;
2259 if (a_Array ==
nullptr)
2261 LOGWARNING(
"cBlockArea: datatype has not been read!");
2264 return a_Array[
MakeIndex(a_RelX, a_RelY, a_RelZ)];
2282 int NewSizeX =
GetSizeX() - a_AddMinX - a_SubMaxX;
2283 int NewSizeY =
GetSizeY() - a_AddMinY - a_SubMaxY;
2284 int NewSizeZ =
GetSizeZ() - a_AddMinZ - a_SubMaxZ;
2287 for (
int y = 0; y < NewSizeY; y++)
2289 for (
int z = 0; z < NewSizeZ; z++)
2291 for (
int x = 0; x < NewSizeX; x++)
2293 auto OldIndex =
MakeIndex(x + a_AddMinX, y + a_AddMinY, z + a_AddMinZ);
2307 int NewSizeX =
GetSizeX() - a_AddMinX - a_SubMaxX;
2308 int NewSizeY =
GetSizeY() - a_AddMinY - a_SubMaxY;
2309 int NewSizeZ =
GetSizeZ() - a_AddMinZ - a_SubMaxZ;
2312 for (
int y = 0; y < NewSizeY; y++)
2314 for (
int z = 0; z < NewSizeZ; z++)
2316 for (
int x = 0; x < NewSizeX; x++)
2318 NewNibbles[idx++] = a_Array[
MakeIndex(x + a_AddMinX, y + a_AddMinY, z + a_AddMinZ)];
2322 a_Array = std::move(NewNibbles);
2331 int NewSizeX =
m_Size.
x + a_SubMinX + a_AddMaxX;
2332 int NewSizeY =
m_Size.
y + a_SubMinY + a_AddMaxY;
2333 int NewSizeZ =
m_Size.
z + a_SubMinZ + a_AddMaxZ;
2334 size_t BlockCount =
static_cast<size_t>(NewSizeX * NewSizeY * NewSizeZ);
2336 memset(NewBlockTypes.get(), 0, BlockCount *
sizeof(
BLOCKTYPE));
2337 size_t OldIndex = 0;
2338 for (
int y = 0; y <
m_Size.
y; y++)
2341 for (
int z = 0; z <
m_Size.
z; z++)
2343 int IndexBaseZ = IndexBaseY + (z + a_SubMinZ) *
m_Size.
x;
2344 auto idx = static_cast<size_t>(IndexBaseZ + a_SubMinX);
2345 for (
int x = 0; x <
m_Size.
x; x++)
2360 int NewSizeX =
m_Size.
x + a_SubMinX + a_AddMaxX;
2361 int NewSizeY =
m_Size.
y + a_SubMinY + a_AddMaxY;
2362 int NewSizeZ =
m_Size.
z + a_SubMinZ + a_AddMaxZ;
2363 size_t BlockCount =
static_cast<size_t>(NewSizeX * NewSizeY * NewSizeZ);
2365 memset(NewNibbles.get(), 0, BlockCount *
sizeof(
NIBBLETYPE));
2366 size_t OldIndex = 0;
2367 for (
int y = 0; y <
m_Size.
y; y++)
2370 for (
int z = 0; z <
m_Size.
z; z++)
2372 int IndexBaseZ = IndexBaseY + (z + a_SubMinZ) *
m_Size.
x;
2373 auto idx = static_cast<size_t>(IndexBaseZ + a_SubMinX);
2374 for (
int x = 0; x <
m_Size.
x; x++)
2376 NewNibbles[idx++] = a_Array[OldIndex++];
2380 a_Array = std::move(NewNibbles);
2388 int a_RelX,
int a_RelY,
int a_RelZ,
2398 auto Index =
MakeIndex(a_RelX, a_RelY, a_RelZ);
2399 if ((a_DataTypes &
baTypes) != 0)
2403 if ((a_DataTypes &
baMetas) != 0)
2407 if ((a_DataTypes &
baLight) != 0)
2422 if (itr->second->GetBlockType() == a_BlockType)
2442 template <
bool MetasVal
id>
2448 LOGWARNING(
"%s: cannot merge because one of the areas doesn't have blocktypes.", __FUNCTION__);
2453 int SrcOffX = std::max(0, -a_RelX);
2454 int DstOffX = std::max(0, a_RelX);
2457 int SrcOffY = std::max(0, -a_RelY);
2458 int DstOffY = std::max(0, a_RelY);
2461 int SrcOffZ = std::max(0, -a_RelZ);
2462 int DstOffZ = std::max(0, a_RelZ);
2471 InternalMergeBlocks<MetasValid, MergeCombinatorOverwrite<MetasValid> >(
2474 SizeX, SizeY, SizeZ,
2475 SrcOffX, SrcOffY, SrcOffZ,
2476 DstOffX, DstOffY, DstOffZ,
2485 InternalMergeBlocks<MetasValid, MergeCombinatorFillAir<MetasValid> >(
2488 SizeX, SizeY, SizeZ,
2489 SrcOffX, SrcOffY, SrcOffZ,
2490 DstOffX, DstOffY, DstOffZ,
2499 InternalMergeBlocks<MetasValid, MergeCombinatorImprint<MetasValid> >(
2502 SizeX, SizeY, SizeZ,
2503 SrcOffX, SrcOffY, SrcOffZ,
2504 DstOffX, DstOffY, DstOffZ,
2513 InternalMergeBlocks<MetasValid, MergeCombinatorLake<MetasValid> >(
2516 SizeX, SizeY, SizeZ,
2517 SrcOffX, SrcOffY, SrcOffZ,
2518 DstOffX, DstOffY, DstOffZ,
2527 InternalMergeBlocks<MetasValid, MergeCombinatorSpongePrint<MetasValid> >(
2530 SizeX, SizeY, SizeZ,
2531 SrcOffX, SrcOffY, SrcOffZ,
2532 DstOffX, DstOffY, DstOffZ,
2541 InternalMergeBlocks<MetasValid, MergeCombinatorDifference<MetasValid> >(
2544 SizeX, SizeY, SizeZ,
2545 SrcOffX, SrcOffY, SrcOffZ,
2546 DstOffX, DstOffY, DstOffZ,
2555 InternalMergeBlocks<MetasValid, MergeCombinatorSimpleCompare<MetasValid> >(
2558 SizeX, SizeY, SizeZ,
2559 SrcOffX, SrcOffY, SrcOffZ,
2560 DstOffX, DstOffY, DstOffZ,
2569 InternalMergeBlocks<MetasValid, MergeCombinatorMask<MetasValid> >(
2572 SizeX, SizeY, SizeZ,
2573 SrcOffX, SrcOffY, SrcOffZ,
2574 DstOffX, DstOffY, DstOffZ,
2581 UNREACHABLE(
"Unsupported block area merge strategy");
2603 for (
auto & keyPair: a_BlockEntities)
2605 delete keyPair.second;
2607 a_BlockEntities.clear();
2626 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)
2644 auto srcX = x + a_RelX;
2645 auto srcY = y + a_RelY;
2646 auto srcZ = z + a_RelZ;
2649 auto srcIdx = a_Src.
MakeIndex(srcX, srcY, srcZ);
2679 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)
2711 for (
auto & keyPair: oldBE)
2713 auto type =
m_BlockTypes[
static_cast<size_t>(keyPair.first)];
2714 if (type == keyPair.second->GetBlockType())
2720 delete keyPair.second;
2748 if (a_BlockEntities !=
nullptr)
2751 delete a_BlockEntities;
2819 for (
int y = 0; y < SizeY; y++)
2821 int ChunkY = MinY + y;
2823 for (
int z = 0; z < SizeZ; z++)
2825 int ChunkZ = BaseZ + z;
2826 int AreaZ = OffZ + z;
2827 for (
int x = 0; x < SizeX; x++)
2829 int ChunkX = BaseX + x;
2830 int AreaX = OffX + x;
2899 for (
int y = 0; y < SizeY; y++)
2901 int InChunkY = MinY + y;
2903 for (
int z = 0; z < SizeZ; z++)
2905 int InChunkZ = BaseZ + z;
2906 int AreaZ = OffZ + z;
2907 for (
int x = 0; x < SizeX; x++)
2909 int InChunkX = BaseX + x;
2910 int AreaX = OffX + x;
2920 for (
int y = 0; y < SizeY; y++)
2922 int InChunkY = MinY + y;
2924 for (
int z = 0; z < SizeZ; z++)
2926 int InChunkZ = BaseZ + z;
2927 int AreaZ = OffZ + z;
2928 for (
int x = 0; x < SizeX; x++)
2930 int InChunkX = BaseX + x;
2931 int AreaX = OffX + x;
2941 for (
int y = 0; y < SizeY; y++)
2943 int InChunkY = MinY + y;
2945 for (
int z = 0; z < SizeZ; z++)
2947 int InChunkZ = BaseZ + z;
2948 int AreaZ = OffZ + z;
2949 for (
int x = 0; x < SizeX; x++)
2951 int InChunkX = BaseX + x;
2952 int AreaX = OffX + x;
2962 for (
int y = 0; y < SizeY; y++)
2964 int InChunkY = MinY + y;
2966 for (
int z = 0; z < SizeZ; z++)
2968 int InChunkZ = BaseZ + z;
2969 int AreaZ = OffZ + z;
2970 for (
int x = 0; x < SizeX; x++)
2972 int InChunkX = BaseX + x;
2973 int AreaX = OffX + x;
bool HasBlockMetas(void) const
BLOCKTYPE GetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ) const
std::map< size_t, cBlockEntity * > cBlockEntities
void CopyFrom(const cBlockArea &a_From)
Copies the contents from the specified BlockArea into this object.
NIBBLETYPE GetBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ) const
Vector3i m_WEOffset
An extra data value sometimes stored in the .schematic file.
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 DumpToRawFile(const AString &a_FileName)
For testing purposes only, dumps the area into a file.
void SetRelBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType)
void RotateCCWNoMeta(void)
Rotates the entire area counter-clockwise around the Y axis, doesn't use blockhandlers for block meta...
void SetWEOffset(int a_OffsetX, int a_OffsetY, int a_OffsetZ)
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta)
Rotates a given block meta counter-clockwise.
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.
std::unique_ptr< BLOCKTYPE[]> BLOCKARRAY
bool ForEachBlockEntity(cBlockEntityCallback a_Callback)
Calls the callback for all the block entities.
size_t CountSpecificBlocks(BLOCKTYPE a_BlockType) const
Returns how many times the specified block is contained in the area.
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.
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta)
Mirrors a given block meta around the XY plane.
NIBBLETYPE GetRelBlockMeta(int a_RelX, int a_RelY, int a_RelZ) const
unsigned char BLOCKTYPE
The datatype used by blockdata.
void RotateCWNoMeta(void)
Rotates the entire area clockwise around the Y axis, doesn't use blockhandlers for block meta...
eMergeStrategy
The per-block strategy to use when merging another block area into this object.
NIBBLETYPE GetBlockLight(Vector3i a_RelPos) const
BLOCKTYPE GetBlock(Vector3i a_RelPos) const
NIBBLETYPE GetBlockSkyLight(int a_BlockX, int a_BlockY, int a_BlockZ) const
void ExpandNibbles(NIBBLEARRAY &a_Array, int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMaxY, int a_SubMinZ, int a_AddMaxZ)
void SetNibble(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Value, NIBBLETYPE *a_Array)
void GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) const
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.
static bool IsValidHeight(int a_Height)
Validates a height-coordinate.
void CopyNibbles(NIBBLETYPE *a_AreaDst, const NIBBLETYPE *a_ChunkSrc)
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 SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockMeta)
void SetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
std::unique_ptr< NIBBLETYPE[]> NIBBLEARRAY
void MirrorXZNoMeta(void)
Mirrors the entire area around the XZ plane, doesn't use blockhandlers for block meta.
bool HasBlockSkyLights(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...
bool HasBlockEntities(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.
void Move(T a_X, T a_Y, T a_Z)
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta)
Mirros a given block meta around the YZ plane.
static void ClearBlockEntities(cBlockEntities &a_BlockEntities)
Clears the block entities from the specified container, freeing each blockentity. ...
void Set(T a_x, T a_y, T a_z)
void RescanBlockEntities(void)
Updates m_BlockEntities to remove BEs that no longer match the blocktype at their coords...
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
void MergeCombinatorLake(BLOCKTYPE &a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE &a_DstMeta, NIBBLETYPE a_SrcMeta)
Combinator used for cBlockArea::msLake merging.
NIBBLETYPE GetNibble(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE *a_Array) const
cBlockEntitiesPtr m_BlockEntities
The block entities contained within the area.
bool HasBlockLights(void) const
void SetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType)
virtual void ChunkData(const cChunkData &a_BlockTypes) override
size_t MakeIndex(Vector3i a_RelPos) const
Returns the index into the internal arrays for the specified coords.
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.
void MergeCombinatorFillAir(BLOCKTYPE &a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE &a_DstMeta, NIBBLETYPE a_SrcMeta)
Combinator used for cBlockArea::msFillAir merging.
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 SetBlockSkyLight(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockSkyLight)
void SetRelBlockLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockLight)
void MergeByStrategy(const cBlockArea &a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy, const NIBBLETYPE *SrcMetas, NIBBLETYPE *DstMetas)
void SetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockSkyLight)
void MergeCombinatorMask(BLOCKTYPE &a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE &a_DstMeta, NIBBLETYPE a_SrcMeta)
Combinator used for cBlockArea::msMask merging.
void MergeCombinatorOverwrite(BLOCKTYPE &a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE &a_DstMeta, NIBBLETYPE a_SrcMeta)
Combinator used for cBlockArea::msOverwrite merging.
void Clear(void)
Clears the data stored to reclaim memory.
void RotateCCW(void)
Rotates the entire area counter-clockwise around the Y axis.
std::unique_ptr< cBlockEntities, sBlockEntitiesDeleter > cBlockEntitiesPtr
cBlockEntity * Clone(Vector3i a_Pos)
Makes an exact copy of this block entity, except for its m_World (set to nullptr), and at a new position.
void CopyTo(cBlockArea &a_Into) const
Copies this object's contents into the specified BlockArea.
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta)
Rotates a given block meta clockwise.
void MirrorYZ(void)
Mirrors the entire area around the YZ plane.
void MergeCombinatorImprint(BLOCKTYPE &a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE &a_DstMeta, NIBBLETYPE a_SrcMeta)
Combinator used for cBlockArea::msImprint merging.
bool Open(const AString &iFileName, eMode iMode)
const Vector3i & GetOrigin(void) const
NIBBLETYPE GetSkyLight(Vector3i a_RelPos) const
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 GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ) const
virtual void BlockEntity(cBlockEntity *a_BlockEntity) override
size_t GetBlockCount(void) const
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:
cCuboid GetBounds(void) const
BLOCKTYPE GetRelBlockType(int a_RelX, int a_RelY, int a_RelZ) const
virtual bool Coords(int a_ChunkX, int a_ChunkZ) override
void SetRelBlockMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockMeta)
void GetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) const
size_t CountNonAirBlocks(void) const
Returns the count of blocks that are not air.
void CropNibbles(NIBBLEARRAY &a_Array, int a_AddMinX, int a_SubMaxX, int a_AddMinY, int a_SubMaxY, int a_AddMinZ, int a_SubMaxZ)
void RemoveNonMatchingBlockEntities(void)
Removes from m_BlockEntities those BEs that no longer match the blocktype at their coords...
void MergeCombinatorSimpleCompare(BLOCKTYPE &a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE &a_DstMeta, NIBBLETYPE a_SrcMeta)
Combinator used for cBlockArea::msSimpleCompare merging.
void LOGWARNING(const char *a_Format, fmt::ArgList a_ArgList)
cCuboid m_AreaBounds
Bounds of the whole area being read, in world coords.
virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta)
Mirros a given block meta around the XZ plane.
void SetBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockLight)
void MirrorXY(void)
Mirrors the entire area around the XY plane.
NIBBLETYPE * GetBlockLight(void) const
NIBBLETYPE * GetBlockSkyLight(void) const
NIBBLETYPE GetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE *a_Array) 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.
static NIBBLETYPE GetNibble(const COMPRESSED_NIBBLETYPE &a_Buffer, int a_BlockIdx, bool a_IsSkyLightNibble=false)
cBlockHandler * BlockHandler(BLOCKTYPE a_BlockType)
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.
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 CropBlockTypes(int a_AddMinX, int a_SubMaxX, int a_AddMinY, int a_SubMaxY, int a_AddMinZ, int a_SubMaxZ)
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. ...
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.
cItems PickupsFromBlock(Vector3i a_AbsPos, const cEntity *a_Digger=nullptr, const cItem *a_Tool=nullptr)
Returns the pickups that would result if the block at the specified position was mined by a_Digger...
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 SetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Value, NIBBLETYPE *a_Array)
static size_t MakeIndexForSize(Vector3i a_RelPos, Vector3i a_Size)
BLOCKTYPE * GetBlockTypes(void) const
Returns the internal pointer to the block types.
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...
bool IsInside(Vector3i v) const
void ExpandBlockTypes(int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMaxY, int a_SubMinZ, int a_AddMaxZ)
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...
NIBBLETYPE * GetBlockMetas(void) const
const Vector3i & GetSize(void) const
static bool IsValidDataTypeCombination(int a_DataTypes)
Returns true if the datatype combination is valid.
void SetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
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...
cChunkReader(cBlockArea &a_Area)
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.
void( CombinatorFunc)(BLOCKTYPE &a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE &a_DstMeta, NIBBLETYPE a_SrcMeta)
void RotateCW(void)
Rotates the entire area clockwise around the Y axis.
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 MirrorXYNoMeta(void)
Mirrors the entire area around the XY plane, doesn't use blockhandlers for block meta.
void SetOrigin(int a_OriginX, int a_OriginY, int a_OriginZ)
Resets the origin.
void MergeCombinatorSpongePrint(BLOCKTYPE &a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE &a_DstMeta, NIBBLETYPE a_SrcMeta)
Combinator used for cBlockArea::msSpongePrint merging.
void operator()(cBlockEntities *a_BlockEntities)
NIBBLETYPE GetRelBlockLight(int a_RelX, int a_RelY, int a_RelZ) const
#define UNREACHABLE(x)
Use to mark code that should be impossible to reach.
NIBBLETYPE GetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ) const
void MirrorYZNoMeta(void)
Mirrors the entire area around the YZ plane, doesn't use blockhandlers for block meta.
static bool IsBlockEntityBlockType(BLOCKTYPE a_BlockType)
Returns true if the specified blocktype is supposed to have an associated block entity.
static cBlockEntity * 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...
This class bridges a vector of cItem for safe access via Lua.
void MergeCombinatorDifference(BLOCKTYPE &a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE &a_DstMeta, NIBBLETYPE a_SrcMeta)
Combinator used for cBlockArea::msDifference merging.
bool HasBlockTypes(void) const
NIBBLETYPE GetMeta(Vector3i a_RelPos) const
int GetDataTypes(void) const
Returns the datatypes that are stored in the object (bitmask of baXXX values)
void MirrorXZ(void)
Mirrors the entire area around the XZ plane.
NIBBLEARRAY m_BlockSkyLight
cBlockEntity * GetBlockEntityRel(Vector3i a_RelPos)
Returns the cBlockEntity at the specified coords, or nullptr if none.