diff --git a/flatscreen-project/assets/photo-images/Knife.jpg b/flatscreen-project/assets/photo-images/Knife.jpg new file mode 100644 index 00000000..fb92ef2a Binary files /dev/null and b/flatscreen-project/assets/photo-images/Knife.jpg differ diff --git a/flatscreen-project/assets/photo-images/Knife.jpg.import b/flatscreen-project/assets/photo-images/Knife.jpg.import new file mode 100644 index 00000000..fe87fb01 --- /dev/null +++ b/flatscreen-project/assets/photo-images/Knife.jpg.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://p7uaxluyc0tk" +path="res://.godot/imported/Knife.jpg-a5a0b11f87ebf896f8f190d2055a6239.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/photo-images/Knife.jpg" +dest_files=["res://.godot/imported/Knife.jpg-a5a0b11f87ebf896f8f190d2055a6239.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/flatscreen-project/clue_db.tres b/flatscreen-project/clue_db.tres new file mode 100644 index 00000000..0bd0cd11 --- /dev/null +++ b/flatscreen-project/clue_db.tres @@ -0,0 +1,13 @@ +[gd_resource type="ClueDB" load_steps=4 format=3 uid="uid://dlf8dxiter8b8"] + +[ext_resource type="Texture2D" uid="uid://p7uaxluyc0tk" path="res://assets/photo-images/Knife.jpg" id="1_q5eka"] + +[sub_resource type="ClueData" id="ClueData_kxjsf"] +id = 0 +image = ExtResource("1_q5eka") + +[sub_resource type="ClueData" id="ClueData_q5eka"] +id = 1 + +[resource] +clues = [SubResource("ClueData_kxjsf"), SubResource("ClueData_q5eka")] diff --git a/flatscreen-project/objects/case_file.tscn b/flatscreen-project/objects/case_file.tscn new file mode 100644 index 00000000..a1ac7d33 --- /dev/null +++ b/flatscreen-project/objects/case_file.tscn @@ -0,0 +1,60 @@ +[gd_scene load_steps=7 format=3 uid="uid://cjyr1b0fxfofx"] + +[sub_resource type="QuadMesh" id="QuadMesh_7cefc"] + +[sub_resource type="GDScript" id="GDScript_7cefc"] +script/source = "extends Area2D + + +func _on_input_event(viewport: Node, event: InputEvent, _shape_idx: int) -> void: + if event is InputEventMouseButton: + if not $\"..\".is_open(): + $\"..\".request_open() + else: + $\"..\".request_close() + viewport.set_input_as_handled() +" + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_vo7lu"] +size = Vector2(52.031464, 209.99301) + +[sub_resource type="TextMesh" id="TextMesh_mes51"] +flip_faces = true +text = "Case" +depth = 0.0 + +[sub_resource type="Gradient" id="Gradient_vo7lu"] +offsets = PackedFloat32Array(1) +colors = PackedColorArray(0, 0, 0, 1) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_wjago"] +gradient = SubResource("Gradient_vo7lu") + +[node name="CaseFile" type="FilePopup"] + +[node name="MeshInstance2D2" type="MeshInstance2D" parent="."] +position = Vector2(21.5, 584.3357) +scale = Vector2(77, 222.67134) +mesh = SubResource("QuadMesh_7cefc") + +[node name="MeshInstance2D" type="MeshInstance2D" parent="."] +position = Vector2(-333.25, 486.25) +scale = Vector2(667.5, 973.5) +mesh = SubResource("QuadMesh_7cefc") + +[node name="Area2D" type="Area2D" parent="."] +position = Vector2(28.170658, 585.06274) +script = SubResource("GDScript_7cefc") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] +scale = Vector2(1.0000002, 1.0000002) +shape = SubResource("RectangleShape2D_vo7lu") + +[node name="MeshInstance2D3" type="MeshInstance2D" parent="."] +position = Vector2(30.888136, 582.9807) +rotation = 1.5707964 +scale = Vector2(-347.0554, 307.87436) +mesh = SubResource("TextMesh_mes51") +texture = SubResource("GradientTexture1D_wjago") + +[connection signal="input_event" from="Area2D" to="Area2D" method="_on_input_event"] diff --git a/flatscreen-project/objects/pinned_photo.tscn b/flatscreen-project/objects/pinned_photo.tscn new file mode 100644 index 00000000..cb2e302b --- /dev/null +++ b/flatscreen-project/objects/pinned_photo.tscn @@ -0,0 +1,21 @@ +[gd_scene load_steps=4 format=3 uid="uid://btcmnw6q6g0h0"] + +[sub_resource type="QuadMesh" id="QuadMesh_87mh6"] + +[sub_resource type="ImageTexture" id="ImageTexture_usqe2"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_usqe2"] +size = Vector2(166, 172) + +[node name="PinnedPhoto" type="PinnedPhoto"] +input_pickable = true + +[node name="MeshInstance2D" type="MeshInstance2D" parent="."] +position = Vector2(0, 73.49998) +scale = Vector2(162.00002, 168.99995) +mesh = SubResource("QuadMesh_87mh6") +texture = SubResource("ImageTexture_usqe2") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +position = Vector2(0, 73) +shape = SubResource("RectangleShape2D_usqe2") diff --git a/flatscreen-project/objects/victim_file.tscn b/flatscreen-project/objects/victim_file.tscn new file mode 100644 index 00000000..48c88e92 --- /dev/null +++ b/flatscreen-project/objects/victim_file.tscn @@ -0,0 +1,60 @@ +[gd_scene load_steps=7 format=3 uid="uid://qmb60kjx6yoe"] + +[sub_resource type="QuadMesh" id="QuadMesh_7cefc"] + +[sub_resource type="GDScript" id="GDScript_7cefc"] +script/source = "extends Area2D + + +func _on_input_event(viewport: Node, event: InputEvent, _shape_idx: int) -> void: + if event is InputEventMouseButton: + if not $\"..\".is_open(): + $\"..\".request_open() + else: + $\"..\".request_close() + viewport.set_input_as_handled() +" + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_vo7lu"] +size = Vector2(52.031464, 209.99301) + +[sub_resource type="TextMesh" id="TextMesh_7cefc"] +flip_faces = true +text = "Victim" +depth = 0.0 + +[sub_resource type="Gradient" id="Gradient_vo7lu"] +offsets = PackedFloat32Array(1) +colors = PackedColorArray(0, 0, 0, 1) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_wjago"] +gradient = SubResource("Gradient_vo7lu") + +[node name="VictimFile" type="FilePopup"] + +[node name="MeshInstance2D2" type="MeshInstance2D" parent="."] +position = Vector2(22.500002, 142.6643) +scale = Vector2(77, 222.67134) +mesh = SubResource("QuadMesh_7cefc") + +[node name="MeshInstance2D" type="MeshInstance2D" parent="."] +position = Vector2(-333.25, 486.25) +scale = Vector2(667.5, 973.5) +mesh = SubResource("QuadMesh_7cefc") + +[node name="Area2D" type="Area2D" parent="."] +position = Vector2(29.17066, 143.39133) +script = SubResource("GDScript_7cefc") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] +scale = Vector2(1.0000002, 1.0000002) +shape = SubResource("RectangleShape2D_vo7lu") + +[node name="MeshInstance2D3" type="MeshInstance2D" parent="."] +position = Vector2(33.037315, 137.30455) +rotation = 1.5707964 +scale = Vector2(-347.0554, 307.87436) +mesh = SubResource("TextMesh_7cefc") +texture = SubResource("GradientTexture1D_wjago") + +[connection signal="input_event" from="Area2D" to="Area2D" method="_on_input_event"] diff --git a/flatscreen-project/objects/witness_report.tscn b/flatscreen-project/objects/witness_report.tscn new file mode 100644 index 00000000..7087082d --- /dev/null +++ b/flatscreen-project/objects/witness_report.tscn @@ -0,0 +1,61 @@ +[gd_scene load_steps=7 format=3 uid="uid://drcl138k0gym0"] + +[sub_resource type="QuadMesh" id="QuadMesh_7cefc"] + +[sub_resource type="GDScript" id="GDScript_7cefc"] +script/source = "extends Area2D + + +func _on_input_event(viewport: Node, event: InputEvent, _shape_idx: int) -> void: + if event is InputEventMouseButton: + if not $\"..\".is_open(): + $\"..\".request_open() + else: + $\"..\".request_close() + viewport.set_input_as_handled() +" + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_vo7lu"] +size = Vector2(52.031464, 209.99301) + +[sub_resource type="TextMesh" id="TextMesh_vo7lu"] +flip_faces = true +text = "Witness" +depth = 0.0 + +[sub_resource type="Gradient" id="Gradient_vo7lu"] +offsets = PackedFloat32Array(1) +colors = PackedColorArray(0, 0, 0, 1) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_wjago"] +gradient = SubResource("Gradient_vo7lu") + +[node name="WitnessReport" type="FilePopup" node_paths=PackedStringArray("open_position")] +open_position = NodePath("") + +[node name="MeshInstance2D2" type="MeshInstance2D" parent="."] +position = Vector2(21.59444, 373.7876) +scale = Vector2(77, 222.67134) +mesh = SubResource("QuadMesh_7cefc") + +[node name="MeshInstance2D" type="MeshInstance2D" parent="."] +position = Vector2(-333.25, 486.25) +scale = Vector2(667.5, 973.5) +mesh = SubResource("QuadMesh_7cefc") + +[node name="Area2D" type="Area2D" parent="."] +position = Vector2(28.265099, 374.51465) +script = SubResource("GDScript_7cefc") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] +scale = Vector2(1.0000002, 1.0000002) +shape = SubResource("RectangleShape2D_vo7lu") + +[node name="MeshInstance2D3" type="MeshInstance2D" parent="."] +position = Vector2(30.982576, 372.43265) +rotation = 1.5707964 +scale = Vector2(-347.0554, 307.87436) +mesh = SubResource("TextMesh_vo7lu") +texture = SubResource("GradientTexture1D_wjago") + +[connection signal="input_event" from="Area2D" to="Area2D" method="_on_input_event"] diff --git a/flatscreen-project/project.godot b/flatscreen-project/project.godot index 85ad8db2..234aa91f 100644 --- a/flatscreen-project/project.godot +++ b/flatscreen-project/project.godot @@ -20,3 +20,7 @@ config/icon="res://icon.svg" window/size/viewport_width=1920 window/size/viewport_height=1080 window/stretch/mode="canvas_items" + +[rendering] + +anti_aliasing/quality/msaa_2d=1 diff --git a/flatscreen-project/scenes/flatscreen_root.tscn b/flatscreen-project/scenes/flatscreen_root.tscn index 01f534fa..2f22838a 100644 --- a/flatscreen-project/scenes/flatscreen_root.tscn +++ b/flatscreen-project/scenes/flatscreen_root.tscn @@ -1,52 +1,20 @@ -[gd_scene load_steps=8 format=3 uid="uid://dosb4sb7pvss4"] +[gd_scene load_steps=3 format=3 uid="uid://dosb4sb7pvss4"] -[sub_resource type="QuadMesh" id="QuadMesh_usqe2"] +[ext_resource type="PackedScene" uid="uid://o3ri154wpbrx" path="res://scenes/workspace.tscn" id="1_87mh6"] +[ext_resource type="PackedScene" uid="uid://owa17yo7q6wo" path="res://scenes/start_server_ui.tscn" id="1_btop4"] -[sub_resource type="Gradient" id="Gradient_usqe2"] -offsets = PackedFloat32Array(1) -colors = PackedColorArray(0.7490196, 0.7019608, 0.6431373, 1) +[node name="FlatscreenRoot" type="Node"] -[sub_resource type="GradientTexture1D" id="GradientTexture1D_87mh6"] -gradient = SubResource("Gradient_usqe2") - -[sub_resource type="RectangleShape2D" id="RectangleShape2D_87mh6"] -size = Vector2(1288, 533) - -[sub_resource type="QuadMesh" id="QuadMesh_87mh6"] - -[sub_resource type="ImageTexture" id="ImageTexture_usqe2"] - -[sub_resource type="RectangleShape2D" id="RectangleShape2D_usqe2"] -size = Vector2(166, 172) - -[node name="FlatscreenRoot" type="Node2D"] +[node name="ServerNode" type="ServerNode" parent="."] [node name="Camera2D" type="Camera2D" parent="."] anchor_mode = 0 -[node name="Pinboard" type="Pinboard" parent="."] -position = Vector2(312, 19) +[node name="FlatscreenRoot" parent="." instance=ExtResource("1_87mh6")] -[node name="MeshInstance2D" type="MeshInstance2D" parent="Pinboard"] -position = Vector2(794.49994, 417) -scale = Vector2(1535.0001, 818) -mesh = SubResource("QuadMesh_usqe2") -texture = SubResource("GradientTexture1D_87mh6") - -[node name="CollisionShape2D" type="CollisionShape2D" parent="Pinboard"] -position = Vector2(798, 465.5) -shape = SubResource("RectangleShape2D_87mh6") - -[node name="PinnedPhoto" type="PinnedPhoto" parent="."] -position = Vector2(479, 904) -input_pickable = true - -[node name="MeshInstance2D" type="MeshInstance2D" parent="PinnedPhoto"] -position = Vector2(0, 73.49998) -scale = Vector2(162.00002, 168.99995) -mesh = SubResource("QuadMesh_87mh6") -texture = SubResource("ImageTexture_usqe2") - -[node name="CollisionShape2D" type="CollisionShape2D" parent="PinnedPhoto"] -position = Vector2(0, 73) -shape = SubResource("RectangleShape2D_usqe2") +[node name="StartServerUI" parent="." instance=ExtResource("1_btop4")] +anchors_preset = 0 +anchor_right = 0.0 +anchor_bottom = 0.0 +offset_right = 1920.0 +offset_bottom = 1080.0 diff --git a/flatscreen-project/scenes/start_server_ui.tscn b/flatscreen-project/scenes/start_server_ui.tscn index f12db7eb..6151ee8c 100644 --- a/flatscreen-project/scenes/start_server_ui.tscn +++ b/flatscreen-project/scenes/start_server_ui.tscn @@ -1,12 +1,11 @@ [gd_scene load_steps=2 format=3 uid="uid://owa17yo7q6wo"] -[sub_resource type="GDScript" id="GDScript_usqe2"] -resource_name = "StartServerUI" -script/source = "extends CenterContainer +[sub_resource type="GDScript" id="GDScript_oroue"] +script/source = "extends PanelContainer -@onready var label := $VBoxContainer/ConnectingText -@onready var open_server_btn := $VBoxContainer/OpenServerButton -@onready var close_server_btn := $VBoxContainer/CloseServerButton +@onready var label := %ConnectingText +@onready var open_server_btn := %OpenServerButton +@onready var close_server_btn := %CloseServerButton func _ready(): ServerNode.get_singleton().connection_established.connect(self._on_server_node_connection_established) @@ -29,40 +28,47 @@ func _on_server_node_connection_established() -> void: self.visible = false " -[node name="StartServerUI" type="CenterContainer"] +[node name="StartServerUI" type="PanelContainer"] anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 +script = SubResource("GDScript_oroue") + +[node name="CenterContainer" type="CenterContainer" parent="."] +layout_mode = 2 size_flags_horizontal = 3 size_flags_vertical = 3 -script = SubResource("GDScript_usqe2") -[node name="VBoxContainer" type="VBoxContainer" parent="."] +[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer"] layout_mode = 2 -[node name="OpenServerButton" type="Button" parent="VBoxContainer"] +[node name="OpenServerButton" type="Button" parent="CenterContainer/VBoxContainer"] +unique_name_in_owner = true layout_mode = 2 text = "Host Game Server" -[node name="CloseServerButton" type="Button" parent="VBoxContainer"] +[node name="CloseServerButton" type="Button" parent="CenterContainer/VBoxContainer"] +unique_name_in_owner = true visible = false layout_mode = 2 text = "Cancel Connection" -[node name="ConnectingText" type="Label" parent="VBoxContainer"] +[node name="ConnectingText" type="Label" parent="CenterContainer/VBoxContainer"] +unique_name_in_owner = true visible = false layout_mode = 2 text = "Waiting for client..." horizontal_alignment = 1 -[node name="PermissionsText" type="Label" parent="VBoxContainer"] +[node name="PermissionsText" type="Label" parent="CenterContainer/VBoxContainer"] +unique_name_in_owner = true layout_mode = 2 text = "Requires permissions to open port 6667. If you have a firewall on your system you may need to open configure it" horizontal_alignment = 1 -[connection signal="pressed" from="VBoxContainer/OpenServerButton" to="." method="_on_open_button_pressed"] -[connection signal="pressed" from="VBoxContainer/CloseServerButton" to="." method="_on_close_button_pressed"] +[connection signal="pressed" from="CenterContainer/VBoxContainer/OpenServerButton" to="." method="_on_open_button_pressed"] +[connection signal="pressed" from="CenterContainer/VBoxContainer/CloseServerButton" to="." method="_on_close_button_pressed"] diff --git a/flatscreen-project/scenes/workspace.tscn b/flatscreen-project/scenes/workspace.tscn new file mode 100644 index 00000000..be09461e --- /dev/null +++ b/flatscreen-project/scenes/workspace.tscn @@ -0,0 +1,100 @@ +[gd_scene load_steps=13 format=3 uid="uid://o3ri154wpbrx"] + +[ext_resource type="PackedScene" uid="uid://btcmnw6q6g0h0" path="res://objects/pinned_photo.tscn" id="1_7cefc"] +[ext_resource type="PackedScene" uid="uid://qmb60kjx6yoe" path="res://objects/victim_file.tscn" id="2_vo7lu"] +[ext_resource type="PackedScene" uid="uid://drcl138k0gym0" path="res://objects/witness_report.tscn" id="3_wjago"] +[ext_resource type="PackedScene" uid="uid://cjyr1b0fxfofx" path="res://objects/case_file.tscn" id="4_cnvne"] + +[sub_resource type="QuadMesh" id="QuadMesh_usqe2"] + +[sub_resource type="Gradient" id="Gradient_usqe2"] +offsets = PackedFloat32Array(1) +colors = PackedColorArray(0.7490196, 0.7019608, 0.6431373, 1) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_87mh6"] +gradient = SubResource("Gradient_usqe2") + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_87mh6"] +size = Vector2(965, 533) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_7cefc"] +size = Vector2(400, 64) + +[sub_resource type="QuadMesh" id="QuadMesh_cnvne"] + +[sub_resource type="QuadMesh" id="QuadMesh_thvsl"] + +[sub_resource type="ImageTexture" id="ImageTexture_cnvne"] + +[node name="FlatscreenRoot" type="Node2D"] + +[node name="Camera2D" type="Camera2D" parent="."] +anchor_mode = 0 + +[node name="Pinboard" type="Pinboard" parent="."] +position = Vector2(312, 19) + +[node name="MeshInstance2D" type="MeshInstance2D" parent="Pinboard"] +position = Vector2(794.49994, 417) +scale = Vector2(1535.0001, 818) +mesh = SubResource("QuadMesh_usqe2") +texture = SubResource("GradientTexture1D_87mh6") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Pinboard"] +position = Vector2(636.5, 465.5) +shape = SubResource("RectangleShape2D_87mh6") + +[node name="CollisionShape2D2" type="CollisionShape2D" parent="Pinboard"] +position = Vector2(1340, 701) +shape = SubResource("RectangleShape2D_7cefc") + +[node name="PhotosParent" type="Node2D" parent="."] + +[node name="PinnedPhoto" parent="PhotosParent" instance=ExtResource("1_7cefc")] +position = Vector2(479, 904) + +[node name="PhotoInbox" type="PhotoInbox" parent="PhotosParent"] +position = Vector2(1679, 900) +photo_scene = ExtResource("1_7cefc") + +[node name="VictimFile" parent="." node_paths=PackedStringArray("open_position") instance=ExtResource("2_vo7lu")] +position = Vector2(12.000002, 0) +rotation = 0.08145886 +open_position = NodePath("../FilePositionTarget") + +[node name="WitnessReport" parent="." node_paths=PackedStringArray("open_position") instance=ExtResource("3_wjago")] +position = Vector2(-20, 7.000004) +rotation = -0.037705522 +open_position = NodePath("../FilePositionTarget") + +[node name="CaseFile" parent="." node_paths=PackedStringArray("open_position") instance=ExtResource("4_cnvne")] +position = Vector2(4.999998, 31) +rotation = 0.013079915 +open_position = NodePath("../FilePositionTarget") + +[node name="FilePositionTarget" type="Node2D" parent="."] +position = Vector2(678.00006, 63.999996) +rotation = -0.0034519732 + +[node name="Handin" type="Node2D" parent="."] +position = Vector2(1544.9998, 15) +rotation = -0.042017065 + +[node name="MeshInstance2D" type="MeshInstance2D" parent="Handin"] +position = Vector2(169.87817, 238.88794) +scale = Vector2(390.23935, 519.97754) +mesh = SubResource("QuadMesh_cnvne") + +[node name="TextEdit" type="TextEdit" parent="Handin"] +offset_left = 3.0 +offset_top = 344.75198 +offset_right = 342.7721 +offset_bottom = 485.0 +backspace_deletes_composite_character_enabled = true +wrap_mode = 1 + +[node name="MeshInstance2D2" type="MeshInstance2D" parent="Handin"] +position = Vector2(296.84607, 57.51972) +scale = Vector2(97.55189, 112.9032) +mesh = SubResource("QuadMesh_thvsl") +texture = SubResource("ImageTexture_cnvne") diff --git a/modules/you_done_it/clue_data.cpp b/modules/you_done_it/clue_data.cpp index 83bfbf84..339c8870 100644 --- a/modules/you_done_it/clue_data.cpp +++ b/modules/you_done_it/clue_data.cpp @@ -4,7 +4,7 @@ void ClueData::_bind_methods() { BIND_HPROPERTY(Variant::INT, id, PROPERTY_HINT_ENUM, NetworkData::ClueID_hint()); - BIND_HPROPERTY(Variant::OBJECT, image, PROPERTY_HINT_RESOURCE_TYPE, "Image"); + BIND_HPROPERTY(Variant::OBJECT, image, PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"); } void ClueData::set_revealed(bool value) { @@ -38,11 +38,10 @@ bool ClueData::get_revealed() const { return this->revealed; } -void ClueData::set_image(Ref image) { +void ClueData::set_image(Ref image) { this->image = image; - // TODO: Sync to server } -Ref ClueData::get_image() const { +Ref ClueData::get_image() const { return this->image; } diff --git a/modules/you_done_it/clue_data.h b/modules/you_done_it/clue_data.h index 8acd1f8b..3e50c7a6 100644 --- a/modules/you_done_it/clue_data.h +++ b/modules/you_done_it/clue_data.h @@ -1,7 +1,7 @@ #pragma once -#include "core/io/image.h" #include "core/io/resource.h" +#include "scene/resources/texture.h" #include "you_done_it/ydi_networking.h" class ClueData : public Resource { @@ -16,11 +16,11 @@ public: NetworkData::ClueID get_id() const; void reveal(); bool get_revealed() const; - void set_image(Ref image); - Ref get_image() const; + void set_image(Ref image); + Ref get_image() const; private: NetworkData::ClueID id{ NetworkData::CLUE_MAX }; bool revealed{ false }; - Ref image{}; + Ref image{}; }; diff --git a/modules/you_done_it/clue_db.cpp b/modules/you_done_it/clue_db.cpp index ff20dbf4..466324e3 100644 --- a/modules/you_done_it/clue_db.cpp +++ b/modules/you_done_it/clue_db.cpp @@ -19,12 +19,6 @@ void ClueDB::ensure_data_valid() { } } -ClueDB::~ClueDB() { - if (singleton_instance == this) { - singleton_instance = nullptr; - } -} - Ref &ClueDB::get_singleton() { if (!singleton_instance.is_valid()) { singleton_instance = Ref(ResourceLoader::load("res://clue_db.tres")); @@ -32,6 +26,10 @@ Ref &ClueDB::get_singleton() { return singleton_instance; } +bool ClueDB::has_singleton() { + return singleton_instance.is_valid(); +} + void ClueDB::set_clues(Array data) { for (Variant value : data) { Ref clue{ Object::cast_to(value) }; diff --git a/modules/you_done_it/clue_db.h b/modules/you_done_it/clue_db.h index cad0b130..af034e8b 100644 --- a/modules/you_done_it/clue_db.h +++ b/modules/you_done_it/clue_db.h @@ -12,8 +12,8 @@ class ClueDB : public Resource { void ensure_data_valid(); public: - virtual ~ClueDB(); static Ref &get_singleton(); + static bool has_singleton(); void set_clues(Array data); Array get_clues(); Ref get_clue(NetworkData::ClueID id); diff --git a/modules/you_done_it/file_popup.cpp b/modules/you_done_it/file_popup.cpp new file mode 100644 index 00000000..4d140104 --- /dev/null +++ b/modules/you_done_it/file_popup.cpp @@ -0,0 +1,84 @@ +#include "file_popup.h" +#include "core/config/engine.h" +#include "core/input/input_event.h" +#include "core/math/math_funcs.h" +#include "scene/main/node.h" +#include "scene/main/viewport.h" +#include "you_done_it/macros.h" + +void FilePopup::_bind_methods() { + BIND_HPROPERTY(Variant::OBJECT, open_position, PROPERTY_HINT_NODE_TYPE, "Node2D"); + ClassDB::bind_method(D_METHOD("request_open"), &self_type::request_open); + ClassDB::bind_method(D_METHOD("request_close"), &self_type::request_close); + ClassDB::bind_method(D_METHOD("is_open"), &self_type::is_open); +} + +void FilePopup::enter_tree() { + this->home_position = get_global_transform(); +} + +void FilePopup::process(double delta) { + if (!this->open_position) { + set_process(false); + return; + } + this->animation_progress = Math::move_toward(this->animation_progress, this->desire_open ? 1.0 : 0.0, delta * this->ANIM_SPEED); + this->set_global_position(this->home_position.get_origin().lerp(this->open_position->get_global_position(), this->animation_progress)); + this->set_global_rotation(Math::lerp_angle(this->home_position.get_rotation(), this->open_position->get_global_rotation(), (float)this->animation_progress)); + if (this->animation_progress == 0.0) { + set_process(false); + set_process_unhandled_input(false); + } + if (this->animation_progress == 1.0) { + set_process(false); + } +} + +void FilePopup::unhandled_input(Ref const &what) { + Ref button{ what }; + if (button.is_valid() && button->is_pressed()) { + this->desire_open = false; + set_process(true); + get_viewport()->set_input_as_handled(); + } +} + +void FilePopup::_notification(int what) { + if (Engine::get_singleton()->is_editor_hint()) { + return; + } + switch (what) { + default: + return; + case NOTIFICATION_ENTER_TREE: + set_process_unhandled_input(true); + enter_tree(); + return; + case NOTIFICATION_PROCESS: + process(get_process_delta_time()); + return; + } +} + +void FilePopup::request_open() { + this->desire_open = true; + set_process_unhandled_input(true); + set_process(true); + set_visible(true); +} + +void FilePopup::request_close() { + this->desire_open = false; +} + +bool FilePopup::is_open() const { + return this->animation_progress == 1.0; +} + +void FilePopup::set_open_position(Node2D *node) { + this->open_position = node; +} + +Node2D *FilePopup::get_open_position() const { + return this->open_position; +} diff --git a/modules/you_done_it/file_popup.h b/modules/you_done_it/file_popup.h new file mode 100644 index 00000000..6ceb53aa --- /dev/null +++ b/modules/you_done_it/file_popup.h @@ -0,0 +1,28 @@ +#pragma once + +#include "scene/2d/node_2d.h" + +class FilePopup : public Node2D { + GDCLASS(FilePopup, Node2D); + static void _bind_methods(); + void enter_tree(); + void process(double delta); + +protected: + virtual void unhandled_input(Ref const &what) override; + void _notification(int what); + +public: + void request_open(); + void request_close(); + bool is_open() const; + void set_open_position(Node2D *node); + Node2D *get_open_position() const; + +private: + double animation_progress{ 0.0 }; + bool desire_open{ false }; + Transform2D home_position{}; + Node2D *open_position{ nullptr }; + double const ANIM_SPEED{ 5.0 }; +}; diff --git a/modules/you_done_it/photo_inbox.cpp b/modules/you_done_it/photo_inbox.cpp new file mode 100644 index 00000000..9e1039f3 --- /dev/null +++ b/modules/you_done_it/photo_inbox.cpp @@ -0,0 +1,75 @@ +#include "photo_inbox.h" +#include "core/input/input_event.h" +#include "core/object/class_db.h" +#include "core/os/keyboard.h" +#include "you_done_it/clue_db.h" +#include "you_done_it/macros.h" +#include "you_done_it/pinned_photo.h" +#include "you_done_it/server_node.h" + +void PhotoInbox::_bind_methods() { + BIND_HPROPERTY(Variant::OBJECT, photo_scene, PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"); +} + +void PhotoInbox::enter_tree() { + if (ServerNode * server{ ServerNode::get_singleton() }) { + server->connect(ServerNode::sig_clue_revealed, callable_mp(this, &self_type::on_clue_revealed)); + } else { + // enable process unhandled input if no server is found, as this implies we should be running in test mode. + set_process_unhandled_input(true); + print_line("No ServerNode singleton found, Running PhotoInbox in testing mode"); + } +} + +void PhotoInbox::unhandled_input(Ref const &event) { + Ref key{ event }; + if (key.is_valid() && key->is_pressed()) { + switch (key->get_key_label()) { + default: + break; + case Key::KEY_1: + on_clue_revealed(NetworkData::CLUE_FIRST); + get_viewport()->set_input_as_handled(); + break; + case Key::KEY_2: + on_clue_revealed(NetworkData::CLUE_SECOND); + get_viewport()->set_input_as_handled(); + break; + } + } +} + +void PhotoInbox::_notification(int what) { + if (Engine::get_singleton()->is_editor_hint()) { + return; + } + switch (what) { + default: + return; + case NOTIFICATION_ENTER_TREE: + enter_tree(); + return; + } +} + +void PhotoInbox::on_clue_revealed(NetworkData::ClueID clue) { + Node *instantiated{ photo_scene->instantiate() }; + if (!instantiated) { + return; + } + if (PinnedPhoto * photo{ cast_to(instantiated) }) { + photo->set_global_position(get_global_position()); + photo->set_visible(false); // make invisible until setup is complete to avoid delay + get_parent()->add_child(instantiated); + photo->set_clue(clue); + photo->set_visible(true); + } +} + +void PhotoInbox::set_photo_scene(Ref scene) { + this->photo_scene = ClassDB::is_parent_class(scene->get_state()->get_node_type(0), "Node2D") ? scene : Ref(); +} + +Ref PhotoInbox::get_photo_scene() const { + return this->photo_scene; +} diff --git a/modules/you_done_it/photo_inbox.h b/modules/you_done_it/photo_inbox.h new file mode 100644 index 00000000..f8fc87de --- /dev/null +++ b/modules/you_done_it/photo_inbox.h @@ -0,0 +1,23 @@ +#pragma once + +#include "scene/2d/node_2d.h" +#include "scene/resources/packed_scene.h" +#include "you_done_it/ydi_networking.h" + +class PhotoInbox : public Node2D { + GDCLASS(PhotoInbox, Node2D); + static void _bind_methods(); + void enter_tree(); + void on_clue_revealed(NetworkData::ClueID id); + +private: + virtual void unhandled_input(Ref const &event) override; + void _notification(int what); + +public: + void set_photo_scene(Ref scene); + Ref get_photo_scene() const; + +private: + Ref photo_scene{}; +}; diff --git a/modules/you_done_it/pinboard.cpp b/modules/you_done_it/pinboard.cpp index f118ee76..df36a14f 100644 --- a/modules/you_done_it/pinboard.cpp +++ b/modules/you_done_it/pinboard.cpp @@ -1,6 +1,7 @@ #include "pinboard.h" #include "core/config/engine.h" #include "pinned_photo.h" +#include "scene/2d/mesh_instance_2d.h" void Pinboard::_bind_methods() { } diff --git a/modules/you_done_it/pinned_photo.cpp b/modules/you_done_it/pinned_photo.cpp index 8d5c609f..2c4a056b 100644 --- a/modules/you_done_it/pinned_photo.cpp +++ b/modules/you_done_it/pinned_photo.cpp @@ -2,6 +2,8 @@ #include "core/config/engine.h" #include "core/input/input_event.h" #include "macros.h" +#include "scene/2d/mesh_instance_2d.h" +#include "you_done_it/clue_db.h" void PinnedPhoto::_bind_methods() { BIND_PROPERTY(Variant::BOOL, can_drop); @@ -10,6 +12,13 @@ void PinnedPhoto::_bind_methods() { void PinnedPhoto::enter_tree() { connect("input_event", callable_mp(this, &self_type::on_input_event)); + connect("child_entered_tree", callable_mp(this, &self_type::on_child_entered_tree)); +} + +void PinnedPhoto::on_child_entered_tree(Node *node) { + if (MeshInstance2D * meshinst{ cast_to(node) }) { + this->photo_mesh = meshinst; + } } void PinnedPhoto::process(double delta) { @@ -27,6 +36,9 @@ void PinnedPhoto::on_input_event(Viewport *viewport, Ref event, int } void PinnedPhoto::unhandled_input(Ref const &event) { + if (!this->is_held) { + return; + } Ref button{ event }; if (button.is_valid() && this->can_drop && button->is_released()) { this->is_held = false; @@ -63,6 +75,12 @@ bool PinnedPhoto::get_can_drop() const { void PinnedPhoto::set_clue(NetworkData::ClueID id) { this->clue = id; + if (photo_mesh) { + Ref texture{ ClueDB::get_singleton()->get_clue(id)->get_image() }; + if (texture.is_valid()) { + photo_mesh->set_texture(texture); + } + } } NetworkData::ClueID PinnedPhoto::get_clue() const { diff --git a/modules/you_done_it/pinned_photo.h b/modules/you_done_it/pinned_photo.h index ec1be4c7..e575f7b9 100644 --- a/modules/you_done_it/pinned_photo.h +++ b/modules/you_done_it/pinned_photo.h @@ -1,6 +1,7 @@ #pragma once #include "core/input/input_event.h" +#include "scene/2d/mesh_instance_2d.h" #include "scene/2d/physics/animatable_body_2d.h" #include "scene/main/viewport.h" #include "ydi_networking.h" @@ -9,6 +10,7 @@ class PinnedPhoto : public AnimatableBody2D { GDCLASS(PinnedPhoto, AnimatableBody2D); static void _bind_methods(); void enter_tree(); + void on_child_entered_tree(Node *node); void process(double delta); void on_input_event(Viewport *viewport, Ref event, int shape); @@ -23,6 +25,7 @@ public: NetworkData::ClueID get_clue() const; private: + MeshInstance2D *photo_mesh{ nullptr }; NetworkData::ClueID clue{ NetworkData::CLUE_MAX }; bool can_drop{ false }; bool is_held{ false }; diff --git a/modules/you_done_it/register_types.cpp b/modules/you_done_it/register_types.cpp index 105d3917..c82312a7 100644 --- a/modules/you_done_it/register_types.cpp +++ b/modules/you_done_it/register_types.cpp @@ -5,6 +5,8 @@ #include "you_done_it/clue_data.h" #include "you_done_it/clue_finder.h" #include "you_done_it/clue_marker.h" +#include "you_done_it/file_popup.h" +#include "you_done_it/photo_inbox.h" #include "you_done_it/pinboard.h" #include "you_done_it/pinned_photo.h" #include "you_done_it/server_node.h" @@ -25,10 +27,15 @@ void initialize_you_done_it_module(ModuleInitializationLevel p_level) { ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); } void uninitialize_you_done_it_module(ModuleInitializationLevel p_level) { if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { return; } + if (ClueDB::has_singleton()) { + ClueDB::get_singleton().unref(); + } } diff --git a/vr-project/scenes/game_scene.tscn b/vr-project/scenes/game_scene.tscn index ac38ad0e..2040562e 100644 --- a/vr-project/scenes/game_scene.tscn +++ b/vr-project/scenes/game_scene.tscn @@ -58,16 +58,6 @@ fog_height_density = -0.4746 [node name="Root" type="Node3D"] [node name="VROrigin" parent="." instance=ExtResource("2_onqr8")] -_import_path = NodePath("") -unique_name_in_owner = false -process_mode = 0 -process_priority = 0 -process_physics_priority = 0 -process_thread_group = 0 -physics_interpolation_mode = 0 -auto_translate_mode = 0 -editor_description = "" -script = null [node name="WorldEnvironment" type="WorldEnvironment" parent="."] environment = SubResource("Environment_bw6k5") @@ -83,17 +73,7 @@ shadow_blur = 1.476 transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.27989578, 0, 1.4924412) [node name="ClueMarker" type="ClueMarker" parent="."] -_import_path = NodePath("") -unique_name_in_owner = false -process_mode = 0 -process_priority = 0 -process_physics_priority = 0 -process_thread_group = 0 -physics_interpolation_mode = 0 -auto_translate_mode = 0 -editor_description = "" clue_id = 0 -script = null [node name="Stapler" parent="." instance=ExtResource("3_ycayy")] transform = Transform3D(-1.8868132, 0, -1.8585076, 0, 2.6484175, 0, 1.8585076, 0, -1.8868132, -1.2748423, 0.9004388, 2.876501)