Permalink
Browse files

Refactor: Move fillBlocks into its own file and remove "fillBlocksFin…

…ite" implementation.
  • Loading branch information...
1 parent a7fd3ed commit ecac4faf93be0c1eb6d9c1925cee792b54ade976 @codewarrior0 codewarrior0 committed Oct 31, 2012
Showing with 104 additions and 126 deletions.
  1. +103 −0 block_fill.py
  2. +0 −83 infiniteworld.py
  3. +1 −43 level.py
View
@@ -0,0 +1,103 @@
+import logging
+log = logging.getLogger(__name__)
+
+import numpy
+
+from mclevelbase import exhaust
+import blockrotation
+from entity import TileEntity
+
+def blockReplaceTable(blocksToReplace):
+ blocktable = numpy.zeros((256, 16), dtype='bool')
+ for b in blocksToReplace:
+ if b.hasVariants:
+ blocktable[b.ID, b.blockData] = True
+ else:
+ blocktable[b.ID] = True
+
+ return blocktable
+
+def fillBlocks(level, box, blockInfo, blocksToReplace=()):
+ return exhaust(level.fillBlocksIter(box, blockInfo, blocksToReplace))
+
+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))
View
@@ -494,90 +494,7 @@ def setSkylightAt(self, x, y, z, lightValue):
createChunk = NotImplemented
- def fillBlocks(self, box, blockInfo, blocksToReplace=()):
- return exhaust(self.fillBlocksIter(box, blockInfo, blocksToReplace))
- def fillBlocksIter(self, box, blockInfo, blocksToReplace=()):
- if box is None:
- chunkIterator = self.getAllChunkSlices()
- box = self.bounds
- else:
- chunkIterator = self.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 = self.blockReplaceTable(blocksToReplace)
- shouldRetainData = all([blockrotation.SameRotationType(blockInfo, b) for b in blocksToReplace])
-
- newAbsorption = self.materials.lightAbsorption[blockInfo.ID]
- oldAbsorptions = [self.materials.lightAbsorption[b.ID] for b in blocksToReplace]
- changesLighting = False
- for a in oldAbsorptions:
- if a != newAbsorption:
- changesLighting = True
-
- newEmission = self.materials.lightEmission[blockInfo.ID]
- oldEmissions = [self.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.value[:] = 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))
def generateLights(self, dirtyChunks=None):
return exhaust(self.generateLightsIter(dirtyChunks))
View
@@ -362,50 +362,8 @@ def setBlockAt(self, x, y, z, blockID):
self.Blocks[x, z, y] = blockID
# --- Fill and Replace ---
- def blockReplaceTable(self, blocksToReplace):
- blocktable = zeros((256, 16), dtype='bool')
- for b in blocksToReplace:
- if b.hasVariants:
- blocktable[b.ID, b.blockData] = True
- else:
- blocktable[b.ID] = True
- return blocktable
-
- def fillBlocksIter(self, box, blockInfo, blocksToReplace=()):
- self.fillBlocks(box, blockInfo, blocksToReplace)
- yield
-
- 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
+ from block_fill import fillBlocks, fillBlocksIter
# --- Transformations ---
def rotateLeft(self):

0 comments on commit ecac4fa

Please sign in to comment.