From cda49b25255bf4a0eff104eb34db43f9e7a8bff4 Mon Sep 17 00:00:00 2001 From: Armored Dragon Date: Wed, 15 Jul 2026 09:12:07 -0500 Subject: [PATCH 01/13] Transform properties. --- .../client_edit_mode/desktop/inspector.tscn | 55 +++++++++++- .../desktop/scripts/inspector.gd | 7 ++ .../desktop/scripts/properties.gd | 87 +++++++++++++++++++ .../desktop/scripts/properties.gd.uid | 1 + .../node_property_editor/partials/Object.tscn | 35 ++++++++ .../partials/Vector3.tscn | 44 ++++++++++ .../node_property_editor/partials/bool.gd | 32 +++++++ .../node_property_editor/partials/bool.gd.uid | 1 + .../node_property_editor/partials/bool.tscn | 42 +++++++++ .../node_property_editor/partials/object.gd | 30 +++++++ .../partials/object.gd.uid | 1 + .../node_property_editor/partials/spin_box.gd | 34 ++++++++ .../partials/spin_box.gd.uid | 1 + .../partials/spin_box.tscn | 16 ++++ .../node_property_editor/partials/vector_3.gd | 45 ++++++++++ .../partials/vector_3.gd.uid | 1 + 16 files changed, 430 insertions(+), 2 deletions(-) create mode 100644 src/userinterface/client_edit_mode/desktop/scripts/properties.gd create mode 100644 src/userinterface/client_edit_mode/desktop/scripts/properties.gd.uid create mode 100644 src/userinterface/client_edit_mode/node_property_editor/partials/Object.tscn create mode 100644 src/userinterface/client_edit_mode/node_property_editor/partials/Vector3.tscn create mode 100644 src/userinterface/client_edit_mode/node_property_editor/partials/bool.gd create mode 100644 src/userinterface/client_edit_mode/node_property_editor/partials/bool.gd.uid create mode 100644 src/userinterface/client_edit_mode/node_property_editor/partials/bool.tscn create mode 100644 src/userinterface/client_edit_mode/node_property_editor/partials/object.gd create mode 100644 src/userinterface/client_edit_mode/node_property_editor/partials/object.gd.uid create mode 100644 src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.gd create mode 100644 src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.gd.uid create mode 100644 src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.tscn create mode 100644 src/userinterface/client_edit_mode/node_property_editor/partials/vector_3.gd create mode 100644 src/userinterface/client_edit_mode/node_property_editor/partials/vector_3.gd.uid diff --git a/src/userinterface/client_edit_mode/desktop/inspector.tscn b/src/userinterface/client_edit_mode/desktop/inspector.tscn index e2dcb7b..b486f33 100644 --- a/src/userinterface/client_edit_mode/desktop/inspector.tscn +++ b/src/userinterface/client_edit_mode/desktop/inspector.tscn @@ -13,7 +13,10 @@ [ext_resource type="Texture2D" uid="uid://bu6vtb71stcjq" path="res://resources/icons/godot/ToolScale.svg" id="7_7pj7g"] [ext_resource type="Texture2D" uid="uid://8rvofwa4k380" path="res://resources/icons/godot/WorldEnvironment.svg" id="8_7pj7g"] [ext_resource type="Texture2D" uid="uid://bx7irvaofgk6n" path="res://resources/icons/godot/CharacterBody3D.svg" id="9_840b7"] +[ext_resource type="PackedScene" uid="uid://wmjsfgx486xa" path="res://userinterface/client_edit_mode/node_property_editor/partials/bool.tscn" id="14_8u8qu"] +[ext_resource type="Script" uid="uid://8lm0oig2kxbj" path="res://userinterface/client_edit_mode/desktop/scripts/properties.gd" id="14_at34i"] [ext_resource type="PackedScene" uid="uid://chbjqqcikq7aj" path="res://userinterface/client_edit_mode/desktop/partial/popup_selection.tscn" id="14_cuj5f"] +[ext_resource type="PackedScene" uid="uid://dkn0gmy8or4hq" path="res://userinterface/client_edit_mode/node_property_editor/partials/Vector3.tscn" id="14_q5c3n"] [ext_resource type="Texture2D" uid="uid://cq2ec6jy8kynp" path="res://resources/icons/godot/Add.svg" id="15_3i2mc"] [ext_resource type="PackedScene" uid="uid://sntuc3p6k4s6" path="res://userinterface/dash/partials/generic_button.tscn" id="16_j7nog"] [ext_resource type="Texture2D" uid="uid://b54viv8d54q83" path="res://resources/icons/godot/Remove.svg" id="17_akq5y"] @@ -161,7 +164,7 @@ size_flags_vertical = 3 [node name="HSplitContainer" type="HSplitContainer" parent="VBoxContainer/HBoxContainer" unique_id=234551977] layout_mode = 2 size_flags_horizontal = 3 -split_offsets = PackedInt32Array(300) +split_offsets = PackedInt32Array(300, -300) split_offset = 300 [node name="MarginContainer" type="MarginContainer" parent="VBoxContainer/HBoxContainer/HSplitContainer" unique_id=1929440074] @@ -276,9 +279,9 @@ size_flags_horizontal = 3 mouse_filter = 1 [node name="Properties" type="MarginContainer" parent="VBoxContainer/HBoxContainer/HSplitContainer" unique_id=1127572109] -visible = false custom_minimum_size = Vector2(300, 0) layout_mode = 2 +script = ExtResource("14_at34i") [node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties" unique_id=1772787264] layout_mode = 2 @@ -301,6 +304,54 @@ mouse_filter = 1 theme = ExtResource("2_plsgj") theme_override_styles/panel = SubResource("StyleBoxFlat_plsgj") +[node name="ScrollContainer" type="ScrollContainer" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container" unique_id=1256337211] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +horizontal_scroll_mode = 0 + +[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer" unique_id=1523084746] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +theme_override_constants/margin_left = 5 +theme_override_constants/margin_top = 5 +theme_override_constants/margin_right = 5 +theme_override_constants/margin_bottom = 5 + +[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer" unique_id=413793585] +layout_mode = 2 + +[node name="Visible" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer" unique_id=933711176 instance=ExtResource("14_8u8qu")] +layout_mode = 2 +property_name = "Visible" + +[node name="FoldableContainer" type="FoldableContainer" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer" unique_id=81728243] +layout_mode = 2 +title = "Transform" +title_alignment = 1 + +[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer" unique_id=216577687] +layout_mode = 2 + +[node name="Position" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer/VBoxContainer" unique_id=921313987 instance=ExtResource("14_q5c3n")] +layout_mode = 2 +size_flags_vertical = 1 +property_name = "Position" + +[node name="Rotation" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer/VBoxContainer" unique_id=1153106054 instance=ExtResource("14_q5c3n")] +layout_mode = 2 +size_flags_vertical = 1 +property_name = "Rotation" + +[node name="Scale" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer/VBoxContainer" unique_id=916704004 instance=ExtResource("14_q5c3n")] +layout_mode = 2 +size_flags_vertical = 1 +property_name = "Scale" + [node name="InspectorPopup" parent="." unique_id=629092317 instance=ExtResource("14_cuj5f")] visible = false layout_mode = 0 diff --git a/src/userinterface/client_edit_mode/desktop/scripts/inspector.gd b/src/userinterface/client_edit_mode/desktop/scripts/inspector.gd index 79db473..edf5e17 100644 --- a/src/userinterface/client_edit_mode/desktop/scripts/inspector.gd +++ b/src/userinterface/client_edit_mode/desktop/scripts/inspector.gd @@ -38,6 +38,8 @@ var _gizmo_space_local: bool = true @onready var _inspector_filter_search: LineEdit = get_node("VBoxContainer/HBoxContainer/HSplitContainer/MarginContainer/VBoxContainer/Container/VBoxContainer/InputString/MarginContainer/HBoxContainer/MarginContainer/LineEdit") @onready var _inspector_filters: Node = get_node("VBoxContainer/HBoxContainer/HSplitContainer/MarginContainer/VBoxContainer/Container/VBoxContainer/Filters/HBoxContainer") +@onready var _node_property_editor: Node = get_node("VBoxContainer/HBoxContainer/HSplitContainer/Properties") + # UI Inspector @onready var _inspector_tree: Tree = get_node("VBoxContainer/HBoxContainer/HSplitContainer/MarginContainer/VBoxContainer/Container/VBoxContainer/MarginContainer/Tree") @@ -464,7 +466,10 @@ func _select(target_node: int) -> void: my_gizmo.mode = _gizmo_mode my_gizmo.use_local_space = _gizmo_space_local + _node_property_editor.get_node_properties(_node_db_entry.node) my_gizmo.transform_changed.connect(func(mode, value): session_spawnable_m.set_transform(target_node, _node_db_entry.node.transform)) + # HACK: Update ALL of the node properties after a transformation was done. + my_gizmo.transform_end.connect(func(mode): _node_property_editor.update_node_properties(_node_db_entry.node)) func _gizmo_delete() -> void: my_gizmo.clear_selection() @@ -532,3 +537,5 @@ func _cem_camera_state(state: bool) -> void: _player_node._cem_camera_state(state) Events.emit_signal("cem_camera_state", state) return + +# Node Property Editor diff --git a/src/userinterface/client_edit_mode/desktop/scripts/properties.gd b/src/userinterface/client_edit_mode/desktop/scripts/properties.gd new file mode 100644 index 0000000..3d9bc38 --- /dev/null +++ b/src/userinterface/client_edit_mode/desktop/scripts/properties.gd @@ -0,0 +1,87 @@ +# --- License +# File: /client/src/userinterface/client_edit_mode/desktop/scripts/properties.gd +# Project: OpenMinerva +# Created Date: 15 July 2026 +# Copyright (c) 2026 OpenMinerva +# License: MIT License +# Authors: Armored Dragon +# --- License +extends MarginContainer + +const _dev_basic_props = ["position", "rotation", "scale", "visible"] +const _dev_whitelist_properties = ["mesh"] +var _node: Node + +@onready var _dev_transform_container: Node = get_node("VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer/VBoxContainer") +@onready var _dev_property_container: Node = get_node("VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer") + +var partials: Dictionary = {} + +func _ready() -> void: + _dev_transform_container.get_node("Position").value_changed.connect(func (new_value): _property_changed("position", new_value)) + _dev_transform_container.get_node("Rotation").value_changed.connect(func (new_value): _property_changed("rotation", new_value)) + _dev_transform_container.get_node("Scale").value_changed.connect(func (new_value): _property_changed("scale", new_value)) + return + +func get_node_properties(node: Node) -> void: + _node = node + _clear_node_properties() + var properties = node.get_property_list() + + for prop in properties: + if _dev_whitelist_properties.has(prop.name) == false: + continue + + var _partial = _get_partial("%s" % type_string(prop.type)) + if _partial == null: + print("Property: %s" % prop.name) + print("Type: %s" % type_string(prop.type)) + print("Class: %s" % prop.class_name) + print("Hint: %s" % prop.hint) + print("Hint String: %s" % prop.hint_string) + print("Value: %s" % node.get(prop.name)) + print("---") + continue + + _dev_property_container.add_child(_partial) + _partial.set_label(prop.name.capitalize()) + _partial.set_value(node.get(prop.name)) + _partial.value_changed.connect(func (new_value): _property_changed(prop.name, new_value)) + + + # Display the values + update_node_properties(node) + return + +func _clear_node_properties() -> void: + var _child_number: int = 0 + for child in _dev_property_container.get_children(): + if _child_number <= 1: + _child_number = _child_number + 1 + continue + child.queue_free() + return + +func update_node_properties(node: Node) -> void: + _dev_transform_container.get_node("Position").set_value(node.get("position")) + _dev_transform_container.get_node("Rotation").set_value(node.get("rotation")) + _dev_transform_container.get_node("Scale").set_value(node.get("scale")) + return + +func _property_changed(property_name: String, property_value: Variant) -> void: + # TODO: Network change + _node.set(property_name, property_value) + return + + +func _get_partial(type: String) -> Node: + if partials.keys().has(type): + return partials[type].instantiate() + + var _new_partial = load("res://userinterface/client_edit_mode/node_property_editor/partials/%s.tscn" % type) + if _new_partial == null: + GlobalLogger.log("Could not find partial for type '%s'" % type, Enum.LogLevel.WARNING) + return null + + partials[type] = _new_partial + return partials[type].instantiate() diff --git a/src/userinterface/client_edit_mode/desktop/scripts/properties.gd.uid b/src/userinterface/client_edit_mode/desktop/scripts/properties.gd.uid new file mode 100644 index 0000000..ed14acc --- /dev/null +++ b/src/userinterface/client_edit_mode/desktop/scripts/properties.gd.uid @@ -0,0 +1 @@ +uid://8lm0oig2kxbj diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/Object.tscn b/src/userinterface/client_edit_mode/node_property_editor/partials/Object.tscn new file mode 100644 index 0000000..9dd7dee --- /dev/null +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/Object.tscn @@ -0,0 +1,35 @@ +[gd_scene format=3 uid="uid://dr4mc2gw53nb6"] + +[ext_resource type="Theme" uid="uid://ckqsvvccivw0x" path="res://resources/themes/default.tres" id="1_dt7qw"] +[ext_resource type="PackedScene" uid="uid://sntuc3p6k4s6" path="res://userinterface/dash/partials/generic_button.tscn" id="2_dt7qw"] +[ext_resource type="Script" uid="uid://s14au1dc165i" path="res://userinterface/client_edit_mode/node_property_editor/partials/object.gd" id="2_ijfgb"] + +[node name="Object" type="Control" unique_id=933711176] +custom_minimum_size = Vector2(80, 30) +layout_mode = 3 +anchor_right = 1.0 +anchor_bottom = 0.027777778 +offset_bottom = -30.0 +grow_horizontal = 2 +size_flags_horizontal = 3 +theme = ExtResource("1_dt7qw") +script = ExtResource("2_ijfgb") +metadata/_edit_use_anchors_ = true + +[node name="VBoxContainer" type="HBoxContainer" parent="." unique_id=1972995258] +layout_mode = 1 +anchors_preset = -1 +anchor_right = 1.0 +anchor_bottom = 0.053703703 +grow_horizontal = 2 +metadata/_edit_use_anchors_ = true + +[node name="Label" type="Label" parent="VBoxContainer" unique_id=482404396] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Vector3" + +[node name="GenericButton" parent="VBoxContainer" unique_id=649942124 instance=ExtResource("2_dt7qw")] +custom_minimum_size = Vector2(0, 30) +layout_mode = 2 +label = "Test" diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/Vector3.tscn b/src/userinterface/client_edit_mode/node_property_editor/partials/Vector3.tscn new file mode 100644 index 0000000..254b6e0 --- /dev/null +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/Vector3.tscn @@ -0,0 +1,44 @@ +[gd_scene format=3 uid="uid://dkn0gmy8or4hq"] + +[ext_resource type="Theme" uid="uid://ckqsvvccivw0x" path="res://resources/themes/default.tres" id="1_fenjf"] +[ext_resource type="Script" uid="uid://fo05ubo6hera" path="res://userinterface/client_edit_mode/node_property_editor/partials/vector_3.gd" id="2_iwkrw"] +[ext_resource type="PackedScene" uid="uid://b58b25jtckb2c" path="res://userinterface/client_edit_mode/node_property_editor/partials/spin_box.tscn" id="3_yo0a0"] + +[node name="Vector3" type="Control" unique_id=933711176] +custom_minimum_size = Vector2(80, 60) +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 3 +size_flags_vertical = 0 +theme = ExtResource("1_fenjf") +script = ExtResource("2_iwkrw") + +[node name="VBoxContainer" type="VBoxContainer" parent="." unique_id=1067102212] +layout_mode = 1 +anchors_preset = -1 +anchor_right = 1.0 +anchor_bottom = 0.053703703 +grow_horizontal = 2 +metadata/_edit_use_anchors_ = true + +[node name="Label" type="Label" parent="VBoxContainer" unique_id=482404396] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Vector3" + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer" unique_id=287908761] +layout_mode = 2 +focus_behavior_recursive = 2 + +[node name="X" parent="VBoxContainer/HBoxContainer" unique_id=1631362233 instance=ExtResource("3_yo0a0")] +layout_mode = 2 + +[node name="Y" parent="VBoxContainer/HBoxContainer" unique_id=1007326326 instance=ExtResource("3_yo0a0")] +layout_mode = 2 + +[node name="Z" parent="VBoxContainer/HBoxContainer" unique_id=1538313912 instance=ExtResource("3_yo0a0")] +layout_mode = 2 diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/bool.gd b/src/userinterface/client_edit_mode/node_property_editor/partials/bool.gd new file mode 100644 index 0000000..0f624ec --- /dev/null +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/bool.gd @@ -0,0 +1,32 @@ +# --- License +# File: /client/src/userinterface/client_edit_mode/node_property_editor/partials/bool.gd +# Project: OpenMinerva +# Created Date: 15 July 2026 +# Copyright (c) 2026 OpenMinerva +# License: MIT License +# Authors: Armored Dragon +# --- License + +extends Control + +signal value_changed(new_value: bool) + +@export var property_name: String = "" +@export var value: bool + +@onready var _label = get_node("VBoxContainer/Label") +@onready var _bool = get_node("VBoxContainer/CheckBox") + +func _ready() -> void: + _label.text = property_name + return + +func set_value(new_value: bool) -> void: + value = new_value + _bool.button_pressed = new_value + return + +func set_label(new_label: String) -> void: + _label.text = new_label + property_name = new_label + return diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/bool.gd.uid b/src/userinterface/client_edit_mode/node_property_editor/partials/bool.gd.uid new file mode 100644 index 0000000..bc04b67 --- /dev/null +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/bool.gd.uid @@ -0,0 +1 @@ +uid://dev0tv8ldaegm diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/bool.tscn b/src/userinterface/client_edit_mode/node_property_editor/partials/bool.tscn new file mode 100644 index 0000000..89fad1f --- /dev/null +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/bool.tscn @@ -0,0 +1,42 @@ +[gd_scene format=3 uid="uid://wmjsfgx486xa"] + +[ext_resource type="Theme" uid="uid://ckqsvvccivw0x" path="res://resources/themes/default.tres" id="1_h5new"] +[ext_resource type="Script" uid="uid://dev0tv8ldaegm" path="res://userinterface/client_edit_mode/node_property_editor/partials/bool.gd" id="2_1puyx"] + +[node name="Bool" type="Control" unique_id=933711176] +custom_minimum_size = Vector2(80, 30) +layout_mode = 3 +anchor_right = 1.0 +anchor_bottom = 0.027777778 +offset_bottom = -30.0 +grow_horizontal = 2 +size_flags_horizontal = 3 +theme = ExtResource("1_h5new") +script = ExtResource("2_1puyx") +metadata/_edit_use_anchors_ = true + +[node name="VBoxContainer" type="HBoxContainer" parent="." unique_id=1972995258] +layout_mode = 1 +anchors_preset = -1 +anchor_right = 1.0 +anchor_bottom = 0.053703703 +grow_horizontal = 2 +metadata/_edit_use_anchors_ = true + +[node name="Label" type="Label" parent="VBoxContainer" unique_id=482404396] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Vector3" + +[node name="CheckBox" type="CheckButton" parent="VBoxContainer" unique_id=643167569] +custom_minimum_size = Vector2(30, 30) +custom_maximum_size = Vector2(120, 30) +layout_mode = 2 +mouse_default_cursor_shape = 2 +theme = ExtResource("1_h5new") +button_pressed = true +flat = true +alignment = 1 +clip_text = true +icon_alignment = 1 +expand_icon = true diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/object.gd b/src/userinterface/client_edit_mode/node_property_editor/partials/object.gd new file mode 100644 index 0000000..8aa828f --- /dev/null +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/object.gd @@ -0,0 +1,30 @@ +# --- License +# File: /client/src/userinterface/client_edit_mode/node_property_editor/partials/object.gd +# Project: OpenMinerva +# Created Date: 15 July 2026 +# Copyright (c) 2026 OpenMinerva +# License: MIT License +# Authors: Armored Dragon +# --- License + +extends Control + +signal value_changed(new_value: Object) + +@export var property_name: String = "" +# @export var value: Object + +@onready var _label = get_node("VBoxContainer/Label") + +func _ready() -> void: + _label.text = property_name + return + +func set_value(new_value: Object) -> void: + # FIXME: Not sure what to do here. + return + +func set_label(new_label: String) -> void: + _label.text = new_label + property_name = new_label + return diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/object.gd.uid b/src/userinterface/client_edit_mode/node_property_editor/partials/object.gd.uid new file mode 100644 index 0000000..dbcb40e --- /dev/null +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/object.gd.uid @@ -0,0 +1 @@ +uid://s14au1dc165i diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.gd b/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.gd new file mode 100644 index 0000000..e42aa0c --- /dev/null +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.gd @@ -0,0 +1,34 @@ +# --- License +# File: /client/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.gd +# Project: OpenMinerva +# Created Date: 15 July 2026 +# Copyright (c) 2026 OpenMinerva +# License: MIT License +# Authors: Armored Dragon +# --- License +extends SpinBox + +signal spinbox_value_changed(value: float) + +@export var max_decimals: int = 4 + +func _ready() -> void: + value_changed.connect(_on_value_changed, CONNECT_DEFERRED) + get_line_edit().focus_entered.connect(_on_focus_entered, CONNECT_DEFERRED) + get_line_edit().focus_exited.connect(_on_focus_exited, CONNECT_DEFERRED) + + get_line_edit().text = _format_value(value) + return + +func _on_value_changed(new_value: float) -> void: + get_line_edit().text = _format_value(new_value) + spinbox_value_changed.emit(new_value) + +func _on_focus_entered() -> void: + get_line_edit().text = String.num(value, max_decimals) + +func _on_focus_exited() -> void: + get_line_edit().text = _format_value(value) + +func _format_value(v: float) -> String: + return (prefix + String.num(v, max_decimals) + suffix).trim_suffix(".0") diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.gd.uid b/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.gd.uid new file mode 100644 index 0000000..e76cd3d --- /dev/null +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.gd.uid @@ -0,0 +1 @@ +uid://susq40b1r4sx diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.tscn b/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.tscn new file mode 100644 index 0000000..0bd5cfc --- /dev/null +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.tscn @@ -0,0 +1,16 @@ +[gd_scene format=3 uid="uid://b58b25jtckb2c"] + +[ext_resource type="Script" uid="uid://susq40b1r4sx" path="res://userinterface/client_edit_mode/node_property_editor/partials/spin_box.gd" id="1_30qog"] + +[node name="SpinBox" type="SpinBox" unique_id=1631362233] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 3 +min_value = inf_neg +max_value = inf +step = 0.001 +alignment = 1 +script = ExtResource("1_30qog") diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/vector_3.gd b/src/userinterface/client_edit_mode/node_property_editor/partials/vector_3.gd new file mode 100644 index 0000000..b0bc356 --- /dev/null +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/vector_3.gd @@ -0,0 +1,45 @@ +# --- License +# File: /client/src/userinterface/client_edit_mode/node_property_editor/partials/vector_3.gd +# Project: OpenMinerva +# Created Date: 15 July 2026 +# Copyright (c) 2026 OpenMinerva +# License: MIT License +# Authors: Armored Dragon +# --- License + +extends Control + +signal value_changed(new_value: Vector3) + +@export var property_name: String = "" +@export var value: Vector3 = Vector3(0, 0, 0) + +@onready var _label = get_node("VBoxContainer/Label") +@onready var _container: HBoxContainer = get_node("VBoxContainer/HBoxContainer") + +func _ready() -> void: + _label.text = property_name + + for child in _container.get_children(): + var _name = child.name + child.spinbox_value_changed.connect(func (new_value): _child_value_changed(_name, new_value)) + return + +func set_value(new_value: Vector3) -> void: + value = new_value + + for child in _container.get_children(): + var _node_name: String = child.name + _container.get_node(_node_name).value = value[_node_name.to_lower()] + return + +func set_label(new_label: String) -> void: + _label.text = new_label + property_name = new_label + return + +func _child_value_changed(type: String, new_value: float) -> void: + type = type.to_lower() + value[type] = new_value + value_changed.emit(value) + return diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/vector_3.gd.uid b/src/userinterface/client_edit_mode/node_property_editor/partials/vector_3.gd.uid new file mode 100644 index 0000000..9d2be77 --- /dev/null +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/vector_3.gd.uid @@ -0,0 +1 @@ +uid://fo05ubo6hera From d9b0445adaa203825d6b0b58e47bff3db09add4f Mon Sep 17 00:00:00 2001 From: Armored Dragon Date: Wed, 15 Jul 2026 11:33:00 -0500 Subject: [PATCH 02/13] Use rotation degrees. --- .../client_edit_mode/desktop/scripts/properties.gd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/userinterface/client_edit_mode/desktop/scripts/properties.gd b/src/userinterface/client_edit_mode/desktop/scripts/properties.gd index 3d9bc38..501e2be 100644 --- a/src/userinterface/client_edit_mode/desktop/scripts/properties.gd +++ b/src/userinterface/client_edit_mode/desktop/scripts/properties.gd @@ -19,7 +19,7 @@ var partials: Dictionary = {} func _ready() -> void: _dev_transform_container.get_node("Position").value_changed.connect(func (new_value): _property_changed("position", new_value)) - _dev_transform_container.get_node("Rotation").value_changed.connect(func (new_value): _property_changed("rotation", new_value)) + _dev_transform_container.get_node("Rotation").value_changed.connect(func (new_value): _property_changed("rotation_degrees", new_value)) _dev_transform_container.get_node("Scale").value_changed.connect(func (new_value): _property_changed("scale", new_value)) return @@ -64,7 +64,7 @@ func _clear_node_properties() -> void: func update_node_properties(node: Node) -> void: _dev_transform_container.get_node("Position").set_value(node.get("position")) - _dev_transform_container.get_node("Rotation").set_value(node.get("rotation")) + _dev_transform_container.get_node("Rotation").set_value(node.get("rotation_degrees")) _dev_transform_container.get_node("Scale").set_value(node.get("scale")) return From 5ef6ea57c8d1e8cc442c545add1ba6333ef3cb56 Mon Sep 17 00:00:00 2001 From: Armored Dragon Date: Wed, 15 Jul 2026 11:39:50 -0500 Subject: [PATCH 03/13] Added visibility toggle. --- .../client_edit_mode/desktop/scripts/properties.gd | 2 ++ .../client_edit_mode/node_property_editor/partials/bool.gd | 4 ++++ .../node_property_editor/partials/spin_box.gd | 6 +++--- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/userinterface/client_edit_mode/desktop/scripts/properties.gd b/src/userinterface/client_edit_mode/desktop/scripts/properties.gd index 501e2be..af096b1 100644 --- a/src/userinterface/client_edit_mode/desktop/scripts/properties.gd +++ b/src/userinterface/client_edit_mode/desktop/scripts/properties.gd @@ -18,6 +18,7 @@ var _node: Node var partials: Dictionary = {} func _ready() -> void: + _dev_property_container.get_node("Visible").value_changed.connect(func (new_value): _property_changed("visible", new_value)) _dev_transform_container.get_node("Position").value_changed.connect(func (new_value): _property_changed("position", new_value)) _dev_transform_container.get_node("Rotation").value_changed.connect(func (new_value): _property_changed("rotation_degrees", new_value)) _dev_transform_container.get_node("Scale").value_changed.connect(func (new_value): _property_changed("scale", new_value)) @@ -63,6 +64,7 @@ func _clear_node_properties() -> void: return func update_node_properties(node: Node) -> void: + _dev_property_container.get_node("Visible").set_value(node.get("visible")) _dev_transform_container.get_node("Position").set_value(node.get("position")) _dev_transform_container.get_node("Rotation").set_value(node.get("rotation_degrees")) _dev_transform_container.get_node("Scale").set_value(node.get("scale")) diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/bool.gd b/src/userinterface/client_edit_mode/node_property_editor/partials/bool.gd index 0f624ec..bcc9edf 100644 --- a/src/userinterface/client_edit_mode/node_property_editor/partials/bool.gd +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/bool.gd @@ -19,6 +19,7 @@ signal value_changed(new_value: bool) func _ready() -> void: _label.text = property_name + _bool.toggled.connect(_on_value_changed) return func set_value(new_value: bool) -> void: @@ -30,3 +31,6 @@ func set_label(new_label: String) -> void: _label.text = new_label property_name = new_label return + +func _on_value_changed(new_value: bool) -> void: + value_changed.emit(new_value) diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.gd b/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.gd index e42aa0c..e8fca43 100644 --- a/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.gd +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.gd @@ -13,9 +13,9 @@ signal spinbox_value_changed(value: float) @export var max_decimals: int = 4 func _ready() -> void: - value_changed.connect(_on_value_changed, CONNECT_DEFERRED) - get_line_edit().focus_entered.connect(_on_focus_entered, CONNECT_DEFERRED) - get_line_edit().focus_exited.connect(_on_focus_exited, CONNECT_DEFERRED) + value_changed.connect(_on_value_changed) + get_line_edit().focus_entered.connect(_on_focus_entered) + get_line_edit().focus_exited.connect(_on_focus_exited) get_line_edit().text = _format_value(value) return From f899e9ba1a79fae04e9ea66d794b7a4b7728f3c2 Mon Sep 17 00:00:00 2001 From: Armored Dragon Date: Wed, 15 Jul 2026 12:54:57 -0500 Subject: [PATCH 04/13] Initial sub-property support. --- .../client_edit_mode/desktop/inspector.tscn | 15 +++--- .../desktop/scripts/properties.gd | 53 +++++++++++++++---- .../node_property_editor/partials/Object.tscn | 34 ++---------- .../node_property_editor/partials/object.gd | 17 ++---- 4 files changed, 57 insertions(+), 62 deletions(-) diff --git a/src/userinterface/client_edit_mode/desktop/inspector.tscn b/src/userinterface/client_edit_mode/desktop/inspector.tscn index b486f33..878a949 100644 --- a/src/userinterface/client_edit_mode/desktop/inspector.tscn +++ b/src/userinterface/client_edit_mode/desktop/inspector.tscn @@ -18,6 +18,7 @@ [ext_resource type="PackedScene" uid="uid://chbjqqcikq7aj" path="res://userinterface/client_edit_mode/desktop/partial/popup_selection.tscn" id="14_cuj5f"] [ext_resource type="PackedScene" uid="uid://dkn0gmy8or4hq" path="res://userinterface/client_edit_mode/node_property_editor/partials/Vector3.tscn" id="14_q5c3n"] [ext_resource type="Texture2D" uid="uid://cq2ec6jy8kynp" path="res://resources/icons/godot/Add.svg" id="15_3i2mc"] +[ext_resource type="PackedScene" uid="uid://c7animyvghvk" path="res://userinterface/client_edit_mode/node_property_editor/partials/Object.tscn" id="16_73wcm"] [ext_resource type="PackedScene" uid="uid://sntuc3p6k4s6" path="res://userinterface/dash/partials/generic_button.tscn" id="16_j7nog"] [ext_resource type="Texture2D" uid="uid://b54viv8d54q83" path="res://resources/icons/godot/Remove.svg" id="17_akq5y"] [ext_resource type="Texture2D" uid="uid://dtwfvglraa8t7" path="res://resources/icons/godot/Edit.svg" id="18_akq5y"] @@ -329,25 +330,20 @@ layout_mode = 2 layout_mode = 2 property_name = "Visible" -[node name="FoldableContainer" type="FoldableContainer" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer" unique_id=81728243] +[node name="FoldableContainer" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer" unique_id=1542739099 instance=ExtResource("16_73wcm")] layout_mode = 2 -title = "Transform" -title_alignment = 1 -[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer" unique_id=216577687] -layout_mode = 2 - -[node name="Position" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer/VBoxContainer" unique_id=921313987 instance=ExtResource("14_q5c3n")] +[node name="Position" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer/VBoxContainer" parent_id_path=PackedInt32Array(1542739099, 238553897) index="0" unique_id=352534286 instance=ExtResource("14_q5c3n")] layout_mode = 2 size_flags_vertical = 1 property_name = "Position" -[node name="Rotation" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer/VBoxContainer" unique_id=1153106054 instance=ExtResource("14_q5c3n")] +[node name="Rotation" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer/VBoxContainer" parent_id_path=PackedInt32Array(1542739099, 238553897) index="1" unique_id=204239032 instance=ExtResource("14_q5c3n")] layout_mode = 2 size_flags_vertical = 1 property_name = "Rotation" -[node name="Scale" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer/VBoxContainer" unique_id=916704004 instance=ExtResource("14_q5c3n")] +[node name="Scale" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer/VBoxContainer" parent_id_path=PackedInt32Array(1542739099, 238553897) index="2" unique_id=172565004 instance=ExtResource("14_q5c3n")] layout_mode = 2 size_flags_vertical = 1 property_name = "Scale" @@ -393,4 +389,5 @@ window_name = "Add Node" [editable path="VBoxContainer/HBoxContainer/HSplitContainer/MarginContainer/VBoxContainer/Container/VBoxContainer/InputString"] [editable path="VBoxContainer/HBoxContainer/HSplitContainer/MarginContainer/VBoxContainer/Container/VBoxContainer/Filters/HBoxContainer/Light"] [editable path="VBoxContainer/HBoxContainer/HSplitContainer/MarginContainer/VBoxContainer/Container/VBoxContainer/Filters/HBoxContainer/Player"] +[editable path="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer"] [editable path="InspectorPopup"] diff --git a/src/userinterface/client_edit_mode/desktop/scripts/properties.gd b/src/userinterface/client_edit_mode/desktop/scripts/properties.gd index af096b1..d86bcae 100644 --- a/src/userinterface/client_edit_mode/desktop/scripts/properties.gd +++ b/src/userinterface/client_edit_mode/desktop/scripts/properties.gd @@ -10,8 +10,12 @@ extends MarginContainer const _dev_basic_props = ["position", "rotation", "scale", "visible"] const _dev_whitelist_properties = ["mesh"] +const _dev_whitelist_mesh_properties = ["material", "flip_faces", "add_uv2", "uv2_padding", "size", "subdivide_width", "subdivide_height", "subdivide_depth", ] + var _node: Node +# TODO: Add protections from making changes on null nodes (invalid nodes) + @onready var _dev_transform_container: Node = get_node("VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer/VBoxContainer") @onready var _dev_property_container: Node = get_node("VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer") @@ -35,25 +39,54 @@ func get_node_properties(node: Node) -> void: var _partial = _get_partial("%s" % type_string(prop.type)) if _partial == null: - print("Property: %s" % prop.name) - print("Type: %s" % type_string(prop.type)) - print("Class: %s" % prop.class_name) - print("Hint: %s" % prop.hint) - print("Hint String: %s" % prop.hint_string) - print("Value: %s" % node.get(prop.name)) - print("---") + # print("Property: %s" % prop.name) + # print("Type: %s" % type_string(prop.type)) + # print("Class: %s" % prop.class_name) + # print("Hint String: %s" % prop.hint_string) + # print("Value: %s" % node.get(prop.name)) + # print("---") continue _dev_property_container.add_child(_partial) + + if prop.class_name == "Mesh": + _get_object_properties(_partial.get_node("VBoxContainer"), node.get("mesh"), "mesh") + _partial.set_label(prop.name.capitalize()) - _partial.set_value(node.get(prop.name)) - _partial.value_changed.connect(func (new_value): _property_changed(prop.name, new_value)) + + # HACK: Filter out Objects since we are treating them like containers. + # Aren't Materials and shaders also treated as objects? + if type_string(prop.type) != "Object": + _partial.set_value(node.get(prop.name)) + _partial.value_changed.connect(func (new_value): _property_changed(prop.name, new_value)) # Display the values update_node_properties(node) return +func _get_object_properties(object_container: Node, obj: Object, property_name: String) -> void: + var _properties = obj.get_property_list() + for _prop in _properties: + var _partial = _get_partial("%s" % type_string(_prop.type)) + + if _dev_whitelist_mesh_properties.has(_prop.name) == false: + continue + + # HACK: Hardcoded avoidance of objects just for debug. + if type_string(_prop.type) == "Object": + continue + + if _partial == null: + continue + + object_container.add_child(_partial) + + _partial.set_label(_prop.name.capitalize()) + _partial.set_value(obj.get(_prop.name)) + _partial.value_changed.connect(func (new_value): _property_changed("%s:%s" % [property_name, _prop.name], new_value)) + return + func _clear_node_properties() -> void: var _child_number: int = 0 for child in _dev_property_container.get_children(): @@ -72,7 +105,7 @@ func update_node_properties(node: Node) -> void: func _property_changed(property_name: String, property_value: Variant) -> void: # TODO: Network change - _node.set(property_name, property_value) + _node.set_indexed(property_name, property_value) return diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/Object.tscn b/src/userinterface/client_edit_mode/node_property_editor/partials/Object.tscn index 9dd7dee..5d125ff 100644 --- a/src/userinterface/client_edit_mode/node_property_editor/partials/Object.tscn +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/Object.tscn @@ -1,35 +1,11 @@ -[gd_scene format=3 uid="uid://dr4mc2gw53nb6"] +[gd_scene format=3 uid="uid://c7animyvghvk"] -[ext_resource type="Theme" uid="uid://ckqsvvccivw0x" path="res://resources/themes/default.tres" id="1_dt7qw"] -[ext_resource type="PackedScene" uid="uid://sntuc3p6k4s6" path="res://userinterface/dash/partials/generic_button.tscn" id="2_dt7qw"] [ext_resource type="Script" uid="uid://s14au1dc165i" path="res://userinterface/client_edit_mode/node_property_editor/partials/object.gd" id="2_ijfgb"] -[node name="Object" type="Control" unique_id=933711176] -custom_minimum_size = Vector2(80, 30) -layout_mode = 3 -anchor_right = 1.0 -anchor_bottom = 0.027777778 -offset_bottom = -30.0 -grow_horizontal = 2 -size_flags_horizontal = 3 -theme = ExtResource("1_dt7qw") +[node name="FoldableContainer" type="FoldableContainer" unique_id=1542739099] +title = "Transform" +title_alignment = 1 script = ExtResource("2_ijfgb") -metadata/_edit_use_anchors_ = true -[node name="VBoxContainer" type="HBoxContainer" parent="." unique_id=1972995258] -layout_mode = 1 -anchors_preset = -1 -anchor_right = 1.0 -anchor_bottom = 0.053703703 -grow_horizontal = 2 -metadata/_edit_use_anchors_ = true - -[node name="Label" type="Label" parent="VBoxContainer" unique_id=482404396] -layout_mode = 2 -size_flags_horizontal = 3 -text = "Vector3" - -[node name="GenericButton" parent="VBoxContainer" unique_id=649942124 instance=ExtResource("2_dt7qw")] -custom_minimum_size = Vector2(0, 30) +[node name="VBoxContainer" type="VBoxContainer" parent="." unique_id=238553897] layout_mode = 2 -label = "Test" diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/object.gd b/src/userinterface/client_edit_mode/node_property_editor/partials/object.gd index 8aa828f..63398b5 100644 --- a/src/userinterface/client_edit_mode/node_property_editor/partials/object.gd +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/object.gd @@ -7,24 +7,13 @@ # Authors: Armored Dragon # --- License -extends Control +extends FoldableContainer -signal value_changed(new_value: Object) - -@export var property_name: String = "" -# @export var value: Object - -@onready var _label = get_node("VBoxContainer/Label") +# signal value_changed(new_value: Object) func _ready() -> void: - _label.text = property_name - return - -func set_value(new_value: Object) -> void: - # FIXME: Not sure what to do here. return func set_label(new_label: String) -> void: - _label.text = new_label - property_name = new_label + title = new_label return From 47b29a84dc3588e1c7c5668156c80f3418f374eb Mon Sep 17 00:00:00 2001 From: Armored Dragon Date: Thu, 16 Jul 2026 07:29:49 -0500 Subject: [PATCH 05/13] Rewrote node property reader. --- .../client_edit_mode/desktop/inspector.tscn | 12 ++- .../desktop/scripts/properties.gd | 87 ++++++++++--------- .../{Object.tscn => FoldableContainer.tscn} | 6 +- .../node_property_editor/partials/bool.tscn | 1 - .../{object.gd => foldable_container.gd} | 4 +- ...bject.gd.uid => foldable_container.gd.uid} | 0 6 files changed, 60 insertions(+), 50 deletions(-) rename src/userinterface/client_edit_mode/node_property_editor/partials/{Object.tscn => FoldableContainer.tscn} (66%) rename src/userinterface/client_edit_mode/node_property_editor/partials/{object.gd => foldable_container.gd} (83%) rename src/userinterface/client_edit_mode/node_property_editor/partials/{object.gd.uid => foldable_container.gd.uid} (100%) diff --git a/src/userinterface/client_edit_mode/desktop/inspector.tscn b/src/userinterface/client_edit_mode/desktop/inspector.tscn index 878a949..15df051 100644 --- a/src/userinterface/client_edit_mode/desktop/inspector.tscn +++ b/src/userinterface/client_edit_mode/desktop/inspector.tscn @@ -18,7 +18,7 @@ [ext_resource type="PackedScene" uid="uid://chbjqqcikq7aj" path="res://userinterface/client_edit_mode/desktop/partial/popup_selection.tscn" id="14_cuj5f"] [ext_resource type="PackedScene" uid="uid://dkn0gmy8or4hq" path="res://userinterface/client_edit_mode/node_property_editor/partials/Vector3.tscn" id="14_q5c3n"] [ext_resource type="Texture2D" uid="uid://cq2ec6jy8kynp" path="res://resources/icons/godot/Add.svg" id="15_3i2mc"] -[ext_resource type="PackedScene" uid="uid://c7animyvghvk" path="res://userinterface/client_edit_mode/node_property_editor/partials/Object.tscn" id="16_73wcm"] +[ext_resource type="PackedScene" uid="uid://c7animyvghvk" path="res://userinterface/client_edit_mode/node_property_editor/partials/FoldableContainer.tscn" id="16_73wcm"] [ext_resource type="PackedScene" uid="uid://sntuc3p6k4s6" path="res://userinterface/dash/partials/generic_button.tscn" id="16_j7nog"] [ext_resource type="Texture2D" uid="uid://b54viv8d54q83" path="res://resources/icons/godot/Remove.svg" id="17_akq5y"] [ext_resource type="Texture2D" uid="uid://dtwfvglraa8t7" path="res://resources/icons/godot/Edit.svg" id="18_akq5y"] @@ -332,18 +332,22 @@ property_name = "Visible" [node name="FoldableContainer" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer" unique_id=1542739099 instance=ExtResource("16_73wcm")] layout_mode = 2 +folded = false -[node name="Position" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer/VBoxContainer" parent_id_path=PackedInt32Array(1542739099, 238553897) index="0" unique_id=352534286 instance=ExtResource("14_q5c3n")] +[node name="VBoxContainer" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer" index="0" unique_id=238553897] +visible = true + +[node name="Position" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer/VBoxContainer" index="0" unique_id=352534286 instance=ExtResource("14_q5c3n")] layout_mode = 2 size_flags_vertical = 1 property_name = "Position" -[node name="Rotation" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer/VBoxContainer" parent_id_path=PackedInt32Array(1542739099, 238553897) index="1" unique_id=204239032 instance=ExtResource("14_q5c3n")] +[node name="Rotation" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer/VBoxContainer" index="1" unique_id=204239032 instance=ExtResource("14_q5c3n")] layout_mode = 2 size_flags_vertical = 1 property_name = "Rotation" -[node name="Scale" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer/VBoxContainer" parent_id_path=PackedInt32Array(1542739099, 238553897) index="2" unique_id=172565004 instance=ExtResource("14_q5c3n")] +[node name="Scale" parent="VBoxContainer/HBoxContainer/HSplitContainer/Properties/VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer/VBoxContainer" index="2" unique_id=172565004 instance=ExtResource("14_q5c3n")] layout_mode = 2 size_flags_vertical = 1 property_name = "Scale" diff --git a/src/userinterface/client_edit_mode/desktop/scripts/properties.gd b/src/userinterface/client_edit_mode/desktop/scripts/properties.gd index d86bcae..aed3aef 100644 --- a/src/userinterface/client_edit_mode/desktop/scripts/properties.gd +++ b/src/userinterface/client_edit_mode/desktop/scripts/properties.gd @@ -29,63 +29,68 @@ func _ready() -> void: return func get_node_properties(node: Node) -> void: - _node = node _clear_node_properties() - var properties = node.get_property_list() - - for prop in properties: - if _dev_whitelist_properties.has(prop.name) == false: - continue - - var _partial = _get_partial("%s" % type_string(prop.type)) - if _partial == null: - # print("Property: %s" % prop.name) - # print("Type: %s" % type_string(prop.type)) - # print("Class: %s" % prop.class_name) - # print("Hint String: %s" % prop.hint_string) - # print("Value: %s" % node.get(prop.name)) - # print("---") - continue + _node = node + var _property_tree: Dictionary = _get_property_tree(node) - _dev_property_container.add_child(_partial) + var _property_categories: Array = _property_tree.keys() + _property_categories.reverse() - if prop.class_name == "Mesh": - _get_object_properties(_partial.get_node("VBoxContainer"), node.get("mesh"), "mesh") + for _category in _property_categories: + # Create the container node. + var _category_node = _get_partial("FoldableContainer") + _dev_property_container.add_child(_category_node) + _category_node.set_label(_category) - _partial.set_label(prop.name.capitalize()) + # Add all of the sub properties. + for _prop in _property_tree[_category]: + var _sub_property = _get_partial("%s" % type_string(_prop.type)) - # HACK: Filter out Objects since we are treating them like containers. - # Aren't Materials and shaders also treated as objects? - if type_string(prop.type) != "Object": - _partial.set_value(node.get(prop.name)) - _partial.value_changed.connect(func (new_value): _property_changed(prop.name, new_value)) + if _sub_property == null: + continue + _category_node.add_child(_sub_property) + _sub_property.set_value(node.get(_prop.name)) + _sub_property.set_label(_prop.name.capitalize()) + _sub_property.value_changed.connect(func (new_value): _property_changed(_prop.name, new_value)) + break - # Display the values update_node_properties(node) return -func _get_object_properties(object_container: Node, obj: Object, property_name: String) -> void: - var _properties = obj.get_property_list() - for _prop in _properties: - var _partial = _get_partial("%s" % type_string(_prop.type)) +func _get_property_tree(node: Node) -> Dictionary: + var tree := {} + var current_category := "" + var group := "" + var sub_group := "" + + for _property in node.get_property_list(): + var _usage: int = _property["usage"] + var _p_name: String = _property["name"] - if _dev_whitelist_mesh_properties.has(_prop.name) == false: + if _p_name.begins_with("metadata/"): + # Metadata is ignored. continue - # HACK: Hardcoded avoidance of objects just for debug. - if type_string(_prop.type) == "Object": + if _dev_basic_props.has(_p_name): + # These properties are handled at the top of the NPE. continue - if _partial == null: + if _usage & PROPERTY_USAGE_CATEGORY: + # If this property is a category. + current_category = _p_name + tree[current_category] = [] continue - object_container.add_child(_partial) + if _usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP): + # Ignore groups and subgroups. + continue - _partial.set_label(_prop.name.capitalize()) - _partial.set_value(obj.get(_prop.name)) - _partial.value_changed.connect(func (new_value): _property_changed("%s:%s" % [property_name, _prop.name], new_value)) - return + if _usage & PROPERTY_USAGE_EDITOR && !current_category.is_empty(): + + tree[current_category].append(_property) + + return tree func _clear_node_properties() -> void: var _child_number: int = 0 @@ -105,10 +110,12 @@ func update_node_properties(node: Node) -> void: func _property_changed(property_name: String, property_value: Variant) -> void: # TODO: Network change + if _node == null: + return + _node.set_indexed(property_name, property_value) return - func _get_partial(type: String) -> Node: if partials.keys().has(type): return partials[type].instantiate() diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/Object.tscn b/src/userinterface/client_edit_mode/node_property_editor/partials/FoldableContainer.tscn similarity index 66% rename from src/userinterface/client_edit_mode/node_property_editor/partials/Object.tscn rename to src/userinterface/client_edit_mode/node_property_editor/partials/FoldableContainer.tscn index 5d125ff..56d9f74 100644 --- a/src/userinterface/client_edit_mode/node_property_editor/partials/Object.tscn +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/FoldableContainer.tscn @@ -1,11 +1,13 @@ [gd_scene format=3 uid="uid://c7animyvghvk"] -[ext_resource type="Script" uid="uid://s14au1dc165i" path="res://userinterface/client_edit_mode/node_property_editor/partials/object.gd" id="2_ijfgb"] +[ext_resource type="Script" uid="uid://s14au1dc165i" path="res://userinterface/client_edit_mode/node_property_editor/partials/foldable_container.gd" id="1_wndr3"] [node name="FoldableContainer" type="FoldableContainer" unique_id=1542739099] +folded = true title = "Transform" title_alignment = 1 -script = ExtResource("2_ijfgb") +script = ExtResource("1_wndr3") [node name="VBoxContainer" type="VBoxContainer" parent="." unique_id=238553897] +visible = false layout_mode = 2 diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/bool.tscn b/src/userinterface/client_edit_mode/node_property_editor/partials/bool.tscn index 89fad1f..ab5e358 100644 --- a/src/userinterface/client_edit_mode/node_property_editor/partials/bool.tscn +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/bool.tscn @@ -34,7 +34,6 @@ custom_maximum_size = Vector2(120, 30) layout_mode = 2 mouse_default_cursor_shape = 2 theme = ExtResource("1_h5new") -button_pressed = true flat = true alignment = 1 clip_text = true diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/object.gd b/src/userinterface/client_edit_mode/node_property_editor/partials/foldable_container.gd similarity index 83% rename from src/userinterface/client_edit_mode/node_property_editor/partials/object.gd rename to src/userinterface/client_edit_mode/node_property_editor/partials/foldable_container.gd index 63398b5..d5d0942 100644 --- a/src/userinterface/client_edit_mode/node_property_editor/partials/object.gd +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/foldable_container.gd @@ -1,5 +1,5 @@ # --- License -# File: /client/src/userinterface/client_edit_mode/node_property_editor/partials/object.gd +# File: /client/src/userinterface/client_edit_mode/node_property_editor/partials/foldable_container.gd # Project: OpenMinerva # Created Date: 15 July 2026 # Copyright (c) 2026 OpenMinerva @@ -9,8 +9,6 @@ extends FoldableContainer -# signal value_changed(new_value: Object) - func _ready() -> void: return diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/object.gd.uid b/src/userinterface/client_edit_mode/node_property_editor/partials/foldable_container.gd.uid similarity index 100% rename from src/userinterface/client_edit_mode/node_property_editor/partials/object.gd.uid rename to src/userinterface/client_edit_mode/node_property_editor/partials/foldable_container.gd.uid From 23ae1b77321e1e8b11193e087cd1f81423e3af3a Mon Sep 17 00:00:00 2001 From: Armored Dragon Date: Thu, 16 Jul 2026 08:19:42 -0500 Subject: [PATCH 06/13] Fixed early exist bug in for loop. Added float and int value fields. --- .../desktop/scripts/properties.gd | 7 ++-- .../node_property_editor/partials/bool.tscn | 1 - .../node_property_editor/partials/float.tscn | 33 +++++++++++++++++ .../node_property_editor/partials/int.gd | 36 +++++++++++++++++++ .../node_property_editor/partials/int.gd.uid | 1 + .../node_property_editor/partials/int.tscn | 35 ++++++++++++++++++ .../node_property_editor/partials/spin_box.gd | 5 +++ .../partials/spin_box.tscn | 1 + 8 files changed, 115 insertions(+), 4 deletions(-) create mode 100644 src/userinterface/client_edit_mode/node_property_editor/partials/float.tscn create mode 100644 src/userinterface/client_edit_mode/node_property_editor/partials/int.gd create mode 100644 src/userinterface/client_edit_mode/node_property_editor/partials/int.gd.uid create mode 100644 src/userinterface/client_edit_mode/node_property_editor/partials/int.tscn diff --git a/src/userinterface/client_edit_mode/desktop/scripts/properties.gd b/src/userinterface/client_edit_mode/desktop/scripts/properties.gd index aed3aef..cb57045 100644 --- a/src/userinterface/client_edit_mode/desktop/scripts/properties.gd +++ b/src/userinterface/client_edit_mode/desktop/scripts/properties.gd @@ -15,6 +15,7 @@ const _dev_whitelist_mesh_properties = ["material", "flip_faces", "add_uv2", "uv var _node: Node # TODO: Add protections from making changes on null nodes (invalid nodes) +# TODO: Handle enums for ints. @onready var _dev_transform_container: Node = get_node("VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer/VBoxContainer") @onready var _dev_property_container: Node = get_node("VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer") @@ -49,11 +50,11 @@ func get_node_properties(node: Node) -> void: if _sub_property == null: continue - _category_node.add_child(_sub_property) + _category_node.get_node("VBoxContainer").add_child(_sub_property) _sub_property.set_value(node.get(_prop.name)) _sub_property.set_label(_prop.name.capitalize()) _sub_property.value_changed.connect(func (new_value): _property_changed(_prop.name, new_value)) - break + continue update_node_properties(node) return @@ -83,11 +84,11 @@ func _get_property_tree(node: Node) -> Dictionary: continue if _usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP): + # TODO: Subgroups? # Ignore groups and subgroups. continue if _usage & PROPERTY_USAGE_EDITOR && !current_category.is_empty(): - tree[current_category].append(_property) return tree diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/bool.tscn b/src/userinterface/client_edit_mode/node_property_editor/partials/bool.tscn index ab5e358..059ac0f 100644 --- a/src/userinterface/client_edit_mode/node_property_editor/partials/bool.tscn +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/bool.tscn @@ -8,7 +8,6 @@ custom_minimum_size = Vector2(80, 30) layout_mode = 3 anchor_right = 1.0 anchor_bottom = 0.027777778 -offset_bottom = -30.0 grow_horizontal = 2 size_flags_horizontal = 3 theme = ExtResource("1_h5new") diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/float.tscn b/src/userinterface/client_edit_mode/node_property_editor/partials/float.tscn new file mode 100644 index 0000000..c3b5798 --- /dev/null +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/float.tscn @@ -0,0 +1,33 @@ +[gd_scene format=3 uid="uid://b1u12udwoner2"] + +[ext_resource type="Theme" uid="uid://ckqsvvccivw0x" path="res://resources/themes/default.tres" id="1_2mmn2"] +[ext_resource type="Script" uid="uid://066ucgk4rilk" path="res://userinterface/client_edit_mode/node_property_editor/partials/int.gd" id="2_c1vag"] +[ext_resource type="PackedScene" uid="uid://b58b25jtckb2c" path="res://userinterface/client_edit_mode/node_property_editor/partials/spin_box.tscn" id="3_j4p26"] + +[node name="float" type="Control" unique_id=933711176] +custom_minimum_size = Vector2(80, 30) +layout_mode = 3 +anchor_right = 1.0 +anchor_bottom = 0.027777778 +offset_bottom = -30.0 +grow_horizontal = 2 +size_flags_horizontal = 3 +theme = ExtResource("1_2mmn2") +script = ExtResource("2_c1vag") +metadata/_edit_use_anchors_ = true + +[node name="VBoxContainer" type="HBoxContainer" parent="." unique_id=1972995258] +layout_mode = 1 +anchors_preset = -1 +anchor_right = 1.0 +anchor_bottom = 0.053703703 +grow_horizontal = 2 +metadata/_edit_use_anchors_ = true + +[node name="Label" type="Label" parent="VBoxContainer" unique_id=482404396] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Vector3" + +[node name="SpinBox" parent="VBoxContainer" unique_id=1631362233 instance=ExtResource("3_j4p26")] +layout_mode = 2 diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/int.gd b/src/userinterface/client_edit_mode/node_property_editor/partials/int.gd new file mode 100644 index 0000000..416604c --- /dev/null +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/int.gd @@ -0,0 +1,36 @@ +# --- License +# File: /client/src/userinterface/client_edit_mode/node_property_editor/partials/int.gd +# Project: OpenMinerva +# Created Date: 16 July 2026 +# Copyright (c) 2026 OpenMinerva +# License: MIT License +# Authors: Armored Dragon +# --- License + +extends Control + +signal value_changed(new_value: bool) + +@export var property_name: String = "" +@export var value: int + +@onready var _label = get_node("VBoxContainer/Label") +@onready var _spinbox = get_node("VBoxContainer/SpinBox") + +func _ready() -> void: + _label.text = property_name + _spinbox.spinbox_value_changed.connect(_on_value_changed) + return + +func set_value(new_value: int) -> void: + value = new_value + _spinbox.set_value(new_value) + return + +func set_label(new_label: String) -> void: + _label.text = new_label + property_name = new_label + return + +func _on_value_changed(new_value: int) -> void: + value_changed.emit(new_value) diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/int.gd.uid b/src/userinterface/client_edit_mode/node_property_editor/partials/int.gd.uid new file mode 100644 index 0000000..97ee63a --- /dev/null +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/int.gd.uid @@ -0,0 +1 @@ +uid://066ucgk4rilk diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/int.tscn b/src/userinterface/client_edit_mode/node_property_editor/partials/int.tscn new file mode 100644 index 0000000..308dc56 --- /dev/null +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/int.tscn @@ -0,0 +1,35 @@ +[gd_scene format=3 uid="uid://c08ywv1r18wq4"] + +[ext_resource type="Theme" uid="uid://ckqsvvccivw0x" path="res://resources/themes/default.tres" id="1_ecork"] +[ext_resource type="Script" uid="uid://066ucgk4rilk" path="res://userinterface/client_edit_mode/node_property_editor/partials/int.gd" id="2_7lgys"] +[ext_resource type="PackedScene" uid="uid://b58b25jtckb2c" path="res://userinterface/client_edit_mode/node_property_editor/partials/spin_box.tscn" id="3_fivcc"] + +[node name="int" type="Control" unique_id=933711176] +custom_minimum_size = Vector2(80, 30) +layout_mode = 3 +anchor_right = 1.0 +anchor_bottom = 0.027777778 +offset_bottom = -30.0 +grow_horizontal = 2 +size_flags_horizontal = 3 +theme = ExtResource("1_ecork") +script = ExtResource("2_7lgys") +metadata/_edit_use_anchors_ = true + +[node name="VBoxContainer" type="HBoxContainer" parent="." unique_id=1972995258] +layout_mode = 1 +anchors_preset = -1 +anchor_right = 1.0 +anchor_bottom = 0.053703703 +grow_horizontal = 2 +metadata/_edit_use_anchors_ = true + +[node name="Label" type="Label" parent="VBoxContainer" unique_id=482404396] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Vector3" + +[node name="SpinBox" parent="VBoxContainer" unique_id=1631362233 instance=ExtResource("3_fivcc")] +layout_mode = 2 +max_decimals = 0 +is_int = true diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.gd b/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.gd index e8fca43..ec7c644 100644 --- a/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.gd +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.gd @@ -11,8 +11,13 @@ extends SpinBox signal spinbox_value_changed(value: float) @export var max_decimals: int = 4 +@export var is_int: bool = false func _ready() -> void: + if is_int == true: + max_decimals = 0 + step = 1 + value_changed.connect(_on_value_changed) get_line_edit().focus_entered.connect(_on_focus_entered) get_line_edit().focus_exited.connect(_on_focus_exited) diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.tscn b/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.tscn index 0bd5cfc..cad0b57 100644 --- a/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.tscn +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.tscn @@ -9,6 +9,7 @@ anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 size_flags_horizontal = 3 +focus_behavior_recursive = 2 min_value = inf_neg max_value = inf step = 0.001 From 14af9ebb5637804d2d3bc2191c38bbfb1e045dfb Mon Sep 17 00:00:00 2001 From: Armored Dragon Date: Thu, 16 Jul 2026 17:51:36 -0500 Subject: [PATCH 07/13] Network property change. --- src/scenes/levels/grid.tscn | 7 ++++--- .../managers/scene/spawnable_manager.gd | 20 +++++++++++++++++-- .../desktop/scripts/properties.gd | 12 ++++++++++- .../node_property_editor/partials/float.tscn | 4 +++- .../node_property_editor/partials/int.tscn | 4 +++- .../partials/spin_box.tscn | 1 + 6 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/scenes/levels/grid.tscn b/src/scenes/levels/grid.tscn index 333f488..5d34794 100644 --- a/src/scenes/levels/grid.tscn +++ b/src/scenes/levels/grid.tscn @@ -45,10 +45,11 @@ metadata/scene_node = true environment = SubResource("Environment_q28r8") metadata/scene_node = true -[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=1644270184] +[node name="Ground" type="MeshInstance3D" parent="." unique_id=1644270184] mesh = SubResource("QuadMesh_8gpll") +metadata/scene_node = true -[node name="StaticBody3D" type="StaticBody3D" parent="MeshInstance3D" unique_id=1945745055] +[node name="StaticBody3D" type="StaticBody3D" parent="Ground" unique_id=1945745055] -[node name="CollisionShape3D" type="CollisionShape3D" parent="MeshInstance3D/StaticBody3D" unique_id=1464818279] +[node name="CollisionShape3D" type="CollisionShape3D" parent="Ground/StaticBody3D" unique_id=1464818279] shape = SubResource("BoxShape3D_8gpll") diff --git a/src/scenes/managers/scene/spawnable_manager.gd b/src/scenes/managers/scene/spawnable_manager.gd index c1a7964..a6ae3ff 100644 --- a/src/scenes/managers/scene/spawnable_manager.gd +++ b/src/scenes/managers/scene/spawnable_manager.gd @@ -88,7 +88,6 @@ func create(node_type: String, node_parent: int = 0, model_path: String = "") -> var database_index: int = _database.find_custom(func(entry): return entry.id == entity) return _database[database_index].node - @rpc("any_peer", "reliable") func destroy(node_id: int) -> Variant: var my_id: int = app_network_m._database.sessions_api[app_scene_m.active_session].get_unique_id() @@ -109,7 +108,6 @@ func destroy(node_id: int) -> Variant: await rpcawaiter.send_rpc(1, destroy.bind(node_id)) return - @rpc("any_peer", "reliable") func set_transform(node_id: int, transform: Transform3D) -> void: var _my_id: int = app_network_m._database.sessions_api[app_scene_m.active_session].get_unique_id() @@ -123,6 +121,17 @@ func set_transform(node_id: int, transform: Transform3D) -> void: return return +@rpc("any_peer", "reliable") +func set_property(node_id: int, property_name: String, property_value: Variant) -> void: + var _my_id: int = app_network_m._database.sessions_api[app_scene_m.active_session].get_unique_id() + var _caller_id: int = multiplayer.get_remote_sender_id() + + if _my_id == 1: + set_property_on_spawnable.rpc(node_id, property_name, property_value) + else: + await rpcawaiter.set_property(1, set_property_on_spawnable.bind(node_id, property_name, property_value)) + return + return # TODO: How would large assets work? @rpc("authority", "reliable") @@ -165,6 +174,13 @@ func transform_spawnable(node_id: int, transform: Transform3D) -> void: _entity_db.node.transform = transform return +@rpc("call_local", "authority", "reliable") +func set_property_on_spawnable(node_id: int, property_name: String, property_value: Variant): + var _entity_db = get_by_id(node_id) + + _entity_db.node.set_indexed(property_name, property_value) + return + func _get_deletion_queue(node_name: String) -> Array: var _entry_index = _database.find_custom(func(item): return item.id == int(node_name)) var _node = _database[_entry_index].node diff --git a/src/userinterface/client_edit_mode/desktop/scripts/properties.gd b/src/userinterface/client_edit_mode/desktop/scripts/properties.gd index cb57045..18f6759 100644 --- a/src/userinterface/client_edit_mode/desktop/scripts/properties.gd +++ b/src/userinterface/client_edit_mode/desktop/scripts/properties.gd @@ -20,6 +20,10 @@ var _node: Node @onready var _dev_transform_container: Node = get_node("VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer/FoldableContainer/VBoxContainer") @onready var _dev_property_container: Node = get_node("VBoxContainer/Container/ScrollContainer/MarginContainer/VBoxContainer") +@onready var app_scene_m: Node = get_tree().current_scene.get_node("SceneManager") + +var session_spawnable_m: Node + var partials: Dictionary = {} func _ready() -> void: @@ -27,6 +31,8 @@ func _ready() -> void: _dev_transform_container.get_node("Position").value_changed.connect(func (new_value): _property_changed("position", new_value)) _dev_transform_container.get_node("Rotation").value_changed.connect(func (new_value): _property_changed("rotation_degrees", new_value)) _dev_transform_container.get_node("Scale").value_changed.connect(func (new_value): _property_changed("scale", new_value)) + + Events.dash_session_changed.connect(_on_session_changed) return func get_node_properties(node: Node) -> void: @@ -114,7 +120,7 @@ func _property_changed(property_name: String, property_value: Variant) -> void: if _node == null: return - _node.set_indexed(property_name, property_value) + session_spawnable_m.set_property(int(_node.name), property_name, property_value) return func _get_partial(type: String) -> Node: @@ -128,3 +134,7 @@ func _get_partial(type: String) -> Node: partials[type] = _new_partial return partials[type].instantiate() + +func _on_session_changed() -> void: + session_spawnable_m = app_scene_m.get_master_scene(app_scene_m.active_session).get_node("SpawnableManager") + return diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/float.tscn b/src/userinterface/client_edit_mode/node_property_editor/partials/float.tscn index c3b5798..028be55 100644 --- a/src/userinterface/client_edit_mode/node_property_editor/partials/float.tscn +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/float.tscn @@ -27,7 +27,9 @@ metadata/_edit_use_anchors_ = true [node name="Label" type="Label" parent="VBoxContainer" unique_id=482404396] layout_mode = 2 size_flags_horizontal = 3 -text = "Vector3" +text = "Float" +clip_text = true +text_overrun_behavior = 3 [node name="SpinBox" parent="VBoxContainer" unique_id=1631362233 instance=ExtResource("3_j4p26")] layout_mode = 2 diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/int.tscn b/src/userinterface/client_edit_mode/node_property_editor/partials/int.tscn index 308dc56..a2e10d1 100644 --- a/src/userinterface/client_edit_mode/node_property_editor/partials/int.tscn +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/int.tscn @@ -27,7 +27,9 @@ metadata/_edit_use_anchors_ = true [node name="Label" type="Label" parent="VBoxContainer" unique_id=482404396] layout_mode = 2 size_flags_horizontal = 3 -text = "Vector3" +text = "Int" +clip_text = true +text_overrun_behavior = 3 [node name="SpinBox" parent="VBoxContainer" unique_id=1631362233 instance=ExtResource("3_fivcc")] layout_mode = 2 diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.tscn b/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.tscn index cad0b57..662060f 100644 --- a/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.tscn +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/spin_box.tscn @@ -14,4 +14,5 @@ min_value = inf_neg max_value = inf step = 0.001 alignment = 1 +select_all_on_focus = true script = ExtResource("1_30qog") From 813fac0cdc2b6f1360b54db61c8ed6593e1dcc22 Mon Sep 17 00:00:00 2001 From: Armored Dragon Date: Thu, 16 Jul 2026 18:12:42 -0500 Subject: [PATCH 08/13] Fix function name mixup. Whoopsie. --- src/scenes/managers/scene/spawnable_manager.gd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scenes/managers/scene/spawnable_manager.gd b/src/scenes/managers/scene/spawnable_manager.gd index a6ae3ff..a87da0c 100644 --- a/src/scenes/managers/scene/spawnable_manager.gd +++ b/src/scenes/managers/scene/spawnable_manager.gd @@ -129,7 +129,7 @@ func set_property(node_id: int, property_name: String, property_value: Variant) if _my_id == 1: set_property_on_spawnable.rpc(node_id, property_name, property_value) else: - await rpcawaiter.set_property(1, set_property_on_spawnable.bind(node_id, property_name, property_value)) + await rpcawaiter.send_rpc(1, set_property.bind(node_id, property_name, property_value)) return return From 51f5f4259f56499bc24d81cf81e75fc2a4b2f945 Mon Sep 17 00:00:00 2001 From: Armored Dragon Date: Fri, 17 Jul 2026 10:17:29 -0500 Subject: [PATCH 09/13] Color picker. Abstracted moveable_window.gd for future windows. --- .../client_edit_mode/desktop/inspector.tscn | 5 -- .../desktop/partial/add_node_window.tscn | 1 + .../desktop/partial/movable_window.tscn | 75 +++++++++++++++++++ .../desktop/scripts/add_node_window.gd | 12 +-- .../desktop/scripts/moveable_window.gd | 66 ++++++++++++++++ .../desktop/scripts/moveable_window.gd.uid | 1 + .../node_property_editor/partials/Color.tscn | 32 ++++++++ .../node_property_editor/partials/color.gd | 36 +++++++++ .../partials/color.gd.uid | 1 + 9 files changed, 213 insertions(+), 16 deletions(-) create mode 100644 src/userinterface/client_edit_mode/desktop/partial/movable_window.tscn create mode 100644 src/userinterface/client_edit_mode/desktop/scripts/moveable_window.gd create mode 100644 src/userinterface/client_edit_mode/desktop/scripts/moveable_window.gd.uid create mode 100644 src/userinterface/client_edit_mode/node_property_editor/partials/Color.tscn create mode 100644 src/userinterface/client_edit_mode/node_property_editor/partials/color.gd create mode 100644 src/userinterface/client_edit_mode/node_property_editor/partials/color.gd.uid diff --git a/src/userinterface/client_edit_mode/desktop/inspector.tscn b/src/userinterface/client_edit_mode/desktop/inspector.tscn index 15df051..5fa61a2 100644 --- a/src/userinterface/client_edit_mode/desktop/inspector.tscn +++ b/src/userinterface/client_edit_mode/desktop/inspector.tscn @@ -384,11 +384,6 @@ icon = ExtResource("18_akq5y") [node name="AddNodeWindow" parent="." unique_id=524781090 instance=ExtResource("21_q5c3n")] visible = false layout_mode = 1 -offset_left = 50.0 -offset_top = 50.0 -offset_right = -1570.0 -offset_bottom = -630.0 -window_name = "Add Node" [editable path="VBoxContainer/HBoxContainer/HSplitContainer/MarginContainer/VBoxContainer/Container/VBoxContainer/InputString"] [editable path="VBoxContainer/HBoxContainer/HSplitContainer/MarginContainer/VBoxContainer/Container/VBoxContainer/Filters/HBoxContainer/Light"] diff --git a/src/userinterface/client_edit_mode/desktop/partial/add_node_window.tscn b/src/userinterface/client_edit_mode/desktop/partial/add_node_window.tscn index 091d1bb..30ac969 100644 --- a/src/userinterface/client_edit_mode/desktop/partial/add_node_window.tscn +++ b/src/userinterface/client_edit_mode/desktop/partial/add_node_window.tscn @@ -28,6 +28,7 @@ grow_vertical = 2 size_flags_horizontal = 4 size_flags_vertical = 4 script = ExtResource("1_u7aab") +window_name = null [node name="BackgroundColor" type="Panel" parent="." unique_id=889545988] material = SubResource("ShaderMaterial_j380t") diff --git a/src/userinterface/client_edit_mode/desktop/partial/movable_window.tscn b/src/userinterface/client_edit_mode/desktop/partial/movable_window.tscn new file mode 100644 index 0000000..70f00f7 --- /dev/null +++ b/src/userinterface/client_edit_mode/desktop/partial/movable_window.tscn @@ -0,0 +1,75 @@ +[gd_scene format=3 uid="uid://b6qb2oq26yooy"] + +[ext_resource type="Script" uid="uid://bapubedba8eiu" path="res://userinterface/client_edit_mode/desktop/scripts/moveable_window.gd" id="1_le5nq"] +[ext_resource type="Shader" uid="uid://bwr4b0mhgi4w6" path="res://userinterface/dash/shaders/blur.gdshader" id="2_4cmho"] +[ext_resource type="Theme" uid="uid://ckqsvvccivw0x" path="res://resources/themes/default.tres" id="3_ddx82"] +[ext_resource type="PackedScene" uid="uid://sntuc3p6k4s6" path="res://userinterface/dash/partials/generic_button.tscn" id="4_l1byb"] +[ext_resource type="Texture2D" uid="uid://bmjw8t1c6bi75" path="res://resources/icons/godot/Close.svg" id="5_752f5"] + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_j380t"] +shader = ExtResource("2_4cmho") +shader_parameter/color = Color(0.2, 0.2, 0.2, 1) +shader_parameter/blur_amount = 3.0000001392401203 +shader_parameter/roughness = 0.2 +shader_parameter/roughness_affect = 0.0 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_u7aab"] +bg_color = Color(0.078431375, 0.078431375, 0.078431375, 0.78431374) + +[node name="MoveableWindow" type="Control" unique_id=524781090] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_right = -1620.0 +offset_bottom = -680.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 4 +size_flags_vertical = 4 +script = ExtResource("1_le5nq") + +[node name="BackgroundColor" type="Panel" parent="." unique_id=889545988] +material = SubResource("ShaderMaterial_j380t") +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 1 +theme = ExtResource("3_ddx82") +theme_override_styles/panel = SubResource("StyleBoxFlat_u7aab") + +[node name="MarginContainer" type="MarginContainer" parent="BackgroundColor" unique_id=802103033] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/margin_left = 5 +theme_override_constants/margin_top = 5 +theme_override_constants/margin_right = 5 +theme_override_constants/margin_bottom = 5 + +[node name="VBoxContainer" type="VBoxContainer" parent="BackgroundColor/MarginContainer" unique_id=969090938] +layout_mode = 2 + +[node name="HBoxContainer" type="HBoxContainer" parent="BackgroundColor/MarginContainer/VBoxContainer" unique_id=1407239756] +layout_mode = 2 + +[node name="Label" type="Label" parent="BackgroundColor/MarginContainer/VBoxContainer/HBoxContainer" unique_id=665280700] +layout_mode = 2 +size_flags_horizontal = 3 +theme_override_font_sizes/font_size = 16 +text = "Window Name" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="GenericButton" parent="BackgroundColor/MarginContainer/VBoxContainer/HBoxContainer" unique_id=649942124 instance=ExtResource("4_l1byb")] +custom_minimum_size = Vector2(30, 30) +layout_mode = 2 +size_flags_horizontal = 1 +icon = ExtResource("5_752f5") +only_icon = true diff --git a/src/userinterface/client_edit_mode/desktop/scripts/add_node_window.gd b/src/userinterface/client_edit_mode/desktop/scripts/add_node_window.gd index 4a94fdd..ae217a8 100644 --- a/src/userinterface/client_edit_mode/desktop/scripts/add_node_window.gd +++ b/src/userinterface/client_edit_mode/desktop/scripts/add_node_window.gd @@ -6,21 +6,11 @@ # License: MIT License # Authors: Armored Dragon # --- License -extends Control - -signal selection(type: String, parent: int) - -@export var window_name: String = "Window Name" +extends "moveable_window.gd" @onready var _list_container = get_node("BackgroundColor/MarginContainer/VBoxContainer/ScrollContainer/VBoxContainer") -@onready var _button_close = get_node("BackgroundColor/MarginContainer/VBoxContainer/HBoxContainer/GenericButton") -@onready var _node_window_title = get_node("BackgroundColor/MarginContainer/VBoxContainer/HBoxContainer/Label") - @onready var _button_template = preload("res://userinterface/dash/partials/generic_button.tscn") -var _is_dragging: bool = false -var _drag_offset: Vector2 - var parent_node_id: int = 0 func _ready() -> void: diff --git a/src/userinterface/client_edit_mode/desktop/scripts/moveable_window.gd b/src/userinterface/client_edit_mode/desktop/scripts/moveable_window.gd new file mode 100644 index 0000000..8267f0c --- /dev/null +++ b/src/userinterface/client_edit_mode/desktop/scripts/moveable_window.gd @@ -0,0 +1,66 @@ +# --- License +# File: /client/src/userinterface/client_edit_mode/desktop/scripts/moveable_window.gd +# Project: OpenMinerva +# Created Date: 17 July 2026 +# Copyright (c) 2026 OpenMinerva +# License: MIT License +# Authors: Armored Dragon +# --- License +extends Control + +signal selection(type: String, parent: int) + +@export var window_name: String = "Window Name" + +@onready var _button_close = get_node("BackgroundColor/MarginContainer/VBoxContainer/HBoxContainer/GenericButton") +@onready var _node_window_title = get_node("BackgroundColor/MarginContainer/VBoxContainer/HBoxContainer/Label") + +var _is_dragging: bool = false +var _drag_offset: Vector2 + +func _ready() -> void: + _node_window_title.text = window_name + _button_close.clicked.connect(_close) + + gui_input.connect(_on_input) + gui_input.connect(_on_input) + return + +func _close() -> void: + visible = false + return + +func _on_input(event) -> void: + if event is InputEventMouseButton: + _mouse_click(event) + return + + if event is InputEventMouseMotion: + _mouse_drag(event) + return + + return + +func _mouse_drag(_event) -> void: + if _is_dragging: + var _game_size: Vector2 = DisplayServer.window_get_size() + var _target_position = get_global_mouse_position() - _drag_offset + var _is_out_of_bounds = _target_position.x < 0 || _target_position.y < 0 || _target_position.x >= _game_size.x - size.x || _target_position.y >= _game_size.y - size.y + + if _is_out_of_bounds == false: + global_position = _target_position + return + +func _mouse_click(event) -> void: + if event.button_index != MOUSE_BUTTON_LEFT: + return + + if event.pressed: + _is_dragging = true + _drag_offset = get_global_mouse_position() - global_position + else: + _is_dragging = false + return + +func _on_item_activated(index: int) -> void: + return diff --git a/src/userinterface/client_edit_mode/desktop/scripts/moveable_window.gd.uid b/src/userinterface/client_edit_mode/desktop/scripts/moveable_window.gd.uid new file mode 100644 index 0000000..4f55547 --- /dev/null +++ b/src/userinterface/client_edit_mode/desktop/scripts/moveable_window.gd.uid @@ -0,0 +1 @@ +uid://bapubedba8eiu diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/Color.tscn b/src/userinterface/client_edit_mode/node_property_editor/partials/Color.tscn new file mode 100644 index 0000000..d41361c --- /dev/null +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/Color.tscn @@ -0,0 +1,32 @@ +[gd_scene format=3 uid="uid://c5iqs1ro62837"] + +[ext_resource type="Theme" uid="uid://ckqsvvccivw0x" path="res://resources/themes/default.tres" id="1_0b8ag"] +[ext_resource type="Script" uid="uid://dht8p10d785is" path="res://userinterface/client_edit_mode/node_property_editor/partials/color.gd" id="2_0b8ag"] + +[node name="Color" type="Control" unique_id=933711176] +custom_minimum_size = Vector2(80, 30) +layout_mode = 3 +anchor_right = 1.0 +anchor_bottom = 0.027777778 +grow_horizontal = 2 +size_flags_horizontal = 3 +theme = ExtResource("1_0b8ag") +script = ExtResource("2_0b8ag") +metadata/_edit_use_anchors_ = true + +[node name="VBoxContainer" type="HBoxContainer" parent="." unique_id=1972995258] +layout_mode = 1 +anchors_preset = -1 +anchor_right = 1.0 +anchor_bottom = 0.053703703 +grow_horizontal = 2 +metadata/_edit_use_anchors_ = true + +[node name="Label" type="Label" parent="VBoxContainer" unique_id=482404396] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Color" + +[node name="ColorPickerButton" type="ColorPickerButton" parent="VBoxContainer" unique_id=1428418942] +custom_minimum_size = Vector2(60, 0) +layout_mode = 2 diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/color.gd b/src/userinterface/client_edit_mode/node_property_editor/partials/color.gd new file mode 100644 index 0000000..7d74d50 --- /dev/null +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/color.gd @@ -0,0 +1,36 @@ +# --- License +# File: /client/src/userinterface/client_edit_mode/node_property_editor/partials/color.gd +# Project: OpenMinerva +# Created Date: 17 July 2026 +# Copyright (c) 2026 OpenMinerva +# License: MIT License +# Authors: Armored Dragon +# --- License + +extends Control + +signal value_changed(new_value: Color) + +@export var property_name: String = "" +@export var value: Color + +@onready var _label = get_node("VBoxContainer/Label") +@onready var _value = get_node("VBoxContainer/ColorPickerButton") + +func _ready() -> void: + _label.text = property_name + _value.color_changed.connect(_on_value_changed) + return + +func set_value(new_value: Color) -> void: + value = new_value + _value.color = new_value + return + +func set_label(new_label: String) -> void: + _label.text = new_label + property_name = new_label + return + +func _on_value_changed(new_value: Color) -> void: + value_changed.emit(new_value) diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/color.gd.uid b/src/userinterface/client_edit_mode/node_property_editor/partials/color.gd.uid new file mode 100644 index 0000000..5f53cc3 --- /dev/null +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/color.gd.uid @@ -0,0 +1 @@ +uid://dht8p10d785is From ab8488078bf819ff44daa893090feb265fe55e22 Mon Sep 17 00:00:00 2001 From: Armored Dragon Date: Fri, 17 Jul 2026 10:27:53 -0500 Subject: [PATCH 10/13] Removed transparency from color picker popup. --- src/resources/themes/default.tres | 1 + .../client_edit_mode/node_property_editor/partials/Color.tscn | 1 + 2 files changed, 2 insertions(+) diff --git a/src/resources/themes/default.tres b/src/resources/themes/default.tres index 54206bb..9a10f21 100644 --- a/src/resources/themes/default.tres +++ b/src/resources/themes/default.tres @@ -135,6 +135,7 @@ PopupMenu/constants/item_start_padding = 5 PopupMenu/constants/v_separation = 10 PopupMenu/styles/hover = SubResource("StyleBoxFlat_kpyni") PopupMenu/styles/panel = SubResource("StyleBoxFlat_x2xen") +PopupPanel/styles/panel = SubResource("StyleBoxFlat_dgxsq") ScrollContainer/constants/scrollbar_h_separation = 10 SessionListing/base_type = &"Button" SessionListing/styles/hover = SubResource("StyleBoxFlat_gvfoe") diff --git a/src/userinterface/client_edit_mode/node_property_editor/partials/Color.tscn b/src/userinterface/client_edit_mode/node_property_editor/partials/Color.tscn index d41361c..1c5e4fe 100644 --- a/src/userinterface/client_edit_mode/node_property_editor/partials/Color.tscn +++ b/src/userinterface/client_edit_mode/node_property_editor/partials/Color.tscn @@ -30,3 +30,4 @@ text = "Color" [node name="ColorPickerButton" type="ColorPickerButton" parent="VBoxContainer" unique_id=1428418942] custom_minimum_size = Vector2(60, 0) layout_mode = 2 +theme = ExtResource("1_0b8ag") From 836990b9f4951a304a4441ebaf0d03a996a62136 Mon Sep 17 00:00:00 2001 From: Armored Dragon Date: Fri, 17 Jul 2026 10:35:17 -0500 Subject: [PATCH 11/13] Hide the NPE when invalid node selected or no node selected. --- src/userinterface/client_edit_mode/desktop/inspector.tscn | 3 ++- .../client_edit_mode/desktop/scripts/inspector.gd | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/userinterface/client_edit_mode/desktop/inspector.tscn b/src/userinterface/client_edit_mode/desktop/inspector.tscn index 5fa61a2..3120b2f 100644 --- a/src/userinterface/client_edit_mode/desktop/inspector.tscn +++ b/src/userinterface/client_edit_mode/desktop/inspector.tscn @@ -165,7 +165,7 @@ size_flags_vertical = 3 [node name="HSplitContainer" type="HSplitContainer" parent="VBoxContainer/HBoxContainer" unique_id=234551977] layout_mode = 2 size_flags_horizontal = 3 -split_offsets = PackedInt32Array(300, -300) +split_offsets = PackedInt32Array(300) split_offset = 300 [node name="MarginContainer" type="MarginContainer" parent="VBoxContainer/HBoxContainer/HSplitContainer" unique_id=1929440074] @@ -280,6 +280,7 @@ size_flags_horizontal = 3 mouse_filter = 1 [node name="Properties" type="MarginContainer" parent="VBoxContainer/HBoxContainer/HSplitContainer" unique_id=1127572109] +visible = false custom_minimum_size = Vector2(300, 0) layout_mode = 2 script = ExtResource("14_at34i") diff --git a/src/userinterface/client_edit_mode/desktop/scripts/inspector.gd b/src/userinterface/client_edit_mode/desktop/scripts/inspector.gd index edf5e17..1e42ba6 100644 --- a/src/userinterface/client_edit_mode/desktop/scripts/inspector.gd +++ b/src/userinterface/client_edit_mode/desktop/scripts/inspector.gd @@ -200,6 +200,7 @@ func _inspector_tree_item_mouse_selected(mouse_position: Vector2, mouse_button_i return _inspector_selected_node = _inspector_selected.get_metadata(0) + _set_npe_state(_inspector_selected_node != null) _select(int(_inspector_selected.get_metadata(0).name)) return @@ -211,6 +212,7 @@ func _inspector_tree_item_mouse_selected(mouse_position: Vector2, mouse_button_i return _inspector_selected_node = _inspector_selected.get_metadata(0) + _set_npe_state(_inspector_selected_node != null) var _mouse_pos = _inspector_tree.get_global_mouse_position() _inspector_popup.position = _mouse_pos @@ -458,6 +460,8 @@ func _select(target_node: int) -> void: if _node_db_entry == {}: GlobalLogger.log("Tried to select a node that should not exist!", Enum.LogLevel.ERROR) + _inspector_selected_node == null + _set_npe_state(false) return my_gizmo = await session_spawnable_m.create("Gizmo") @@ -539,3 +543,6 @@ func _cem_camera_state(state: bool) -> void: return # Node Property Editor +func _set_npe_state(state: bool) -> void: + _node_property_editor.visible = state + return From 02556a85decb6e76e5cfc1acab08c42b7a39a97d Mon Sep 17 00:00:00 2001 From: Armored Dragon Date: Sun, 19 Jul 2026 13:40:36 -0500 Subject: [PATCH 12/13] Session player count. This hooks up the player cound in the CEM to show the current amount of connected players. --- src/scenes/managers/scene/player.gd | 3 +++ .../client_edit_mode/desktop/scripts/inspector.gd | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/scenes/managers/scene/player.gd b/src/scenes/managers/scene/player.gd index 9bf1fff..3bc95dc 100644 --- a/src/scenes/managers/scene/player.gd +++ b/src/scenes/managers/scene/player.gd @@ -69,3 +69,6 @@ func spawn_player(peer_id: String) -> void: func kill_player() -> void: GlobalLogger.log("'%s' is not implemented." % get_stack()[0]["function"], Enum.LogLevel.WARNING) return + +func get_player_count() -> int: + return players.keys().size() diff --git a/src/userinterface/client_edit_mode/desktop/scripts/inspector.gd b/src/userinterface/client_edit_mode/desktop/scripts/inspector.gd index 1e42ba6..2d630f7 100644 --- a/src/userinterface/client_edit_mode/desktop/scripts/inspector.gd +++ b/src/userinterface/client_edit_mode/desktop/scripts/inspector.gd @@ -32,6 +32,7 @@ var _gizmo_space_local: bool = true @onready var _node_toolbar_gizmo_control_container: Control = _node_toolbar.get_node("MarginContainer/HBoxContainer/GizmoControl") @onready var _node_toolbar_gizmo_control_container_misc: Control = _node_toolbar.get_node("MarginContainer/HBoxContainer/GizmoControlMisc") @onready var _node_toolbar_spawnable_count: Control = _node_toolbar.get_node("MarginContainer/HBoxContainer/SpawnableCount") +@onready var _node_toolbar_player_count: Control = _node_toolbar.get_node("MarginContainer/HBoxContainer/PlayerCount") @onready var _node_crosshair: Node = get_tree().current_scene.get_node("Crosshair") @onready var _inspector_popup: Node = get_node("InspectorPopup") @onready var _inspector_add_node_window: Node = get_node("AddNodeWindow") @@ -264,6 +265,7 @@ func _inspector_build(root_node: Node = session_root) -> void: await get_tree().process_frame var _total_spawnable_label: String = str(session_spawnable_m._database.size()) + var _total_player_label: String = str(session_players_m.get_player_count()) GlobalLogger.log("Generating the inspector view with parent '%s'." % root_node) _inspector_save_openness() @@ -276,6 +278,7 @@ func _inspector_build(root_node: Node = session_root) -> void: # Update the Toolbar counts. _node_toolbar_spawnable_count.update_meta(_total_spawnable_label) + _node_toolbar_player_count.update_meta(_total_player_label) return From 1eb1e9565cbc62965c31b186028cafbeff65404e Mon Sep 17 00:00:00 2001 From: Armored Dragon Date: Sun, 19 Jul 2026 13:41:15 -0500 Subject: [PATCH 13/13] Minor change in the default grid skybox. --- src/scenes/levels/grid.tscn | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/scenes/levels/grid.tscn b/src/scenes/levels/grid.tscn index 5d34794..a786e69 100644 --- a/src/scenes/levels/grid.tscn +++ b/src/scenes/levels/grid.tscn @@ -2,16 +2,16 @@ [ext_resource type="Shader" uid="uid://bh250q6rfv615" path="res://resources/shaders/grid_shader.gdshader" id="1_ikf4c"] -[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_dbach"] -sky_horizon_color = Color(0.66224277, 0.6717428, 0.6867428, 1) -ground_horizon_color = Color(0.66224277, 0.6717428, 0.6867428, 1) +[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_bcgop"] +sky_top_color = Color(0.297, 0.40241668, 0.55, 1) +energy_multiplier = 1.25 -[sub_resource type="Sky" id="Sky_ikf4c"] -sky_material = SubResource("ProceduralSkyMaterial_dbach") +[sub_resource type="Sky" id="Sky_gbca3"] +sky_material = SubResource("ProceduralSkyMaterial_bcgop") [sub_resource type="Environment" id="Environment_q28r8"] background_mode = 2 -sky = SubResource("Sky_ikf4c") +sky = SubResource("Sky_gbca3") tonemap_mode = 2 ssr_enabled = true ssao_enabled = true