summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordusoleil <howcansocksbereal@gmail.com>2022-09-20 02:00:08 -0400
committerdusoleil <howcansocksbereal@gmail.com>2022-09-20 02:00:08 -0400
commit7e75beb7b1f3b1121961f8df36f0fee3cd41cb58 (patch)
tree297727d30a8cb5be309b47c1e8bfe41e0792888b
parent51a0664a1c2265adddbf4c42d4eda747c8ea8aaf (diff)
downloadgame_jam49-7e75beb7b1f3b1121961f8df36f0fee3cd41cb58.tar.gz
game_jam49-7e75beb7b1f3b1121961f8df36f0fee3cd41cb58.zip
Add ability to add static monuments to the world
-rw-r--r--project.godot12
-rw-r--r--world/World.gd4
-rw-r--r--world/World.tscn7
-rw-r--r--world/chunk/ChunkGen.gd51
-rw-r--r--world/chunk/ChunkLoader.gd64
-rw-r--r--world/monuments/Dock.tscn163
-rw-r--r--world/monuments/DockMonument.gd19
-rw-r--r--world/monuments/Monument.gd21
8 files changed, 306 insertions, 35 deletions
diff --git a/project.godot b/project.godot
index 26f3e5b..67ac57f 100644
--- a/project.godot
+++ b/project.godot
@@ -9,12 +9,24 @@
config_version=4
_global_script_classes=[ {
+"base": "Monument",
+"class": "DockMonument",
+"language": "GDScript",
+"path": "res://world/monuments/DockMonument.gd"
+}, {
+"base": "Reference",
+"class": "Monument",
+"language": "GDScript",
+"path": "res://world/monuments/Monument.gd"
+}, {
"base": "Resource",
"class": "Wave",
"language": "GDScript",
"path": "res://water/Wave.gd"
} ]
_global_script_class_icons={
+"DockMonument": "",
+"Monument": "",
"Wave": ""
}
diff --git a/world/World.gd b/world/World.gd
index 04c3ef1..3afc4eb 100644
--- a/world/World.gd
+++ b/world/World.gd
@@ -12,12 +12,12 @@ onready var lod_distance = chunk_render_distance.get_node("Radius").shape.radius
onready var lod_mid = chunk_render_mid.get_node("Radius").shape.radius
onready var lod_close = chunk_render_close.get_node("Radius").shape.radius
-onready var chunk_half_size = $"Chunks/Chunk/Size".shape.radius
+onready var chunk_half_size = $"Chunk/Size".shape.radius
onready var chunk_size = chunk_half_size * 2.0
func _ready():
ChunkLoader.world = self
- ChunkGen.chunk_half_size = self.chunk_half_size
+ ChunkGen.setup_monuments()
func _on_ChunkRenderDistance_area_entered(area:Area):
if area.lod < area.LOD.DISTANCE:
diff --git a/world/World.tscn b/world/World.tscn
index 647f47b..e5b4a67 100644
--- a/world/World.tscn
+++ b/world/World.tscn
@@ -39,6 +39,10 @@ collision_mask = 32
[node name="Radius" type="CollisionShape" parent="ChunkRenderClose"]
shape = SubResource( 26 )
+[node name="Chunk" parent="." instance=ExtResource( 3 )]
+visible = false
+collision_layer = 0
+
[node name="Chunks" type="RigidBody" parent="."]
collision_layer = 0
collision_mask = 0
@@ -52,9 +56,6 @@ linear_damp = 0.5
[node name="CollisionShape" type="CollisionShape" parent="Chunks"]
shape = SubResource( 23 )
-[node name="Chunk" parent="Chunks" instance=ExtResource( 3 )]
-visible = false
-collision_layer = 0
[connection signal="area_entered" from="ChunkRenderDistance" to="." method="_on_ChunkRenderDistance_area_entered"]
[connection signal="area_exited" from="ChunkRenderDistance" to="." method="_on_ChunkRenderDistance_area_exited"]
diff --git a/world/chunk/ChunkGen.gd b/world/chunk/ChunkGen.gd
index e71cc57..994d624 100644
--- a/world/chunk/ChunkGen.gd
+++ b/world/chunk/ChunkGen.gd
@@ -1,16 +1,11 @@
extends Node
-var chunk_half_size setget _set_chunk_size
-var chunk_size
-
-func _set_chunk_size(val):
- chunk_half_size = val
- chunk_size = val * 2.0
-
onready var noise = OpenSimplexNoise.new()
onready var rng = RandomNumberGenerator.new()
var _seed
+var monuments = []
+
func _ready():
#randomize()
#self._seed = randi()
@@ -21,13 +16,36 @@ func _ready():
self.noise.persistence = 0
self.rng.seed = self._seed
+func setup_monuments():
+ monuments.push_back(DockMonument.new(Transform(Basis().rotated(Vector3.UP,0.0),Vector3(0.0,0.0,-600.0))))
+ monuments.push_back(DockMonument.new(Transform(Basis().rotated(Vector3.UP,PI),Vector3(0.0,0.0,600.0))))
+
func rng_2dv(coords:Vector2):
self.rng.seed = hash(coords)
-func gen_chunk(chunk):
- 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 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 offset_to_origin = monument.origin_chunk - ChunkLoader.v2_coords(chunk.transform.origin)
+ var inst = monument.scene.instance()
+ inst.transform.origin = ChunkLoader.v3_coords(offset_to_origin)
+ inst.transform.basis = monument.xform.basis
+ chunk.add_child(inst)
func gen_distance(chunk,tree):
gen_lowres_rocks(chunk,tree)
@@ -38,13 +56,8 @@ func gen_mid(chunk,tree):
func gen_close(chunk,tree):
gen_rock_hitboxes(chunk,tree)
-func v2_coords(coords:Vector3):
- return Vector2(coords.x,coords.z)
-
-func v3_coords(coords:Vector2):
- return Vector3(coords.x,0.0,coords.y)
-
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):
@@ -81,9 +94,9 @@ func gen_rock_hitboxes(chunk,tree):
iterate_chunk(chunk, tree, Vector2(20.0,20.0), funcref(self,"rock_rng"), [0.4,0.6,1.0,4.0,1.0,funcref(self,"make_rock_hitbox")])
func rock_rng(chunk,rocks,chunk_coords:Vector2,data):
- var coords = v3_coords(chunk_coords)
+ var coords = ChunkLoader.v3_coords(chunk_coords)
var basis = Basis()
- var world_coords = chunk_coords + v2_coords(chunk.transform.origin)
+ var world_coords = chunk_coords + ChunkLoader.v2_coords(chunk.transform.origin)
self.rng_2dv(world_coords)
var rng_val = self.rng.randf_range(0.0,TAU)
basis = Basis(Vector3.UP,rng_val) * basis
diff --git a/world/chunk/ChunkLoader.gd b/world/chunk/ChunkLoader.gd
index 42e40bb..0ea422a 100644
--- a/world/chunk/ChunkLoader.gd
+++ b/world/chunk/ChunkLoader.gd
@@ -4,12 +4,14 @@ var world = null
var Chunk = preload("res://world/chunk/Chunk.tscn")
var loaded_chunks = {}
+var freed_chunks = {}
var chunk_thread = Thread.new()
var mtx = Mutex.new()
var sgnl = Semaphore.new()
var exit = false
var chunk_to_load = null
var chunk_to_len
+var chunk_to_dummy
func _ready():
chunk_thread.start(self, "chunk_loader")
@@ -27,14 +29,29 @@ func v2_coords(coords:Vector3):
func chunk_coords(coords:Vector2):
return coords.snapped(Vector2(world.chunk_size,world.chunk_size))
+func v3_coords(coords:Vector2):
+ return Vector3(coords.x,0.0,coords.y)
+
func free_chunk(coords:Vector2):
+ var monument = ChunkGen.get_monument_at_chunk(coords)
+ if monument != null && monument.loaded_chunk != null && monument.loaded_chunk == coords:
+ return
if !loaded_chunks.has(coords):
return
- var c = loaded_chunks[coords].get_ref()
- if c != null:
- c.queue_free()
+ freed_chunks[coords] = loaded_chunks[coords]
loaded_chunks.erase(coords)
+func clean_chunks():
+ var cleaned = {}
+ for chunk in freed_chunks.keys():
+ var c = freed_chunks[chunk].get_ref()
+ if c == null:
+ cleaned[chunk] = c
+ continue
+ c.queue_free()
+ for chunk in cleaned.keys():
+ freed_chunks.erase(chunk)
+
func chunk_update():
var chunks = {}
var gen_center = -v2_coords(world.get_node("Chunks").transform.origin)
@@ -43,10 +60,11 @@ func chunk_update():
for x in range(-gen_radius_rounded, gen_radius_rounded+world.chunk_size, world.chunk_size):
for y in range(-gen_radius_rounded, gen_radius_rounded+world.chunk_size, world.chunk_size):
var gen_coords = Vector2(x,y)
- if gen_coords.length() > gen_radius:
+ var coords_len = gen_coords.length()
+ if coords_len > gen_radius:
continue
var coords = chunk_coords(gen_coords + gen_center)
- chunks[coords] = coords.length()
+ chunks[coords] = coords_len
var closest_unloaded_chunk = null
var closest_len = 0.0
for chunk in chunks.keys():
@@ -56,15 +74,30 @@ func chunk_update():
closest_unloaded_chunk = chunk
closest_len = chunk_len
if closest_unloaded_chunk != null:
+ var dummy = false
+ var monument = ChunkGen.get_monument_at_chunk(closest_unloaded_chunk)
+ if monument != null && monument.loaded_chunk != null:
+ dummy = true
mtx.lock()
if chunk_to_load == null:
chunk_to_load = closest_unloaded_chunk
chunk_to_len = closest_len
+ chunk_to_dummy = dummy
sgnl.post()
mtx.unlock()
+ for monument in ChunkGen.monuments:
+ if monument.loaded_chunk != null:
+ var loaded = false
+ for chunk in chunks.keys():
+ if monument.chunks.has(chunk):
+ loaded = true
+ break
+ if !loaded:
+ monument.loaded_chunk = null
for chunk in loaded_chunks.keys():
if !chunks.has(chunk):
free_chunk(chunk)
+ clean_chunks()
func chunk_loader():
while true:
@@ -72,18 +105,27 @@ func chunk_loader():
mtx.lock()
var x = exit
var coords = chunk_to_load
- var owo = chunk_to_len
- chunk_to_load = null
+ var lod = chunk_to_len
+ var dummy = chunk_to_dummy
mtx.unlock()
if x:
break
var chunk = Chunk.instance()
chunk.transform.origin = Vector3(coords.x,0.0,coords.y)
- owo -= world.chunk_size
- chunk.lod = 2 if owo <= world.lod_close else 1 if owo <= world.lod_mid else 0
- ChunkGen.gen_chunk(chunk)
+ lod -= world.chunk_size
+ var tmp = world.get_node("Chunk")
+ chunk.lod = tmp.LOD.CLOSE if lod <= world.lod_close else tmp.LOD.MID if lod <= world.lod_mid else tmp.LOD.DISTANCE
+ ChunkGen.gen_chunk(chunk,dummy)
self.call_deferred("finish_chunk", chunk)
func finish_chunk(chunk):
+ mtx.lock()
+ chunk_to_load = null
+ mtx.unlock()
world.get_node("Chunks").add_child(chunk)
- loaded_chunks[v2_coords(chunk.transform.origin)] = weakref(chunk)
+ var coords = v2_coords(chunk.transform.origin)
+ loaded_chunks[coords] = weakref(chunk)
+ var monument = ChunkGen.get_monument_at_chunk(coords)
+ if monument != null:
+ if monument.loaded_chunk == null:
+ monument.loaded_chunk = coords
diff --git a/world/monuments/Dock.tscn b/world/monuments/Dock.tscn
new file mode 100644
index 0000000..5a21576
--- /dev/null
+++ b/world/monuments/Dock.tscn
@@ -0,0 +1,163 @@
+[gd_scene load_steps=14 format=2]
+
+[sub_resource type="OpenSimplexNoise" id=1]
+period = 128.0
+persistence = 1.0
+lacunarity = 4.0
+
+[sub_resource type="NoiseTexture" id=2]
+noise = SubResource( 1 )
+
+[sub_resource type="NoiseTexture" id=3]
+seamless = true
+as_normalmap = true
+noise = SubResource( 1 )
+
+[sub_resource type="SpatialMaterial" id=4]
+albedo_color = Color( 0.905882, 0.823529, 0.427451, 1 )
+albedo_texture = SubResource( 2 )
+emission_enabled = true
+emission = Color( 0.905882, 0.823529, 0.427451, 1 )
+emission_energy = 0.2
+emission_operator = 0
+emission_on_uv2 = false
+normal_enabled = true
+normal_scale = 1.0
+normal_texture = SubResource( 3 )
+uv1_triplanar = true
+
+[sub_resource type="SphereMesh" id=5]
+material = SubResource( 4 )
+radius = 50.0
+height = 50.0
+
+[sub_resource type="SpatialMaterial" id=6]
+emission_enabled = true
+emission = Color( 1, 1, 1, 1 )
+emission_energy = 0.25
+emission_operator = 0
+emission_on_uv2 = false
+
+[sub_resource type="CubeMesh" id=7]
+material = SubResource( 6 )
+size = Vector3( 150, 50, 100 )
+
+[sub_resource type="Gradient" id=8]
+interpolation_mode = 1
+offsets = PoolRealArray( 0.0724138, 0.52069 )
+colors = PoolColorArray( 1, 1, 1, 1, 0, 0, 0, 1 )
+
+[sub_resource type="GradientTexture2D" id=9]
+gradient = SubResource( 8 )
+width = 5
+height = 5
+fill = 1
+fill_from = Vector2( 0.5, 0.5 )
+repeat = 1
+
+[sub_resource type="SpatialMaterial" id=10]
+albedo_color = Color( 0.521569, 0.298039, 0.00392157, 1 )
+albedo_texture = SubResource( 9 )
+uv1_triplanar = true
+
+[sub_resource type="PrismMesh" id=11]
+material = SubResource( 10 )
+size = Vector3( 150, 50, 100 )
+
+[sub_resource type="CubeMesh" id=12]
+material = SubResource( 10 )
+size = Vector3( 5, 50, 150 )
+
+[sub_resource type="CubeMesh" id=13]
+material = SubResource( 10 )
+size = Vector3( 100, 5, 30 )
+
+[node name="Dock" type="Spatial"]
+
+[node name="Shore" type="Spatial" parent="."]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -15, 0 )
+
+[node name="MeshInstance" type="MeshInstance" parent="Shore"]
+transform = Transform( -4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -100, 0, 0 )
+mesh = SubResource( 5 )
+skeleton = NodePath("../..")
+
+[node name="MeshInstance2" type="MeshInstance" parent="Shore"]
+transform = Transform( -4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 100, 0, 0 )
+mesh = SubResource( 5 )
+skeleton = NodePath("../..")
+
+[node name="MeshInstance7" type="MeshInstance" parent="Shore"]
+transform = Transform( -4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -100, 0, 70 )
+mesh = SubResource( 5 )
+skeleton = NodePath("../..")
+
+[node name="MeshInstance8" type="MeshInstance" parent="Shore"]
+transform = Transform( -4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 100, 0, 70 )
+mesh = SubResource( 5 )
+skeleton = NodePath("../..")
+
+[node name="MeshInstance3" type="MeshInstance" parent="Shore"]
+transform = Transform( -4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -30, 0, -50 )
+mesh = SubResource( 5 )
+skeleton = NodePath("../..")
+
+[node name="MeshInstance4" type="MeshInstance" parent="Shore"]
+transform = Transform( -4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 30, 0, -50 )
+mesh = SubResource( 5 )
+skeleton = NodePath("../..")
+
+[node name="MeshInstance5" type="MeshInstance" parent="Shore"]
+transform = Transform( -4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -30, 0, -140 )
+mesh = SubResource( 5 )
+skeleton = NodePath("../..")
+
+[node name="MeshInstance9" type="MeshInstance" parent="Shore"]
+transform = Transform( -4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -115, 0, -50 )
+mesh = SubResource( 5 )
+skeleton = NodePath("../..")
+
+[node name="MeshInstance10" type="MeshInstance" parent="Shore"]
+transform = Transform( -4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -115, 0, -140 )
+mesh = SubResource( 5 )
+skeleton = NodePath("../..")
+
+[node name="MeshInstance6" type="MeshInstance" parent="Shore"]
+transform = Transform( -4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 30, 0, -140 )
+mesh = SubResource( 5 )
+skeleton = NodePath("../..")
+
+[node name="MeshInstance11" type="MeshInstance" parent="Shore"]
+transform = Transform( -4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 115, 0, -50 )
+mesh = SubResource( 5 )
+skeleton = NodePath("../..")
+
+[node name="MeshInstance12" type="MeshInstance" parent="Shore"]
+transform = Transform( -4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 115, 0, -140 )
+mesh = SubResource( 5 )
+skeleton = NodePath("../..")
+
+[node name="House" type="Spatial" parent="."]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 25, -80 )
+
+[node name="MeshInstance" type="MeshInstance" parent="House"]
+mesh = SubResource( 7 )
+
+[node name="MeshInstance2" type="MeshInstance" parent="House"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 50, 0 )
+mesh = SubResource( 11 )
+
+[node name="Dock" type="Spatial" parent="."]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -10, 50 )
+
+[node name="MeshInstance" type="MeshInstance" parent="Dock"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 50, 0, 0 )
+mesh = SubResource( 12 )
+
+[node name="MeshInstance2" type="MeshInstance" parent="Dock"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -50, 0, 0 )
+mesh = SubResource( 12 )
+
+[node name="MeshInstance3" type="MeshInstance" parent="Dock"]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 5, -40 )
+mesh = SubResource( 13 )
diff --git a/world/monuments/DockMonument.gd b/world/monuments/DockMonument.gd
new file mode 100644
index 0000000..2ac0c71
--- /dev/null
+++ b/world/monuments/DockMonument.gd
@@ -0,0 +1,19 @@
+extends Monument
+class_name DockMonument
+
+var packed_scene = preload("res://world/monuments/Dock.tscn")
+
+func _init(xform:Transform).(xform,packed_scene,_chunks(),_origin()):
+ pass
+
+func _chunks():
+ var chunk_size = ChunkLoader.world.chunk_size
+ var c = {}
+ var width = stepify(200.0,chunk_size)
+ for x in range(-width,width+chunk_size,chunk_size):
+ for y in range(-width,width+chunk_size,chunk_size):
+ c[Vector2(x,y)] = true
+ return c
+
+func _origin():
+ return Vector2(0.0,0.0)
diff --git a/world/monuments/Monument.gd b/world/monuments/Monument.gd
new file mode 100644
index 0000000..86074f1
--- /dev/null
+++ b/world/monuments/Monument.gd
@@ -0,0 +1,21 @@
+class_name Monument
+
+var xform:Transform = Transform(Basis(),Vector3.ZERO)
+var scene:PackedScene = null
+var chunks = {}
+var origin_chunk = Vector2.ZERO
+var loaded_chunk = null
+
+func is_chunk_in_monument(chunk_coords:Vector2):
+ return self.chunks.has(chunk_coords)
+
+func _init(transform,scn,member_chunks, origin):
+ self.xform = transform
+ self.xform.origin = ChunkLoader.v3_coords(ChunkLoader.chunk_coords(ChunkLoader.v2_coords(self.xform.origin)))
+ self.scene = scn
+ var org = ChunkLoader.chunk_coords(ChunkLoader.v2_coords(self.xform.origin))
+ for c in member_chunks.keys():
+ var c2 = ChunkLoader.v2_coords(self.xform.basis * ChunkLoader.v3_coords(c))
+ self.chunks[ChunkLoader.chunk_coords(c2)+org] = member_chunks[c]
+ origin = ChunkLoader.v2_coords(self.xform.basis * ChunkLoader.v3_coords(origin))
+ self.origin_chunk = ChunkLoader.chunk_coords(origin)+org