var height_map: Dictionary = {} for x in range(int(model_size.x)): for z in range(int(model_size.y)): var height_noise = noise.get_noise_2d(x, z) var normalized_height = (height_noise + 1.0) / 2.0 var h = int(round(normalized_height * noise_strength))
for pos_2d in height_map: var column_height = height_map[pos_2d] for y in range(min_height, column_height): block_data[Vector3i(pos_2d.x, y, pos_2d.y)] = 1
func apply_growth(t: float): var current_max_y = lerp(min_height, max_height, t) var st = SurfaceTool.new() var vertex_idx := 0 var directions = [ Vector3i.UP, Vector3i.DOWN, Vector3i.LEFT, Vector3i.RIGHT, Vector3i.FORWARD, Vector3i.BACK ]
for pos in block_data.keys(): if pos.y > current_max_y: continue
for dir in directions: var neighbor_pos = pos + dir if not block_data.has(neighbor_pos) or neighbor_pos.y > current_max_y: add_cube_face(st, pos, dir, vertex_idx) vertex_idx += 4
func _generate_height_map(noise: FastNoiseLite) -> Dictionary: var height_map: Dictionary = {} var offset: Vector2i = map_size / 2
for x in range(map_size.x): for z in range(map_size.y): var noise_val: float = noise.get_noise_2d(x, z) var normalized_height: float = (noise_val + 1.0) / 2.0 var centered_pos := Vector2i(x - offset.x, z - offset.y) height_map[centered_pos] = int(round(normalized_height * noise_strength))
var h: int = height_map[pos_centered] var terrain_pos := Vector3i(pos_centered.x, h, pos_centered.y) var top_terrain_id: int = grid_terrain.get_cell_item(terrain_pos)
if top_terrain_id >= Terrain.GRASS_1 and top_terrain_id <= Terrain.GRASS_6: var structure_pos := terrain_pos + Vector3i.UP grid_trees.set_cell_item(structure_pos, GridMap.INVALID_CELL_ITEM) grid_structures.set_cell_item(structure_pos, Structure.HOUSE)
if border_size > 0: for z in depth: for x in width: var dist_x = min(x, width - 1 - x) var dist_z = min(z, depth - 1 - z) var dist_to_edge = min(dist_x, dist_z)
if dist_to_edge < border_size: height_map[z][x] *= pow(float(dist_to_edge) / border_size, border_falloff_strength)
func apply_erosion(height_map: Array[PackedFloat32Array]): for i in range(erosion_iterations): var pos = Vector2(rng.randf_range(0, width - 1), rng.randf_range(0, depth - 1)) var dir = Vector2.ZERO var speed = 1.0 var water = 1.0 var sediment = 0.0
for step in range(max_steps): if not in_height_map(pos): break
var current_height = get_interpolated_height(pos, height_map) var gradient = get_gradient(pos, height_map)