def prepareLot(matrix, p, height_map, biome):

	areaScore = utilityFunctions.getScoreArea_type1(height_map, p[2],p[3], p[4], p[5], height_map[p[2]][p[4]])
	logging.info("Preparing lot {} with score {}".format(p, areaScore))

	if areaScore != 0:
		terrain_height = flattenPartition(matrix, p[2],p[3], p[4], p[5], height_map, biome)
		logging.info("Terrain was flattened at height {}".format(terrain_height))
		utilityFunctions.updateHeightMap(height_map, p[2], p[3], p[4], p[5], terrain_height)
		h = matrix.getMatrixY(terrain_height)
	else:
		heightCounts = utilityFunctions.getHeightCounts(height_map, p[2],p[3], p[4], p[5])
		terrain_height = max(heightCounts, key=heightCounts.get)
		logging.info("No changes in terrain were necessary, terrain at height {}".format(terrain_height))
		utilityFunctions.updateHeightMap(height_map, p[2], p[3], p[4], p[5], terrain_height)
		# update the ground with the grass block
		for x in range(x_min, x_max):
			for z in range(z_min,z_max):
				matrix.setValue(terrain_height, x, z, ground)
		h = matrix.getMatrixY(terrain_height)


	logging.info("Index of height {} in selection box matrix: {}".format(terrain_height, h))

	return h
Exemple #2
0
def flattenPartition(matrix, x_min, x_max, z_min, z_max, height_map, block):

    heightCounts = utilityFunctions.getHeightCounts(height_map, x_min, x_max,
                                                    z_min, z_max)
    most_ocurred_height = max(heightCounts, key=heightCounts.get)

    logging.info("Flattening {}".format((x_min, x_max, z_min, z_max)))

    if block == None:
        block = utilityFunctions.getMostOcurredGroundBlock(
            matrix, height_map, x_min, x_max, z_min, z_max)
        if block == (3, 0):
            block = (2, 0)
    logging.info("Most occurred ground block: {}".format(block))
    logging.info("Flattening at height {}".format(most_ocurred_height))

    for x in range(x_min, x_max + 1):
        for z in range(z_min, z_max + 1):
            if height_map[x][z] == most_ocurred_height:
                # Equal height! No flattening needed
                # but lets use the base block just in case
                matrix.setValue(height_map[x][z], x, z, block)
            if height_map[x][z] != most_ocurred_height:

                if height_map[x][z] == -1:
                    logging.warning(
                        "Flattening invalid area. Position ", x, z,
                        " of height_map is -1. Cannot do earthworks.")
                    continue

                matrix_height = matrix.getMatrixY(height_map[x][z])
                desired_matrix_height = matrix.getMatrixY(most_ocurred_height)

                if desired_matrix_height > matrix_height:
                    for y in range(matrix_height, desired_matrix_height + 1):
                        matrix.setValue(y, x, z, block)
                else:
                    #update every block between top height and the desired height
                    # when bringing the ground to a lower level, this will have the
                    # effect of e.g. erasing trees that were on top of that block
                    # this may cause some things to be unproperly erased
                    # (e.g. a branch of a tree coming from an nearby block)
                    # but this is probably the best/less complex solution for this
                    for y in range(matrix.height - 1, desired_matrix_height,
                                   -1):
                        matrix.setValue(y, x, z, 0)
                    matrix.setValue(desired_matrix_height, x, z, block)

    return most_ocurred_height
Exemple #3
0
def prepareLot(matrix, p, height_map, block):

    areaScore = utilityFunctions.getScoreArea_type4(height_map, p[2], p[3],
                                                    p[4], p[5])
    logging.info("Preparing lot {} with score {}".format(p, areaScore))

    if areaScore != 0:
        terrain_height = flattenPartition(matrix, p[2], p[3], p[4], p[5],
                                          height_map, block)
        logging.info(
            "Terrain was flattened at height {}".format(terrain_height))
        utilityFunctions.updateHeightMap(height_map, p[2], p[3], p[4], p[5],
                                         terrain_height)
        h = matrix.getMatrixY(terrain_height)
    else:
        heightCounts = utilityFunctions.getHeightCounts(
            height_map, p[2], p[3], p[4], p[5])
        terrain_height = max(heightCounts, key=heightCounts.get)
        logging.info(
            "No changes in terrain were necessary, terrain at height {}".
            format(terrain_height))
        utilityFunctions.updateHeightMap(height_map, p[2], p[3], p[4], p[5],
                                         terrain_height)
        # update the ground with the most occured block
        if block == None:
            block = utilityFunctions.getMostOcurredGroundBlock(
                matrix, height_map, p[2], p[3], p[4], p[5])
            if block == (3, 0):
                block = (2, 0)
        for x in range(p[2], p[3] + 1):
            for z in range(p[4], p[5] + 1):
                matrix.setValue(terrain_height, x, z, block)
        h = matrix.getMatrixY(terrain_height)

    logging.info("Index of height {} in selection box matrix: {}".format(
        terrain_height, h))

    return h
def flattenPartition(matrix, x_min, x_max, z_min, z_max, height_map, biome, shifting = 12):
	x_min_height_count = x_min - shifting if x_min - shifting >= 0 else 0
	x_max_height_count = x_max + shifting if x_max + shifting < matrix.width else matrix.width - 1
	z_min_height_count = z_min - shifting if z_min - shifting >= 0 else 0
	z_max_height_count = z_max + shifting if z_max + shifting < matrix.depth else matrix.depth - 1
	heightCounts = utilityFunctions.getHeightCounts(height_map, x_min_height_count, x_max_height_count, z_min_height_count, z_max_height_count)

	average_height = max(heightCounts, key=heightCounts.get)
	#count = 0
	#for key in heightCounts.keys() :
	#	value = heightCounts[key]
	#	if value > round((x_max_height_count - x_min_height_count) * (z_max_height_count - z_min_height_count) * 0.01) :
	#		average_height += key * value
	#		count += value
	#average_height = average_height / count

	logging.info("Flattening {}".format((x_min, x_max, z_min, z_max)))

	base_block = utilityFunctions.getMostOcurredGroundBlock(matrix, height_map, x_min, x_max, z_min, z_max)
	if base_block == BlocksInfo.SAND_ID and biome == 'Badlands' :
		base_block = BlocksInfo.RED_SAND_ID
	elif base_block == BlocksInfo.DIRT_ID and biome == 'Taiga' :
		base_block = BlocksInfo.PODZOL_ID

	if base_block == BlocksInfo.TERRACOTTA_ID :
		 #Temporary need change
		 underground_block = BlocksInfo.TERRACOTTA_ID
	else :
		underground_block = BlocksInfo.getUndergroundBlockId(base_block)
	logging.info("Most occurred ground block: {}".format(base_block))
	logging.info("Flattening at height {}".format(average_height))

	saved_trees = utilityFunctions.saveTreesInArea(matrix, height_map, average_height, x_min, x_max, z_min, z_max)

	for x in range(x_min, x_max):
		for z in range(z_min,z_max):
			if height_map[x][z] == average_height:
				# Equal height! No flattening needed
				# but lets use the base block just in case
				matrix.setValue(height_map[x][z], x, z, base_block)
			if height_map[x][z] != average_height:

				if height_map[x][z] == -1:
					logging.warning("Flattening invalid area. Position ", x, z, " of height_map is -1. Cannot do earthworks.")
					continue

				matrix_height = matrix.getMatrixY(height_map[x][z])
				desired_matrix_height = matrix.getMatrixY(average_height)

				if desired_matrix_height > matrix_height:
					for y in range(matrix_height, desired_matrix_height):
						matrix.setValue(y,x,z, underground_block)
					matrix.setValue(desired_matrix_height, x, z, base_block)
				else:
					for y in range(matrix.height-1, desired_matrix_height, -1):
						value = utilityFunctions.getBlockAndBlockData(matrix, y, x, z)
						if type(value) == tuple :
							value = value[0]
						if not value in BlocksInfo.LEAVES_ID :
							matrix.setValue(y, x, z, BlocksInfo.AIR_ID)
					matrix.setValue(desired_matrix_height,x,z, base_block)

	utilityFunctions.repositionateTrees(matrix, saved_trees, average_height, x_min, x_max, z_min, z_max)

	return average_height
Exemple #5
0
def area_partitioning_and_flattening(space, height_map, matrix, biome):
    minimum_h = 10
    minimum_w = 40
    mininum_d = 40

    iterate = 100
    maximum_tries = 50
    current_try = 0
    minimum_lots = 100  #origin = 20
    available_lots = 0
    threshold = 10
    partitioning_list = []
    final_partitioning = []

    while available_lots < minimum_lots and current_try < maximum_tries:
        partitioning_list = []
        for i in range(iterate):

            # generate a partitioning through some algorithm
            if RNG.random() < 0.5:
                partitioning = binarySpacePartitioning(
                    space.y_min, space.y_max, space.x_min, space.x_max,
                    space.z_min, space.z_max, [])
            else:
                partitioning = quadtreeSpacePartitioning(
                    space.y_min, space.y_max, space.x_min, space.x_max,
                    space.z_min, space.z_max, [])

            # remove invalid partitions from the partitioning
            valid_partitioning = []
            for p in partitioning:
                (y_min, y_max, x_min, x_max, z_min, z_max) = (p[0], p[1], p[2],
                                                              p[3], p[4], p[5])
                failed_conditions = []
                #cond2 = utilityFunctions.hasMinimumSize(y_min, y_max, x_min, x_max,z_min,z_max, minimum_h, minimum_w, mininum_d)
                #if cond2 == False: failed_conditions.append(2)
                cond3 = utilityFunctions.hasAcceptableSteepness(
                    x_min, x_max, z_min, z_max, height_map,
                    utilityFunctions.getScoreArea_type1, threshold)
                if cond3 == False: failed_conditions.append(3)
                if cond3:
                    heightCounts = utilityFunctions.getHeightCounts(
                        height_map, x_min, x_max, z_min, z_max)
                    score = max(heightCounts, key=heightCounts.get)
                    valid_partitioning.append((score, p))
                else:
                    logging.info(
                        "Failed Conditions {}".format(failed_conditions))

            partitioning_list.extend(valid_partitioning)
            logging.info(
                "Generated a partition with {} valid area and {} invalids ones"
                .format(len(valid_partitioning),
                        len(partitioning) - len(valid_partitioning)))

        # order partitions by steepness
        partitioning_list = sorted(partitioning_list)
        final_partitioning = utilityFunctions.fusionIntersectingPartitions(
            partitioning_list, height_map)

        available_lots = len(final_partitioning)
        logging.info(
            "Current partitioning with most available_lots: {}, current threshold {}"
            .format(available_lots, threshold))

        threshold = threshold + 1 if threshold < 20 else 20
        current_try += 1

    for partition in final_partitioning:
        prepareArea(matrix, partition, height_map, biome)