
import random
from pymclevel import MCSchematic

#Use the inputs variable to tell MCEdit we want a Density option. See filterdemo.py for more info.
inputs = (
  ("Density", (10, 1, 100)),  #Integer input, default: 10, min: 1, max: 100.
)

#The perform function is where we receive a reference to the level object, a BoundingBox object for the current selection, and an options dict holding the options the user specified.

def perform(level, box, options):
    density = options["Density"]
    treeChance = 0.05 * float(density) / 100.0 #Scale Density input to the range 0.0% - 5.0%
    
    treeSchematic = makeTreeSchematic()
    
    #Visit each column and check the top block for dirt or grass
    #Adjust the min and max inward because the tree is 5x5
    for x in xrange(box.minx+2, box.maxx-2):
      for z in xrange(box.minz+2, box.maxz-2):

        #Loop through the column from top to bottom until we find the top block
        for y in reversed(xrange(box.miny, box.maxy)):
          block = level.blockAt(x, y, z)
          
          if block != 0: #found the first non-air block
            if block == 2 or block == 3: #dirt or grass
              if random.random() < treeChance:
                #copy the tree from the schematic
                level.copyBlocksFrom(treeSchematic, treeSchematic.bounds, (x-2, y+1, z-2))

            break; #next column
            
def makeTreeSchematic():
    schem = MCSchematic(shape = (5,6,5)) #shape is x,y,z
    #Here I use array slicing to fill out the different parts of the tree.
    
    #Leaves, crown
    schem.Blocks[1:4,1:4,5] = [
      [0, 18, 0],
      [18, 18, 18],
      [0, 18, 0],
    ]
    schem.Blocks[1:4,1:4,4] = 18
    
    #Leaves, midsection
    schem.Blocks[:,:,2:4] = 18
    
    #Trunk
    schem.Blocks[2,2,0:5] = 17
    
    return schem
