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))))
monuments.push_back(DockMonument.new(Transform(Basis().rotated(Vector3.UP,PI/2.0),Vector3(-500.0,0.0,0.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)