def findFullAcacia(matrix, height_map, h, xt, zt): tree_block = [] height_tree = 1 while matrix.getValue(h+height_tree, xt, zt) in trunk_like: #find all the leaves that are around the trunk level by level distance = 1 visited = [] block_to_expand_queue = [(h+height_tree, xt, zt)] new_block_queue = [] tree_block.append((h+height_tree, xt, zt, utilityFunctions.getBlockFullValue(matrix, h+height_tree, xt, zt))) while distance <= 5: #go through the level and find the leaves without going too far while len(block_to_expand_queue) != 0: actual_block = block_to_expand_queue.pop() addSameLevelAcaciaBlockToQueue(matrix, h+height_tree, new_block_queue, visited, tree_block, actual_block, (xt, zt)) block_to_expand_queue = new_block_queue new_block_queue = [] distance += 1 height_tree += 1 #do the same once again for one level above the last block of trunk, since there can be leaves up there distance = 1 visited = [] block_to_expand_queue = [(h+height_tree, xt, zt)] new_block_queue = [] tree_block.append((h+height_tree, xt, zt, utilityFunctions.getBlockFullValue(matrix, h+height_tree, xt, zt))) while distance <= 5: while len(block_to_expand_queue) != 0: actual_block = block_to_expand_queue.pop() addSameLevelAcaciaBlockToQueue(matrix, h+height_tree, new_block_queue, visited, tree_block, actual_block, (xt, zt)) block_to_expand_queue = new_block_queue new_block_queue = [] distance +=1 height_tree += 1 return tree_block
def setIfCorrect(matrix, h, x, z, i): #put block only if the position given is correct (b, d) = utilityFunctions.getBlockFullValue(matrix, h - 1, x, z) if matrix.getValue( h, x, z) in air_like + water_like and (b, d) not in [ bridge_Side_Double, bridge_Side_Top, bridge_Side_Bottom, bridge_Middle_Double, bridge_Middle_Top, bridge_Middle_Bottom ]: matrix.setValue(h, x, z, i)
def fillUnder(matrix, h, x, z): #put blocks under the position if there is air (b, d) = utilityFunctions.getBlockFullValue(matrix, h, x, z) if (b, d) == bridge_Middle_Top: matrix.setValue(h, x, z, bridge_Middle_Double) elif (b, d) == bridge_Side_Top: matrix.setValue(h, x, z, bridge_Side_Double) h -= 1 while matrix.getValue(h, x, z) in air_like + water_like: matrix.setValue(h, x, z, bridge_Side_Double) h -= 1
def putLightT(matrix, h, x, z): h -= 1 for neighbor_position in [(0, -1), (0, 1), (-1, 0), (1, 0)]: new_position = (x + neighbor_position[0], z + neighbor_position[1]) if utilityFunctions.getBlockFullValue(matrix, h, new_position[0], new_position[1]) == (45, 0): if x < new_position[0]: matrix.setValue(h, x, z, (50, 2)) return True elif x > new_position[0]: matrix.setValue(h, x, z, (50, 1)) return True elif z < new_position[1]: matrix.setValue(h, x, z, (50, 4)) return True elif z > new_position[1]: matrix.setValue(h, x, z, (50, 3)) return True return False
def buildPlatform(matrix, h, x_actual, z_actual): anvil = False craftingTable = False light = False for neighbor_position in [(0, -1), (0, 1), (-1, 0), (1, 0), (1, 1), (-1, -1), (1, -1), (-1, 1), (0, 0)]: new_position = (x_actual + neighbor_position[0], z_actual + neighbor_position[1]) if utilityFunctions.getBlockFullValue(matrix, h, new_position[0], new_position[1]) == (0, 0): matrix.setValue(h, new_position[0], new_position[1], (44, 10)) if craftingTable == False: matrix.setValue(h + 1, new_position[0], new_position[1], (58, 0)) craftingTable = True elif anvil == False: matrix.setValue(h + 1, new_position[0], new_position[1], (145, 0)) anvil = True elif light == False: matrix.setValue(h + 1, new_position[0], new_position[1], (50, 5)) light = True
def checkIfGroundValid(matrix, height_map, tree): #check that the tree is not above a path, a rail, or in a building lot min_x = 255 max_x = 0 min_z = 255 max_z = 0 for h, x, z, i in tree: if x > max_x: max_x = x if x < min_x: min_x = x if z > max_z: max_z = z if z < min_z: min_z = z for x in range(min_x, max_x+1): for z in range(min_z, max_z+1): try: (b, d) = utilityFunctions.getBlockFullValue(matrix, height_map[x][z], x, z) if height_map[x][z] == -1 or (b, d) == (1,6) or b in [27, 28, 66, 157, 17, 208]: return False except: continue return True
def generatePath(matrix, path, height_map, pavement_Type): if pavement_Type == "Grass": pavement_Block = (208, 0) baseBlock = (3, 0) light_Pillar = (85,0) elif pavement_Type == "Stone": pavement_Block = (1, 6) baseBlock = (1, 0) light_Pillar = (139,0) def fillUnderneath(matrix, y, x, z): if y < 0: return block = matrix.getValue(y, x, z) if type(block) == tuple: block = block[0] if block in air_like or block in water_like: matrix.setValue(y, x, z, baseBlock) fillUnderneath(matrix, y-1, x, z) def fillAbove(matrix, y, x, z, up_to): if up_to < 0 or y >= matrix.height: return block = matrix.getValue(y, x, z) if type(block) == tuple: block = block[0] if block in air_like: matrix.setValue(y,x,z, (0,0)) fillAbove(matrix, y+1, x, z, up_to-1) def getOrientation(x1, z1, x2, z2): if x1 < x2: return "E" elif x1 > x2: return "W" elif z1 < z2: return "S" elif z1 > z2: return "N" else: return None def generateLight(matrix, block_section, path, height_map): #generate a light by using the center of mass if it is possible (x, z) = computeCenterOfMass(block_section) if height_map[x][z] != -1 and matrix.getValue(height_map[x][z]+1, x, z) not in light_pillar_like+[65] and matrix.getValue(height_map[x][z]-1, x, z) not in air_like: #validity of the center of mass if isNeighborLight(matrix,height_map, x, z) != True: buildLight(matrix, height_map[x][z], x, z) else: (x, z) = findPos(matrix, x, z, path, height_map) if (x, z) != (-1, -1): if isNeighborLight(matrix,height_map, x, z) != True: buildLight(matrix, height_map[x][z], x, z) else: return False def buildLight(matrix, h, x, z): #put the light at the position given logging.info("Generating light at point {}, {}, {}".format(h+1, x, z)) try: matrix.setValue(h+1,x,z,light_Pillar) matrix.setValue(h+2,x,z,light_Pillar) matrix.setValue(h+3,x,z,(123,0)) matrix.setEntity(h+4, x, z, (178,15), "daylight_detector") except: logging.info("Error when generating light at position : {}, {}, {}".format(h+1, x, z)) def computeCenterOfMass(block_section): #compute the center of gravity to have a general idea of where a light could be put x = 0 z = 0 for i in range(0, len(block_section)): x += block_section[i][0] z += block_section[i][1] x = int(round(x/len(block_section))) z = int(round(z/len(block_section))) return (x, z) def findPos(matrix, x, z, path, height_map): #try to find a position next to the one given that is suitable for building a light for neighbor_position in [(0, -1), (0, 1), (-1, 0), (1, 0), (1, 1), (-1, -1), (1, -1), (-1, 1)]: new_position = (x + neighbor_position[0], z + neighbor_position[1]) try: if height_map[new_position[0]][new_position[1]] != -1 and matrix.getValue(height_map[new_position[0]][new_position[1]]+1,new_position[0],new_position[1]) not in light_pillar_like+[65] and matrix.getValue(height_map[new_position[0]][new_position[1]]-1,new_position[0],new_position[1]) not in air_like: return new_position except: continue return (-1, -1) def isNeighborLight(matrix,height_map, x, z): #return True if a light is neighbor to the position x, y for neighbor_position in [(0, -1), (0, 1), (-1, 0), (1, 0), (1, 1), (1, -1), (-1, 1), (-1, -1)]: new_position = (x + neighbor_position[0], z + neighbor_position[1]) try: if matrix.getValue(height_map[new_position[0]][new_position[1]]+1, new_position[0], new_position[1]) in light_pillar_like: return True except: continue for i in range(0, len(path)-1): block = path[i] x = block[0] z = block[1] h = height_map[x][z] next_block = path[i+1] next_h = height_map[next_block[0]][next_block[1]] if i!=0: previous_block = path[i-1] previous_h = height_map[previous_block[0]][previous_block[1]] logging.info("Generating road at point ({}, {}, {})".format(h, x, z)) (b, d) = utilityFunctions.getBlockFullValue(matrix, h, x, z) if (b, d) != (1, 6): matrix.setValue(h,x,z,pavement_Block) fillUnderneath(matrix, h-1, x, z) fillAbove(matrix, h+1, x, z, 6) # check if we are moving in the x axis (so to add a new pavement # on the z-1, z+1 block) if x != next_block[0]: # if that side block is walkable if z-1 >= 0 and height_map[x][z-1] != -1 and h-height_map[x][z-1] in [0, 1]: matrix.setValue(h,x,z-1,pavement_Block) height_map[x][z-1] = h # try to fill with earth underneath if it's empty #logging.info("Filling underneath at height {}".format(h-1)) fillUnderneath(matrix, h-1, x, z-1) # fill upwards with air to remove any obstacles fillAbove(matrix, h+1, x, z-1, 6) # if the opposite side block is walkable if z+1 < matrix.depth and height_map[x][z+1] != -1 and h-height_map[x][z+1] in [0, 1]: matrix.setValue(h,x,z+1,pavement_Block) height_map[x][z+1] = h #logging.info("Filling underneath at height {}".format(h-1)) fillUnderneath(matrix, h-1, x, z+1) fillAbove(matrix, h+1, x, z+1, 6) elif z != next_block[1]: # check if we are moving in the z axis (so add a new pavement # on the x-1 block) and if that side block is walkable if x-1 >= 0 and height_map[x-1][z] != -1 and h-height_map[x-1][z] in [0, 1]: matrix.setValue(h,x-1,z,pavement_Block) height_map[x-1][z] = h #logging.info("Filling underneath at height {}".format(h-1)) fillUnderneath(matrix, h-1, x-1, z) fillAbove(matrix, h+1, x-1, z, 6) if x+1 < matrix.width and height_map[x+1][z] != -1 and h-height_map[x+1][z] in [0, 1]: matrix.setValue(h,x+1,z,pavement_Block) height_map[x+1][z] = h #logging.info("Filling underneath at height {}".format(h-1)) fillUnderneath(matrix, h-1, x+1, z) fillAbove(matrix, h+1, x+1, z, 6) else: logging.info("Stone path at point ({}, {}, {}) already existing, going forward".format(h, x, z)) # another iteration over the path to generate ladders and lights # this is to guarantee that fillAbove or any other # manipulations of the environment around the path # will erase the ladder blocks or the lights block_section = path[0:20] # Block section of 20 blocks to find the right place to put lights isPut = generateLight(matrix, block_section, path, height_map) if isPut == False: #Failed to find a good position with the center of mass, build it next to or on the path try: (xl, zl) = findPos(matrix, path[10][0], path[10][1], path, height_map) except: #not enough block left in the path, so take the position of half of what remains (xl, zl) = findPos(matrix, path[int(((i-len(path)-1)/2))][0], path[int(((i-len(path)-1)/2))][1], path, height_map) if (xl, zl) != (-1, -1): if isNeighborLight(matrix,height_map, xl, zl) != True: buildLight(matrix, height_map[xl][zl], xl, zl) else: if isNeighborLight(matrix,height_map, path[10][0], path[10][1]) != True: buildLight(matrix, height_map[path[10][0]][path[10][1]], path[10][0], path[10][1]) for i in range(0, len(path)-1): block = path[i] x = block[0] z = block[1] h = height_map[x][z] next_block = path[i+1] next_h = height_map[next_block[0]][next_block[1]] orientation = getOrientation(x, z, next_block[0], next_block[1]) if abs(h-next_h) > 1: if h < next_h: if orientation == "N": stair_subID = 3 elif orientation == "S": stair_subID = 2 elif orientation == "E": stair_subID = 4 elif orientation == "W": stair_subID = 5 for ladder_h in range(h+1, next_h+1): matrix.setValue(ladder_h, x, z,(65,stair_subID)) # make sure that the ladders in which the stairs are attached # are pathblock and not dirt, etc (b, d) = utilityFunctions.getBlockFullValue(matrix, ladder_h, next_block[0], next_block[1]) if (b, d) != (1, 6): matrix.setValue(ladder_h, next_block[0], next_block[1], (pavement_Block)) fillAbove(matrix, next_h+1, x, z, 6) elif h > next_h: if orientation == "N": stair_subID = 2 elif orientation == "S": stair_subID = 3 elif orientation == "E": stair_subID = 5 elif orientation == "W": stair_subID = 4 for ladder_h in range(next_h+1, h+1): matrix.setValue(ladder_h, next_block[0], next_block[1], (65,stair_subID)) # make sure that the ladders in which the stairs are attached # are pathblock and not dirt, etc (b, d) = utilityFunctions.getBlockFullValue(matrix, h, x, z) if (b, d) != (1, 6): matrix.setValue(ladder_h, x, z, (pavement_Block)) fillAbove(matrix, h+1, x, z, 6) #build next light and update the blocksection if block == block_section[len(block_section)-1]: isPut = generateLight(matrix, block_section, path, height_map) if isPut == False: #Failed to find a good position with the center of mass, build it next to or on the path try: (xl, zl) = findPos(matrix, path[i+10][0], path[i+10][1], path, height_map) except: #not enogh block left in the path, so take the position of half of what remains (xl, zl) = findPos(matrix, path[i+int(((i-len(path)-1)/2))][0], path[i+int(((i-len(path)-1)/2))][1], path, height_map) if (xl, zl) != (-1, -1): if isNeighborLight(matrix,height_map, xl, zl) != True: buildLight(matrix, height_map[xl][zl], xl, zl) else: if isNeighborLight(matrix,height_map, path[i+10][0], path[i+10][1]) != True: buildLight(matrix, height_map[path[i+10][0]][path[i+10][1]], path[i+10][0], path[i+10][1]) try: block_section = path[i:i+20] except: block_section = path[i:len(path)]
def checkIfTreeUntouched(matrix, tree): #check that nothing was built on the position of the tree's blocks for h, x, z, i in tree: if utilityFunctions.getBlockFullValue(matrix, h, x, z) != (0,0): return False return True
while len(block_to_expand_queue) != 0: actual_block = block_to_expand_queue.pop() addSameLevelTreeBlockToQueue(matrix, h+height_tree, new_block_queue, visited, tree_block, actual_block, (xt, zt)) block_to_expand_queue = new_block_queue new_block_queue = [] distance +=1 height_tree += 1 return tree_block def addSameLevelTreeBlockToQueue(matrix, h, new_block_queue, visited, tree_block, actual_block, (xt, zt)): for neighbor_position in [(1, 0),(-1, 0),(0, 1),(0, -1)]: neighbor_block = (actual_block[0] + neighbor_position[0], actual_block[1] + neighbor_position[1]) try: if neighbor_block not in visited and matrix.getValue(h, neighbor_block[0], neighbor_block[1]) in leaf_like+[78] and abs(xt-neighbor_block[0])<=2 and abs(zt-neighbor_block[1])<=2: tree_block.append((h, neighbor_block[0], neighbor_block[1], utilityFunctions.getBlockFullValue(matrix, h, neighbor_block[0], neighbor_block[1]))) new_block_queue.append(neighbor_block) elif neighbor_block not in visited and matrix.getValue(h, neighbor_block[0], neighbor_block[1]) in trunk_like and abs(xt-neighbor_block[0])<=1 and abs(zt-neighbor_block[1])<=1: tree_block.append((h, neighbor_block[0], neighbor_block[1], utilityFunctions.getBlockFullValue(matrix, h, neighbor_block[0], neighbor_block[1]))) new_block_queue.append(neighbor_block) except: continue visited.append(neighbor_block) def putBackTrees(matrix, height_map, list_trees): #go through the list saved and see if all the blocks of a tree are valid, if so we put the tree back using the id we saved for each block for tree, origin in list_trees: if checkIfGroundValid(matrix, height_map, tree) == True and checkIfTreeUntouched(matrix, tree) == True: #check validity of a tree saved for h, x, z, i in tree: matrix.setValue(h, x, z, i) def checkIfTreeUntouched(matrix, tree): #check that nothing was built on the position of the tree's blocks