Add DeployToSteamOS and Procedural Dungeon Generation addons

This commit is contained in:
2024-08-22 16:51:05 -07:00
parent 6a6be038e8
commit 5c81398c83
108 changed files with 17406 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
@tool
extends Node3D
@export var text = "" :
set(v):
text = v
if is_inside_tree(): update_visual()
func update_visual():
self.visible = len(text) > 0
self.global_transform.basis = self.global_transform.basis.orthonormalized() * self.global_transform.basis.y.length()
$Label3D.text = text
$Sprite3D.texture = preload("res://addons/SimpleDungeons/res/error-sign.svg") if text.begins_with("Error") else preload("res://addons/SimpleDungeons/res/warning-sign.svg")
func _ready():
update_visual()
set_process_input(false)

View File

@@ -0,0 +1,20 @@
[gd_scene load_steps=3 format=3 uid="uid://djjvvvx7svoux"]
[ext_resource type="Script" path="res://addons/SimpleDungeons/debug_visuals/DebugAlert.gd" id="1_ngt8o"]
[ext_resource type="Texture2D" uid="uid://byywkosue8x0q" path="res://addons/SimpleDungeons/res/warning-sign.svg" id="2_q7g1p"]
[node name="DebugAlert" type="Node3D"]
visible = false
script = ExtResource("1_ngt8o")
metadata/_edit_lock_ = true
[node name="Label3D" type="Label3D" parent="."]
pixel_size = 0.02
billboard = 1
no_depth_test = true
[node name="Sprite3D" type="Sprite3D" parent="."]
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 4.17956, 0)
billboard = 1
no_depth_test = true
texture = ExtResource("2_q7g1p")

View File

@@ -0,0 +1,54 @@
[gd_scene load_steps=4 format=3 uid="uid://cjxyp5lrix0pu"]
[ext_resource type="Material" uid="uid://pq2fqq4ophsy" path="res://addons/SimpleDungeons/debug_visuals/WireframeColorMat.tres" id="1_3h4gq"]
[sub_resource type="GDScript" id="GDScript_18siu"]
script/source = "@tool
extends Node3D
@export var text = \"DOOR\"
@export var color = Color(0, 1, 0)
func _ready():
set_process_input(false)
func _process(_delta):
$CSGCylinder3D2.material.set_shader_parameter(\"color\", Vector3(color.r, color.g, color.b))
$CSGBox3D2.material.set_shader_parameter(\"color\", Vector3(color.r, color.g, color.b))
$MeshInstance3D.mesh.material.set_shader_parameter(\"color\", Vector3(color.r, color.g, color.b))
$Label3D.modulate = color
$Label3D.text = text
"
[sub_resource type="QuadMesh" id="QuadMesh_35eqg"]
resource_local_to_scene = true
material = ExtResource("1_3h4gq")
size = Vector2(10, 10)
[node name="DoorDebugVisual" type="Node3D"]
script = SubResource("GDScript_18siu")
metadata/_edit_lock_ = true
[node name="Label3D" type="Label3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.657576, 0)
pixel_size = 0.01
no_depth_test = true
modulate = Color(0, 1, 0, 1)
text = "DOOR"
[node name="CSGCylinder3D2" type="CSGCylinder3D" parent="."]
transform = Transform3D(0.48016, 1.27422e-07, 0.48016, 0.48016, -2.09885e-08, -0.48016, -7.52601e-08, 0.679049, -1.04942e-07, 0, 0, 0.997)
radius = 0.423
height = 0.716463
sides = 4
cone = true
smooth_faces = false
material = ExtResource("1_3h4gq")
[node name="CSGBox3D2" type="CSGBox3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.464)
size = Vector3(0.166, 0.166, 0.682)
material = ExtResource("1_3h4gq")
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
mesh = SubResource("QuadMesh_35eqg")

View File

@@ -0,0 +1,50 @@
@tool
extends Node3D
var dungeon_generator : DungeonGenerator3D = null
var wireframe_cube : Node3D = null
var debug_alert : Node3D = null
func update_visual():
var show_editor = Engine.is_editor_hint() and dungeon_generator.show_debug_in_editor
var show_game = not Engine.is_editor_hint() and dungeon_generator.show_debug_in_game
if not show_editor and not show_game:
if wireframe_cube and is_instance_valid(wireframe_cube):
remove_child(wireframe_cube)
wireframe_cube.queue_free()
wireframe_cube = null
if debug_alert and is_instance_valid(debug_alert):
remove_child(debug_alert)
debug_alert.queue_free()
debug_alert = null
return
if not wireframe_cube or not is_instance_valid(wireframe_cube):
wireframe_cube = preload("res://addons/SimpleDungeons/debug_visuals/WireframeCube.tscn").instantiate()
wireframe_cube.enable_depth_test = true
add_child(wireframe_cube)
wireframe_cube.scale = Vector3(dungeon_generator.dungeon_size) * dungeon_generator.voxel_scale
wireframe_cube.grid_size = dungeon_generator.dungeon_size
if not debug_alert or not is_instance_valid(debug_alert):
debug_alert = preload("res://addons/SimpleDungeons/debug_visuals/DebugAlert.tscn").instantiate()
add_child(debug_alert)
debug_alert.scale = Vector3(dungeon_generator.voxel_scale.y/5.0, dungeon_generator.voxel_scale.y/5.0, dungeon_generator.voxel_scale.y/5.0)
debug_alert.position = ((Vector3(dungeon_generator.dungeon_size) / 2) + Vector3(0,0.35,0)) * Vector3(0, dungeon_generator.voxel_scale.y, 0)
var err_warning = {"error": "", "warning": ""} # Closure won't capture normal vars
dungeon_generator.validate_dungeon(
(func(str):
err_warning["error"] = "Error: " + str),
(func(str): err_warning["warning"] = "Warning: " + str))
debug_alert.text = err_warning["error"] if err_warning["error"] else err_warning["warning"]
if not debug_alert.text: debug_alert.position = Vector3() # Fix AABB visual in editor
func _ready():
dungeon_generator = get_parent()
update_visual.call_deferred() # Call after parent _ready()
set_process_input(false)
func _process(_delta):
update_visual()

View File

@@ -0,0 +1,92 @@
@tool
extends Node3D
var dungeon_room : DungeonRoom3D = null
var wireframe_cube : Node3D = null
var debug_alert : Node3D = null
var aabb_with_doors : Node3D = null
# Dict mapping DungeonRoom3D Door:DoorDebugVisual
var door_visuals = []
func update_door_visuals(show_visuals : bool):
var room_doors := []
if show_visuals:
room_doors = dungeon_room.get_doors()
# Add/remove debug visuals to match
while len(door_visuals) < len(room_doors):
var door_visual = preload("res://addons/SimpleDungeons/debug_visuals/DoorDebugVisual.tscn").instantiate()
add_child(door_visual)
door_visuals.push_back(door_visual)
while len(door_visuals) > len(room_doors):
var door_visual = door_visuals.pop_back()
remove_child(door_visual)
door_visual.queue_free()
for i in len(room_doors):
door_visuals[i].position = (Vector3(room_doors[i].local_pos) + Vector3(.5,.5,.5)) * dungeon_room.voxel_scale
door_visuals[i].position -= Vector3(dungeon_room.size_in_voxels) * dungeon_room.voxel_scale * 0.5
door_visuals[i].position += DungeonUtils.DIRECTION_VECTORS[room_doors[i].dir] * 0.5 * dungeon_room.voxel_scale
door_visuals[i].rotation.y = -DungeonUtils.DIRECTION_VECTORS[room_doors[i].dir].signed_angle_to(DungeonUtils.DIRECTION_VECTORS[DungeonUtils.Direction.FRONT], Vector3.UP)
door_visuals[i].scale = dungeon_room.voxel_scale / 10.0
var col = Color.YELLOW if room_doors[i].optional else Color.GREEN
door_visuals[i].text = "OPTIONAL DOOR" if room_doors[i].optional else "DOOR"
door_visuals[i].color = col if room_doors[i].validate_door() else Color.RED
func update_visual():
var show_editor = Engine.is_editor_hint() and dungeon_room.show_debug_in_editor
var show_game = not Engine.is_editor_hint() and dungeon_room.show_debug_in_game
#if not get_parent() is DungeonGenerator3D:
#print(dungeon_room.name)
if dungeon_room.dungeon_generator and dungeon_room.dungeon_generator.hide_debug_visuals_for_all_generated_rooms and not (dungeon_room.get_parent() is DungeonGenerator3D):
show_editor = false
show_game = false
if not show_editor and not show_game:
update_door_visuals(false)
for dbg_visual in [wireframe_cube, debug_alert, aabb_with_doors]:
if dbg_visual and is_instance_valid(dbg_visual):
remove_child(dbg_visual)
dbg_visual.queue_free()
wireframe_cube = null; debug_alert = null; aabb_with_doors = null;
return
update_door_visuals(true)
if not wireframe_cube or not is_instance_valid(wireframe_cube):
wireframe_cube = preload("res://addons/SimpleDungeons/debug_visuals/WireframeCube.tscn").instantiate()
add_child(wireframe_cube)
wireframe_cube.scale = Vector3(dungeon_room.size_in_voxels) * dungeon_room.voxel_scale
wireframe_cube.grid_size = dungeon_room.size_in_voxels
wireframe_cube.show_coordinates = false
wireframe_cube.color = Color.WHITE if dungeon_room.was_preplaced else Color.BLACK
# Show grid AABB with doors
if not aabb_with_doors:
aabb_with_doors = CSGBox3D.new()
aabb_with_doors.material = preload("res://addons/SimpleDungeons/debug_visuals/WireframeColorMat.tres")
add_child(aabb_with_doors)
var rel_room_aabb = dungeon_room.xform_aabb(dungeon_room.get_grid_aabbi(true).to_AABB(), dungeon_room.get_xform_to(DungeonRoom3D.SPACE.DUNGEON_GRID, DungeonRoom3D.SPACE.LOCAL_SPACE)).abs()
aabb_with_doors.size = rel_room_aabb.size if dungeon_room.show_grid_aabb_with_doors else Vector3()
aabb_with_doors.position = rel_room_aabb.get_center()
aabb_with_doors.visible = dungeon_room.show_grid_aabb_with_doors
if not debug_alert or not is_instance_valid(debug_alert):
debug_alert = preload("res://addons/SimpleDungeons/debug_visuals/DebugAlert.tscn").instantiate()
add_child(debug_alert)
debug_alert.scale = Vector3(dungeon_room.voxel_scale.y/10.0, dungeon_room.voxel_scale.y/10.0, dungeon_room.voxel_scale.y/10.0)
debug_alert.position = ((Vector3(dungeon_room.size_in_voxels) / 2) + Vector3(0,0.35,0)) * Vector3(0, dungeon_room.voxel_scale.y, 0)
var err_warning = {"error": "", "warning": ""} # Closure won't capture normal vars
dungeon_room.validate_room(
(func(str):
err_warning["error"] = "Error: " + str),
(func(str): err_warning["warning"] = "Warning: " + str))
debug_alert.text = err_warning["error"] if err_warning["error"] else err_warning["warning"]
if not debug_alert.text: debug_alert.position = Vector3() # Fix AABB visual in editor
func _ready():
dungeon_room = get_parent()
update_visual.call_deferred() # Call after parent _ready()
set_process_input(false)
func _process(_delta):
update_visual()

View File

@@ -0,0 +1,44 @@
[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://pq2fqq4ophsy"]
[sub_resource type="Shader" id="Shader_xtf8b"]
resource_local_to_scene = true
code = "shader_type spatial;
render_mode unshaded, cull_disabled, depth_draw_always, depth_test_disabled;
uniform vec3 color = vec3(0.0, 1.0, 0.0);
uniform float line_width : hint_range(0.0, 10.0) = 0.85;
varying vec3 barycentric;
void vertex() {
vec3 b_coords[3] = vec3[](vec3(1, 0, 0), vec3(0, 1, 0), vec3(0, 0, 1));
int vertex_id = int(VERTEX_ID) % 3;
barycentric = b_coords[vertex_id];
}
void fragment() {
// Calculate the screen-space derivatives of the barycentric coordinates
vec3 dFdx_barycentric = dFdx(barycentric);
vec3 dFdy_barycentric = dFdy(barycentric);
// Calculate the minimum barycentric coordinate value
float min_bary = min(min(barycentric.x, barycentric.y), barycentric.z);
// Calculate the screen-space line width
float screen_line_width = line_width * length(vec2(dFdx_barycentric.x, dFdy_barycentric.x));
// Draw the line based on the calculated screen-space line width
if (min_bary < screen_line_width) {
ALBEDO = color;
} else {
discard;
}
}
"
[resource]
resource_local_to_scene = true
render_priority = 0
shader = SubResource("Shader_xtf8b")
shader_parameter/color = Vector3(0, 1, 0)
shader_parameter/line_width = 0.85

View File

@@ -0,0 +1,69 @@
@tool
extends Node3D
@export var grid_size := Vector3i(1,1,1)
@export var show_coordinates := true
@export var color := Color.BLACK
@export var enable_depth_test := false
var last_grid_size = null
var last_voxel_scale = null
var last_show_coordinates = null
var last_enable_depth = null
func update_grid():
for child in %Levels.get_children():
%Levels.remove_child(child)
child.queue_free()
%Front.mesh.material.shader = preload("res://addons/SimpleDungeons/debug_visuals/WireframeCubeDepthEnabled.gdshader") if enable_depth_test else preload("res://addons/SimpleDungeons/debug_visuals/WireframeCube.gdshader")
%Right.mesh.material.shader = preload("res://addons/SimpleDungeons/debug_visuals/WireframeCubeDepthEnabled.gdshader") if enable_depth_test else preload("res://addons/SimpleDungeons/debug_visuals/WireframeCube.gdshader")
%Top.mesh.material.shader = preload("res://addons/SimpleDungeons/debug_visuals/WireframeCubeDepthEnabled.gdshader") if enable_depth_test else preload("res://addons/SimpleDungeons/debug_visuals/WireframeCube.gdshader")
%Front.mesh.material.set_shader_parameter("grid_size", Vector2(grid_size.x, grid_size.y))
%Right.mesh.material.set_shader_parameter("grid_size", Vector2(grid_size.z, grid_size.y))
%Top.mesh.material.set_shader_parameter("grid_size", Vector2(grid_size.x, grid_size.z))
%Front.mesh.material.set_shader_parameter("color", Vector3(color.r, color.g, color.b))
%Right.mesh.material.set_shader_parameter("color", Vector3(color.r, color.g, color.b))
%Top.mesh.material.set_shader_parameter("color", Vector3(color.r, color.g, color.b))
if grid_size.x < 1 or grid_size.y < 1 or grid_size.z < 1:
return
if grid_size.x <= 1 and grid_size.y <= 1 and grid_size.z <= 1:
return
for y in range(1, grid_size.y):
var level = %Top.duplicate()
%Levels.add_child(level)
level.position.y -= float(y) / grid_size.y - 0.00001
var b = grid_size - Vector3i(1,1,1)
var positions = [Vector3i(0,0,0), Vector3i(grid_size.x-1,0,0), Vector3i(0,grid_size.y-1,0), Vector3i(0,0,grid_size.z-1),
b, b - Vector3i(grid_size.x-1,0,0), b - Vector3i(0,grid_size.y-1,0), b - Vector3i(0,0,grid_size.z-1)]
if not show_coordinates:
return
var make_scale_uniform_node = Node3D.new()
%Levels.add_child(make_scale_uniform_node)
make_scale_uniform_node.scale = self.transform.basis.inverse().get_scale()
for grid_pos in positions:
var label = Label3D.new()
label.text = str(grid_pos)
make_scale_uniform_node.add_child(label)
label.position = ((Vector3(grid_pos) + Vector3(0.5, 0.5, 0.5)) / Vector3(grid_size)) * self.scale - self.scale/2
label.scale *= (Vector3(1,1,1) / Vector3(grid_size)) * self.scale
label.scale.x = min(label.scale.x, label.scale.y, label.scale.z)
label.scale.y = min(label.scale.x, label.scale.y, label.scale.z)
label.scale.z = min(label.scale.x, label.scale.y, label.scale.z)
func _ready():
update_grid()
set_process_input(false)
func _process(delta):
if last_grid_size != grid_size or last_show_coordinates != show_coordinates or last_enable_depth != enable_depth_test:
update_grid()
last_grid_size = grid_size
last_show_coordinates = show_coordinates
last_enable_depth = enable_depth_test

View File

@@ -0,0 +1,14 @@
shader_type spatial;
render_mode unshaded, cull_disabled, depth_test_disabled;
uniform vec2 grid_size;
uniform vec3 color = vec3(0.);
void fragment() {
vec2 uv = fract(UV * grid_size);
vec2 eps = 0.0015 * grid_size;
vec2 inv_eps = 1.0 - eps;
if(uv.x > eps.x && uv.x < inv_eps.x && uv.y > eps.y && uv.y < inv_eps.y) {
discard;
}
ALBEDO = color;
}

View File

@@ -0,0 +1,79 @@
[gd_scene load_steps=11 format=3 uid="uid://cfch5o0wphv4r"]
[ext_resource type="Script" path="res://addons/SimpleDungeons/debug_visuals/WireframeCube.gd" id="1_unksl"]
[ext_resource type="Shader" path="res://addons/SimpleDungeons/debug_visuals/WireframeCube.gdshader" id="2_hwi17"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_jymxj"]
resource_local_to_scene = true
render_priority = 0
shader = ExtResource("2_hwi17")
shader_parameter/grid_size = Vector2(1, 1)
shader_parameter/color = Vector3(0, 0, 0)
[sub_resource type="QuadMesh" id="QuadMesh_pwl2e"]
resource_local_to_scene = true
material = SubResource("ShaderMaterial_jymxj")
[sub_resource type="ShaderMaterial" id="ShaderMaterial_lnw1d"]
resource_local_to_scene = true
render_priority = 0
shader = ExtResource("2_hwi17")
shader_parameter/grid_size = Vector2(1, 1)
shader_parameter/color = Vector3(0, 0, 0)
[sub_resource type="QuadMesh" id="QuadMesh_llwc2"]
resource_local_to_scene = true
material = SubResource("ShaderMaterial_lnw1d")
[sub_resource type="QuadMesh" id="QuadMesh_hdmjf"]
resource_local_to_scene = true
material = SubResource("ShaderMaterial_lnw1d")
[sub_resource type="ShaderMaterial" id="ShaderMaterial_3xn3f"]
resource_local_to_scene = true
render_priority = 0
shader = ExtResource("2_hwi17")
shader_parameter/grid_size = Vector2(1, 1)
shader_parameter/color = Vector3(0, 0, 0)
[sub_resource type="QuadMesh" id="QuadMesh_d7b6y"]
resource_local_to_scene = true
material = SubResource("ShaderMaterial_3xn3f")
[sub_resource type="QuadMesh" id="QuadMesh_kjtax"]
resource_local_to_scene = true
material = SubResource("ShaderMaterial_3xn3f")
[node name="WireframeCube" type="Node3D"]
script = ExtResource("1_unksl")
metadata/_edit_lock_ = true
[node name="Back" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.5)
mesh = SubResource("QuadMesh_pwl2e")
[node name="Front" type="MeshInstance3D" parent="."]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.5)
mesh = SubResource("QuadMesh_pwl2e")
[node name="Right" type="MeshInstance3D" parent="."]
unique_name_in_owner = true
transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 0.5, 0, 0)
mesh = SubResource("QuadMesh_llwc2")
[node name="Left" type="MeshInstance3D" parent="."]
transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, -0.5, 0, 0)
mesh = SubResource("QuadMesh_hdmjf")
[node name="Top" type="MeshInstance3D" parent="."]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0.5, 0)
mesh = SubResource("QuadMesh_d7b6y")
[node name="Bottom" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.5, 0)
mesh = SubResource("QuadMesh_kjtax")
[node name="Levels" type="Node3D" parent="."]
unique_name_in_owner = true

View File

@@ -0,0 +1,14 @@
shader_type spatial;
render_mode unshaded, cull_disabled;
uniform vec2 grid_size;
uniform vec3 color = vec3(0.);
void fragment() {
vec2 uv = fract(UV * grid_size);
vec2 eps = 0.0015 * grid_size;
vec2 inv_eps = 1.0 - eps;
if(uv.x > eps.x && uv.x < inv_eps.x && uv.y > eps.y && uv.y < inv_eps.y) {
discard;
}
ALBEDO = color;
}