1. # This will leave the top X layers of the selected area.
  2. # The area underneath will be set to Air or what the user chooses.
  3. # copied from topsoil.py - all credit to codewarrior0 (assuming he is the author)
  4. from numpy import zeros
  5. import itertools
  6. from pymclevel import alphaMaterials
  7. from pymclevel.level import extractHeights
  8.  
  9. am = alphaMaterials
  10.  
  11. #naturally occuring materials
  12. blocks = [
  13.   am.Grass,
  14.   am.Dirt,
  15.   am.Stone,
  16.   am.Bedrock,
  17.   am.Sand,
  18.   am.Gravel,
  19.   am.GoldOre,
  20.   am.IronOre,
  21.   am.CoalOre,
  22.   am.LapisLazuliOre,
  23.   am.DiamondOre,
  24.   am.RedstoneOre,
  25.   am.RedstoneOreGlowing,
  26.   am.Netherrack,
  27.   am.SoulSand,
  28.   am.Clay,
  29.   am.Glowstone
  30. ]
  31. blocktypes = [b.ID for b in blocks]
  32.  
  33. def naturalBlockmask():
  34.     blockmask = zeros((256,), dtype='bool')
  35.     blockmask[blocktypes] = True
  36.     return blockmask
  37.  
  38. inputs = (
  39.   ("Layers to keep", (1, 1, 128)),
  40.   ("Fill under with:", alphaMaterials.Air),
  41. )
  42.  
  43. def perform(level, box, options):
  44.     depth = options["Layers to keep"]
  45.     blocktype = options["Fill under with:"]
  46.  
  47.     #compute a truth table that we can index to find out whether a block
  48.     # is naturally occuring and should be considered in a heightmap
  49.     blockmask = naturalBlockmask()
  50.  
  51.     #iterate through the slices of each chunk in the selection box
  52.     for chunk, slices, point in level.getChunkSlices(box):
  53.         # slicing the block array is straightforward. blocks will contain only
  54.         # the area of interest in this chunk.
  55.         blocks = chunk.Blocks[slices]
  56.         data = chunk.Data[slices]
  57.  
  58.         # use indexing to look up whether or not each block in blocks is
  59.         # naturally-occuring. these blocks will "count" for column height.
  60.         maskedBlocks = blockmask[blocks]
  61.  
  62.         heightmap = extractHeights(maskedBlocks)
  63.  
  64.         for x, z in itertools.product(*map(xrange, heightmap.shape)):
  65.             h = heightmap[x, z]
  66.             # Take 'lowest point' through 'naturally occuring'
  67.             # then subtract users 'depth' input and set it all as air
  68.             blocks[x, z, 0:(h - depth)] = blocktype.ID
  69.             data[x, z, 0:(h - depth)] = blocktype.blockData
  70.  
  71.         #remember to do this to make sure the chunk is saved
  72.         chunk.chunkChanged()