def fillBlocks(self, box, blockInfo, blocksToReplace=[]): if box is None: box = self.bounds else: box = box.intersect(self.bounds) info(u"Filling blocks in {0} with {1}, replacing{2}".format( box, blockInfo, blocksToReplace)) slices = map(slice, box.origin, box.maximum) blocks = self.Blocks[slices[0], slices[2], slices[1]] if len(blocksToReplace): blocktable = self.blockReplaceTable(blocksToReplace) shouldRetainData = (self.materials == materials.alphaMaterials) and all([ blockrotation.SameRotationType( blockInfo, b) for b in blocksToReplace ]) if hasattr(self, "Data") and shouldRetainData: data = self.Data[slices[0], slices[2], slices[1]] mask = blocktable[blocks, data] data[mask] = blockInfo.blockData else: mask = blocktable[blocks, 0] blocks[mask] = blockInfo.ID else: blocks[:] = blockInfo.ID if hasattr(self, "Data"): self.Data[slices[0], slices[2], slices[1]] = blockInfo.blockData
def fillBlocksIter(level, box, blockInfo, blocksToReplace=()): if box is None: chunkIterator = level.getAllChunkSlices() box = level.bounds else: chunkIterator = level.getChunkSlices(box) # shouldRetainData = (not blockInfo.hasVariants and not any([b.hasVariants for b in blocksToReplace])) # if shouldRetainData: # log.info( "Preserving data bytes" ) shouldRetainData = False # xxx old behavior overwrote blockdata with 0 when e.g. replacing water with lava log.info("Replacing {0} with {1}".format(blocksToReplace, blockInfo)) changesLighting = True blocktable = None if len(blocksToReplace): blocktable = blockReplaceTable(blocksToReplace) shouldRetainData = all([ blockrotation.SameRotationType(blockInfo, b) for b in blocksToReplace ]) newAbsorption = level.materials.lightAbsorption[blockInfo.ID] oldAbsorptions = [ level.materials.lightAbsorption[b.ID] for b in blocksToReplace ] changesLighting = False for a in oldAbsorptions: if a != newAbsorption: changesLighting = True newEmission = level.materials.lightEmission[blockInfo.ID] oldEmissions = [ level.materials.lightEmission[b.ID] for b in blocksToReplace ] for a in oldEmissions: if a != newEmission: changesLighting = True i = 0 skipped = 0 replaced = 0 for (chunk, slices, point) in chunkIterator: i += 1 if i % 100 == 0: log.info(u"Chunk {0}...".format(i)) yield i, box.chunkCount blocks = chunk.Blocks[slices] data = chunk.Data[slices] mask = slice(None) needsLighting = changesLighting if blocktable is not None: mask = blocktable[blocks, data] blockCount = mask.sum() replaced += blockCount # don't waste time relighting and copying if the mask is empty if blockCount: blocks[:][mask] = blockInfo.ID if not shouldRetainData: data[mask] = blockInfo.blockData else: skipped += 1 needsLighting = False def include(tileEntity): p = TileEntity.pos(tileEntity) x, y, z = map(lambda a, b, c: (a - b) - c, p, point, box.origin) return not ((p in box) and mask[x, z, y]) chunk.TileEntities[:] = filter(include, chunk.TileEntities) else: blocks[:] = blockInfo.ID if not shouldRetainData: data[:] = blockInfo.blockData chunk.removeTileEntitiesInBox(box) chunk.chunkChanged(needsLighting) if len(blocksToReplace): log.info(u"Replace: Skipped {0} chunks, replaced {1} blocks".format( skipped, replaced))