AString cSchematicFileSerializer::SaveToSchematicNBT(const cBlockArea & a_BlockArea)
{
	cFastNBTWriter Writer("Schematic");
	Writer.AddShort("Width",  static_cast<Int16>(a_BlockArea.m_Size.x));
	Writer.AddShort("Height", static_cast<Int16>(a_BlockArea.m_Size.y));
	Writer.AddShort("Length", static_cast<Int16>(a_BlockArea.m_Size.z));
	Writer.AddString("Materials", "Alpha");
	if (a_BlockArea.HasBlockTypes())
	{
		Writer.AddByteArray("Blocks", reinterpret_cast<const char *>(a_BlockArea.GetBlockTypes()), a_BlockArea.GetBlockCount());
	}
	else
	{
		AString Dummy(a_BlockArea.GetBlockCount(), 0);
		Writer.AddByteArray("Blocks", Dummy.data(), Dummy.size());
	}
	if (a_BlockArea.HasBlockMetas())
	{
		Writer.AddByteArray("Data", reinterpret_cast<const char *>(a_BlockArea.GetBlockMetas()), a_BlockArea.GetBlockCount());
	}
	else
	{
		AString Dummy(a_BlockArea.GetBlockCount(), 0);
		Writer.AddByteArray("Data", Dummy.data(), Dummy.size());
	}

	Writer.AddInt("WEOffsetX", a_BlockArea.m_WEOffset.x);
	Writer.AddInt("WEOffsetY", a_BlockArea.m_WEOffset.y);
	Writer.AddInt("WEOffsetZ", a_BlockArea.m_WEOffset.z);

	// TODO: Save entities and block entities
	Writer.BeginList("Entities", TAG_Compound);
	Writer.EndList();
	Writer.BeginList("TileEntities", TAG_Compound);
	Writer.EndList();
	Writer.Finish();

	return Writer.GetResult();
}
示例#2
0
void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy)
{
	// Block types are compulsory, block metas are voluntary
	if (!HasBlockTypes() || !a_Src.HasBlockTypes())
	{
		LOGWARNING("%s: cannot merge because one of the areas doesn't have blocktypes.", __FUNCTION__);
		return;
	}
	
	// Dst is *this, Src is a_Src
	int SrcOffX = std::max(0, -a_RelX);  // Offset in Src where to start reading
	int DstOffX = std::max(0,  a_RelX);  // Offset in Dst where to start writing
	int SizeX   = std::min(a_Src.GetSizeX() - SrcOffX, GetSizeX() - DstOffX);  // How many blocks to copy

	int SrcOffY = std::max(0, -a_RelY);  // Offset in Src where to start reading
	int DstOffY = std::max(0,  a_RelY);  // Offset in Dst where to start writing
	int SizeY   = std::min(a_Src.GetSizeY() - SrcOffY, GetSizeY() - DstOffY);  // How many blocks to copy

	int SrcOffZ = std::max(0, -a_RelZ);  // Offset in Src where to start reading
	int DstOffZ = std::max(0,  a_RelZ);  // Offset in Dst where to start writing
	int SizeZ   = std::min(a_Src.GetSizeZ() - SrcOffZ, GetSizeZ() - DstOffZ);  // How many blocks to copy

	const NIBBLETYPE * SrcMetas = a_Src.GetBlockMetas();
	NIBBLETYPE * DstMetas = m_BlockMetas;
	bool IsDummyMetas = ((SrcMetas == NULL) || (DstMetas == NULL));
	
	if (IsDummyMetas)
	{
		SrcMetas = new NIBBLETYPE[a_Src.GetBlockCount()];
		DstMetas = new NIBBLETYPE[GetBlockCount()];
	}
	
	switch (a_Strategy)
	{
		case msOverwrite:
		{
			InternalMergeBlocks(
				m_BlockTypes, a_Src.GetBlockTypes(),
				DstMetas, SrcMetas,
				SizeX, SizeY, SizeZ,
				SrcOffX, SrcOffY, SrcOffZ,
				DstOffX, DstOffY, DstOffZ,
				a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
				m_SizeX, m_SizeY, m_SizeZ,
				MergeCombinatorOverwrite
			);
			break;
		}  // case msOverwrite
		
		case msFillAir:
		{
			InternalMergeBlocks(
				m_BlockTypes, a_Src.GetBlockTypes(),
				DstMetas, SrcMetas,
				SizeX, SizeY, SizeZ,
				SrcOffX, SrcOffY, SrcOffZ,
				DstOffX, DstOffY, DstOffZ,
				a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
				m_SizeX, m_SizeY, m_SizeZ,
				MergeCombinatorFillAir
			);
			break;
		}  // case msFillAir
		
		case msImprint:
		{
			InternalMergeBlocks(
				m_BlockTypes, a_Src.GetBlockTypes(),
				DstMetas, SrcMetas,
				SizeX, SizeY, SizeZ,
				SrcOffX, SrcOffY, SrcOffZ,
				DstOffX, DstOffY, DstOffZ,
				a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
				m_SizeX, m_SizeY, m_SizeZ,
				MergeCombinatorImprint
			);
			break;
		}  // case msImprint
		
		case msLake:
		{
			InternalMergeBlocks(
				m_BlockTypes, a_Src.GetBlockTypes(),
				DstMetas, SrcMetas,
				SizeX, SizeY, SizeZ,
				SrcOffX, SrcOffY, SrcOffZ,
				DstOffX, DstOffY, DstOffZ,
				a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
				m_SizeX, m_SizeY, m_SizeZ,
				MergeCombinatorLake
			);
			break;
		}  // case msLake
		
		default:
		{
			LOGWARNING("Unknown block area merge strategy: %d", a_Strategy);
			ASSERT(!"Unknown block area merge strategy");
			break;
		}
	}  // switch (a_Strategy)
	
	if (IsDummyMetas)
	{
		delete[] SrcMetas;
		delete[] DstMetas;
	}
}
示例#3
0
void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy, const NIBBLETYPE * SrcMetas, NIBBLETYPE * DstMetas)
{
	// Block types are compulsory, block metas are voluntary
	if (!HasBlockTypes() || !a_Src.HasBlockTypes())
	{
		LOGWARNING("%s: cannot merge because one of the areas doesn't have blocktypes.", __FUNCTION__);
		return;
	}
	
	// Dst is *this, Src is a_Src
	int SrcOffX = std::max(0, -a_RelX);  // Offset in Src where to start reading
	int DstOffX = std::max(0,  a_RelX);  // Offset in Dst where to start writing
	int SizeX   = std::min(a_Src.GetSizeX() - SrcOffX, GetSizeX() - DstOffX);  // How many blocks to copy

	int SrcOffY = std::max(0, -a_RelY);  // Offset in Src where to start reading
	int DstOffY = std::max(0,  a_RelY);  // Offset in Dst where to start writing
	int SizeY   = std::min(a_Src.GetSizeY() - SrcOffY, GetSizeY() - DstOffY);  // How many blocks to copy

	int SrcOffZ = std::max(0, -a_RelZ);  // Offset in Src where to start reading
	int DstOffZ = std::max(0,  a_RelZ);  // Offset in Dst where to start writing
	int SizeZ   = std::min(a_Src.GetSizeZ() - SrcOffZ, GetSizeZ() - DstOffZ);  // How many blocks to copy
	
	switch (a_Strategy)
	{
		case cBlockArea::msOverwrite:
		{
			InternalMergeBlocks<MetasValid, MergeCombinatorOverwrite<MetasValid> >(
				m_BlockTypes, a_Src.GetBlockTypes(),
				DstMetas, SrcMetas,
				SizeX, SizeY, SizeZ,
				SrcOffX, SrcOffY, SrcOffZ,
				DstOffX, DstOffY, DstOffZ,
				a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
				m_Size.x, m_Size.y, m_Size.z
			);
			return;
		}  // case msOverwrite
		
		case cBlockArea::msFillAir:
		{
			InternalMergeBlocks<MetasValid, MergeCombinatorFillAir<MetasValid> >(
				m_BlockTypes, a_Src.GetBlockTypes(),
				DstMetas, SrcMetas,
				SizeX, SizeY, SizeZ,
				SrcOffX, SrcOffY, SrcOffZ,
				DstOffX, DstOffY, DstOffZ,
				a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
				m_Size.x, m_Size.y, m_Size.z
			);
			return;
		}  // case msFillAir
		
		case cBlockArea::msImprint:
		{
			InternalMergeBlocks<MetasValid, MergeCombinatorImprint<MetasValid> >(
				m_BlockTypes, a_Src.GetBlockTypes(),
				DstMetas, SrcMetas,
				SizeX, SizeY, SizeZ,
				SrcOffX, SrcOffY, SrcOffZ,
				DstOffX, DstOffY, DstOffZ,
				a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
				m_Size.x, m_Size.y, m_Size.z
			);
			return;
		}  // case msImprint
		
		case cBlockArea::msLake:
		{
			InternalMergeBlocks<MetasValid, MergeCombinatorLake<MetasValid> >(
				m_BlockTypes, a_Src.GetBlockTypes(),
				DstMetas, SrcMetas,
				SizeX, SizeY, SizeZ,
				SrcOffX, SrcOffY, SrcOffZ,
				DstOffX, DstOffY, DstOffZ,
				a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
				m_Size.x, m_Size.y, m_Size.z
			);
			return;
		}  // case msLake
		
		case cBlockArea::msSpongePrint:
		{
			InternalMergeBlocks<MetasValid, MergeCombinatorSpongePrint<MetasValid> >(
				m_BlockTypes, a_Src.GetBlockTypes(),
				DstMetas, SrcMetas,
				SizeX, SizeY, SizeZ,
				SrcOffX, SrcOffY, SrcOffZ,
				DstOffX, DstOffY, DstOffZ,
				a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
				m_Size.x, m_Size.y, m_Size.z
			);
			return;
		}  // case msSpongePrint

		case cBlockArea::msDifference:
		{
			InternalMergeBlocks<MetasValid, MergeCombinatorDifference<MetasValid> >(
				m_BlockTypes, a_Src.GetBlockTypes(),
				DstMetas, SrcMetas,
				SizeX, SizeY, SizeZ,
				SrcOffX, SrcOffY, SrcOffZ,
				DstOffX, DstOffY, DstOffZ,
				a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
				m_Size.x, m_Size.y, m_Size.z
			);
			return;
		}	// case msDifference
		
		case cBlockArea::msMask:
		{
			InternalMergeBlocks<MetasValid, MergeCombinatorMask<MetasValid> >(
				m_BlockTypes, a_Src.GetBlockTypes(),
				DstMetas, SrcMetas,
				SizeX, SizeY, SizeZ,
				SrcOffX, SrcOffY, SrcOffZ,
				DstOffX, DstOffY, DstOffZ,
				a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
				m_Size.x, m_Size.y, m_Size.z
			);
			return;
		}  // case msMask
	}  // switch (a_Strategy)
	
	LOGWARNING("Unknown block area merge strategy: %d", a_Strategy);
	ASSERT(!"Unknown block area merge strategy");
	return;
}