You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
222 lines
5.7 KiB
222 lines
5.7 KiB
extends Control
|
|
|
|
@export var world_width = 1024
|
|
@export var world_height = 512
|
|
|
|
@export var min_continent = 5
|
|
@export var max_continent = 5
|
|
@export var min_area = 0.5
|
|
@export var max_area = 2.0
|
|
@export var min_ratio = -1.0
|
|
@export var max_ratio = 1.0
|
|
@export var ocean_ratio = 0
|
|
@export var nbr_rect_position = 10000
|
|
@export var max_intersection_area = 1000.0
|
|
|
|
@export var mountain_frequency = 1.5 # higher number means less mountains
|
|
@export var world_elevation = 10
|
|
@export var max_moisture = 2
|
|
@export var details = 2
|
|
@export var coasts_thickness = 0.055
|
|
|
|
|
|
var heightmap: Array
|
|
var moisturemap: Array
|
|
var oceanmap: Array
|
|
var coastmap: Array
|
|
|
|
var rivers: Array
|
|
|
|
var continents: Array
|
|
var nbr_continent
|
|
var list_continents = []
|
|
var list_rect_continents = []
|
|
|
|
var blocs: Array
|
|
|
|
var noise = FastNoiseLite.new()
|
|
|
|
func _ready():
|
|
Global.world.width = world_width
|
|
Global.world.height = world_height
|
|
|
|
noise.seed = randi()
|
|
noise.fractal_lacunarity = details
|
|
noise.frequency = 0.005
|
|
|
|
init_maps()
|
|
init_blocs()
|
|
create_continents()
|
|
|
|
for continent in continents:
|
|
fill_continent(continent)
|
|
|
|
set_oceans()
|
|
set_coasts()
|
|
fix_heightmap()
|
|
|
|
set_moisture()
|
|
|
|
set_blocs()
|
|
|
|
Global.world.heightMap = heightmap
|
|
Global.world.moistureMap = moisturemap
|
|
Global.world.blocs = blocs
|
|
|
|
set_entities()
|
|
|
|
get_tree().change_scene_to_file("scenes/Game.tscn")
|
|
|
|
func init_maps():
|
|
for x in world_width:
|
|
heightmap.append([])
|
|
oceanmap.append([])
|
|
coastmap.append([])
|
|
moisturemap.append([])
|
|
for y in world_height:
|
|
heightmap[x].append([])
|
|
heightmap[x][y] = 0
|
|
|
|
oceanmap[x].append([])
|
|
oceanmap[x][y] = 0
|
|
|
|
coastmap[x].append([])
|
|
coastmap[x][y] = 0
|
|
|
|
moisturemap[x].append([])
|
|
moisturemap[x][y] = 0
|
|
|
|
func create_continents():
|
|
var america = Rect2i(Vector2i(0, 0), Vector2i(world_width / 4, world_height))
|
|
continents.append(america)
|
|
|
|
var antarctica = Rect2i(Vector2i(world_width / 4, world_height / 2), Vector2i(3 * world_width / 4, world_height / 2))
|
|
continents.append(antarctica)
|
|
|
|
var africa = Rect2i(Vector2i(world_width / 4, 3 * world_height / 8), Vector2i(3 * world_width / 8, 3 * world_height / 8))
|
|
continents.append(africa)
|
|
|
|
var europa = Rect2i(Vector2i(3 * world_width / 8, 10), Vector2i(world_width / 4, world_height / 2))
|
|
continents.append(europa)
|
|
|
|
var asia = Rect2i(Vector2i(4 * world_width / 9, world_height / 8), Vector2i(world_width / 2, 3 * world_height / 8))
|
|
continents.append(asia)
|
|
|
|
func fill_continent(continent: Rect2i):
|
|
for x in continent.size.x:
|
|
for y in continent.size.y:
|
|
# set rectange radius
|
|
var center = Vector2(float(continent.size.x) / 2.0, float(continent.size.y) / 2.0)
|
|
var distance_x = abs(float(x) - center.x) / center.x
|
|
var distance_y = abs(float(y) - center.y) / center.y
|
|
var distance = sqrt(pow(distance_x, 2) + pow(distance_y, 2))
|
|
|
|
distance = remap(distance, 0, sqrt(2), 0, 1) * 1.2
|
|
|
|
# set height
|
|
var height = noise.get_noise_2d(x, y)
|
|
height = remap(height, -1, 1, 0, 1)
|
|
height -= distance
|
|
|
|
if height > 0:
|
|
var current_height = heightmap[continent.position.x + x][continent.position.y + y]
|
|
height = pow(height * 1.2, mountain_frequency)
|
|
height = remap(height, 0, 1, 1, world_elevation)
|
|
heightmap[continent.position.x + x][continent.position.y + y] = max(current_height, height)
|
|
if height > heightmap[continent.position.x + x][continent.position.y + y]:
|
|
heightmap[continent.position.x + x][continent.position.y + y] = height
|
|
elif height > 0 - coasts_thickness:
|
|
coastmap[x + continent.position.x][y + continent.position.y] = 1
|
|
|
|
|
|
func set_oceans():
|
|
var stack = []
|
|
var first_coord = Vector2i(0, 0)
|
|
|
|
stack.append(first_coord)
|
|
while stack.size():
|
|
var coord = stack.pop_back()
|
|
oceanmap[coord.x][coord.y] = 1
|
|
for neighbour in neighbours(coord).values():
|
|
if heightmap[neighbour.x][neighbour.y] == 0 and oceanmap[neighbour.x][neighbour.y] == 0:
|
|
stack.append(neighbour)
|
|
|
|
for x in world_width:
|
|
for y in world_height:
|
|
if heightmap[x][y] == 0 and not oceanmap[x][y]:
|
|
heightmap[x][y] = 2
|
|
|
|
|
|
func set_coasts():
|
|
for x in world_width:
|
|
for y in world_height:
|
|
if coastmap[x][y] and heightmap[x][y] == 0:
|
|
heightmap[x][y] = 1
|
|
pass
|
|
|
|
func set_moisture():
|
|
for x in world_width:
|
|
for y in world_height:
|
|
moisturemap[x][y] = remap(noise.get_noise_2d(x + 6789, y + 5927), -1, 1, 0, max_moisture)
|
|
|
|
|
|
|
|
|
|
func neighbours(coord: Vector2i):
|
|
var neighbours: Dictionary
|
|
if coord.x + 1 < world_width:
|
|
neighbours.right = Vector2i(coord.x + 1, coord.y)
|
|
|
|
if coord.y + 1 < world_height :
|
|
neighbours.bottom = Vector2i(coord.x, coord.y + 1)
|
|
|
|
if coord.x - 1 >= 0:
|
|
neighbours.left = Vector2i(coord.x - 1, coord.y)
|
|
|
|
if coord.y - 1 >= 0:
|
|
neighbours.top = Vector2i(coord.x, coord.y - 1)
|
|
|
|
return neighbours
|
|
|
|
|
|
func fix_heightmap():
|
|
for x in world_width:
|
|
for y in world_height:
|
|
heightmap[x][y] = ceil(heightmap[x][y])
|
|
# if heightmap[x][y] > 4:
|
|
# mountain_blocs.append(Vector2i(x, y))
|
|
|
|
func init_blocs():
|
|
for x in world_width:
|
|
blocs.append([])
|
|
for y in world_height:
|
|
var bloc = {
|
|
"type": 0,
|
|
"entity": -1
|
|
}
|
|
|
|
blocs[x].append(bloc)
|
|
|
|
func set_blocs():
|
|
for x in world_width:
|
|
for y in world_height:
|
|
if not blocs[x][y].type:
|
|
if heightmap[x][y] > 0:
|
|
blocs[x][y].type = Global.blocs.SAND
|
|
if heightmap[x][y] > 1:
|
|
blocs[x][y].type = Global.blocs.GRASS
|
|
if heightmap[x][y] > 4:
|
|
blocs[x][y].type = Global.blocs.STONE
|
|
if heightmap[x][y] > 6:
|
|
blocs[x][y].type = Global.blocs.SNOW
|
|
|
|
return blocs
|
|
|
|
func set_entities():
|
|
for x in Global.world.width:
|
|
for z in Global.world.height:
|
|
var moisture = Global.world.get_moisture(Vector2i(x, z))
|
|
var height = Global.world.get_height(Vector2i(x, z))
|
|
if height > 1:
|
|
if moisture > 1.5 and randi_range(1, 10) == 1:
|
|
Global.world.add_entity("OakTree", Vector2i(x, z))
|
|
|