extends Node onready var noise = OpenSimplexNoise.new() onready var rng = RandomNumberGenerator.new() var _seed var monuments = [] func _ready(): randomize() self._seed = randi() self.noise.seed = self._seed self.noise.seed = 0 self.noise.period = 16 self.noise.persistence = 0 self.rng.seed = self._seed func setup_monuments(): monuments.push_back(lighthouseMonument.new(Transform(Basis(),Vector3(300.0,0.0,-300.0)))) monuments.push_back(lighthouseMonument.new(Transform(Basis(),Vector3(0.0,0.0,-1000.0)))) monuments.push_back(lighthouseMonument.new(Transform(Basis(),Vector3(-500.0,0.0,-2500.0)))) func rng_2dv(coords:Vector2): self.rng.seed = hash(coords) func gen_chunk(chunk,dummy=false): if dummy: return var monument = get_monument_at_chunk(ChunkLoader.v2_coords(chunk.transform.origin)) if monument != null: gen_monument(chunk, monument) else: gen_distance(chunk,chunk.get_node("gen_tree/lod_distance")) gen_mid(chunk,chunk.get_node("gen_tree/lod_mid")) gen_close(chunk,chunk.get_node("gen_tree/lod_close")) func get_monument_at_chunk(chunk_coords:Vector2): for monument in monuments: if monument.is_chunk_in_monument(chunk_coords): return monument return null func gen_monument(chunk, monument): var inst = monument.scene.instance() var offset_to_origin = monument.xform.origin - chunk.transform.origin inst.transform.origin = offset_to_origin inst.transform.basis = monument.xform.basis chunk.add_child(inst) func gen_distance(chunk,tree): gen_lowres_rocks(chunk,tree) func gen_mid(chunk,tree): gen_rocks(chunk,tree) func gen_close(chunk,tree): gen_rock_hitboxes(chunk,tree) func iterate_chunk(chunk,tree,step:Vector2,cb:FuncRef,data): var chunk_half_size = ChunkLoader.world.chunk_half_size var chunk_size_rounded = Vector2(chunk_half_size,chunk_half_size).snapped(step) for x in range(-chunk_size_rounded.x,chunk_size_rounded.x,step.x): for y in range(-chunk_size_rounded.y,chunk_size_rounded.y,step.y): cb.call_func(chunk,tree,Vector2(x,y),data) func make_multimesh(name,cnt,mesh): var multi_inst = MultiMeshInstance.new() multi_inst.name = name var multi = MultiMesh.new() multi_inst.multimesh = multi multi.transform_format = MultiMesh.TRANSFORM_3D multi.mesh = mesh multi.instance_count = cnt multi.visible_instance_count = 0 return multi_inst var rock1_mesh = preload("res://world/obstacles/rock/rock_1.obj") var rock2_mesh = preload("res://world/obstacles/rock/rock_2.obj") var rock3_mesh = preload("res://world/obstacles/rock/rock_3.obj") var rock4_mesh = preload("res://world/obstacles/rock/rock_4.obj") var rock_mat = preload("res://world/obstacles/rock/rock_material.tres") func gen_rocks(chunk,tree): var rocks1 = make_multimesh("rocks1",100,rock1_mesh) var rocks2 = make_multimesh("rocks2",100,rock2_mesh) var rocks3 = make_multimesh("rocks3",100,rock3_mesh) var rocks4 = make_multimesh("rocks4",100,rock4_mesh) rocks1.material_override = rock_mat rocks2.material_override = rock_mat rocks3.material_override = rock_mat rocks4.material_override = rock_mat tree.add_child(rocks1) tree.add_child(rocks2) tree.add_child(rocks3) tree.add_child(rocks4) iterate_chunk(chunk, rocks1.multimesh, Vector2(10.0,10.0), funcref(self,"rock_rng"), [1,funcref(self,"make_rock")]) iterate_chunk(chunk, rocks2.multimesh, Vector2(10.0,10.0), funcref(self,"rock_rng"), [3,funcref(self,"make_rock")]) iterate_chunk(chunk, rocks3.multimesh, Vector2(10.0,10.0), funcref(self,"rock_rng"), [4,funcref(self,"make_rock")]) iterate_chunk(chunk, rocks4.multimesh, Vector2(10.0,10.0), funcref(self,"rock_rng"), [2,funcref(self,"make_rock")]) var rock_lowres_mesh = preload("res://world/obstacles/rock/rock_lowres_mesh.tres") func gen_lowres_rocks(chunk,tree): rock_lowres_mesh.material = rock_mat var multi = make_multimesh("rocks",50,rock_lowres_mesh) tree.add_child(multi) iterate_chunk(chunk, multi.multimesh, Vector2(20.0,20.0), funcref(self,"rock_rng"), [0,funcref(self,"make_rock")]) var rock_coll = preload("res://world/obstacles/rock/rock_collision.tres") func gen_rock_hitboxes(chunk,tree): iterate_chunk(chunk, tree, Vector2(20.0,20.0), funcref(self,"rock_rng"), [0,funcref(self,"make_rock_hitbox")]) func rock_rng(chunk,rocks,chunk_coords:Vector2,data): var coords = ChunkLoader.v3_coords(chunk_coords) var basis = Basis() var world_coords = chunk_coords + ChunkLoader.v2_coords(chunk.transform.origin) self.rng_2dv(world_coords) var noise_val = self.noise.get_noise_2dv(world_coords * 0.125) #threshold to generate a rock var noise_min_pointy = 0.4 var noise_max_pointy = 0.5 var noise_max_round = 0.7 if noise_val < noise_min_pointy: return var rock = self.rng.randi_range(1,4) #choose a rock if data[0] != 0: if noise_val <= noise_max_pointy: if rock != data[0]: return else: if ((rock%2)+1) != data[0]: return #normalize noise from 0.0 to 1.0 noise_val = min(noise_val,noise_max_round) noise_val -= noise_min_pointy noise_val /= noise_max_round - noise_min_pointy #random rotation var rng_val = self.rng.randf_range(0.0,TAU) basis = Basis(Vector3.UP,rng_val) * basis #scale based on noise var scale_min = 0.167 var scale_max = 0.667 var scale = lerp(scale_min,scale_max,noise_val) basis = basis.scaled(Vector3.ONE*scale) #scale the pointy rocks taller if rock == 3 || rock == 4: rng_val = self.rng.randf_range(1.0,1.25) scale = rng_val * scale basis = basis.scaled(Vector3(1.0,rng_val,1.0)) #normalize height match rock: 0: coords.y += 30.0 * scale 1: coords.y += 31.5 * scale 2: coords.y += 27.5 * scale 3: coords.y += 42.5 * scale 4: coords.y += 40.0 * scale #shift them all slightly down coords.y -= 5.0 data[1].call_func(rocks,Transform(basis,coords)) func make_rock(rocks,xform:Transform): rocks.visible_instance_count += 1 rocks.set_instance_transform(rocks.visible_instance_count-1, xform) func make_rock_hitbox(rocks,xform:Transform): var shape = CollisionShape.new() shape.shape = rock_coll shape.transform = xform rocks.add_child(shape)