diff --git a/block_copy.py b/block_copy.py index e507f69..f9af384 100644 --- a/block_copy.py +++ b/block_copy.py @@ -47,7 +47,7 @@ def adjustCopyParameters(destLevel, sourceLevel, sourceBox, destinationPoint): -def copyBlocksFromIter(destLevel, sourceLevel, sourceBox, destinationPoint, blocksToCopy=None, entities=True, create=False): +def copyBlocksFromIter(destLevel, sourceLevel, sourceBox, destinationPoint, blocksToCopy=None, entities=True, create=False, biomes=False): """ copy blocks between two infinite levels by looping through the destination's chunks. make a sub-box of the source level for each chunk and copy block and entities in the sub box to the dest chunk.""" @@ -134,13 +134,16 @@ def copyBlocksFromIter(destLevel, sourceLevel, sourceBox, destinationPoint, bloc eTag = TileEntity.copyWithOffset(tileEntityTag, copyOffset) destLevel.addTileEntity(eTag) + if biomes and hasattr(destChunk, 'Biomes') and hasattr(sourceChunk, 'Biomes'): + destChunk.Biomes[destSlices[:2]] = sourceChunk.Biomes[sourceSlices[:2]] + destChunk.chunkChanged() log.info("Duration: {0}".format(datetime.now() - startTime)) log.info("Copied {0} entities and {1} tile entities".format(e, t)) -def copyBlocksFrom(destLevel, sourceLevel, sourceBox, destinationPoint, blocksToCopy=None, entities=True, create=False): - return exhaust(copyBlocksFromIter(destLevel, sourceLevel, sourceBox, destinationPoint, blocksToCopy, entities, create)) +def copyBlocksFrom(destLevel, sourceLevel, sourceBox, destinationPoint, blocksToCopy=None, entities=True, create=False, biomes=False): + return exhaust(copyBlocksFromIter(destLevel, sourceLevel, sourceBox, destinationPoint, blocksToCopy, entities, create, biomes)) diff --git a/schematic.py b/schematic.py index eba6a17..f5c8649 100644 --- a/schematic.py +++ b/schematic.py @@ -98,6 +98,8 @@ class MCSchematic (EntityLevel): self.root_tag["Data"].value = self.root_tag["Data"].value.reshape(h, l, w) + if "Biomes" in self.root_tag: + self.root_tag["Biomes"].value.shape = (l, w) else: assert shape is not None @@ -113,6 +115,8 @@ class MCSchematic (EntityLevel): self._Blocks = zeros((shape[1], shape[2], shape[0]), 'uint16') root_tag["Data"] = nbt.TAG_Byte_Array(zeros((shape[1], shape[2], shape[0]), uint8)) + root_tag["Biomes"] = nbt.TAG_Byte_Array(zeros((shape[2], shape[0]), uint8)) + self.root_tag = root_tag self.root_tag["Data"].value &= 0xF # discard high bits @@ -198,6 +202,10 @@ class MCSchematic (EntityLevel): self.root_tag["Materials"] = nbt.TAG_String() self.root_tag["Materials"].value = val + @property + def Biomes(self): + return swapaxes(self.root_tag["Biomes"].value, 0, 1) + @classmethod def _isTagLevel(cls, root_tag): return "Schematic" == root_tag.name @@ -343,6 +351,15 @@ class MCSchematic (EntityLevel): return chest + def getChunk(self, cx, cz): + chunk = super(MCSchematic, self).getChunk(cx, cz) + if "Biomes" in self.root_tag: + x = cx << 4 + z = cz << 4 + chunk.Biomes = self.Biomes[x:x + 16, z:z + 16] + return chunk + + class INVEditChest(MCSchematic): Width = 1 Height = 1 @@ -523,7 +540,7 @@ def extractSchematicFromIter(sourceLevel, box, entities=True): newbox, destPoint = p tempSchematic = MCSchematic(shape=box.size, mats=sourceLevel.materials) - for i in tempSchematic.copyBlocksFromIter(sourceLevel, newbox, destPoint, entities=entities): + for i in tempSchematic.copyBlocksFromIter(sourceLevel, newbox, destPoint, entities=entities, biomes=True): yield i yield tempSchematic @@ -557,7 +574,7 @@ def extractZipSchematicFromIter(sourceLevel, box, zipfilename=None, entities=Tru tempSchematic = ZipSchematic(zipfilename, create=True) tempSchematic.materials = sourceLevel.materials - for i in tempSchematic.copyBlocksFromIter(sourceLevel, sourceBox, destPoint, entities=entities, create=True): + for i in tempSchematic.copyBlocksFromIter(sourceLevel, sourceBox, destPoint, entities=entities, create=True, biomes=True): yield i tempSchematic.Width, tempSchematic.Height, tempSchematic.Length = sourceBox.size