diff --git a/content/functions/movable.gd b/content/functions/movable.gd index 8bcf12f..9e9b99f 100644 --- a/content/functions/movable.gd +++ b/content/functions/movable.gd @@ -2,14 +2,22 @@ extends Function class_name Movable +@export var restricted: bool = false +@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 + get_parent().global_position = hit_node.global_position + + if !lock_rotation: + get_parent().global_rotation = hit_node.global_rotation func _on_grab_up(event: EventPointer): event.initiator.node.remove_child(hit_node) diff --git a/content/main.gd b/content/main.gd index e6389ba..e553ded 100644 --- a/content/main.gd +++ b/content/main.gd @@ -40,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): @@ -59,7 +61,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() @@ -103,7 +105,7 @@ func _input(event): vp.debug_draw = (vp.debug_draw + 1) % 5 if event is InputEventKey and Input.is_key_pressed(KEY_M): - _toggle_menu() + toggle_menu() func _get_menu_transform(): var transform = camera.get_global_transform() diff --git a/content/system/armband/armband.gd b/content/system/armband/armband.gd new file mode 100644 index 0000000..c9db1a0 --- /dev/null +++ b/content/system/armband/armband.gd @@ -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 + ) diff --git a/content/system/armband/armband.tscn b/content/system/armband/armband.tscn new file mode 100644 index 0000000..fa24fd9 --- /dev/null +++ b/content/system/armband/armband.tscn @@ -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" diff --git a/content/system/hands/hands.tscn b/content/system/hands/hands.tscn index a0efb03..2a69cfa 100644 --- a/content/system/hands/hands.tscn +++ b/content/system/hands/hands.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=6 format=3 uid="uid://bsx12q23v8apy"] +[gd_scene load_steps=7 format=3 uid="uid://bsx12q23v8apy"] [ext_resource type="Script" path="res://content/system/hands/hands.gd" id="1_c4f76"] [ext_resource type="PackedScene" uid="uid://c0kow4g10wolq" path="res://assets/models/hands_steam/right_hand.glb" id="1_uekbj"] [ext_resource type="PackedScene" uid="uid://dt4ksvogfctkr" path="res://assets/models/hands_steam/left_hand.glb" id="2_n73lt"] +[ext_resource type="PackedScene" uid="uid://bexxngoxcegul" path="res://content/system/armband/armband.tscn" id="3_ck75s"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_dopke"] radius = 0.001 @@ -42,7 +43,7 @@ transform = Transform3D(1, -7.45058e-09, -2.22045e-16, 7.45058e-09, 1, 0, 0, 0, shape = SubResource("CapsuleShape3D_dopke") [node name="ThumbTip" type="BoneAttachment3D" parent="XRHandLeft"] -transform = Transform3D(0.937246, 0.0284254, -0.347508, 0.0184905, 0.991216, 0.130949, 0.348178, -0.129157, 0.928488, 0.0498668, 0.0560917, -0.112777) +transform = Transform3D(0.937246, 0.0284254, -0.347508, 0.0184905, 0.991216, 0.130949, 0.348178, -0.129157, 0.928487, 0.0498668, 0.0560917, -0.112777) bone_name = "Thumb_Tip_L" bone_idx = 4 use_external_skeleton = true @@ -52,7 +53,7 @@ external_skeleton = NodePath("../left_hand/Armature_001/Skeleton3D") gizmo_extents = 0.02 [node name="MiddleTip" type="BoneAttachment3D" parent="XRHandLeft"] -transform = Transform3D(0.0812012, -0.650531, -0.755125, 0.996577, 0.064817, 0.051326, 0.0155558, -0.756708, 0.653568, 0.032112, 0.00654224, -0.171612) +transform = Transform3D(0.0812012, -0.650531, -0.755125, 0.996576, 0.064817, 0.051326, 0.0155558, -0.756708, 0.653567, 0.032112, 0.00654224, -0.171612) bone_name = "Middle_Tip_L" bone_idx = 14 use_external_skeleton = true @@ -80,6 +81,9 @@ collision_mask = 8 transform = Transform3D(1, 1.05818e-16, 4.75779e-13, -2.32831e-10, 1, -1.77636e-14, -4.97946e-12, 1.77636e-15, 1, -7.7486e-07, 1.33878e-09, -0.030436) shape = SubResource("BoxShape3D_1pxrt") +[node name="Armband" parent="XRHandLeft/AnimatableBody3D" instance=ExtResource("3_ck75s")] +transform = Transform3D(0.5, -8.74228e-08, 0, 8.74228e-08, 0.5, 0, 0, 0, 0.5, 0, 5.00223e-14, 0.11) + [node name="RemoteTransform3D" type="RemoteTransform3D" parent="XRHandLeft"] remote_path = NodePath("../AnimatableBody3D") @@ -94,7 +98,7 @@ hand_skeleton = NodePath("right_hand/Armature/Skeleton3D") transform = Transform3D(1, 0, 4.7579e-13, 0, 1, 0, -1.34149e-12, 1.77636e-15, 1, 0, 0, 0) [node name="IndexTip" type="BoneAttachment3D" parent="XRHandRight"] -transform = Transform3D(0.19221, 0.669966, 0.717079, -0.091543, -0.715277, 0.69282, 0.977075, -0.19881, -0.0761527, -0.0345977, -0.164767, -0.0355401) +transform = Transform3D(0.19221, 0.669966, 0.717078, -0.091543, -0.715277, 0.69282, 0.977075, -0.19881, -0.0761527, -0.0345978, -0.164767, -0.0355401) bone_name = "Index_Tip_R" bone_idx = 9 use_external_skeleton = true diff --git a/content/system/house/house.gd b/content/system/house/house.gd index dd154a5..5638b90 100644 --- a/content/system/house/house.gd +++ b/content/system/house/house.gd @@ -4,8 +4,13 @@ const Room = preload("./room/room.tscn") const RoomType = preload("./room/room.gd") @onready var levels = $Levels +@onready var collision_shape = $Levels/CollisionShape3D var editing_room: RoomType = null +var mini_view: bool = false: + set(value): + mini_view = value + update_mini_view() func create_room(room_name: String, level: int) -> RoomType: if editing_room != null: @@ -76,6 +81,28 @@ func find_room_at(entity_position: Vector3): 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() @@ -93,4 +120,23 @@ func create_entity(entity_id: String, entity_position: Vector3): 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) + + levels.scale.x = 0.2 if mini_view else 1.0 + levels.scale.y = 0.2 if mini_view else 1.0 + levels.scale.z = 0.2 if mini_view else 1.0 + + for room in get_rooms(0): + room.state_machine.change_to("Mini" if mini_view else "View") \ No newline at end of file diff --git a/content/system/house/house.tscn b/content/system/house/house.tscn index d2de65c..21124de 100644 --- a/content/system/house/house.tscn +++ b/content/system/house/house.tscn @@ -1,10 +1,22 @@ -[gd_scene load_steps=2 format=3 uid="uid://cbemihbxkd4ll"] +[gd_scene load_steps=4 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"] + +[sub_resource type="BoxShape3D" id="BoxShape3D_x81up"] [node name="House" type="Node3D"] script = ExtResource("1_p8amj") -[node name="Levels" type="Node3D" parent="."] +[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 diff --git a/content/system/house/room/room.gd b/content/system/house/room/room.gd index c0dbc7c..722b32f 100644 --- a/content/system/house/room/room.gd +++ b/content/system/house/room/room.gd @@ -27,7 +27,7 @@ func get_edge(index: int) -> MeshInstance3D: return wall_edges.get_child(index % wall_edges.get_child_count()) func has_point(point: Vector3) -> bool: - return wall_mesh.get_aabb().has_point(point) + return get_aabb().has_point(point) func remove_corner(index: int): get_corner(index).queue_free() @@ -39,6 +39,26 @@ func _save(): "name": name } +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)) + + func _load(data): await ready return diff --git a/content/system/house/room/room.tscn b/content/system/house/room/room.tscn index 688e140..bd0cedd 100644 --- a/content/system/house/room/room.tscn +++ b/content/system/house/room/room.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=10 format=3 uid="uid://bswgmclohuqui"] +[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"] @@ -61,3 +62,6 @@ 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") diff --git a/content/system/house/room/states/mini.gd b/content/system/house/room/states/mini.gd new file mode 100644 index 0000000..99f17d6 --- /dev/null +++ b/content/system/house/room/states/mini.gd @@ -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 + + diff --git a/content/system/house/room/states/view.gd b/content/system/house/room/states/view.gd index b20b181..d8dd590 100644 --- a/content/system/house/room/states/view.gd +++ b/content/system/house/room/states/view.gd @@ -13,6 +13,8 @@ func _on_enter(): room_height = room.get_corner(0).global_position.y + room.wall_mesh.visible = true + room.ceiling_mesh.visible = true room.wall_mesh.mesh = generate_mesh() if room.wall_mesh.mesh == null: @@ -36,8 +38,8 @@ func _on_enter(): room.wall_mesh.visible = true func _on_leave(): - room.wall_mesh.mesh = null - room.ceiling_mesh.mesh = null + room.wall_mesh.visible = false + room.ceiling_mesh.visible = false for collision in room.wall_collisions.get_children(): collision.queue_free() diff --git a/content/system/house/room/walls_mini.tres b/content/system/house/room/walls_mini.tres new file mode 100644 index 0000000..1432646 --- /dev/null +++ b/content/system/house/room/walls_mini.tres @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e6b87dd767a03b39f93f17a71b75b3a6ce82623a7703c24722dd112e31718376 +size 157 diff --git a/content/ui/menu/room/room_menu.gd b/content/ui/menu/room/room_menu.gd index cd7c76d..f0aecc5 100644 --- a/content/ui/menu/room/room_menu.gd +++ b/content/ui/menu/room/room_menu.gd @@ -97,14 +97,15 @@ func _on_click(event: EventPointer): func _generate_room_map(): var rooms = House.body.get_rooms(0) - var target_size = Vector2(0.3, 0.24) + 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 current_min = null - var current_max = null + 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 @@ -127,33 +128,14 @@ func _generate_room_map(): rooms_map.add_child(body) - var aabb_position = room.ceiling_mesh.to_global(mesh.get_aabb().position) - var aabb_end = room.ceiling_mesh.to_global(mesh.get_aabb().end) - - if current_min == null: - current_min = Vector2(aabb_position.x, aabb_position.z) - current_max = Vector2(aabb_end.x, aabb_end.z) - else: - if aabb_position.x < current_min.x: - current_min.x = aabb_position.x - - if aabb_position.z < current_min.y: - current_min.y = aabb_position.z - - if aabb_end.x > current_max.x: - current_max.x = aabb_end.x - - if aabb_end.z > current_max.y: - current_max.y = aabb_end.z - 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.y) + 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.y * scale_value + rooms_map.position.z = -current_min.z * scale_value rooms_map.scale = Vector3(scale_value, scale_value, scale_value) diff --git a/lib/globals/save_system.gd b/lib/globals/save_system.gd index a45321f..22510e7 100644 --- a/lib/globals/save_system.gd +++ b/lib/globals/save_system.gd @@ -44,6 +44,9 @@ func load(): var json_text = save_file.get_line() var save_tree = JSON.parse_string(json_text) + if save_tree == null: + return + if save_tree is Array: for tree in save_tree: _build_save_tree(tree) diff --git a/lib/utils/state_machine/state_machine.gd b/lib/utils/state_machine/state_machine.gd index 6fb7f7a..a5dbc81 100644 --- a/lib/utils/state_machine/state_machine.gd +++ b/lib/utils/state_machine/state_machine.gd @@ -29,4 +29,4 @@ func change_to(new_state: String) -> void: current_state = states[new_state] add_child(current_state) current_state._on_enter() - changed.emit(new_state, old_state) \ No newline at end of file + changed.emit(new_state, old_state)