From 850fe5865bd6ece7263e92aeb0f917bfa2d654cb Mon Sep 17 00:00:00 2001 From: Sara Date: Thu, 30 Oct 2025 16:34:54 +0100 Subject: [PATCH 1/5] feat: created photo inbox class --- modules/you_done_it/photo_inbox.cpp | 4 ++++ modules/you_done_it/photo_inbox.h | 8 ++++++++ 2 files changed, 12 insertions(+) create mode 100644 modules/you_done_it/photo_inbox.cpp create mode 100644 modules/you_done_it/photo_inbox.h diff --git a/modules/you_done_it/photo_inbox.cpp b/modules/you_done_it/photo_inbox.cpp new file mode 100644 index 00000000..e15ad480 --- /dev/null +++ b/modules/you_done_it/photo_inbox.cpp @@ -0,0 +1,4 @@ +#include "photo_inbox.h" + +void PhotoInbox::_bind_methods() { +} diff --git a/modules/you_done_it/photo_inbox.h b/modules/you_done_it/photo_inbox.h new file mode 100644 index 00000000..2ba49aab --- /dev/null +++ b/modules/you_done_it/photo_inbox.h @@ -0,0 +1,8 @@ +#pragma once + +#include "scene/2d/node_2d.h" + +class PhotoInbox : public Node2D { + GDCLASS(PhotoInbox, Node2D); + static void _bind_methods(); +}; From 2577d41e469e8acde51a7c2def84f7a3cb17edb1 Mon Sep 17 00:00:00 2001 From: Sara Date: Thu, 30 Oct 2025 21:33:22 +0100 Subject: [PATCH 2/5] feat: implemented photo inbox and notepad --- .../assets/photo-images/Knife.jpg | Bin 0 -> 41224 bytes .../assets/photo-images/Knife.jpg.import | 40 ++++++++++ flatscreen-project/clue_db.tres | 13 ++++ flatscreen-project/objects/pinned_photo.tscn | 21 ++++++ .../scenes/flatscreen_root.tscn | 56 +++----------- .../scenes/start_server_ui.tscn | 36 +++++---- flatscreen-project/scenes/workspace.tscn | 53 +++++++++++++ modules/you_done_it/clue_data.cpp | 7 +- modules/you_done_it/clue_data.h | 8 +- modules/you_done_it/clue_db.cpp | 10 +-- modules/you_done_it/clue_db.h | 2 +- modules/you_done_it/photo_inbox.cpp | 71 ++++++++++++++++++ modules/you_done_it/photo_inbox.h | 15 ++++ modules/you_done_it/pinboard.cpp | 1 + modules/you_done_it/pinned_photo.cpp | 18 +++++ modules/you_done_it/pinned_photo.h | 3 + modules/you_done_it/register_types.cpp | 5 ++ 17 files changed, 285 insertions(+), 74 deletions(-) create mode 100644 flatscreen-project/assets/photo-images/Knife.jpg create mode 100644 flatscreen-project/assets/photo-images/Knife.jpg.import create mode 100644 flatscreen-project/clue_db.tres create mode 100644 flatscreen-project/objects/pinned_photo.tscn create mode 100644 flatscreen-project/scenes/workspace.tscn diff --git a/flatscreen-project/assets/photo-images/Knife.jpg b/flatscreen-project/assets/photo-images/Knife.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fb92ef2a025557dc6da85dae05c1352242a03718 GIT binary patch literal 41224 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 literal 0 HcmV?d00001 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/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/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..95c20339 --- /dev/null +++ b/flatscreen-project/scenes/workspace.tscn @@ -0,0 +1,53 @@ +[gd_scene load_steps=7 format=3 uid="uid://o3ri154wpbrx"] + +[ext_resource type="PackedScene" uid="uid://btcmnw6q6g0h0" path="res://objects/pinned_photo.tscn" id="1_7cefc"] + +[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(1074, 533) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_7cefc"] +size = Vector2(295, 346) + +[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(691, 465.5) +shape = SubResource("RectangleShape2D_87mh6") + +[node name="CollisionShape2D2" type="CollisionShape2D" parent="Pinboard"] +position = Vector2(1392.5, 560) +shape = SubResource("RectangleShape2D_7cefc") + +[node name="PinnedPhoto" parent="." instance=ExtResource("1_7cefc")] +position = Vector2(479, 904) + +[node name="PhotoInbox" type="PhotoInbox" parent="."] +position = Vector2(1767, 890) +photo_scene = ExtResource("1_7cefc") + +[node name="TextEdit" type="TextEdit" parent="."] +offset_left = 1604.0 +offset_top = 181.0 +offset_right = 1822.0 +offset_bottom = 346.0 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/photo_inbox.cpp b/modules/you_done_it/photo_inbox.cpp index e15ad480..9e1039f3 100644 --- a/modules/you_done_it/photo_inbox.cpp +++ b/modules/you_done_it/photo_inbox.cpp @@ -1,4 +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 index 2ba49aab..f8fc87de 100644 --- a/modules/you_done_it/photo_inbox.h +++ b/modules/you_done_it/photo_inbox.h @@ -1,8 +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..e203bfba 100644 --- a/modules/you_done_it/register_types.cpp +++ b/modules/you_done_it/register_types.cpp @@ -5,6 +5,7 @@ #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/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 +26,14 @@ void initialize_you_done_it_module(ModuleInitializationLevel p_level) { 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(); + } } From 10bb9a7f5bcc1236688f30ebcb5ed870d457fa90 Mon Sep 17 00:00:00 2001 From: Sara Date: Thu, 30 Oct 2025 22:06:02 +0100 Subject: [PATCH 3/5] fix: reimported main scene to remove incorrect data --- vr-project/scenes/game_scene.tscn | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/vr-project/scenes/game_scene.tscn b/vr-project/scenes/game_scene.tscn index ccf33625..0fc4a775 100644 --- a/vr-project/scenes/game_scene.tscn +++ b/vr-project/scenes/game_scene.tscn @@ -55,16 +55,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") @@ -85,17 +75,7 @@ shadow_blur = 2.834 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) From 05a06b455a87db14020518c40f7c06c259cc7cac Mon Sep 17 00:00:00 2001 From: Sara Date: Thu, 30 Oct 2025 23:50:32 +0100 Subject: [PATCH 4/5] feat: implemented victim file animation and popup --- flatscreen-project/scenes/workspace.tscn | 68 ++++++++++++++++++- modules/you_done_it/file_popup.cpp | 84 ++++++++++++++++++++++++ modules/you_done_it/file_popup.h | 28 ++++++++ modules/you_done_it/register_types.cpp | 2 + 4 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 modules/you_done_it/file_popup.cpp create mode 100644 modules/you_done_it/file_popup.h diff --git a/flatscreen-project/scenes/workspace.tscn b/flatscreen-project/scenes/workspace.tscn index 95c20339..994dc840 100644 --- a/flatscreen-project/scenes/workspace.tscn +++ b/flatscreen-project/scenes/workspace.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=7 format=3 uid="uid://o3ri154wpbrx"] +[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"] @@ -17,6 +17,36 @@ size = Vector2(1074, 533) [sub_resource type="RectangleShape2D" id="RectangleShape2D_7cefc"] size = Vector2(295, 346) +[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="FlatscreenRoot" type="Node2D"] [node name="Camera2D" type="Camera2D" parent="."] @@ -51,3 +81,39 @@ offset_left = 1604.0 offset_top = 181.0 offset_right = 1822.0 offset_bottom = 346.0 + +[node name="FilePopup" type="FilePopup" parent="." node_paths=PackedStringArray("open_position")] +position = Vector2(12.000002, 0) +rotation = 0.08145886 +open_position = NodePath("../FilePositionTarget") + +[node name="MeshInstance2D2" type="MeshInstance2D" parent="FilePopup"] +position = Vector2(22.500002, 142.6643) +scale = Vector2(77, 222.67134) +mesh = SubResource("QuadMesh_7cefc") + +[node name="MeshInstance2D" type="MeshInstance2D" parent="FilePopup"] +position = Vector2(-333.25, 486.25) +scale = Vector2(667.5, 973.5) +mesh = SubResource("QuadMesh_7cefc") + +[node name="Area2D" type="Area2D" parent="FilePopup"] +position = Vector2(29.17066, 143.39133) +script = SubResource("GDScript_7cefc") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="FilePopup/Area2D"] +scale = Vector2(1.0000002, 1.0000002) +shape = SubResource("RectangleShape2D_vo7lu") + +[node name="MeshInstance2D3" type="MeshInstance2D" parent="FilePopup"] +position = Vector2(33.037315, 137.30455) +rotation = 1.5707964 +scale = Vector2(-347.0554, 307.87436) +mesh = SubResource("TextMesh_7cefc") +texture = SubResource("GradientTexture1D_wjago") + +[node name="FilePositionTarget" type="Node2D" parent="."] +position = Vector2(593, 40.000004) +rotation = 0.24976808 + +[connection signal="input_event" from="FilePopup/Area2D" to="FilePopup/Area2D" method="_on_input_event"] 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..e71ce019 --- /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{ 3.0 }; +}; diff --git a/modules/you_done_it/register_types.cpp b/modules/you_done_it/register_types.cpp index e203bfba..c82312a7 100644 --- a/modules/you_done_it/register_types.cpp +++ b/modules/you_done_it/register_types.cpp @@ -5,6 +5,7 @@ #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" @@ -27,6 +28,7 @@ void initialize_you_done_it_module(ModuleInitializationLevel p_level) { ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); + ClassDB::register_class(); } void uninitialize_you_done_it_module(ModuleInitializationLevel p_level) { From dda31f9b606b941abf05deaa65bb0b2570815660 Mon Sep 17 00:00:00 2001 From: Sara Date: Fri, 31 Oct 2025 15:33:59 +0100 Subject: [PATCH 5/5] feat: added case, victim and witness UI elements --- flatscreen-project/objects/case_file.tscn | 60 +++++++++ flatscreen-project/objects/victim_file.tscn | 60 +++++++++ .../objects/witness_report.tscn | 61 ++++++++++ flatscreen-project/project.godot | 4 + flatscreen-project/scenes/workspace.tscn | 115 ++++++++---------- modules/you_done_it/file_popup.h | 2 +- 6 files changed, 234 insertions(+), 68 deletions(-) create mode 100644 flatscreen-project/objects/case_file.tscn create mode 100644 flatscreen-project/objects/victim_file.tscn create mode 100644 flatscreen-project/objects/witness_report.tscn 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/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/workspace.tscn b/flatscreen-project/scenes/workspace.tscn index 994dc840..be09461e 100644 --- a/flatscreen-project/scenes/workspace.tscn +++ b/flatscreen-project/scenes/workspace.tscn @@ -1,6 +1,9 @@ [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"] @@ -12,40 +15,16 @@ colors = PackedColorArray(0.7490196, 0.7019608, 0.6431373, 1) gradient = SubResource("Gradient_usqe2") [sub_resource type="RectangleShape2D" id="RectangleShape2D_87mh6"] -size = Vector2(1074, 533) +size = Vector2(965, 533) [sub_resource type="RectangleShape2D" id="RectangleShape2D_7cefc"] -size = Vector2(295, 346) +size = Vector2(400, 64) -[sub_resource type="QuadMesh" id="QuadMesh_7cefc"] +[sub_resource type="QuadMesh" id="QuadMesh_cnvne"] -[sub_resource type="GDScript" id="GDScript_7cefc"] -script/source = "extends Area2D +[sub_resource type="QuadMesh" id="QuadMesh_thvsl"] - -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") +[sub_resource type="ImageTexture" id="ImageTexture_cnvne"] [node name="FlatscreenRoot" type="Node2D"] @@ -62,58 +41,60 @@ mesh = SubResource("QuadMesh_usqe2") texture = SubResource("GradientTexture1D_87mh6") [node name="CollisionShape2D" type="CollisionShape2D" parent="Pinboard"] -position = Vector2(691, 465.5) +position = Vector2(636.5, 465.5) shape = SubResource("RectangleShape2D_87mh6") [node name="CollisionShape2D2" type="CollisionShape2D" parent="Pinboard"] -position = Vector2(1392.5, 560) +position = Vector2(1340, 701) shape = SubResource("RectangleShape2D_7cefc") -[node name="PinnedPhoto" parent="." instance=ExtResource("1_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="."] -position = Vector2(1767, 890) +[node name="PhotoInbox" type="PhotoInbox" parent="PhotosParent"] +position = Vector2(1679, 900) photo_scene = ExtResource("1_7cefc") -[node name="TextEdit" type="TextEdit" parent="."] -offset_left = 1604.0 -offset_top = 181.0 -offset_right = 1822.0 -offset_bottom = 346.0 - -[node name="FilePopup" type="FilePopup" parent="." node_paths=PackedStringArray("open_position")] +[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="MeshInstance2D2" type="MeshInstance2D" parent="FilePopup"] -position = Vector2(22.500002, 142.6643) -scale = Vector2(77, 222.67134) -mesh = SubResource("QuadMesh_7cefc") +[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="MeshInstance2D" type="MeshInstance2D" parent="FilePopup"] -position = Vector2(-333.25, 486.25) -scale = Vector2(667.5, 973.5) -mesh = SubResource("QuadMesh_7cefc") - -[node name="Area2D" type="Area2D" parent="FilePopup"] -position = Vector2(29.17066, 143.39133) -script = SubResource("GDScript_7cefc") - -[node name="CollisionShape2D" type="CollisionShape2D" parent="FilePopup/Area2D"] -scale = Vector2(1.0000002, 1.0000002) -shape = SubResource("RectangleShape2D_vo7lu") - -[node name="MeshInstance2D3" type="MeshInstance2D" parent="FilePopup"] -position = Vector2(33.037315, 137.30455) -rotation = 1.5707964 -scale = Vector2(-347.0554, 307.87436) -mesh = SubResource("TextMesh_7cefc") -texture = SubResource("GradientTexture1D_wjago") +[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(593, 40.000004) -rotation = 0.24976808 +position = Vector2(678.00006, 63.999996) +rotation = -0.0034519732 -[connection signal="input_event" from="FilePopup/Area2D" to="FilePopup/Area2D" method="_on_input_event"] +[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/file_popup.h b/modules/you_done_it/file_popup.h index e71ce019..6ceb53aa 100644 --- a/modules/you_done_it/file_popup.h +++ b/modules/you_done_it/file_popup.h @@ -24,5 +24,5 @@ private: bool desire_open{ false }; Transform2D home_position{}; Node2D *open_position{ nullptr }; - double const ANIM_SPEED{ 3.0 }; + double const ANIM_SPEED{ 5.0 }; };