diff --git a/block_copy.py b/block_copy.py index 54a97f7..d2e34ab 100644 --- a/block_copy.py +++ b/block_copy.py @@ -1,11 +1,13 @@ from datetime import datetime import logging +log = logging.getLogger(__name__) + import numpy from box import BoundingBox from mclevelbase import exhaust import materials +from entity import Entity, TileEntity -log = logging.getLogger(__name__) def convertBlocks(destLevel, sourceLevel, blocks, blockData): return materials.convertBlocks(destLevel.materials, sourceLevel.materials, blocks, blockData) @@ -86,6 +88,9 @@ def copyBlocksFromIter(destLevel, sourceLevel, sourceBox, destinationPoint, bloc destBox = BoundingBox(destinationPoint, sourceBox.size) chunkCount = destBox.chunkCount i = 0 + e = 0 + t = 0 + sourceMask = sourceMaskFunc(blocksToCopy) copyOffset = [d - s for s, d in zip(sourceBox.origin, destinationPoint)] @@ -139,12 +144,36 @@ def copyBlocksFromIter(destLevel, sourceLevel, sourceBox, destinationPoint, bloc if convertedSourceData is not None: destChunk.Data[destSlices][mask] = convertedSourceData[mask] + if entities: + e += len(sourceChunk.Entities) + for entityTag in sourceChunk.Entities: + x, y, z = Entity.pos(entityTag) + if (x, y, z) not in sourceBox: + continue + + eTag = Entity.copyWithOffset(entityTag, copyOffset) + + destLevel.addEntity(eTag) + + t += len(sourceChunk.TileEntities) + for tileEntityTag in sourceChunk.TileEntities: + x, y, z = TileEntity.pos(tileEntityTag) + if (x, y, z) not in sourceBox: + continue + + eTag = TileEntity.copyWithOffset(tileEntityTag, copyOffset) + + destLevel.addTileEntity(eTag) + destChunk.chunkChanged() - for i in destLevel.copyEntitiesFromIter(sourceLevel, sourceBox, destinationPoint, entities): - yield i - 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)) + + + + + diff --git a/level.py b/level.py index 3e6559a..a416011 100644 --- a/level.py +++ b/level.py @@ -207,9 +207,6 @@ class MCLevel(object): def getTileEntitiesInBox(self, box): return [] - def copyEntitiesFromIter(self, *args, **kw): - yield - def removeEntitiesInBox(self, box): pass @@ -475,78 +472,6 @@ class MCLevel(object): class EntityLevel(MCLevel): """Abstract subclass of MCLevel that adds default entity behavior""" - def copyEntitiesFromInfiniteIter(self, sourceLevel, sourceBox, destinationPoint, entities): - chunkCount = sourceBox.chunkCount - i = 0 - copyOffset = map(lambda x, y: x - y, destinationPoint, sourceBox.origin) - e = t = 0 - - for (chunk, slices, point) in sourceLevel.getChunkSlices(sourceBox): - yield (i, chunkCount) - i += 1 - - if entities: - e += len(chunk.Entities) - for entityTag in chunk.Entities: - x, y, z = Entity.pos(entityTag) - if (x, y, z) not in sourceBox: - continue - - eTag = Entity.copyWithOffset(entityTag, copyOffset) - - self.addEntity(eTag) - - t += len(chunk.TileEntities) - for tileEntityTag in chunk.TileEntities: - x, y, z = TileEntity.pos(tileEntityTag) - if (x, y, z) not in sourceBox: - continue - - eTag = TileEntity.copyWithOffset(tileEntityTag, copyOffset) - - self.addTileEntity(eTag) - - info("Copied {0} entities, {1} tile entities".format(e, t)) - - def copyEntitiesFromIter(self, sourceLevel, sourceBox, destinationPoint, entities=True): - # assume coords have already been adjusted by copyBlocks - # if not self.hasEntities or not sourceLevel.hasEntities: - # return - sourcePoint0 = sourceBox.origin - - if sourceLevel.isInfinite: - for i in self.copyEntitiesFromInfiniteIter(sourceLevel, sourceBox, destinationPoint, entities): - yield i - else: - entsCopied = 0 - tileEntsCopied = 0 - copyOffset = map(lambda x, y: x - y, destinationPoint, sourcePoint0) - if entities: - for entity in sourceLevel.getEntitiesInBox(sourceBox): - eTag = Entity.copyWithOffset(entity, copyOffset) - - self.addEntity(eTag) - entsCopied += 1 - - i = 0 - for entity in sourceLevel.getTileEntitiesInBox(sourceBox): - i += 1 - if i % 100 == 0: - yield - - if not 'x' in entity: - continue - eTag = TileEntity.copyWithOffset(entity, copyOffset) - - try: - self.addTileEntity(eTag) - tileEntsCopied += 1 - except ChunkNotPresent: - pass - - yield - info(u"Copied {0} entities, {1} tile entities".format(entsCopied, tileEntsCopied)) - def getEntitiesInBox(self, box): """Returns a list of references to entities in this chunk, whose positions are within box""" return [ent for ent in self.Entities if Entity.pos(ent) in box]