Merge pull request #83 from Nitwel/room-setup
Add support for multiple rooms and advanced room configuration
This commit is contained in:
commit
c5cb73867f
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,6 +1,7 @@
|
|||
# Godot 4+ specific ignores
|
||||
.godot/
|
||||
android/build/
|
||||
builds/
|
||||
|
||||
# Godot-specific ignores
|
||||
.import/
|
||||
|
|
3
addons/godot-cdt/libcdt.android.template_debug.arm64.so
Normal file
3
addons/godot-cdt/libcdt.android.template_debug.arm64.so
Normal file
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:5b6a62d5ec5e2c9414b983a90041f1d674e092f71a9b5563277d2b6ad552a8d2
|
||||
size 6274408
|
3
addons/godot-cdt/libcdt.android.template_debug.x86_64.so
Normal file
3
addons/godot-cdt/libcdt.android.template_debug.x86_64.so
Normal file
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:70a9f2c799d3d6703bd95abaacdd82c0d1b7a66fc39098aac64c330b0be0db06
|
||||
size 5855024
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3e679688861d608c244393a7e3366539fa067ca75f71c3efb916d8745423cc7f
|
||||
size 6003048
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:27f82d0c296c1ae8d71754353ee3f9c32955fe7a56ffbd54ca4f171a40827387
|
||||
size 5612432
|
21
addons/godot-cdt/libcdt.gdextension
Normal file
21
addons/godot-cdt/libcdt.gdextension
Normal file
|
@ -0,0 +1,21 @@
|
|||
[configuration]
|
||||
|
||||
entry_symbol = "example_library_init"
|
||||
compatibility_minimum = 4.1
|
||||
|
||||
[libraries]
|
||||
|
||||
macos.debug = "res://addons/godot-cdt/libcdt.macos.template_debug.framework"
|
||||
macos.release = "res://addons/godot-cdt/libcdt.macos.template_release.framework"
|
||||
windows.debug.x86_32 = "res://addons/godot-cdt/libcdt.windows.template_debug.x86_32.dll"
|
||||
windows.release.x86_32 = "res://addons/godot-cdt/libcdt.windows.template_release.x86_32.dll"
|
||||
windows.debug.x86_64 = "res://addons/godot-cdt/libcdt.windows.template_debug.x86_64.dll"
|
||||
windows.release.x86_64 = "res://addons/godot-cdt/libcdt.windows.template_release.x86_64.dll"
|
||||
linux.debug.x86_64 = "res://addons/godot-cdt/libcdt.linux.template_debug.x86_64.so"
|
||||
linux.release.x86_64 = "res://addons/godot-cdt/libcdt.linux.template_release.x86_64.so"
|
||||
linux.debug.arm64 = "res://addons/godot-cdt/libcdt.linux.template_debug.arm64.so"
|
||||
linux.release.arm64 = "res://addons/godot-cdt/libcdt.linux.template_release.arm64.so"
|
||||
linux.debug.rv64 = "res://addons/godot-cdt/libcdt.linux.template_debug.rv64.so"
|
||||
linux.release.rv64 = "res://addons/godot-cdt/libcdt.linux.template_release.rv64.so"
|
||||
android.debug.arm64 = "res://addons/godot-cdt/libcdt.android.template_debug.arm64.so"
|
||||
android.release.arm64 = "res://addons/godot-cdt/libcdt.android.template_release.arm64.so"
|
3
addons/godot-cdt/libcdt.linux.template_debug.x86_64.so
Normal file
3
addons/godot-cdt/libcdt.linux.template_debug.x86_64.so
Normal file
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:95bda34ae6ebb2010c5a5e1bd0ccd994df43e5e5f956e214da3c6adae4521add
|
||||
size 974176
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:418c2ca8e73932710184b3bc4de4b40a32fc7ef0369354f8a08fbacd01155f50
|
||||
size 871936
|
BIN
addons/godot-cdt/libcdt.windows.template_debug.x86_64.exp
Normal file
BIN
addons/godot-cdt/libcdt.windows.template_debug.x86_64.exp
Normal file
Binary file not shown.
BIN
addons/godot-cdt/libcdt.windows.template_debug.x86_64.lib
Normal file
BIN
addons/godot-cdt/libcdt.windows.template_debug.x86_64.lib
Normal file
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:418c2ca8e73932710184b3bc4de4b40a32fc7ef0369354f8a08fbacd01155f50
|
||||
size 871936
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e54002ccb9b04b9b4fb4642cc3b5fd6512f910e65ecb52e41c117a2345d1d22b
|
||||
size 17810864
|
||||
oid sha256:b117dc5a7537a60ff341010636802131c9aa3b80982130e63d5d94902c002d07
|
||||
size 13505995
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:68e2b9d5e723a2009f341e45e2968893dd2a1dd5077fe1d9ba970f01d0d75e02
|
||||
size 56989
|
||||
oid sha256:9738010a57d2157a53e4f537afbcfb50dd28e9de40bae510621d0ea8c94c5844
|
||||
size 51682
|
||||
|
|
|
@ -2,14 +2,34 @@
|
|||
extends Function
|
||||
class_name Movable
|
||||
|
||||
signal on_move(position: Vector3, rotation: Vector3)
|
||||
|
||||
@export var restricted: bool = false
|
||||
@export var restrict_movement: Callable
|
||||
@export var lock_rotation: bool = false
|
||||
var hit_node := Node3D.new()
|
||||
|
||||
func _on_grab_down(event: EventPointer):
|
||||
if restricted && event.target != get_parent():
|
||||
return
|
||||
|
||||
event.initiator.node.add_child(hit_node)
|
||||
hit_node.global_transform = get_parent().global_transform
|
||||
|
||||
func _on_grab_move(_event: EventPointer):
|
||||
get_parent().global_transform = hit_node.global_transform
|
||||
if hit_node.get_parent() == null:
|
||||
return
|
||||
|
||||
if restrict_movement:
|
||||
get_parent().global_position = restrict_movement.call(hit_node.global_position)
|
||||
else:
|
||||
get_parent().global_position = hit_node.global_position
|
||||
|
||||
if !lock_rotation:
|
||||
get_parent().global_basis = hit_node.global_basis
|
||||
on_move.emit(get_parent().global_position, get_parent().global_rotation)
|
||||
else:
|
||||
on_move.emit(get_parent().global_position, Vector3(0, 0, 0))
|
||||
|
||||
func _on_grab_up(event: EventPointer):
|
||||
event.initiator.node.remove_child(hit_node)
|
||||
|
|
|
@ -16,9 +16,8 @@ func _ready():
|
|||
if OS.get_name() == "Android":
|
||||
# OS.request_permissions()
|
||||
environment.environment.sky.set_material(sky_passthrough)
|
||||
house.visible = false
|
||||
else:
|
||||
house.visible = true
|
||||
RenderingServer.set_debug_generate_wireframes(true)
|
||||
|
||||
controller_left.button_pressed.connect(func(name):
|
||||
_emit_action(name, true, false)
|
||||
|
@ -41,7 +40,9 @@ func _ready():
|
|||
|
||||
EventSystem.on_action_down.connect(func(action):
|
||||
if action.name == "menu_button":
|
||||
_toggle_menu()
|
||||
toggle_menu()
|
||||
elif action.name == "by_button":
|
||||
House.body.mini_view = !House.body.mini_view
|
||||
)
|
||||
|
||||
EventSystem.on_focus_in.connect(func(event):
|
||||
|
@ -49,8 +50,7 @@ func _ready():
|
|||
return
|
||||
|
||||
add_child(keyboard)
|
||||
if event.previous_target == null:
|
||||
keyboard.global_transform = menu.get_node("AnimationContainer/KeyboardPlace").global_transform
|
||||
keyboard.global_transform = menu.get_node("AnimationContainer/KeyboardPlace").global_transform
|
||||
)
|
||||
|
||||
EventSystem.on_focus_out.connect(func(event):
|
||||
|
@ -60,7 +60,7 @@ func _ready():
|
|||
remove_child(keyboard)
|
||||
)
|
||||
|
||||
func _toggle_menu():
|
||||
func toggle_menu():
|
||||
if menu.show_menu == false:
|
||||
add_child(menu)
|
||||
menu.global_transform = _get_menu_transform()
|
||||
|
@ -98,9 +98,13 @@ func _process(delta):
|
|||
controller_left.position += movement
|
||||
controller_right.position += movement
|
||||
|
||||
func _input(evnet):
|
||||
if Input.is_key_pressed(KEY_M):
|
||||
_toggle_menu()
|
||||
func _input(event):
|
||||
if event is InputEventKey and Input.is_key_pressed(KEY_F10):
|
||||
var vp = get_viewport()
|
||||
vp.debug_draw = (vp.debug_draw + 1) % 5
|
||||
|
||||
if event is InputEventKey and Input.is_key_pressed(KEY_M):
|
||||
toggle_menu()
|
||||
|
||||
func _get_menu_transform():
|
||||
var transform = camera.get_global_transform()
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
[ext_resource type="PackedScene" uid="uid://ctltchlf2j2r4" path="res://addons/xr-simulator/XRSimulator.tscn" id="5_3qc8g"]
|
||||
[ext_resource type="Material" uid="uid://bf5ina366dwm6" path="res://assets/materials/sky.material" id="5_wgwf8"]
|
||||
[ext_resource type="PackedScene" uid="uid://c3kdssrmv84kv" path="res://content/ui/menu/menu.tscn" id="8_du83w"]
|
||||
[ext_resource type="PackedScene" uid="uid://83lb5p4e0qk0" path="res://content/scenes/house.tscn" id="8_qkrg7"]
|
||||
[ext_resource type="PackedScene" uid="uid://lrehk38exd5n" path="res://content/system/keyboard/keyboard.tscn" id="9_e5n3p"]
|
||||
[ext_resource type="PackedScene" uid="uid://cbemihbxkd4ll" path="res://content/system/house/house.tscn" id="9_np6mw"]
|
||||
|
||||
[sub_resource type="Sky" id="Sky_vhymk"]
|
||||
sky_material = ExtResource("5_wgwf8")
|
||||
|
@ -78,10 +78,8 @@ transform = Transform3D(0.999998, -0.000514899, -6.55874e-05, 1.96975e-05, 0.163
|
|||
[node name="Keyboard" parent="." instance=ExtResource("9_e5n3p")]
|
||||
transform = Transform3D(0.499999, -0.000139169, -6.50204e-05, 5.24307e-05, 0.353553, -0.353553, 0.000144383, 0.353553, 0.353553, -0.0199266, 0.550784, -0.47368)
|
||||
|
||||
[node name="House" parent="." instance=ExtResource("8_qkrg7")]
|
||||
transform = Transform3D(0.404247, 0.000180645, 0.914648, 0.00017221, 0.999999, -0.000273614, -0.914648, 0.00026812, 0.404247, -0.343479, 0.000110551, 1.91547)
|
||||
visible = false
|
||||
|
||||
[node name="Rooms" type="Node3D" parent="."]
|
||||
|
||||
[node name="House" parent="." instance=ExtResource("9_np6mw")]
|
||||
|
||||
[editable path="XROrigin3D/XRControllerLeft"]
|
||||
|
|
15
content/system/armband/armband.gd
Normal file
15
content/system/armband/armband.gd
Normal file
|
@ -0,0 +1,15 @@
|
|||
extends Node3D
|
||||
|
||||
@onready var menu_button = $Menu
|
||||
@onready var mini_button = $Mini
|
||||
@onready var clock = $Clock
|
||||
@onready var main = $"/root/Main"
|
||||
|
||||
func _ready():
|
||||
menu_button.on_button_down.connect(func():
|
||||
main.toggle_menu()
|
||||
)
|
||||
|
||||
mini_button.on_button_down.connect(func():
|
||||
House.body.mini_view = !House.body.mini_view
|
||||
)
|
23
content/system/armband/armband.tscn
Normal file
23
content/system/armband/armband.tscn
Normal file
|
@ -0,0 +1,23 @@
|
|||
[gd_scene load_steps=3 format=3 uid="uid://bexxngoxcegul"]
|
||||
|
||||
[ext_resource type="Script" path="res://content/system/armband/armband.gd" id="1_4tskg"]
|
||||
[ext_resource type="PackedScene" uid="uid://bsjqdvkt0u87c" path="res://content/ui/components/button/button.tscn" id="1_egcvm"]
|
||||
|
||||
[node name="Armband" type="Node3D"]
|
||||
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 0, 0)
|
||||
script = ExtResource("1_4tskg")
|
||||
|
||||
[node name="Menu" parent="." instance=ExtResource("1_egcvm")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.04, 0, 0.04)
|
||||
label = "menu"
|
||||
icon = true
|
||||
|
||||
[node name="Mini" parent="." instance=ExtResource("1_egcvm")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.02, 0, 0.04)
|
||||
label = "view_comfy"
|
||||
icon = true
|
||||
|
||||
[node name="Clock" type="Label3D" parent="."]
|
||||
transform = Transform3D(1, 4.37114e-08, 4.37114e-08, -4.37114e-08, -4.37114e-08, 1, 4.37114e-08, -1, -4.37114e-08, 0, 0.02, -0.02)
|
||||
pixel_size = 0.001
|
||||
text = "10:00"
|
46
content/system/house/align_reference.gd
Normal file
46
content/system/house/align_reference.gd
Normal file
|
@ -0,0 +1,46 @@
|
|||
extends Node3D
|
||||
|
||||
@onready var corner1 = $Corner1
|
||||
@onready var corner2 = $Corner1/Corner2
|
||||
@onready var edge = $Edge
|
||||
@onready var marker = $Edge/Marker3D
|
||||
|
||||
@export var disabled: bool:
|
||||
set(value):
|
||||
disabled = value
|
||||
|
||||
if !is_node_ready(): await ready
|
||||
|
||||
corner1.get_node("CollisionShape3D").disabled = value
|
||||
corner2.get_node("CollisionShape3D").disabled = value
|
||||
edge.get_node("CollisionShape3D").disabled = value
|
||||
corner1.visible = !value
|
||||
corner2.visible = !value
|
||||
edge.visible = !value
|
||||
|
||||
func _ready():
|
||||
update_initial_positions()
|
||||
|
||||
corner1.get_node("Movable").on_move.connect(func(position, rotation):
|
||||
edge.align_to_corners(corner1.global_position, corner2.global_position)
|
||||
)
|
||||
|
||||
corner2.get_node("Movable").on_move.connect(func(position, rotation):
|
||||
edge.align_to_corners(corner1.global_position, corner2.global_position)
|
||||
)
|
||||
|
||||
corner2.get_node("Movable").restrict_movement = func(new_position):
|
||||
new_position.y = corner1.global_position.y
|
||||
|
||||
var delta_new_pos_corner1 = (new_position - corner1.position).normalized()
|
||||
|
||||
return corner1.position + delta_new_pos_corner1
|
||||
|
||||
func update_initial_positions():
|
||||
edge.align_to_corners(corner1.global_position, corner2.global_position)
|
||||
marker.global_transform = House.body.transform
|
||||
|
||||
func get_new_transform(old_transform: Transform3D):
|
||||
marker.scale = Vector3(1, 1, 1)
|
||||
return marker.global_transform
|
||||
|
41
content/system/house/align_reference.tscn
Normal file
41
content/system/house/align_reference.tscn
Normal file
|
@ -0,0 +1,41 @@
|
|||
[gd_scene load_steps=7 format=3 uid="uid://jls16btb8nko"]
|
||||
|
||||
[ext_resource type="Script" path="res://content/system/house/align_reference.gd" id="1_8fatp"]
|
||||
[ext_resource type="PackedScene" uid="uid://brf6mm2gxj7y2" path="res://content/system/house/room/wall_corner.tscn" id="2_ppkie"]
|
||||
[ext_resource type="PackedScene" uid="uid://dlj5chj7ndgua" path="res://content/system/house/room/wall_edge.tscn" id="3_6o3xn"]
|
||||
[ext_resource type="Script" path="res://content/functions/movable.gd" id="3_7ktdq"]
|
||||
[ext_resource type="Material" uid="uid://dxyuncqxagt28" path="res://content/system/house/room/walls_mini.tres" id="4_jkpj4"]
|
||||
|
||||
[sub_resource type="CylinderMesh" id="CylinderMesh_k2m3v"]
|
||||
top_radius = 0.001
|
||||
bottom_radius = 0.05
|
||||
height = 0.1
|
||||
|
||||
[node name="AlignReference" type="Node3D"]
|
||||
script = ExtResource("1_8fatp")
|
||||
|
||||
[node name="Corner1" parent="." instance=ExtResource("2_ppkie")]
|
||||
|
||||
[node name="Movable" type="Node" parent="Corner1"]
|
||||
script = ExtResource("3_7ktdq")
|
||||
restricted = true
|
||||
lock_rotation = true
|
||||
|
||||
[node name="Corner2" parent="Corner1" instance=ExtResource("2_ppkie")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0)
|
||||
|
||||
[node name="MeshInstance3D" parent="Corner1/Corner2" index="1"]
|
||||
transform = Transform3D(-4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0, 1, 0, 0, 0)
|
||||
material_override = ExtResource("4_jkpj4")
|
||||
mesh = SubResource("CylinderMesh_k2m3v")
|
||||
|
||||
[node name="Movable" type="Node" parent="Corner1/Corner2"]
|
||||
script = ExtResource("3_7ktdq")
|
||||
lock_rotation = true
|
||||
|
||||
[node name="Edge" parent="." instance=ExtResource("3_6o3xn")]
|
||||
transform = Transform3D(-4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0, 1, 0.5, 0, 0)
|
||||
|
||||
[node name="Marker3D" type="Marker3D" parent="Edge"]
|
||||
|
||||
[editable path="Corner1/Corner2"]
|
168
content/system/house/house.gd
Normal file
168
content/system/house/house.gd
Normal file
|
@ -0,0 +1,168 @@
|
|||
extends Node3D
|
||||
|
||||
const Room = preload("./room/room.tscn")
|
||||
const RoomType = preload("./room/room.gd")
|
||||
|
||||
@onready var levels = $Levels
|
||||
@onready var collision_shape = $Levels/CollisionShape3D
|
||||
@onready var align_reference = $AlignReference
|
||||
|
||||
var fixing_reference: bool = false
|
||||
var editing_room: RoomType = null
|
||||
var mini_view: bool = false:
|
||||
set(value):
|
||||
mini_view = value
|
||||
update_mini_view()
|
||||
|
||||
var target_size: float = 1.0
|
||||
|
||||
func _physics_process(delta):
|
||||
levels.scale.x = lerp(levels.scale.x, target_size, 10.0 * delta)
|
||||
levels.scale.y = lerp(levels.scale.y, target_size, 10.0 * delta)
|
||||
levels.scale.z = lerp(levels.scale.z, target_size, 10.0 * delta)
|
||||
|
||||
|
||||
func create_room(room_name: String, level: int) -> RoomType:
|
||||
if editing_room != null:
|
||||
editing_room.editable = false
|
||||
editing_room = null
|
||||
|
||||
var room = Room.instantiate()
|
||||
room.name = room_name
|
||||
room.editable = true
|
||||
editing_room = room
|
||||
|
||||
get_level(level).add_child(room)
|
||||
|
||||
return room
|
||||
|
||||
func edit_room(room_name):
|
||||
var room = find_room(room_name)
|
||||
|
||||
if room == editing_room:
|
||||
return
|
||||
|
||||
if editing_room != null:
|
||||
editing_room.editable = false
|
||||
editing_room = null
|
||||
|
||||
if room != null:
|
||||
room.editable = true
|
||||
editing_room = room
|
||||
|
||||
func is_valid_room(room_name):
|
||||
var room = find_room(room_name)
|
||||
|
||||
if room == null:
|
||||
return
|
||||
|
||||
return room.wall_corners.get_child_count() >= 3
|
||||
|
||||
|
||||
func delete_room(room_name):
|
||||
var room = find_room(room_name)
|
||||
|
||||
if room == null:
|
||||
return
|
||||
|
||||
if editing_room == room:
|
||||
editing_room = null
|
||||
|
||||
room.get_parent().remove_child(room)
|
||||
room.queue_free()
|
||||
|
||||
func is_editiong(room_name):
|
||||
return editing_room != null && editing_room.name == room_name
|
||||
|
||||
func find_room(room_name):
|
||||
for level in levels.get_children():
|
||||
for room in level.get_children():
|
||||
if room.name == room_name:
|
||||
return room
|
||||
return null
|
||||
|
||||
func find_room_at(entity_position: Vector3):
|
||||
for level in levels.get_children():
|
||||
for room in level.get_children():
|
||||
if room.has_point(entity_position):
|
||||
return room
|
||||
return null
|
||||
|
||||
func get_level(level: int):
|
||||
return levels.get_child(level)
|
||||
|
||||
func get_level_aabb(level: int):
|
||||
var rooms = get_level(level).get_children()
|
||||
if rooms.size() == 0:
|
||||
return AABB()
|
||||
|
||||
var min_pos = rooms[0].get_aabb().position
|
||||
var max_pos = min_pos + rooms[0].get_aabb().size
|
||||
|
||||
for room in rooms:
|
||||
var room_min = room.get_aabb().position
|
||||
var room_max = room_min + room.get_aabb().size
|
||||
|
||||
min_pos.x = min(min_pos.x, room_min.x)
|
||||
min_pos.y = min(min_pos.y, room_min.y)
|
||||
min_pos.z = min(min_pos.z, room_min.z)
|
||||
|
||||
max_pos.x = max(max_pos.x, room_max.x)
|
||||
max_pos.y = max(max_pos.y, room_max.y)
|
||||
max_pos.z = max(max_pos.z, room_max.z)
|
||||
|
||||
return AABB(min_pos, max_pos - min_pos)
|
||||
|
||||
func get_rooms(level: int):
|
||||
return get_level(level).get_children()
|
||||
|
||||
func create_entity(entity_id: String, entity_position: Vector3):
|
||||
var room = find_room_at(entity_position)
|
||||
|
||||
if room == null:
|
||||
return
|
||||
|
||||
var entity = EntityFactory.create_entity(entity_id)
|
||||
|
||||
if entity == null:
|
||||
return
|
||||
|
||||
room.add_child(entity)
|
||||
entity.global_position = entity_position
|
||||
|
||||
func update_mini_view():
|
||||
collision_shape.disabled = !mini_view
|
||||
|
||||
if mini_view:
|
||||
var aabb = get_level_aabb(0)
|
||||
aabb.position.y = -0.03
|
||||
aabb.size.y = 0.06
|
||||
var center = aabb.position + aabb.size / 2.0
|
||||
|
||||
collision_shape.global_position = center
|
||||
collision_shape.shape.size = aabb.size
|
||||
else:
|
||||
levels.position = Vector3(0, 0, 0)
|
||||
|
||||
target_size = 0.1 if mini_view else 1.0
|
||||
|
||||
for room in get_rooms(0):
|
||||
room.state_machine.change_to("Mini" if mini_view else "View")
|
||||
|
||||
func edit_reference():
|
||||
fixing_reference = false
|
||||
align_reference.disabled = false
|
||||
|
||||
func fix_reference():
|
||||
fixing_reference = true
|
||||
align_reference.disabled = false
|
||||
align_reference.update_initial_positions()
|
||||
|
||||
func save_reference():
|
||||
if fixing_reference:
|
||||
var align_transform = align_reference.global_transform
|
||||
transform = align_reference.get_new_transform(transform)
|
||||
align_reference.global_transform = align_transform
|
||||
|
||||
align_reference.disabled = true
|
||||
align_reference.update_initial_positions()
|
27
content/system/house/house.tscn
Normal file
27
content/system/house/house.tscn
Normal file
|
@ -0,0 +1,27 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://cbemihbxkd4ll"]
|
||||
|
||||
[ext_resource type="Script" path="res://content/system/house/house.gd" id="1_p8amj"]
|
||||
[ext_resource type="Script" path="res://content/functions/movable.gd" id="2_w1auk"]
|
||||
[ext_resource type="PackedScene" uid="uid://jls16btb8nko" path="res://content/system/house/align_reference.tscn" id="3_e1tcn"]
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_x81up"]
|
||||
|
||||
[node name="House" type="Node3D"]
|
||||
script = ExtResource("1_p8amj")
|
||||
|
||||
[node name="Levels" type="StaticBody3D" parent="."]
|
||||
|
||||
[node name="Level0" type="Node3D" parent="Levels"]
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Levels"]
|
||||
shape = SubResource("BoxShape3D_x81up")
|
||||
disabled = true
|
||||
|
||||
[node name="Movable" type="Node" parent="Levels"]
|
||||
script = ExtResource("2_w1auk")
|
||||
restricted = true
|
||||
lock_rotation = true
|
||||
|
||||
[node name="AlignReference" parent="." instance=ExtResource("3_e1tcn")]
|
||||
visible = false
|
||||
disabled = true
|
53
content/system/house/room/room.gd
Normal file
53
content/system/house/room/room.gd
Normal file
|
@ -0,0 +1,53 @@
|
|||
extends Node3D
|
||||
|
||||
@onready var wall_corners = $Ceiling/WallCorners
|
||||
@onready var wall_edges = $Ceiling/WallEdges
|
||||
@onready var wall_mesh: MeshInstance3D = $WallMesh
|
||||
@onready var ceiling_mesh: MeshInstance3D = $CeilingMesh
|
||||
@onready var wall_collisions = $WallCollisions
|
||||
|
||||
@onready var room_floor = $Floor
|
||||
@onready var room_ceiling = $Ceiling
|
||||
|
||||
@onready var state_machine = $StateMachine
|
||||
|
||||
var editable: bool = false:
|
||||
set(value):
|
||||
if !is_node_ready(): await ready
|
||||
|
||||
if value:
|
||||
state_machine.change_to("Edit")
|
||||
else:
|
||||
state_machine.change_to("View")
|
||||
|
||||
func get_corner(index: int) -> MeshInstance3D:
|
||||
return wall_corners.get_child(index % wall_corners.get_child_count())
|
||||
|
||||
func get_edge(index: int) -> MeshInstance3D:
|
||||
return wall_edges.get_child(index % wall_edges.get_child_count())
|
||||
|
||||
func has_point(point: Vector3) -> bool:
|
||||
return get_aabb().has_point(point)
|
||||
|
||||
func remove_corner(index: int):
|
||||
get_corner(index).queue_free()
|
||||
get_edge(index).queue_free()
|
||||
|
||||
func get_aabb():
|
||||
if wall_corners.get_child_count() == 0:
|
||||
return AABB()
|
||||
|
||||
var min_pos = wall_corners.get_child(0).position
|
||||
var max_pos = wall_corners.get_child(0).position
|
||||
|
||||
for corner in wall_corners.get_children():
|
||||
min_pos.x = min(min_pos.x, corner.position.x)
|
||||
min_pos.z = min(min_pos.z, corner.position.z)
|
||||
|
||||
max_pos.x = max(max_pos.x, corner.position.x)
|
||||
max_pos.z = max(max_pos.z, corner.position.z)
|
||||
|
||||
min_pos.y = room_floor.position.y
|
||||
max_pos.y = room_ceiling.position.y
|
||||
|
||||
return AABB(to_global(min_pos), to_global(max_pos) - to_global(min_pos))
|
67
content/system/house/room/room.tscn
Normal file
67
content/system/house/room/room.tscn
Normal file
|
@ -0,0 +1,67 @@
|
|||
[gd_scene load_steps=11 format=3 uid="uid://bswgmclohuqui"]
|
||||
|
||||
[ext_resource type="Script" path="res://content/system/house/room/room.gd" id="1_fccq0"]
|
||||
[ext_resource type="Script" path="res://content/functions/clickable.gd" id="1_ugebq"]
|
||||
[ext_resource type="Material" uid="uid://bbx6fv7jq50tr" path="res://content/system/house/room/walls.tres" id="3_al1ev"]
|
||||
[ext_resource type="Script" path="res://lib/utils/state_machine/state_machine.gd" id="4_nbbo6"]
|
||||
[ext_resource type="Script" path="res://content/system/house/room/states/mini.gd" id="6_g4qca"]
|
||||
[ext_resource type="Script" path="res://content/system/house/room/states/view.gd" id="6_g066t"]
|
||||
[ext_resource type="Script" path="res://content/system/house/room/states/edit.gd" id="7_ap14h"]
|
||||
|
||||
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_08sv0"]
|
||||
|
||||
[sub_resource type="ArrayMesh" id="ArrayMesh_7dibq"]
|
||||
|
||||
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_ap613"]
|
||||
plane = Plane(0, -1, 0, 0)
|
||||
|
||||
[node name="Room" type="Node3D"]
|
||||
script = ExtResource("1_fccq0")
|
||||
|
||||
[node name="Floor" type="StaticBody3D" parent="."]
|
||||
collision_layer = 24
|
||||
collision_mask = 0
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Floor"]
|
||||
shape = SubResource("WorldBoundaryShape3D_08sv0")
|
||||
|
||||
[node name="Clickable" type="Node" parent="Floor"]
|
||||
script = ExtResource("1_ugebq")
|
||||
|
||||
[node name="WallMesh" type="MeshInstance3D" parent="."]
|
||||
material_override = ExtResource("3_al1ev")
|
||||
mesh = SubResource("ArrayMesh_7dibq")
|
||||
|
||||
[node name="CeilingMesh" type="MeshInstance3D" parent="."]
|
||||
material_override = ExtResource("3_al1ev")
|
||||
|
||||
[node name="WallCollisions" type="Node3D" parent="."]
|
||||
|
||||
[node name="Ceiling" type="StaticBody3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0)
|
||||
collision_layer = 24
|
||||
collision_mask = 0
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Ceiling"]
|
||||
shape = SubResource("WorldBoundaryShape3D_ap613")
|
||||
disabled = true
|
||||
|
||||
[node name="Clickable" type="Node" parent="Ceiling"]
|
||||
script = ExtResource("1_ugebq")
|
||||
|
||||
[node name="WallCorners" type="Node3D" parent="Ceiling"]
|
||||
|
||||
[node name="WallEdges" type="Node3D" parent="Ceiling"]
|
||||
|
||||
[node name="StateMachine" type="Node" parent="." node_paths=PackedStringArray("current_state")]
|
||||
script = ExtResource("4_nbbo6")
|
||||
current_state = NodePath("View")
|
||||
|
||||
[node name="View" type="Node" parent="StateMachine"]
|
||||
script = ExtResource("6_g066t")
|
||||
|
||||
[node name="Edit" type="Node" parent="StateMachine"]
|
||||
script = ExtResource("7_ap14h")
|
||||
|
||||
[node name="Mini" type="Node" parent="StateMachine"]
|
||||
script = ExtResource("6_g4qca")
|
238
content/system/house/room/states/edit.gd
Normal file
238
content/system/house/room/states/edit.gd
Normal file
|
@ -0,0 +1,238 @@
|
|||
extends RoomState
|
||||
|
||||
const wall_corner_scene = preload("../wall_corner.tscn")
|
||||
const wall_edge_scene = preload("../wall_edge.tscn")
|
||||
const RoomState = preload("./room_state.gd")
|
||||
|
||||
var moving = null
|
||||
var deleting: bool = false
|
||||
var floor_corner: StaticBody3D = null
|
||||
var height_corner: StaticBody3D = null
|
||||
var height_edge: StaticBody3D = null
|
||||
|
||||
func _on_enter():
|
||||
room.wall_corners.visible = true
|
||||
room.wall_edges.visible = true
|
||||
|
||||
if floor_corner != null:
|
||||
floor_corner.visible = true
|
||||
height_corner.visible = true
|
||||
height_edge.visible = true
|
||||
|
||||
room.room_ceiling.get_node("CollisionShape3D").disabled = (floor_corner == null && height_corner == null)
|
||||
room.room_floor.get_node("CollisionShape3D").disabled = false
|
||||
|
||||
var ceiling_shape = WorldBoundaryShape3D.new()
|
||||
ceiling_shape.plane = Plane(Vector3.DOWN, 0)
|
||||
|
||||
room.room_ceiling.get_node("CollisionShape3D").shape = ceiling_shape
|
||||
room.room_floor.get_node("CollisionShape3D").shape = WorldBoundaryShape3D.new()
|
||||
|
||||
room.room_ceiling.get_node("Clickable").on_click.connect(_on_click_ceiling)
|
||||
room.room_floor.get_node("Clickable").on_click.connect(_on_click_floor)
|
||||
|
||||
func _on_leave():
|
||||
room.wall_corners.visible = false
|
||||
room.wall_edges.visible = false
|
||||
|
||||
if floor_corner != null:
|
||||
floor_corner.visible = false
|
||||
height_corner.visible = false
|
||||
height_edge.visible = false
|
||||
|
||||
room.room_ceiling.get_node("CollisionShape3D").disabled = true
|
||||
room.room_floor.get_node("CollisionShape3D").disabled = true
|
||||
|
||||
room.room_ceiling.get_node("Clickable").on_click.disconnect(_on_click_ceiling)
|
||||
room.room_floor.get_node("Clickable").on_click.disconnect(_on_click_floor)
|
||||
|
||||
func _on_click_floor(event):
|
||||
if floor_corner != null && height_corner != null:
|
||||
return
|
||||
|
||||
add_floor_corner(event.ray.get_collision_point())
|
||||
add_height_corner(event.ray.get_collision_point())
|
||||
room.room_ceiling.get_node("CollisionShape3D").disabled = false
|
||||
|
||||
func _on_click_ceiling(event):
|
||||
if floor_corner == null || height_corner == null || event.target != room.room_ceiling:
|
||||
return
|
||||
|
||||
var pos = event.ray.get_collision_point()
|
||||
pos.y = 0
|
||||
|
||||
add_corner(pos)
|
||||
|
||||
func add_floor_corner(position: Vector3):
|
||||
floor_corner = wall_corner_scene.instantiate()
|
||||
floor_corner.position = position
|
||||
|
||||
height_edge = wall_edge_scene.instantiate()
|
||||
height_edge.align_to_corners(position, position + Vector3.UP * room.room_ceiling.global_position.y)
|
||||
|
||||
floor_corner.get_node("Clickable").on_grab_down.connect(func(event):
|
||||
if !is_active() || moving != null:
|
||||
return
|
||||
|
||||
moving = event.target
|
||||
)
|
||||
|
||||
floor_corner.get_node("Clickable").on_grab_move.connect(func(event):
|
||||
if moving == null:
|
||||
return
|
||||
|
||||
var moving_index = height_corner.get_index()
|
||||
var direction = -event.ray.global_transform.basis.z
|
||||
var new_position = room.room_floor.get_node("CollisionShape3D").shape.plane.intersects_ray(event.ray.global_position, direction)
|
||||
|
||||
if new_position == null:
|
||||
return
|
||||
|
||||
moving.position = new_position
|
||||
|
||||
height_edge.align_to_corners(new_position, new_position + Vector3.UP * room.room_ceiling.global_position.y)
|
||||
|
||||
room.get_corner(moving_index).position.x = new_position.x
|
||||
room.get_corner(moving_index).position.z = new_position.z
|
||||
|
||||
if room.wall_edges.get_child_count() == 0:
|
||||
return
|
||||
|
||||
room.get_edge(moving_index).align_to_corners(new_position, room.get_corner(moving_index + 1).position)
|
||||
room.get_edge(moving_index - 1).align_to_corners(room.get_corner(moving_index - 1).position, new_position)
|
||||
)
|
||||
|
||||
floor_corner.get_node("Clickable").on_grab_up.connect(func(_event):
|
||||
moving = null
|
||||
)
|
||||
|
||||
room.add_child(floor_corner)
|
||||
room.add_child(height_edge)
|
||||
|
||||
func add_height_corner(position: Vector3):
|
||||
height_corner = wall_corner_scene.instantiate()
|
||||
height_corner.position.x = position.x
|
||||
height_corner.position.z = position.z
|
||||
|
||||
height_corner.get_node("Clickable").on_grab_down.connect(func(event):
|
||||
if !is_active() || moving != null:
|
||||
return
|
||||
|
||||
moving = event.target
|
||||
)
|
||||
|
||||
height_corner.get_node("Clickable").on_grab_move.connect(func(event):
|
||||
if moving == null:
|
||||
return
|
||||
|
||||
var direction = -event.ray.global_transform.basis.z
|
||||
var plane_direction = direction
|
||||
plane_direction.y = 0
|
||||
plane_direction = plane_direction.normalized() * -1
|
||||
|
||||
var plane = Plane(plane_direction, moving.position)
|
||||
|
||||
var new_position = plane.intersects_ray(event.ray.global_position, direction)
|
||||
|
||||
if new_position == null:
|
||||
return
|
||||
|
||||
room.room_ceiling.position.y = new_position.y
|
||||
height_edge.align_to_corners(floor_corner.global_position, height_corner.global_position)
|
||||
|
||||
)
|
||||
|
||||
height_corner.get_node("Clickable").on_grab_up.connect(func(_event):
|
||||
moving = null
|
||||
)
|
||||
|
||||
room.wall_corners.add_child(height_corner)
|
||||
|
||||
func add_corner(position: Vector3, index: int = -1):
|
||||
var corner = wall_corner_scene.instantiate()
|
||||
corner.position.x = position.x
|
||||
corner.position.z = position.z
|
||||
|
||||
corner.get_node("Clickable").on_grab_down.connect(func(event):
|
||||
if !is_active() || moving != null:
|
||||
return
|
||||
|
||||
moving = event.target
|
||||
)
|
||||
|
||||
corner.get_node("Clickable").on_grab_move.connect(func(event):
|
||||
if moving == null:
|
||||
return
|
||||
|
||||
var moving_index = moving.get_index()
|
||||
var direction = -event.ray.global_transform.basis.z
|
||||
var ceiling_plane = Plane(Vector3.DOWN, room.room_ceiling.global_position)
|
||||
var new_position = ceiling_plane.intersects_ray(event.ray.global_position, direction)
|
||||
|
||||
if new_position == null:
|
||||
deleting = true
|
||||
|
||||
new_position = event.ray.global_position + direction
|
||||
|
||||
room.get_corner(moving_index).global_position = new_position
|
||||
|
||||
if room.wall_edges.get_child_count() == 0:
|
||||
return
|
||||
|
||||
room.get_edge(moving_index).align_to_corners(room.get_corner(moving_index - 1).position, room.get_corner(moving_index + 1).position)
|
||||
room.get_edge(moving_index - 1).transform = room.get_edge(moving_index).transform
|
||||
|
||||
return
|
||||
|
||||
deleting = false
|
||||
|
||||
new_position.y = 0
|
||||
|
||||
moving.position = new_position
|
||||
|
||||
|
||||
if room.wall_edges.get_child_count() == 0:
|
||||
return
|
||||
|
||||
room.get_edge(moving_index).align_to_corners(new_position, room.get_corner(moving_index + 1).position)
|
||||
room.get_edge(moving_index - 1).align_to_corners(room.get_corner(moving_index - 1).position, new_position)
|
||||
)
|
||||
|
||||
corner.get_node("Clickable").on_grab_up.connect(func(_event):
|
||||
if deleting:
|
||||
var moving_index = moving.get_index()
|
||||
room.remove_corner(moving_index)
|
||||
|
||||
moving = null
|
||||
deleting = false
|
||||
)
|
||||
|
||||
room.wall_corners.add_child(corner)
|
||||
room.wall_corners.move_child(corner, index)
|
||||
|
||||
var num_corners = room.wall_corners.get_child_count()
|
||||
|
||||
if num_corners > 1:
|
||||
add_edge(position, room.get_corner(index + 1).position, index)
|
||||
|
||||
if num_corners > 2:
|
||||
if num_corners != room.wall_edges.get_child_count():
|
||||
add_edge(room.get_corner(-2).position, room.get_corner(-1).position, -2)
|
||||
else:
|
||||
room.get_edge(index - 1).align_to_corners(room.get_corner(index - 1).position, position)
|
||||
|
||||
|
||||
func add_edge(from_pos: Vector3, to_pos: Vector3, index: int = -1):
|
||||
var edge: StaticBody3D = wall_edge_scene.instantiate()
|
||||
edge.align_to_corners(from_pos, to_pos)
|
||||
|
||||
edge.get_node("Clickable").on_press_down.connect(func(event):
|
||||
var point = event.ray.get_collision_point()
|
||||
point.y = 0
|
||||
add_corner(point, edge.get_index() + 1)
|
||||
)
|
||||
|
||||
|
||||
room.wall_edges.add_child(edge)
|
||||
room.wall_edges.move_child(edge, index)
|
||||
return edge
|
41
content/system/house/room/states/mini.gd
Normal file
41
content/system/house/room/states/mini.gd
Normal file
|
@ -0,0 +1,41 @@
|
|||
extends RoomState
|
||||
|
||||
const RoomState = preload("./room_state.gd")
|
||||
const walls_mini_material = preload("../walls_mini.tres")
|
||||
const walls_material = preload("../walls.tres")
|
||||
|
||||
func _on_enter():
|
||||
room.wall_mesh.visible = true
|
||||
room.ceiling_mesh.visible = true
|
||||
room.wall_mesh.material_override = walls_mini_material
|
||||
room.room_ceiling.get_node("CollisionShape3D").disabled = true
|
||||
room.room_floor.get_node("CollisionShape3D").disabled = true
|
||||
|
||||
for collision in room.wall_collisions.get_children():
|
||||
collision.get_child(0).disabled = true
|
||||
|
||||
for corner in room.wall_corners.get_children():
|
||||
corner.get_node("CollisionShape3D").disabled = true
|
||||
|
||||
for edge in room.wall_edges.get_children():
|
||||
edge.get_node("CollisionShape3D").disabled = true
|
||||
|
||||
|
||||
|
||||
func _on_leave():
|
||||
room.wall_mesh.visible = false
|
||||
room.ceiling_mesh.visible = false
|
||||
room.wall_mesh.material_override = walls_material
|
||||
room.room_ceiling.get_node("CollisionShape3D").disabled = false
|
||||
room.room_floor.get_node("CollisionShape3D").disabled = false
|
||||
|
||||
for collision in room.wall_collisions.get_children():
|
||||
collision.get_child(0).disabled = false
|
||||
|
||||
for corner in room.wall_corners.get_children():
|
||||
corner.get_node("CollisionShape3D").disabled = false
|
||||
|
||||
for edge in room.wall_edges.get_children():
|
||||
edge.get_node("CollisionShape3D").disabled = false
|
||||
|
||||
|
7
content/system/house/room/states/room_state.gd
Normal file
7
content/system/house/room/states/room_state.gd
Normal file
|
@ -0,0 +1,7 @@
|
|||
extends State
|
||||
const Room = preload("res://content/system/house/room/room.gd")
|
||||
|
||||
var room: Room
|
||||
|
||||
func _ready():
|
||||
room = get_parent().get_parent()
|
144
content/system/house/room/states/view.gd
Normal file
144
content/system/house/room/states/view.gd
Normal file
|
@ -0,0 +1,144 @@
|
|||
extends RoomState
|
||||
|
||||
const RoomState = preload("./room_state.gd")
|
||||
|
||||
var room_height = 3
|
||||
var corner_count = 0
|
||||
|
||||
func _on_enter():
|
||||
corner_count = room.wall_corners.get_child_count()
|
||||
|
||||
if corner_count < 3:
|
||||
return
|
||||
|
||||
room_height = room.room_ceiling.position.y
|
||||
|
||||
room.wall_mesh.visible = true
|
||||
room.ceiling_mesh.visible = true
|
||||
room.wall_mesh.mesh = generate_mesh()
|
||||
|
||||
if room.wall_mesh.mesh == null:
|
||||
return
|
||||
|
||||
var ceiling_shape = room.room_ceiling.get_node("CollisionShape3D")
|
||||
var floor_shape = room.room_floor.get_node("CollisionShape3D")
|
||||
|
||||
ceiling_shape.disabled = false
|
||||
floor_shape.disabled = false
|
||||
|
||||
room.ceiling_mesh.mesh = generate_ceiling_mesh()
|
||||
ceiling_shape.shape = room.ceiling_mesh.mesh.create_trimesh_shape()
|
||||
floor_shape.shape = room.ceiling_mesh.mesh.create_trimesh_shape()
|
||||
ceiling_shape.shape.backface_collision = true
|
||||
|
||||
var collisions = generate_collision()
|
||||
|
||||
for collision in collisions:
|
||||
var static_body = StaticBody3D.new()
|
||||
static_body.set_collision_layer_value(4, true)
|
||||
static_body.set_collision_layer_value(5, true)
|
||||
static_body.collision_mask = 0
|
||||
static_body.add_child(collision)
|
||||
room.wall_collisions.add_child(static_body)
|
||||
|
||||
room.wall_mesh.visible = true
|
||||
|
||||
func _on_leave():
|
||||
room.wall_mesh.visible = false
|
||||
room.ceiling_mesh.visible = false
|
||||
|
||||
room.room_ceiling.get_node("CollisionShape3D").disabled = true
|
||||
room.room_floor.get_node("CollisionShape3D").disabled = true
|
||||
|
||||
for collision in room.wall_collisions.get_children():
|
||||
collision.queue_free()
|
||||
|
||||
func generate_mesh():
|
||||
var st = SurfaceTool.new()
|
||||
var wall_up = Vector3.UP * room_height
|
||||
|
||||
st.begin(Mesh.PRIMITIVE_TRIANGLE_STRIP)
|
||||
|
||||
for i in range(corner_count):
|
||||
var corner = room.get_corner(i)
|
||||
|
||||
st.add_vertex(corner.position)
|
||||
st.add_vertex(corner.position + wall_up)
|
||||
|
||||
var first_corner = room.get_corner(0)
|
||||
|
||||
st.add_vertex(first_corner.position)
|
||||
st.add_vertex(first_corner.position + wall_up)
|
||||
|
||||
st.index()
|
||||
st.generate_normals()
|
||||
st.generate_tangents()
|
||||
var mesh = st.commit()
|
||||
|
||||
return mesh
|
||||
|
||||
func generate_ceiling_mesh():
|
||||
var points: PackedVector2Array = PackedVector2Array()
|
||||
var edges: PackedInt32Array = PackedInt32Array()
|
||||
var triangles: PackedInt32Array
|
||||
|
||||
for i in range(corner_count):
|
||||
var corner = room.get_corner(i)
|
||||
points.append(Vector2(corner.position.x, corner.position.z))
|
||||
edges.append(i)
|
||||
edges.append((i + 1) % corner_count)
|
||||
|
||||
var cdt: ConstrainedTriangulation = ConstrainedTriangulation.new()
|
||||
|
||||
cdt.init(true, true, 0.1)
|
||||
|
||||
cdt.insert_vertices(points)
|
||||
cdt.insert_edges(edges)
|
||||
|
||||
cdt.erase_outer_triangles()
|
||||
|
||||
points = cdt.get_all_vertices()
|
||||
triangles = cdt.get_all_triangles()
|
||||
|
||||
var st = SurfaceTool.new()
|
||||
|
||||
st.begin(Mesh.PRIMITIVE_TRIANGLES)
|
||||
|
||||
for i in range(points.size()):
|
||||
st.add_vertex(Vector3(points[i].x, 0, points[i].y))
|
||||
|
||||
for i in range(triangles.size()):
|
||||
st.add_index(triangles[i])
|
||||
|
||||
st.index()
|
||||
st.generate_normals()
|
||||
st.generate_tangents()
|
||||
|
||||
var mesh = st.commit()
|
||||
|
||||
return mesh
|
||||
|
||||
func generate_collision():
|
||||
var collision_shapes: Array[CollisionShape3D] = []
|
||||
|
||||
for i in range(corner_count):
|
||||
var corner = room.get_corner(i)
|
||||
var next_corner = room.get_corner(i + 1)
|
||||
|
||||
var shape = BoxShape3D.new()
|
||||
shape.size = Vector3((next_corner.position - corner.position).length(), room_height, 0.04)
|
||||
|
||||
var transform = Transform3D()
|
||||
var back_vector = (corner.position - next_corner.position).cross(Vector3.UP).normalized() * shape.size.z / 2
|
||||
|
||||
transform.basis = Basis((next_corner.position - corner.position).normalized(), Vector3.UP, back_vector.normalized())
|
||||
transform.origin = corner.position + (next_corner.position - corner.position) / 2 + back_vector + Vector3.UP * shape.size.y / 2
|
||||
|
||||
var collision_shape = CollisionShape3D.new()
|
||||
|
||||
collision_shape.shape = shape
|
||||
collision_shape.transform = transform
|
||||
|
||||
collision_shapes.append(collision_shape)
|
||||
|
||||
return collision_shapes
|
|
@ -3,7 +3,7 @@
|
|||
[ext_resource type="Script" path="res://content/functions/clickable.gd" id="1_e5awq"]
|
||||
|
||||
[sub_resource type="SphereShape3D" id="SphereShape3D_86rci"]
|
||||
radius = 0.05
|
||||
radius = 0.1
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_i1w3w"]
|
||||
transparency = 1
|
16
content/system/house/room/wall_edge.gd
Normal file
16
content/system/house/room/wall_edge.gd
Normal file
|
@ -0,0 +1,16 @@
|
|||
extends StaticBody3D
|
||||
|
||||
|
||||
func align_to_corners(from_pos: Vector3, to_pos: Vector3):
|
||||
var diff = to_pos - from_pos
|
||||
var direction = diff.normalized()
|
||||
var tangent = Vector3(direction.z, 0, -direction.x).normalized()
|
||||
|
||||
if tangent == Vector3.ZERO:
|
||||
tangent = Vector3(1, 0, 0)
|
||||
|
||||
var edge_position = from_pos + diff / 2
|
||||
|
||||
var edge_basis = Basis(tangent, diff, tangent.cross(direction))
|
||||
|
||||
transform = Transform3D(edge_basis, edge_position)
|
26
content/system/house/room/wall_edge.tscn
Normal file
26
content/system/house/room/wall_edge.tscn
Normal file
|
@ -0,0 +1,26 @@
|
|||
[gd_scene load_steps=6 format=3 uid="uid://dlj5chj7ndgua"]
|
||||
|
||||
[ext_resource type="Script" path="res://content/system/house/room/wall_edge.gd" id="1_0c5rj"]
|
||||
[ext_resource type="Material" uid="uid://j12e5wwthtaa" path="res://content/system/house/room/edge.tres" id="1_hs3tw"]
|
||||
[ext_resource type="Script" path="res://content/functions/clickable.gd" id="2_cfvx2"]
|
||||
|
||||
[sub_resource type="CapsuleMesh" id="CapsuleMesh_a2dct"]
|
||||
material = ExtResource("1_hs3tw")
|
||||
radius = 0.01
|
||||
height = 1.0
|
||||
|
||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_6m53l"]
|
||||
radius = 0.04
|
||||
height = 1.0
|
||||
|
||||
[node name="StaticBody3D" type="StaticBody3D"]
|
||||
script = ExtResource("1_0c5rj")
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||
mesh = SubResource("CapsuleMesh_a2dct")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||
shape = SubResource("CapsuleShape3D_6m53l")
|
||||
|
||||
[node name="Clickable" type="Node" parent="."]
|
||||
script = ExtResource("2_cfvx2")
|
3
content/system/house/room/walls_mini.tres
Normal file
3
content/system/house/room/walls_mini.tres
Normal file
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e6b87dd767a03b39f93f17a71b75b3a6ce82623a7703c24722dd112e31718376
|
||||
size 157
|
|
@ -90,5 +90,4 @@ func _emit_event(type: String, key: Key):
|
|||
event.shift_pressed = caps
|
||||
|
||||
EventSystem.emit(type, event)
|
||||
print("Emitting event: " + type + " " + EventKey.key_to_string(key, caps))
|
||||
|
||||
|
|
|
@ -1,205 +0,0 @@
|
|||
extends Node3D
|
||||
|
||||
const wall_corner_scene = preload("./wall_corner.tscn")
|
||||
const wall_edge_scene = preload("./wall_edge.tscn")
|
||||
|
||||
@onready var wall_corners = $WallCorners
|
||||
@onready var wall_edges = $WallEdges
|
||||
@onready var wall_mesh = $WallMesh
|
||||
@onready var wall_collisions = $WallCollisions
|
||||
|
||||
@onready var ground = $Ground/Clickable
|
||||
|
||||
var moving = null
|
||||
var editable := false:
|
||||
set(value):
|
||||
if value == editable:
|
||||
return
|
||||
|
||||
editable = value
|
||||
if value:
|
||||
_start_edit_mode()
|
||||
else:
|
||||
_end_edit_mode()
|
||||
var ground_plane = Plane(Vector3.UP, Vector3.ZERO)
|
||||
|
||||
|
||||
func _ready():
|
||||
ground.on_click.connect(func(event):
|
||||
if !editable:
|
||||
return
|
||||
|
||||
add_corner(event.ray.get_collision_point())
|
||||
)
|
||||
|
||||
func _start_edit_mode():
|
||||
wall_corners.visible = true
|
||||
wall_edges.visible = true
|
||||
wall_mesh.visible = false
|
||||
wall_mesh.mesh = null
|
||||
|
||||
for old_coll in wall_collisions.get_children():
|
||||
old_coll.queue_free()
|
||||
|
||||
func _end_edit_mode():
|
||||
wall_corners.visible = false
|
||||
wall_edges.visible = false
|
||||
wall_mesh.mesh = generate_mesh()
|
||||
|
||||
if wall_mesh.mesh == null:
|
||||
return
|
||||
|
||||
var collisions = generate_collision(wall_mesh.mesh)
|
||||
|
||||
for collision in collisions:
|
||||
var static_body = StaticBody3D.new()
|
||||
static_body.set_collision_layer_value(4, true)
|
||||
static_body.set_collision_layer_value(5, true)
|
||||
static_body.collision_mask = 0
|
||||
static_body.add_child(collision)
|
||||
wall_collisions.add_child(static_body)
|
||||
|
||||
wall_mesh.visible = true
|
||||
|
||||
func generate_mesh():
|
||||
var corner_count = wall_corners.get_child_count()
|
||||
|
||||
if corner_count < 3:
|
||||
return
|
||||
|
||||
var st = SurfaceTool.new()
|
||||
var wall_up = Vector3.UP * 3
|
||||
|
||||
st.begin(Mesh.PRIMITIVE_TRIANGLE_STRIP)
|
||||
|
||||
for i in range(corner_count):
|
||||
var corner = get_corner(i)
|
||||
|
||||
st.add_vertex(corner.position)
|
||||
st.add_vertex(corner.position + wall_up)
|
||||
|
||||
var first_corner = get_corner(0)
|
||||
|
||||
st.add_vertex(first_corner.position)
|
||||
st.add_vertex(first_corner.position + wall_up)
|
||||
|
||||
st.index()
|
||||
st.generate_normals()
|
||||
st.generate_tangents()
|
||||
var mesh = st.commit()
|
||||
|
||||
return mesh
|
||||
|
||||
func generate_collision(mesh: ArrayMesh):
|
||||
var corner_count = wall_corners.get_child_count()
|
||||
|
||||
if corner_count < 3:
|
||||
return
|
||||
|
||||
var collision_shapes: Array[CollisionShape3D] = []
|
||||
|
||||
for i in range(corner_count):
|
||||
var corner = get_corner(i)
|
||||
var next_corner = get_corner(i + 1)
|
||||
|
||||
var shape = BoxShape3D.new()
|
||||
shape.size = Vector3((next_corner.position - corner.position).length(), 3, 0.04)
|
||||
|
||||
var transform = Transform3D()
|
||||
var back_vector = (corner.position - next_corner.position).cross(Vector3.UP).normalized() * shape.size.z / 2
|
||||
|
||||
transform.basis = Basis((next_corner.position - corner.position).normalized(), Vector3.UP, back_vector.normalized())
|
||||
transform.origin = corner.position + (next_corner.position - corner.position) / 2 + back_vector + Vector3.UP * shape.size.y / 2
|
||||
|
||||
var collision_shape = CollisionShape3D.new()
|
||||
|
||||
collision_shape.shape = shape
|
||||
collision_shape.transform = transform
|
||||
|
||||
collision_shapes.append(collision_shape)
|
||||
|
||||
return collision_shapes
|
||||
|
||||
func add_corner(position: Vector3):
|
||||
var corner = wall_corner_scene.instantiate()
|
||||
corner.position = position
|
||||
|
||||
corner.get_node("Clickable").on_grab_down.connect(func(event):
|
||||
if !editable:
|
||||
return
|
||||
|
||||
moving = event.target
|
||||
)
|
||||
|
||||
corner.get_node("Clickable").on_grab_move.connect(func(event):
|
||||
if moving == null:
|
||||
return
|
||||
|
||||
var direction = -event.ray.global_transform.basis.z
|
||||
var new_position = ground_plane.intersects_ray(event.ray.global_position, direction)
|
||||
|
||||
if new_position == null:
|
||||
return
|
||||
|
||||
moving.position = new_position
|
||||
var moving_index = moving.get_index()
|
||||
|
||||
get_edge(moving_index).transform = corners_to_edge_transform(new_position, get_corner(moving_index + 1).position)
|
||||
get_edge(moving_index - 1).transform = corners_to_edge_transform(get_corner(moving_index - 1).position, new_position)
|
||||
)
|
||||
|
||||
corner.get_node("Clickable").on_grab_up.connect(func(_event):
|
||||
moving = null
|
||||
)
|
||||
|
||||
wall_corners.add_child(corner)
|
||||
|
||||
|
||||
var num_corners = wall_corners.get_child_count()
|
||||
var edge
|
||||
|
||||
if num_corners > 1:
|
||||
edge = add_edge(wall_corners.get_child(num_corners - 2).position, position)
|
||||
|
||||
if num_corners > 2:
|
||||
if num_corners != wall_edges.get_child_count():
|
||||
add_edge(position, wall_corners.get_child(0).position)
|
||||
else:
|
||||
wall_edges.move_child(edge, num_corners - 2)
|
||||
get_edge(-1).transform = corners_to_edge_transform(position, get_corner(0).position)
|
||||
|
||||
func get_corner(index: int) -> MeshInstance3D:
|
||||
return wall_corners.get_child(index % wall_corners.get_child_count())
|
||||
|
||||
func get_edge(index: int) -> MeshInstance3D:
|
||||
return wall_edges.get_child(index % wall_edges.get_child_count())
|
||||
|
||||
|
||||
func add_edge(from_pos: Vector3, to_pos: Vector3):
|
||||
var edge: MeshInstance3D = wall_edge_scene.instantiate()
|
||||
edge.transform = corners_to_edge_transform(from_pos, to_pos)
|
||||
wall_edges.add_child(edge)
|
||||
return edge
|
||||
|
||||
func corners_to_edge_transform(from_pos: Vector3, to_pos: Vector3) -> Transform3D:
|
||||
var diff = to_pos - from_pos
|
||||
var direction = diff.normalized()
|
||||
|
||||
var edge_position = from_pos + diff / 2
|
||||
var edge_basis = Basis(Vector3.UP, diff, direction.cross(Vector3.UP))
|
||||
|
||||
var edge_transform = Transform3D(edge_basis, edge_position)
|
||||
return edge_transform
|
||||
|
||||
func _save():
|
||||
return {
|
||||
"corners": wall_corners.get_children().map(func(corner): return corner.position),
|
||||
}
|
||||
|
||||
func _load(data):
|
||||
await ready
|
||||
|
||||
for corner in data["corners"]:
|
||||
add_corner(corner)
|
||||
|
||||
_end_edit_mode()
|
|
@ -1,42 +0,0 @@
|
|||
[gd_scene load_steps=7 format=3 uid="uid://bswgmclohuqui"]
|
||||
|
||||
[ext_resource type="Script" path="res://content/system/room/room.gd" id="1_fccq0"]
|
||||
[ext_resource type="Script" path="res://content/functions/clickable.gd" id="1_ugebq"]
|
||||
[ext_resource type="Material" uid="uid://bbx6fv7jq50tr" path="res://content/system/room/walls.tres" id="3_al1ev"]
|
||||
|
||||
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_08sv0"]
|
||||
|
||||
[sub_resource type="ArrayMesh" id="ArrayMesh_7dibq"]
|
||||
|
||||
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_ap613"]
|
||||
|
||||
[node name="Room" type="Node3D"]
|
||||
script = ExtResource("1_fccq0")
|
||||
|
||||
[node name="Ground" type="StaticBody3D" parent="."]
|
||||
collision_layer = 24
|
||||
collision_mask = 0
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Ground"]
|
||||
shape = SubResource("WorldBoundaryShape3D_08sv0")
|
||||
|
||||
[node name="Clickable" type="Node" parent="Ground"]
|
||||
script = ExtResource("1_ugebq")
|
||||
|
||||
[node name="WallCorners" type="Node3D" parent="."]
|
||||
|
||||
[node name="WallEdges" type="Node3D" parent="."]
|
||||
|
||||
[node name="WallMesh" type="MeshInstance3D" parent="."]
|
||||
material_override = ExtResource("3_al1ev")
|
||||
mesh = SubResource("ArrayMesh_7dibq")
|
||||
|
||||
[node name="WallCollisions" type="Node3D" parent="."]
|
||||
|
||||
[node name="Celing" type="StaticBody3D" parent="."]
|
||||
transform = Transform3D(-1, 8.74228e-08, 0, -8.74228e-08, -1, 0, 0, 0, 1, 0, 3.07, 0)
|
||||
collision_layer = 0
|
||||
collision_mask = 0
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Celing"]
|
||||
shape = SubResource("WorldBoundaryShape3D_ap613")
|
|
@ -1,11 +0,0 @@
|
|||
[gd_scene load_steps=3 format=3 uid="uid://dlj5chj7ndgua"]
|
||||
|
||||
[ext_resource type="Material" uid="uid://j12e5wwthtaa" path="res://content/ui/menu/room/edge.tres" id="1_b21dw"]
|
||||
|
||||
[sub_resource type="CapsuleMesh" id="CapsuleMesh_a2dct"]
|
||||
material = ExtResource("1_b21dw")
|
||||
radius = 0.01
|
||||
height = 1.0
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D"]
|
||||
mesh = SubResource("CapsuleMesh_a2dct")
|
|
@ -3,8 +3,6 @@
|
|||
extends Node3D
|
||||
class_name Button3D
|
||||
|
||||
const Proxy = preload("res://lib/utils/proxy.gd")
|
||||
|
||||
signal on_button_down()
|
||||
signal on_button_up()
|
||||
|
||||
|
@ -38,7 +36,7 @@ const IconFont = preload("res://assets/icons/icons.tres")
|
|||
|
||||
if value:
|
||||
label_node.font = IconFont
|
||||
label_node.font_size = 48
|
||||
label_node.font_size = 36
|
||||
label_node.width = 1000
|
||||
label_node.autowrap_mode = TextServer.AUTOWRAP_OFF
|
||||
else:
|
||||
|
@ -50,13 +48,24 @@ const IconFont = preload("res://assets/icons/icons.tres")
|
|||
@export var toggleable: bool = false
|
||||
@export var disabled: bool = false
|
||||
@export var initial_active: bool = false
|
||||
var external_value: Proxy = null
|
||||
var external_value: Proxy = null:
|
||||
set(value):
|
||||
if !is_node_ready(): await ready
|
||||
|
||||
external_value = value
|
||||
if value != null:
|
||||
value.on_set.connect(func(_value):
|
||||
update_animation()
|
||||
)
|
||||
|
||||
var active: bool = false:
|
||||
get:
|
||||
if external_value != null:
|
||||
return external_value.value
|
||||
return active
|
||||
set(value):
|
||||
if !is_node_ready(): await ready
|
||||
|
||||
if external_value != null:
|
||||
external_value.value = value
|
||||
else:
|
||||
|
|
|
@ -116,7 +116,6 @@ func update_caret_position(event):
|
|||
|
||||
|
||||
func _on_focus_out(_event):
|
||||
print("focus out")
|
||||
animation.stop()
|
||||
caret.hide()
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ extends Node3D
|
|||
set(value):
|
||||
type = value
|
||||
if !is_node_ready(): await ready
|
||||
print(value, " ", _type_to_string(value))
|
||||
icon_label.text = _type_to_string(value)
|
||||
@export var text: String = "":
|
||||
set(value):
|
||||
|
|
28
content/ui/components/tabs/tabs.gd
Normal file
28
content/ui/components/tabs/tabs.gd
Normal file
|
@ -0,0 +1,28 @@
|
|||
extends Node3D
|
||||
class_name Tabs3D
|
||||
|
||||
signal on_select(selected: int)
|
||||
|
||||
var selected: Node3D
|
||||
@export var initial_selected: Node3D
|
||||
var proxy_group = ProxyGroup.new()
|
||||
|
||||
func _ready():
|
||||
if initial_selected != null:
|
||||
selected = initial_selected
|
||||
on_select.emit(selected.get_index())
|
||||
|
||||
for option in get_children():
|
||||
if option is Button3D == false:
|
||||
continue
|
||||
|
||||
var proxy = proxy_group.proxy(func():
|
||||
return selected == option
|
||||
, func(value: bool):
|
||||
if value == true:
|
||||
selected = option
|
||||
on_select.emit(selected.get_index())
|
||||
)
|
||||
|
||||
option.external_value = proxy
|
||||
option.toggleable = true
|
6
content/ui/components/tabs/tabs.tscn
Normal file
6
content/ui/components/tabs/tabs.tscn
Normal file
|
@ -0,0 +1,6 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://doavdm6fskmrt"]
|
||||
|
||||
[ext_resource type="Script" path="res://content/ui/components/tabs/tabs.gd" id="1_xt6wm"]
|
||||
|
||||
[node name="Tabs" type="Node3D"]
|
||||
script = ExtResource("1_xt6wm")
|
22
content/ui/components/tabs/tabs_content.gd
Normal file
22
content/ui/components/tabs/tabs_content.gd
Normal file
|
@ -0,0 +1,22 @@
|
|||
extends Node3D
|
||||
class_name TabsContent3D
|
||||
|
||||
@export var tabs: Tabs3D
|
||||
|
||||
var children: Array = []
|
||||
|
||||
func _ready():
|
||||
children = get_children()
|
||||
|
||||
for child in children:
|
||||
child.visible = true
|
||||
if tabs.selected != null && tabs.selected.get_index() == child.get_index():
|
||||
continue
|
||||
remove_child(child)
|
||||
|
||||
tabs.on_select.connect(func(index):
|
||||
for child in get_children():
|
||||
remove_child(child)
|
||||
|
||||
add_child(children[index])
|
||||
)
|
6
content/ui/components/tabs/tabs_content.tscn
Normal file
6
content/ui/components/tabs/tabs_content.tscn
Normal file
|
@ -0,0 +1,6 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://wewhef3qmulp"]
|
||||
|
||||
[ext_resource type="Script" path="res://content/ui/components/tabs/tabs_content.gd" id="1_ljgkj"]
|
||||
|
||||
[node name="TabsContent" type="Node3D"]
|
||||
script = ExtResource("1_ljgkj")
|
|
@ -1,7 +1,6 @@
|
|||
extends Node3D
|
||||
|
||||
const ButtonScene = preload("res://content/ui/components/button/button.tscn")
|
||||
const EntityCreator = preload("./entity_creator.gd")
|
||||
|
||||
@onready var devices_node: GridContainer3D = $Devices
|
||||
@onready var next_page_button = $Buttons/NextPageButton
|
||||
|
@ -145,22 +144,11 @@ func _on_entity_click(entity_name):
|
|||
render()
|
||||
return
|
||||
|
||||
var type = entity_name.split(".")[0]
|
||||
AudioPlayer.play_effect("spawn")
|
||||
|
||||
var entity = EntityCreator.create_entity(type, entity_name)
|
||||
|
||||
if entity == null:
|
||||
return
|
||||
|
||||
entity.set_position(global_position)
|
||||
get_node("/root/Main").add_child(entity)
|
||||
House.body.create_entity(entity_name, global_position)
|
||||
|
||||
func clear_menu():
|
||||
for child in devices_node.get_children():
|
||||
devices_node.remove_child(child)
|
||||
child.queue_free()
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta):
|
||||
pass
|
||||
child.queue_free()
|
|
@ -3,15 +3,6 @@ extends Node3D
|
|||
const Proxy = preload("res://lib/utils/proxy.gd")
|
||||
const Notification = preload("res://content/ui/components/notification/notification.tscn")
|
||||
|
||||
@onready var nav_view = $AnimationContainer/Navigation/View
|
||||
@onready var nav_edit: Button3D = $AnimationContainer/Navigation/Edit
|
||||
@onready var menu_edit: Node3D = $AnimationContainer/Content/EditMenu
|
||||
@onready var nav_room = $AnimationContainer/Navigation/Room
|
||||
@onready var menu_room: Node3D = $AnimationContainer/Content/RoomMenu
|
||||
@onready var nav_automate = $AnimationContainer/Navigation/Automate
|
||||
@onready var nav_settings = $AnimationContainer/Navigation/Settings
|
||||
@onready var menu_settings: Node3D = $AnimationContainer/Content/SettingsMenu
|
||||
|
||||
@onready var menu_root = $AnimationContainer
|
||||
@onready var content = $AnimationContainer/Content
|
||||
@onready var nav = $AnimationContainer/Navigation
|
||||
|
@ -41,61 +32,3 @@ func _ready():
|
|||
|
||||
notify_place.add_child(notification_node)
|
||||
)
|
||||
|
||||
var nav_buttons = [
|
||||
nav_view,
|
||||
nav_edit,
|
||||
nav_room,
|
||||
nav_automate,
|
||||
nav_settings
|
||||
]
|
||||
|
||||
for nav_button in nav_buttons:
|
||||
var getter = func():
|
||||
return nav_button == selected_nav
|
||||
|
||||
var setter = func(value):
|
||||
if value:
|
||||
select_menu(nav_button)
|
||||
|
||||
nav_button.external_value = Proxy.new(getter, setter)
|
||||
|
||||
select_menu(nav_edit)
|
||||
|
||||
func select_menu(nav):
|
||||
if _is_valid_nav(nav) == false || selected_nav == nav:
|
||||
return
|
||||
|
||||
for child in content.get_children():
|
||||
content.remove_child(child)
|
||||
|
||||
var old_nav = selected_nav
|
||||
|
||||
selected_nav = nav
|
||||
|
||||
if old_nav != null:
|
||||
old_nav.update_animation()
|
||||
|
||||
if selected_nav != null:
|
||||
selected_nav.update_animation()
|
||||
var menu = _nav_to_menu(selected_nav)
|
||||
if menu != null:
|
||||
content.add_child(menu)
|
||||
menu.visible = true
|
||||
|
||||
func _is_valid_nav(nav):
|
||||
return nav == nav_view || nav == nav_edit || nav == nav_room || nav == nav_automate || nav == nav_settings
|
||||
|
||||
func _nav_to_menu(nav):
|
||||
match nav:
|
||||
nav_view:
|
||||
return null
|
||||
nav_edit:
|
||||
return menu_edit
|
||||
nav_room:
|
||||
return menu_room
|
||||
nav_automate:
|
||||
return null
|
||||
nav_settings:
|
||||
return menu_settings
|
||||
return null
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
[gd_scene load_steps=16 format=3 uid="uid://c3kdssrmv84kv"]
|
||||
[gd_scene load_steps=19 format=3 uid="uid://c3kdssrmv84kv"]
|
||||
|
||||
[ext_resource type="Script" path="res://content/ui/menu/menu.gd" id="1_ng4u3"]
|
||||
[ext_resource type="Material" uid="uid://bnwimm214q67g" path="res://assets/materials/sec-500.material" id="2_0x5at"]
|
||||
[ext_resource type="Script" path="res://content/functions/movable.gd" id="2_8coxu"]
|
||||
[ext_resource type="Script" path="res://content/ui/components/tabs/tabs.gd" id="4_eavfx"]
|
||||
[ext_resource type="PackedScene" uid="uid://crrb0l3ekuotj" path="res://content/ui/menu/edit/edit_menu.tscn" id="4_r2raj"]
|
||||
[ext_resource type="PackedScene" uid="uid://bsjqdvkt0u87c" path="res://content/ui/components/button/button.tscn" id="5_w4i01"]
|
||||
[ext_resource type="Script" path="res://content/ui/components/tabs/tabs_content.gd" id="6_7rntr"]
|
||||
[ext_resource type="ArrayMesh" uid="uid://cbqhhnknyium2" path="res://assets/immersive_home_panels/immersive_home_panels.obj" id="7_f4u4o"]
|
||||
[ext_resource type="PackedScene" uid="uid://ddpxthb414unp" path="res://content/ui/menu/view/view_menu.tscn" id="8_71pkg"]
|
||||
[ext_resource type="PackedScene" uid="uid://c01gkeldvjwtr" path="res://content/ui/menu/room/room_menu.tscn" id="10_u4i1x"]
|
||||
[ext_resource type="PackedScene" uid="uid://c6r4higceibif" path="res://content/ui/menu/settings/settings_menu.tscn" id="11_7wm6b"]
|
||||
|
||||
|
@ -181,48 +184,58 @@ skeleton = NodePath("../..")
|
|||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.21, 0, 0.15)
|
||||
shape = SubResource("ConvexPolygonShape3D_mgnm0")
|
||||
|
||||
[node name="Navigation" type="Node3D" parent="AnimationContainer"]
|
||||
[node name="Tabs" type="Node3D" parent="AnimationContainer" node_paths=PackedStringArray("initial_selected")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.06, 0, 0)
|
||||
script = ExtResource("4_eavfx")
|
||||
initial_selected = NodePath("View")
|
||||
|
||||
[node name="View" parent="AnimationContainer/Navigation" instance=ExtResource("5_w4i01")]
|
||||
[node name="View" parent="AnimationContainer/Tabs" instance=ExtResource("5_w4i01")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.03, 0, 0.03)
|
||||
label = "visibility"
|
||||
icon = true
|
||||
toggleable = true
|
||||
|
||||
[node name="Edit" parent="AnimationContainer/Navigation" instance=ExtResource("5_w4i01")]
|
||||
[node name="Edit" parent="AnimationContainer/Tabs" instance=ExtResource("5_w4i01")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.03, 0, 0.09)
|
||||
label = "widgets"
|
||||
icon = true
|
||||
toggleable = true
|
||||
|
||||
[node name="Room" parent="AnimationContainer/Navigation" instance=ExtResource("5_w4i01")]
|
||||
[node name="Room" parent="AnimationContainer/Tabs" instance=ExtResource("5_w4i01")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.03, 0, 0.15)
|
||||
label = "view_in_ar"
|
||||
icon = true
|
||||
toggleable = true
|
||||
|
||||
[node name="Automate" parent="AnimationContainer/Navigation" instance=ExtResource("5_w4i01")]
|
||||
[node name="Automate" parent="AnimationContainer/Tabs" instance=ExtResource("5_w4i01")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.03, 0, 0.21)
|
||||
label = "schema"
|
||||
icon = true
|
||||
toggleable = true
|
||||
|
||||
[node name="Settings" parent="AnimationContainer/Navigation" instance=ExtResource("5_w4i01")]
|
||||
[node name="Settings" parent="AnimationContainer/Tabs" instance=ExtResource("5_w4i01")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.03, 0, 0.27)
|
||||
label = "settings"
|
||||
icon = true
|
||||
toggleable = true
|
||||
|
||||
[node name="Content" type="Node3D" parent="AnimationContainer"]
|
||||
[node name="TabsContent" type="Node3D" parent="AnimationContainer" node_paths=PackedStringArray("tabs")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.06, 0, 0)
|
||||
script = ExtResource("6_7rntr")
|
||||
tabs = NodePath("../Tabs")
|
||||
|
||||
[node name="EditMenu" parent="AnimationContainer/Content" instance=ExtResource("4_r2raj")]
|
||||
|
||||
[node name="RoomMenu" parent="AnimationContainer/Content" instance=ExtResource("10_u4i1x")]
|
||||
[node name="ViewMenu" parent="AnimationContainer/TabsContent" instance=ExtResource("8_71pkg")]
|
||||
visible = false
|
||||
|
||||
[node name="SettingsMenu" parent="AnimationContainer/Content" instance=ExtResource("11_7wm6b")]
|
||||
[node name="EditMenu" parent="AnimationContainer/TabsContent" instance=ExtResource("4_r2raj")]
|
||||
|
||||
[node name="RoomMenu" parent="AnimationContainer/TabsContent" instance=ExtResource("10_u4i1x")]
|
||||
visible = false
|
||||
|
||||
[node name="AutomateMenu" type="Node3D" parent="AnimationContainer/TabsContent"]
|
||||
visible = false
|
||||
|
||||
[node name="SettingsMenu" parent="AnimationContainer/TabsContent" instance=ExtResource("11_7wm6b")]
|
||||
visible = false
|
||||
|
||||
[node name="NotifyPlace" type="Marker3D" parent="AnimationContainer"]
|
||||
|
|
|
@ -1,40 +1,16 @@
|
|||
extends Node3D
|
||||
|
||||
const Room = preload("res://content/system/room/room.tscn")
|
||||
|
||||
const window_scene = preload("./window.tscn")
|
||||
|
||||
@onready var background = $Background
|
||||
@onready var toggle_edit_button = $Interface/ToggleEdit
|
||||
@onready var spawn_windows = $SpawnWindows
|
||||
@onready var rooms = get_tree().root.get_node("Main/Rooms")
|
||||
var room: Node3D
|
||||
|
||||
func _ready():
|
||||
background.visible = false
|
||||
|
||||
HomeApi.on_connect.connect(func():
|
||||
if rooms.get_child_count() == 0:
|
||||
room = Room.instantiate()
|
||||
rooms.add_child(room)
|
||||
else:
|
||||
room = rooms.get_child(0)
|
||||
if rooms.get_child_count() > 1:
|
||||
for child in rooms.get_children():
|
||||
if child != room:
|
||||
child.queue_free()
|
||||
)
|
||||
# var rooms = House.body.get_rooms(0)
|
||||
|
||||
spawn_windows.on_button_down.connect(func():
|
||||
get_tree().root.get_node("Main").add_child.call_deferred(window_scene.instantiate())
|
||||
)
|
||||
|
||||
toggle_edit_button.on_button_down.connect(func():
|
||||
if room != null:
|
||||
room.editable = true
|
||||
)
|
||||
|
||||
toggle_edit_button.on_button_up.connect(func():
|
||||
if room != null:
|
||||
room.editable = false
|
||||
# for room in rooms:
|
||||
# var mesh = room.wall_mesh
|
||||
pass
|
||||
)
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://c01gkeldvjwtr"]
|
||||
[gd_scene load_steps=9 format=3 uid="uid://c01gkeldvjwtr"]
|
||||
|
||||
[ext_resource type="Script" path="res://content/ui/menu/room/room_menu.gd" id="1_ch4jb"]
|
||||
[ext_resource type="Script" path="res://content/functions/clickable.gd" id="2_elugy"]
|
||||
[ext_resource type="PackedScene" uid="uid://bsjqdvkt0u87c" path="res://content/ui/components/button/button.tscn" id="3_whl7a"]
|
||||
[ext_resource type="Material" uid="uid://bujy3egn1oqac" path="res://assets/materials/pri-500.material" id="2_7m4yn"]
|
||||
[ext_resource type="PackedScene" uid="uid://bsjqdvkt0u87c" path="res://content/ui/components/button/button.tscn" id="4_cghmp"]
|
||||
[ext_resource type="Script" path="res://content/ui/components/tabs/tabs.gd" id="5_ddrep"]
|
||||
[ext_resource type="PackedScene" uid="uid://dd71loi64gnmp" path="res://content/ui/menu/room/views/overview.tscn" id="6_206ad"]
|
||||
[ext_resource type="Script" path="res://content/ui/components/tabs/tabs_content.gd" id="6_ba00g"]
|
||||
[ext_resource type="PackedScene" uid="uid://bpta22fahai46" path="res://content/ui/menu/room/views/rooms.tscn" id="7_2f8e0"]
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_e37nn"]
|
||||
size = Vector3(0.3, 0.01, 0.3)
|
||||
|
@ -12,35 +16,27 @@ script = ExtResource("1_ch4jb")
|
|||
|
||||
[node name="Background" type="MeshInstance3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.15, 0, 0.15)
|
||||
material_override = ExtResource("2_7m4yn")
|
||||
mesh = SubResource("BoxMesh_e37nn")
|
||||
|
||||
[node name="Interface" type="Node3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.01, 0)
|
||||
|
||||
[node name="ToggleEdit" parent="Interface" instance=ExtResource("3_whl7a")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.05, 0, 0.05)
|
||||
label = "room_preferences"
|
||||
icon = true
|
||||
toggleable = true
|
||||
[node name="Tabs3D" type="Node3D" parent="Interface" node_paths=PackedStringArray("initial_selected")]
|
||||
script = ExtResource("5_ddrep")
|
||||
initial_selected = NodePath("Overview")
|
||||
|
||||
[node name="Clickable" type="Node" parent="Interface/ToggleEdit"]
|
||||
script = ExtResource("2_elugy")
|
||||
[node name="Overview" parent="Interface/Tabs3D" instance=ExtResource("4_cghmp")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.03, 0, -0.02)
|
||||
label = "Overview"
|
||||
|
||||
[node name="Label3D" type="Label3D" parent="Interface"]
|
||||
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.13, -1.86265e-09, 0.05)
|
||||
pixel_size = 0.001
|
||||
text = "Edit Room"
|
||||
font_size = 18
|
||||
outline_size = 0
|
||||
[node name="Rooms" parent="Interface/Tabs3D" instance=ExtResource("4_cghmp")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.09, 0, -0.02)
|
||||
label = "Rooms"
|
||||
|
||||
[node name="CreateBlur" type="Label3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.15, 0.01, 0.261858)
|
||||
pixel_size = 0.001
|
||||
text = "Fake Windows"
|
||||
font_size = 18
|
||||
outline_size = 0
|
||||
[node name="TabsContent3D" type="Node3D" parent="Interface" node_paths=PackedStringArray("tabs")]
|
||||
script = ExtResource("6_ba00g")
|
||||
tabs = NodePath("../Tabs3D")
|
||||
|
||||
[node name="SpawnWindows" parent="." instance=ExtResource("3_whl7a")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.05, 0, 0.26)
|
||||
label = "lens_blur"
|
||||
icon = true
|
||||
[node name="Overview" parent="Interface/TabsContent3D" instance=ExtResource("6_206ad")]
|
||||
|
||||
[node name="Rooms" parent="Interface/TabsContent3D" instance=ExtResource("7_2f8e0")]
|
||||
|
|
3
content/ui/menu/room/room_selected.tres
Normal file
3
content/ui/menu/room/room_selected.tres
Normal file
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:5245272378c86fb17cf012dee95460df366d7781d3119604e447ae2330de7199
|
||||
size 134
|
3
content/ui/menu/room/room_unselected.tres
Normal file
3
content/ui/menu/room/room_unselected.tres
Normal file
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b77e182a6941bd1837cdbae2586f5a7561e033fc26a1a2c50c0eb1a600d40322
|
||||
size 101
|
31
content/ui/menu/room/views/overview.gd
Normal file
31
content/ui/menu/room/views/overview.gd
Normal file
|
@ -0,0 +1,31 @@
|
|||
extends Node3D
|
||||
|
||||
@onready var edit_button = $EditButton
|
||||
@onready var fix_button = $FixButton
|
||||
|
||||
var active = false:
|
||||
set(value):
|
||||
if value:
|
||||
edit_button.label = "save"
|
||||
fix_button.disabled = true
|
||||
fix_button.visible = false
|
||||
else:
|
||||
edit_button.label = "edit"
|
||||
fix_button.disabled = false
|
||||
fix_button.visible = true
|
||||
active = value
|
||||
|
||||
func _ready():
|
||||
|
||||
edit_button.on_button_down.connect(func():
|
||||
if active:
|
||||
House.body.save_reference()
|
||||
else:
|
||||
House.body.edit_reference()
|
||||
active = !active
|
||||
)
|
||||
|
||||
fix_button.on_button_down.connect(func():
|
||||
House.body.fix_reference()
|
||||
active = true
|
||||
)
|
24
content/ui/menu/room/views/overview.tscn
Normal file
24
content/ui/menu/room/views/overview.tscn
Normal file
|
@ -0,0 +1,24 @@
|
|||
[gd_scene load_steps=3 format=3 uid="uid://dd71loi64gnmp"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://bsjqdvkt0u87c" path="res://content/ui/components/button/button.tscn" id="1_fteh8"]
|
||||
[ext_resource type="Script" path="res://content/ui/menu/room/views/overview.gd" id="1_jesad"]
|
||||
|
||||
[node name="Overview" type="Node3D"]
|
||||
script = ExtResource("1_jesad")
|
||||
|
||||
[node name="EditButton" parent="." instance=ExtResource("1_fteh8")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.04, 0, 0.07)
|
||||
label = "edit"
|
||||
icon = true
|
||||
|
||||
[node name="FixButton" parent="." instance=ExtResource("1_fteh8")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.1, 0, 0.07)
|
||||
label = "healing"
|
||||
icon = true
|
||||
|
||||
[node name="Label3D" type="Label3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.06, 0.01, 0.02)
|
||||
pixel_size = 0.001
|
||||
text = "Reference"
|
||||
font_size = 18
|
||||
outline_size = 0
|
130
content/ui/menu/room/views/rooms.gd
Normal file
130
content/ui/menu/room/views/rooms.gd
Normal file
|
@ -0,0 +1,130 @@
|
|||
extends Node3D
|
||||
|
||||
const Room = preload("res://content/system/house/room/room.tscn")
|
||||
const RoomType = preload("res://content/system/house/room/room.gd")
|
||||
|
||||
const material_selected = preload("../room_selected.tres")
|
||||
const material_unselected = preload("../room_unselected.tres")
|
||||
|
||||
|
||||
@onready var room_button = $Button
|
||||
@onready var input = $Input
|
||||
@onready var rooms_map = $Rooms
|
||||
|
||||
var selected_room = null:
|
||||
set(value):
|
||||
if selected_room != null && value == null:
|
||||
room_button.label = "add"
|
||||
input.text = "Room %s" % (rooms_map.get_child_count() + 1)
|
||||
|
||||
if selected_room != null:
|
||||
var old_room = get_room(selected_room)
|
||||
if old_room != null:
|
||||
old_room.get_node("MeshInstance3D").material_override = material_unselected
|
||||
|
||||
if value != null:
|
||||
input.text = value
|
||||
edit_room = false
|
||||
var new_room = get_room(value)
|
||||
if new_room != null:
|
||||
new_room.get_node("MeshInstance3D").material_override = material_selected
|
||||
|
||||
|
||||
selected_room = value
|
||||
|
||||
var edit_room = false:
|
||||
set(value):
|
||||
edit_room = value
|
||||
if value:
|
||||
room_button.label = "save"
|
||||
else:
|
||||
room_button.label = "edit"
|
||||
|
||||
func _ready():
|
||||
|
||||
room_button.on_button_down.connect(func():
|
||||
if selected_room == null:
|
||||
var room_name = input.text
|
||||
if get_room(room_name) != null:
|
||||
EventSystem.notify("Name already taken", EventNotify.Type.WARNING)
|
||||
return
|
||||
|
||||
House.body.create_room(room_name, 0)
|
||||
selected_room = room_name
|
||||
edit_room = true
|
||||
else:
|
||||
if edit_room:
|
||||
edit_room = false
|
||||
|
||||
if !House.body.is_valid_room(selected_room):
|
||||
House.body.delete_room(selected_room)
|
||||
selected_room = null
|
||||
else:
|
||||
House.body.edit_room(null)
|
||||
_generate_room_map()
|
||||
else:
|
||||
edit_room = true
|
||||
House.body.edit_room(selected_room)
|
||||
)
|
||||
|
||||
func get_room(room_name):
|
||||
if rooms_map.has_node("%s" % room_name):
|
||||
return rooms_map.get_node("%s" % room_name)
|
||||
return null
|
||||
|
||||
func _on_click(event: EventPointer):
|
||||
if event.target.get_parent() == rooms_map:
|
||||
var room_name = event.target.name
|
||||
|
||||
if selected_room == room_name:
|
||||
selected_room = null
|
||||
House.body.edit_room(null)
|
||||
return
|
||||
|
||||
selected_room = room_name
|
||||
|
||||
func _generate_room_map():
|
||||
var rooms = House.body.get_rooms(0)
|
||||
|
||||
var target_size = Vector3(0.3, 1, 0.24)
|
||||
|
||||
for old_room in rooms_map.get_children():
|
||||
old_room.queue_free()
|
||||
await old_room.tree_exited
|
||||
|
||||
var aabb = House.body.get_level_aabb(0)
|
||||
var current_min = aabb.position
|
||||
var current_max = aabb.position + aabb.size
|
||||
|
||||
for room in rooms:
|
||||
var mesh = room.ceiling_mesh.mesh
|
||||
if mesh == null:
|
||||
continue
|
||||
|
||||
var body = StaticBody3D.new()
|
||||
body.name = room.name
|
||||
|
||||
|
||||
var mesh_instance = MeshInstance3D.new()
|
||||
mesh_instance.name = "MeshInstance3D"
|
||||
mesh_instance.mesh = mesh
|
||||
mesh_instance.material_override = material_unselected if selected_room != room.name else material_selected
|
||||
body.add_child(mesh_instance)
|
||||
|
||||
var collision_shape = CollisionShape3D.new()
|
||||
collision_shape.shape = mesh.create_trimesh_shape()
|
||||
body.add_child(collision_shape)
|
||||
|
||||
rooms_map.add_child(body)
|
||||
|
||||
if current_min == null:
|
||||
return
|
||||
|
||||
var current_size = current_max - current_min
|
||||
var target_scale = target_size / current_size
|
||||
var scale_value = min(target_scale.x, target_scale.z)
|
||||
|
||||
rooms_map.position.x = -current_min.x * scale_value
|
||||
rooms_map.position.z = -current_min.z * scale_value
|
||||
|
||||
rooms_map.scale = Vector3(scale_value, scale_value, scale_value)
|
20
content/ui/menu/room/views/rooms.tscn
Normal file
20
content/ui/menu/room/views/rooms.tscn
Normal file
|
@ -0,0 +1,20 @@
|
|||
[gd_scene load_steps=4 format=3 uid="uid://bpta22fahai46"]
|
||||
|
||||
[ext_resource type="Script" path="res://content/ui/menu/room/views/rooms.gd" id="1_3a1oa"]
|
||||
[ext_resource type="PackedScene" uid="uid://bsjqdvkt0u87c" path="res://content/ui/components/button/button.tscn" id="1_y3lty"]
|
||||
[ext_resource type="PackedScene" uid="uid://blrhy2uccrdn4" path="res://content/ui/components/input/input.tscn" id="2_hstw7"]
|
||||
|
||||
[node name="Rooms" type="Node3D"]
|
||||
script = ExtResource("1_3a1oa")
|
||||
|
||||
[node name="Rooms" type="Node3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.15, 0.01, 0.12)
|
||||
|
||||
[node name="Button" parent="." instance=ExtResource("1_y3lty")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.27, 0, 0.27)
|
||||
label = "add"
|
||||
icon = true
|
||||
|
||||
[node name="Input" parent="." instance=ExtResource("2_hstw7")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.12, 0.005, 0.27)
|
||||
text = "Room 1"
|
|
@ -23,14 +23,14 @@ mesh = SubResource("BoxMesh_e51x8")
|
|||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.007, 0)
|
||||
|
||||
[node name="Label3D" type="Label3D" parent="Content"]
|
||||
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.134377, 0, 0.253575)
|
||||
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.124377, 0, 0.263575)
|
||||
pixel_size = 0.001
|
||||
text = "Spawn Ball"
|
||||
font_size = 18
|
||||
outline_size = 0
|
||||
|
||||
[node name="Button" parent="Content" instance=ExtResource("1_faxng")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0458097, 0, 0.253575)
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0358097, 0, 0.263575)
|
||||
label = "sports_basketball"
|
||||
icon = true
|
||||
|
||||
|
@ -109,11 +109,11 @@ outline_size = 0
|
|||
script = ExtResource("3_qmg6q")
|
||||
|
||||
[node name="Save" parent="Content" instance=ExtResource("1_faxng")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.04, 0, 0.17)
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.03, 0, 0.12)
|
||||
label = "save"
|
||||
icon = true
|
||||
|
||||
[node name="ClearSave" parent="Content" instance=ExtResource("1_faxng")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.1, 0, 0.17)
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.09, 0, 0.12)
|
||||
label = "close"
|
||||
icon = true
|
||||
|
|
12
content/ui/menu/view/view_menu.gd
Normal file
12
content/ui/menu/view/view_menu.gd
Normal file
|
@ -0,0 +1,12 @@
|
|||
extends Node3D
|
||||
|
||||
@onready var mini_view = $Content/MiniView
|
||||
@onready var background = $Background
|
||||
|
||||
func _ready():
|
||||
background.visible = false
|
||||
|
||||
mini_view.on_button_down.connect(func():
|
||||
House.body.mini_view = !House.body.mini_view
|
||||
)
|
||||
|
21
content/ui/menu/view/view_menu.tscn
Normal file
21
content/ui/menu/view/view_menu.tscn
Normal file
|
@ -0,0 +1,21 @@
|
|||
[gd_scene load_steps=4 format=3 uid="uid://ddpxthb414unp"]
|
||||
|
||||
[ext_resource type="Script" path="res://content/ui/menu/view/view_menu.gd" id="1_hxajx"]
|
||||
[ext_resource type="PackedScene" uid="uid://bsjqdvkt0u87c" path="res://content/ui/components/button/button.tscn" id="2_qan1b"]
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_qr3bi"]
|
||||
size = Vector3(0.3, 0.01, 0.3)
|
||||
|
||||
[node name="ViewMenu" type="Node3D"]
|
||||
script = ExtResource("1_hxajx")
|
||||
|
||||
[node name="Background" type="MeshInstance3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.15, 0, 0.15)
|
||||
mesh = SubResource("BoxMesh_qr3bi")
|
||||
|
||||
[node name="Content" type="Node3D" parent="."]
|
||||
|
||||
[node name="MiniView" parent="Content" instance=ExtResource("2_qan1b")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.03, 0, 0.03)
|
||||
label = "view_comfy"
|
||||
icon = true
|
|
@ -96,4 +96,5 @@ func watch_state(entity: String, callback: Callable):
|
|||
|
||||
func _notification(what):
|
||||
if what == NOTIFICATION_WM_CLOSE_REQUEST || what == NOTIFICATION_WM_GO_BACK_REQUEST:
|
||||
SaveSystem.save()
|
||||
# SaveSystem.save()
|
||||
pass
|
3
lib/globals/house_body.gd
Normal file
3
lib/globals/house_body.gd
Normal file
|
@ -0,0 +1,3 @@
|
|||
extends Node
|
||||
|
||||
@onready var body = get_node("/root/Main/House")
|
|
@ -2,8 +2,17 @@ extends Node
|
|||
|
||||
const VariantSerializer = preload("res://lib/utils/variant_serializer.gd")
|
||||
|
||||
signal loaded()
|
||||
signal unloaded()
|
||||
|
||||
var is_loaded := false
|
||||
var export_config = ConfigFile.new()
|
||||
var export_config_path = "res://export_presets.cfg"
|
||||
|
||||
func clear():
|
||||
await _clear_save_tree(get_tree().root.get_node("Main"))
|
||||
unloaded.emit()
|
||||
is_loaded = false
|
||||
|
||||
func save():
|
||||
if HomeApi.has_connected() == false:
|
||||
|
@ -18,7 +27,10 @@ func save():
|
|||
|
||||
var save_tree = _generate_save_tree(get_tree().root.get_node("Main"))
|
||||
|
||||
var json_text = JSON.stringify(save_tree)
|
||||
var json_text = JSON.stringify({
|
||||
"version": get_version(),
|
||||
"tree": save_tree
|
||||
})
|
||||
save_file.store_line(json_text)
|
||||
|
||||
func load():
|
||||
|
@ -35,7 +47,19 @@ func load():
|
|||
return
|
||||
|
||||
var json_text = save_file.get_line()
|
||||
var save_tree = JSON.parse_string(json_text)
|
||||
var save_data = JSON.parse_string(json_text)
|
||||
|
||||
if save_data == null:
|
||||
return
|
||||
|
||||
if save_data.has("version") == false:
|
||||
save()
|
||||
return
|
||||
|
||||
var save_tree = save_data["tree"]
|
||||
|
||||
if save_tree == null:
|
||||
return
|
||||
|
||||
if save_tree is Array:
|
||||
for tree in save_tree:
|
||||
|
@ -43,6 +67,22 @@ func load():
|
|||
else:
|
||||
_build_save_tree(save_tree)
|
||||
|
||||
loaded.emit()
|
||||
is_loaded = true
|
||||
|
||||
func get_version():
|
||||
var config_error = export_config.load(export_config_path)
|
||||
|
||||
if config_error != OK:
|
||||
return null
|
||||
|
||||
var version = export_config.get_value("preset.1.options", "version/name")
|
||||
|
||||
if version == null:
|
||||
return null
|
||||
|
||||
return version
|
||||
|
||||
func _clear_save_tree(node: Node):
|
||||
for child in node.get_children():
|
||||
await _clear_save_tree(child)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
extends RefCounted
|
||||
class_name EntityFactory
|
||||
|
||||
const Switch = preload("res://content/entities/switch/switch.tscn")
|
||||
const Light = preload("res://content/entities/light/light.tscn")
|
||||
|
@ -7,8 +8,9 @@ const MediaPlayer = preload("res://content/entities/media_player/media_player.ts
|
|||
const Camera = preload("res://content/entities/camera/camera.tscn")
|
||||
const ButtonEntity = preload("res://content/entities/button/button.tscn")
|
||||
|
||||
static func create_entity(type: String, id: String):
|
||||
static func create_entity(id: String):
|
||||
var entity = null
|
||||
var type = id.split(".")[0]
|
||||
|
||||
match type:
|
||||
"switch":
|
|
@ -1,4 +1,7 @@
|
|||
extends RefCounted
|
||||
class_name Proxy
|
||||
|
||||
signal on_set(new_value: Variant)
|
||||
|
||||
var gettable: Callable
|
||||
var settable: Callable
|
||||
|
@ -7,8 +10,12 @@ func _init(gettable: Callable, settable: Callable):
|
|||
self.gettable = gettable
|
||||
self.settable = settable
|
||||
|
||||
|
||||
|
||||
var value: Variant:
|
||||
get:
|
||||
return gettable.call()
|
||||
set(new_value):
|
||||
settable.call(new_value)
|
||||
settable.call(new_value)
|
||||
on_set.emit(new_value)
|
||||
|
||||
|
|
19
lib/utils/proxy_group.gd
Normal file
19
lib/utils/proxy_group.gd
Normal file
|
@ -0,0 +1,19 @@
|
|||
extends RefCounted
|
||||
class_name ProxyGroup
|
||||
|
||||
var proxies = []
|
||||
|
||||
func proxy(_get: Callable, _set: Callable):
|
||||
var _proxy
|
||||
_proxy = Proxy.new(_get, func(value):
|
||||
_set.call(value)
|
||||
|
||||
for p in proxies:
|
||||
if p != _proxy:
|
||||
p.on_set.emit(value)
|
||||
)
|
||||
|
||||
proxies.append(_proxy)
|
||||
|
||||
return _proxy
|
||||
|
13
lib/utils/state_machine/state.gd
Normal file
13
lib/utils/state_machine/state.gd
Normal file
|
@ -0,0 +1,13 @@
|
|||
extends Node
|
||||
class_name State
|
||||
|
||||
var state_machine: StateMachine
|
||||
|
||||
func is_active():
|
||||
return state_machine.current_state == self
|
||||
|
||||
func _on_enter():
|
||||
pass
|
||||
|
||||
func _on_leave():
|
||||
pass
|
32
lib/utils/state_machine/state_machine.gd
Normal file
32
lib/utils/state_machine/state_machine.gd
Normal file
|
@ -0,0 +1,32 @@
|
|||
class_name StateMachine
|
||||
extends Node
|
||||
|
||||
signal changed(state_name: String, old_state: String)
|
||||
|
||||
@export var current_state: Node
|
||||
var states: Dictionary = {}
|
||||
|
||||
func _ready() -> void:
|
||||
for state in get_children():
|
||||
states[state.get_name()] = state
|
||||
state.state_machine = self
|
||||
|
||||
if state != current_state:
|
||||
remove_child(state)
|
||||
|
||||
await get_parent().ready
|
||||
|
||||
current_state._on_enter()
|
||||
|
||||
func change_to(new_state: String) -> void:
|
||||
if states.has(new_state) == false:
|
||||
return
|
||||
|
||||
var old_state = current_state.get_name()
|
||||
|
||||
current_state._on_leave()
|
||||
remove_child(current_state)
|
||||
current_state = states[new_state]
|
||||
add_child(current_state)
|
||||
current_state._on_enter()
|
||||
changed.emit(new_state, old_state)
|
|
@ -24,6 +24,7 @@ HomeApi="*res://lib/globals/home_api.gd"
|
|||
AudioPlayer="*res://lib/globals/audio_player.gd"
|
||||
EventSystem="*res://lib/globals/event_system.gd"
|
||||
SaveSystem="*res://lib/globals/save_system.gd"
|
||||
House="*res://lib/globals/house_body.gd"
|
||||
|
||||
[editor_plugins]
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user