From 7ec7552d0a9bb661dee48130da541d239d8b4d0c Mon Sep 17 00:00:00 2001 From: Tiger Jove Date: Mon, 5 Jan 2026 16:04:59 +0100 Subject: [PATCH 1/8] chore: working towards a better inheritance and render order for mementos --- .../youth_room/youth_room.gd | 39 +- .../youth_room/youth_room.tscn | 382 +----------------- .../youth_room/youth_room_environment.gd | 1 + .../youth_room/youth_room_scene_player.gd | 81 ++-- src/logic-scenes/card_burner/card_burner.gd | 8 +- src/logic-scenes/card_picker/card_picker.gd | 4 +- .../collectable/collectable_ui.gd | 57 ++- .../collectable/collectable_ui.gd.uid | 2 +- .../collectable/collectable_ui.tscn | 3 + .../interactive_sprite.tscn | 74 ++++ .../luna/playables/story_playable.gd | 4 + .../player_controller/player_controller.gd | 2 +- src/singletons/global_state.gd | 180 +++++---- src/singletons/scene_reference.gd | 91 +++-- 14 files changed, 368 insertions(+), 560 deletions(-) create mode 100644 src/logic-scenes/interactive_sprite/interactive_sprite.tscn diff --git a/src/base-environments/youth_room/youth_room.gd b/src/base-environments/youth_room/youth_room.gd index 10a4580..5b0b56f 100644 --- a/src/base-environments/youth_room/youth_room.gd +++ b/src/base-environments/youth_room/youth_room.gd @@ -1,6 +1,9 @@ class_name YouthRoom extends RoomTemplate +## Used by the stage system when this room takes stage for intro playback +var has_stage: bool = false + @onready var board_trigger: InteractiveSprite = %MindBoard @onready var door_trigger: InteractiveSprite = %Door @onready var card_board: CardBoard = %Board @@ -12,19 +15,32 @@ signal interaction(interactable: Object) func start_room(): %UI.show() $logic/PlayerController.process_mode = Node.PROCESS_MODE_INHERIT + if not Scenes.is_sequence_repeating(Scenes.id.YOUTH_DRAEVEN): - Scenes.start_sequence(Scenes.id.YOUTH_DRAEVEN) - State.queue_for_stage(%PlayerController) + # Play intro scene directly (not triggered by CollectableUi) + await _play_intro_scene() + State.pass_stage_to(%PlayerController) else: State.pass_stage_to(%PlayerController) %LightAnimation.lights_on() - while true: # playing? - var interactable = await interaction - if interactable is StoryPlayable: - await interactable.play() - # check gamestate to quit? - pass + +func _play_intro_scene() -> void: + # The intro scene is auto-played, not triggered by CollectableUi + var intro_playable: StoryPlayable = $logic/ScenePlayer/draven + + State.take_stage(self) + Scenes.begin_sequence(Scenes.id.YOUTH_DRAEVEN) + + Input.mouse_mode = Input.MOUSE_MODE_HIDDEN + + # Play the story (StoryPlayable handles its own visibility via animations) + await intro_playable.play() + + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + + State.leave_stage(self) + Scenes.end_sequence(Scenes.id.YOUTH_DRAEVEN) @@ -36,7 +52,7 @@ func get_ready(): save_game.is_childhood_board_complete = true save_room()) - Scenes.sign_up_for_sequence(play_chest_animation, Scenes.id.YOUTH_VOICE_TRAINING, 0) + # Scene registration is now handled by youth_room_scene_player ui.hide() $sfx/distant_rain.play() @@ -73,11 +89,10 @@ func prepare_transition(): unload() -func play_chest_animation(_id): +# Called by youth_room_scene_player when voice training scene starts +func play_chest_reveal() -> void: $AnimationPlayer.play("chest_reveal") $visuals/SecondaryAnimation.play("chest_reveal") - await $AnimationPlayer.animation_finished - Scenes.continue_sequence(self) func unload(): diff --git a/src/base-environments/youth_room/youth_room.tscn b/src/base-environments/youth_room/youth_room.tscn index 4efbb0e..ab628ea 100644 --- a/src/base-environments/youth_room/youth_room.tscn +++ b/src/base-environments/youth_room/youth_room.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=135 format=4 uid="uid://b3b0gyvklqn50"] +[gd_scene load_steps=120 format=4 uid="uid://b3b0gyvklqn50"] [ext_resource type="Script" uid="uid://bsop46tqngddc" path="res://base-environments/youth_room/youth_room.gd" id="1_aitp0"] [ext_resource type="AudioStream" uid="uid://1h6k2d8q1kw3" path="res://base-environments/youth_room/import/sounds/rain_on_window.mp3" id="2_3haaq"] @@ -16,9 +16,6 @@ [ext_resource type="AudioStream" uid="uid://cho5neuxkvpyh" path="res://base-environments/youth_room/audio/Voice Loop.wav" id="10_wwwdq"] [ext_resource type="Script" uid="uid://c1oub0cs7cph6" path="res://dev-util/stereo-switch.gd" id="10_ypa88"] [ext_resource type="PackedScene" uid="uid://g2a27jwdapai" path="res://logic-scenes/card_burner/card_burner.tscn" id="11_5bsh1"] -[ext_resource type="Script" uid="uid://dr4wd80dobxjd" path="res://base-environments/youth_room/interactive_sprite.gd" id="11_6fwv8"] -[ext_resource type="Script" uid="uid://dbdw3v7mbqscf" path="res://dev-util/click-trough-area.gd" id="11_7uxd8"] -[ext_resource type="PackedScene" uid="uid://bdnesuqroi7ss" path="res://vfx/collectable_particles.tscn" id="12_qxx2k"] [ext_resource type="PackedScene" uid="uid://c3l8tm8ku50vt" path="res://base-environments/youth_room/scnees/childhood.tscn" id="12_viwxf"] [ext_resource type="PackedScene" uid="uid://23bshas7sk6h" path="res://base-environments/youth_room/scnees/jui_jutsu.tscn" id="12_x3dlb"] [ext_resource type="Script" uid="uid://c3xbkwm4x3es7" path="res://base-environments/youth_room/youth_room_scene_player.gd" id="13_5bsh1"] @@ -30,12 +27,11 @@ [ext_resource type="ArrayMesh" uid="uid://bfc3d4g40n0wy" path="res://logic-scenes/collectable/import/old-mask.res" id="19_jr2bb"] [ext_resource type="PackedScene" uid="uid://dwtxjvprjyx8p" path="res://base-environments/youth_room/lava-lamp.tscn" id="21_0k2gr"] [ext_resource type="AudioStream" uid="uid://bghjiqkyehs1p" path="res://base-environments/youth_room/import/sounds/rain and thunder.mp3" id="22_xrkbj"] -[ext_resource type="Texture2D" uid="uid://d0ucjqi8tx6vt" path="res://import/interface-elements/frame.png" id="24_ghmim"] [ext_resource type="Shader" uid="uid://ci37nlh06b5y2" path="res://logic-scenes/collectable/collectable.gdshader" id="25_dqyng"] -[ext_resource type="PackedScene" uid="uid://wfyna16xhlo0" path="res://logic-scenes/collectable/collectable_ui.tscn" id="25_ghmim"] [ext_resource type="PackedScene" uid="uid://bpjympn3ps3wo" path="res://logic-scenes/luna/luna_imported.tscn" id="27_pb1jl"] [ext_resource type="Material" uid="uid://ct7uc5i5yp5qf" path="res://base-environments/youth_room/import/materials/wall.tres" id="28_oiweb"] [ext_resource type="PackedScene" uid="uid://bw47g00bi710i" path="res://base-environments/youth_room/youth_room_visuals.tscn" id="30_dqyng"] +[ext_resource type="PackedScene" uid="uid://cy4yesucptcr3" path="res://logic-scenes/interactive_sprite/interactive_sprite.tscn" id="30_ypa88"] [ext_resource type="PackedScene" uid="uid://bwc2wp7tckm7t" path="res://base-environments/youth_room/outside.tscn" id="32_2vgep"] [ext_resource type="Script" uid="uid://br1w2nt4pj8lt" path="res://vfx/post_processing/post_process_shader_template.gd" id="32_corra"] [ext_resource type="Shader" uid="uid://d324neibxpomg" path="res://base-environments/intro/shaders/stars.gdshader" id="32_k5rvd"] @@ -930,57 +926,14 @@ _surfaces = [{ blend_shape_mode = 0 shadow_mesh = SubResource("ArrayMesh_lag5h") -[sub_resource type="BoxShape3D" id="BoxShape3D_cb3g8"] -size = Vector3(2.31545, 2.13395, 0.0774798) - -[sub_resource type="ViewportTexture" id="ViewportTexture_ghmim"] +[sub_resource type="ViewportTexture" id="ViewportTexture_ypa88"] viewport_path = NodePath("logic/MaskMemento/UiWrapper/UiSprite/SubViewport") -[sub_resource type="ShaderMaterial" id="ShaderMaterial_dqyng"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_mhuct"] resource_local_to_scene = true render_priority = 0 shader = ExtResource("25_dqyng") -shader_parameter/default_texture = SubResource("ViewportTexture_ghmim") - -[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_72g2i"] -radius = 0.387255 -height = 1.1225358 - -[sub_resource type="ViewportTexture" id="ViewportTexture_7hana"] -viewport_path = NodePath("logic/ClothesMemento/UiWrapper/UiSprite/SubViewport") - -[sub_resource type="ShaderMaterial" id="ShaderMaterial_e5y1q"] -resource_local_to_scene = true -render_priority = 0 -shader = ExtResource("25_dqyng") -shader_parameter/default_texture = SubResource("ViewportTexture_7hana") - -[sub_resource type="ViewportTexture" id="ViewportTexture_nn6wl"] -viewport_path = NodePath("logic/ComicMemento/UiWrapper/UiSprite/SubViewport") - -[sub_resource type="ViewportTexture" id="ViewportTexture_8rywf"] -viewport_path = NodePath("logic/CeilingMemento/UiWrapper/UiSprite/SubViewport") - -[sub_resource type="ShaderMaterial" id="ShaderMaterial_xbjb2"] -resource_local_to_scene = true -render_priority = 0 -shader = ExtResource("25_dqyng") -shader_parameter/default_texture = SubResource("ViewportTexture_8rywf") - -[sub_resource type="SphereShape3D" id="SphereShape3D_c7buh"] -radius = 0.469631 - -[sub_resource type="ViewportTexture" id="ViewportTexture_hdmps"] -viewport_path = NodePath("logic/MindBoard/UiWrapper/UiSprite/SubViewport") - -[sub_resource type="ViewportTexture" id="ViewportTexture_v3447"] -viewport_path = NodePath("logic/Door/UiWrapper/UiSprite/SubViewport") - -[sub_resource type="ShaderMaterial" id="ShaderMaterial_5bsh1"] -resource_local_to_scene = true -render_priority = 0 -shader = ExtResource("25_dqyng") -shader_parameter/default_texture = SubResource("ViewportTexture_v3447") +shader_parameter/default_texture = SubResource("ViewportTexture_ypa88") [sub_resource type="Animation" id="Animation_xum02"] length = 0.001 @@ -2016,308 +1969,27 @@ light_energy = 100.0 light_size = 20.0 omni_range = 16.8518 -[node name="MaskMemento" type="Area3D" parent="logic" groups=["interactables"]] -unique_name_in_owner = true -transform = Transform3D(-0.863025, 0, 0.50516, 0, 1, 0, -0.50516, 0, -0.863025, 0.0754588, 0.948372, 2.42068) -collision_layer = 16 -collision_mask = 0 -script = ExtResource("11_6fwv8") +[node name="MaskMemento" parent="logic" instance=ExtResource("30_ypa88")] +transform = Transform3D(-0.8630245, 0, 0.5051597, 0, 1, 0, -0.5051597, 0, -0.8630245, 0.0754588, 0.948372, 2.42068) -[node name="collectable_particles" parent="logic/MaskMemento" instance=ExtResource("12_qxx2k")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00898492, -0.14171, 0.152755) +[node name="ClothesMemento" parent="logic" instance=ExtResource("30_ypa88")] +transform = Transform3D(0.8604294, 0, -0.5095667, 0, 1, 0, 0.5095667, 0, 0.8604294, 1.3658599, 1.17096, -0.6365988) -[node name="UiWrapper" type="Area3D" parent="logic/MaskMemento"] -transform = Transform3D(0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, -0.134171, -0.20001, -0.000299692) -script = ExtResource("11_7uxd8") +[node name="ComicMemento" parent="logic" instance=ExtResource("30_ypa88")] +transform = Transform3D(0.9699434, 0, 0.24332686, 0, 1, 0, -0.24332686, 0, 0.9699434, 2.91664, 0.595014, -0.75655603) -[node name="UI_click_collider" type="CollisionShape3D" parent="logic/MaskMemento/UiWrapper"] -transform = Transform3D(2.56, -5.96046e-08, 4.76837e-07, 1.78814e-07, 2.56, -4.17233e-07, 0, -5.96046e-08, 2.56, -3.32987, -0.143251, 0.0614357) -shape = SubResource("BoxShape3D_cb3g8") +[node name="CeilingMemento" parent="logic" instance=ExtResource("30_ypa88")] +transform = Transform3D(0.71489924, 0, 0.6992255, 0, 1, 0, -0.6992255, 0, 0.71489924, -0.13478619, 2.0720484, -0.42032808) -[node name="UiSprite" type="Sprite3D" parent="logic/MaskMemento/UiWrapper"] -transform = Transform3D(1, 0, -5.96046e-08, 0, 1, 0, 5.96046e-08, 0, 1, -3.4386, -0.143253, 0.433798) -material_override = SubResource("ShaderMaterial_dqyng") -modulate = Color(0.52473676, 0.353479, 0.20148611, 1) -pixel_size = 0.015 -shaded = true -no_depth_test = true -texture = SubResource("ViewportTexture_ghmim") +[node name="MindBoard" parent="logic" instance=ExtResource("30_ypa88")] +transform = Transform3D(-4.3711374e-08, 0, 0.9999984, 0, 1, 0, -0.9999984, 0, -4.3711374e-08, -0.907206, 1.17661, 1.74337) -[node name="SubViewport" type="SubViewport" parent="logic/MaskMemento/UiWrapper/UiSprite"] -transparent_bg = true -size = Vector2i(400, 350) -render_target_update_mode = 4 +[node name="UiSprite" parent="logic/MindBoard/UiWrapper" index="1"] +material_override = SubResource("ShaderMaterial_mhuct") +texture = SubResource("ViewportTexture_ypa88") -[node name="CollectableUi" parent="logic/MaskMemento/UiWrapper/UiSprite/SubViewport" instance=ExtResource("25_ghmim")] - -[node name="Frame" type="Sprite3D" parent="logic/MaskMemento/UiWrapper"] -transform = Transform3D(0.704571, 0, -1.19209e-07, 0, 0.704571, 0, 1.19209e-07, 0, 0.704571, -2.9410253, -0.7882633, 0.5234841) -visibility_range_end = 0.6 -visibility_range_end_margin = 0.3 -visibility_range_fade_mode = 1 -modulate = Color(1.8247963, 1.8247963, 1.8247963, 1) -no_depth_test = true -texture = ExtResource("24_ghmim") -region_enabled = true -region_rect = Rect2(735.5, 0, 995.5, 1024) - -[node name="HoverDetect" type="CollisionShape3D" parent="logic/MaskMemento"] -transform = Transform3D(-0.0152331, -0.999545, -0.0260244, 0.863025, -5.87663e-08, -0.50516, 0.50493, -0.0301548, 0.862633, -0.266952, -0.0898764, 0.0160832) -shape = SubResource("CapsuleShape3D_72g2i") - -[node name="ClothesMemento" type="Area3D" parent="logic" groups=["interactables"]] -unique_name_in_owner = true -transform = Transform3D(0.86043, 0, -0.509567, 0, 1, 0, 0.509567, 0, 0.86043, 1.36586, 1.17096, -0.636599) -collision_layer = 16 -collision_mask = 0 -script = ExtResource("11_6fwv8") - -[node name="collectable_particles" parent="logic/ClothesMemento" instance=ExtResource("12_qxx2k")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00898492, -0.14171, 0.152755) - -[node name="UiWrapper" type="Area3D" parent="logic/ClothesMemento"] -transform = Transform3D(0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, 0, 0, 0) -script = ExtResource("11_7uxd8") - -[node name="UI_click_collider" type="CollisionShape3D" parent="logic/ClothesMemento/UiWrapper"] -transform = Transform3D(2.56, -5.96046e-08, 4.76837e-07, 1.78814e-07, 2.56, -4.17233e-07, -2.38419e-07, -5.96046e-08, 2.56, -4.02, -0.8, -0.764) -shape = SubResource("BoxShape3D_cb3g8") - -[node name="UiSprite" type="Sprite3D" parent="logic/ClothesMemento/UiWrapper"] -transform = Transform3D(1, 0, 2.4869e-14, 0, 1, 0, -2.4869e-14, 0, 1, -4.02, -0.8, -0.764) -material_override = SubResource("ShaderMaterial_e5y1q") -modulate = Color(0.47926962, 0.2837075, 0.3487274, 1) -pixel_size = 0.015 -shaded = true -no_depth_test = true -texture = SubResource("ViewportTexture_7hana") - -[node name="SubViewport" type="SubViewport" parent="logic/ClothesMemento/UiWrapper/UiSprite"] -transparent_bg = true -use_hdr_2d = true -size = Vector2i(400, 350) -render_target_update_mode = 4 - -[node name="CollectableUi" parent="logic/ClothesMemento/UiWrapper/UiSprite/SubViewport" instance=ExtResource("25_ghmim")] -scene = 3 - -[node name="Frame" type="Sprite3D" parent="logic/ClothesMemento/UiWrapper"] -transform = Transform3D(0.7045712, 0, 0, 0, 0.70457095, 0, 0, 0, 0.7045712, -3.912711, -1.4219285, -3.3596572e-07) -visibility_range_end = 0.6 -visibility_range_end_margin = 0.3 -visibility_range_fade_mode = 1 -modulate = Color(1.8247963, 1.8247963, 1.8247963, 1) -no_depth_test = true -texture = ExtResource("24_ghmim") -region_enabled = true -region_rect = Rect2(735.5, 0, 995.5, 1024) - -[node name="HoverDetect" type="CollisionShape3D" parent="logic/ClothesMemento"] -transform = Transform3D(0, 0.99999976, -4.371139e-08, 0, -4.371139e-08, -1, -0.99999976, 0, 0, -0.16334146, -0.13, 0) -shape = SubResource("CapsuleShape3D_72g2i") - -[node name="ComicMemento" type="Area3D" parent="logic" groups=["interactables"]] -unique_name_in_owner = true -transform = Transform3D(0.969944, 0, 0.243327, 0, 1, 0, -0.243327, 0, 0.969944, 2.91664, 0.595014, -0.75655603) -collision_layer = 16 -collision_mask = 0 -script = ExtResource("11_6fwv8") - -[node name="collectable_particles" parent="logic/ComicMemento" instance=ExtResource("12_qxx2k")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00898492, -0.14171, 0.152755) - -[node name="UiWrapper" type="Area3D" parent="logic/ComicMemento"] -transform = Transform3D(0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, 0, 0, 0) -script = ExtResource("11_7uxd8") - -[node name="UI_click_collider" type="CollisionShape3D" parent="logic/ComicMemento/UiWrapper"] -transform = Transform3D(2.56, -5.96046e-08, 4.76837e-07, 1.78814e-07, 2.56, -4.17233e-07, -2.38419e-07, -5.96046e-08, 2.56, 0, 1.90735e-06, 0.238397) -shape = SubResource("BoxShape3D_cb3g8") - -[node name="UiSprite" type="Sprite3D" parent="logic/ComicMemento/UiWrapper"] -transform = Transform3D(1, 0, 2.4869e-14, 0, 1, 0, -2.4869e-14, 0, 1, 0, 0, 0.610758) -modulate = Color(0.887414, 0.865536, 0.791715, 1) -pixel_size = 0.015 -shaded = true -no_depth_test = true -texture = SubResource("ViewportTexture_nn6wl") - -[node name="SubViewport" type="SubViewport" parent="logic/ComicMemento/UiWrapper/UiSprite"] -transparent_bg = true -use_hdr_2d = true -size = Vector2i(400, 350) -render_target_update_mode = 4 - -[node name="CollectableUi" parent="logic/ComicMemento/UiWrapper/UiSprite/SubViewport" instance=ExtResource("25_ghmim")] -scene = 2 - -[node name="Frame" type="Sprite3D" parent="logic/ComicMemento/UiWrapper"] -transform = Transform3D(0.70457107, 0, 0, 0, 0.7045709, 0, 0, 0, 0.70457107, 1.0969601, -0.6430273, -0.2718675) -visibility_range_end = 0.6 -visibility_range_end_margin = 0.3 -visibility_range_fade_mode = 1 -modulate = Color(1.8247963, 1.8247963, 1.8247963, 1) -no_depth_test = true -texture = ExtResource("24_ghmim") -region_enabled = true -region_rect = Rect2(735.5, 0, 995.5, 1024) - -[node name="HoverDetect" type="CollisionShape3D" parent="logic/ComicMemento"] -transform = Transform3D(1, 0, 2.98023e-08, 0, 1, 0, -2.98023e-08, 0, 1, 6.2613066e-09, -0.237872, 0.21009475) -shape = SubResource("CapsuleShape3D_72g2i") - -[node name="CeilingMemento" type="Area3D" parent="logic" groups=["interactables"]] -unique_name_in_owner = true -transform = Transform3D(0.71489966, 0, 0.6992259, 0, 1, 0, -0.6992259, 0, 0.71489966, -0.13478619, 2.0720484, -0.42032808) -collision_layer = 16 -collision_mask = 0 -script = ExtResource("11_6fwv8") - -[node name="collectable_particles" parent="logic/CeilingMemento" instance=ExtResource("12_qxx2k")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00898492, -0.14171, 0.152755) - -[node name="UiWrapper" type="Area3D" parent="logic/CeilingMemento"] -transform = Transform3D(0.10000001, 0, -3.7252903e-09, 0, 0.1, 0, 3.7252903e-09, 0, 0.10000001, 0, 0.06951594, 0) -script = ExtResource("11_7uxd8") - -[node name="UI_click_collider" type="CollisionShape3D" parent="logic/CeilingMemento/UiWrapper"] -transform = Transform3D(2.56, -5.96046e-08, 4.76837e-07, 1.78814e-07, 2.56, -4.17233e-07, -2.38419e-07, -5.96046e-08, 2.56, 0, 1.90735e-06, 0.238397) -shape = SubResource("BoxShape3D_cb3g8") - -[node name="UiSprite" type="Sprite3D" parent="logic/CeilingMemento/UiWrapper"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.48293114, 0.61075807) -material_override = SubResource("ShaderMaterial_xbjb2") -modulate = Color(0.8516355, 0.8703886, 0.9474099, 1) -pixel_size = 0.015 -shaded = true -no_depth_test = true -texture = SubResource("ViewportTexture_8rywf") - -[node name="SubViewport" type="SubViewport" parent="logic/CeilingMemento/UiWrapper/UiSprite"] -transparent_bg = true -use_hdr_2d = true -size = Vector2i(400, 350) -render_target_update_mode = 4 - -[node name="CollectableUi" parent="logic/CeilingMemento/UiWrapper/UiSprite/SubViewport" instance=ExtResource("25_ghmim")] -scene = 0 - -[node name="Frame" type="Sprite3D" parent="logic/CeilingMemento/UiWrapper"] -transform = Transform3D(0.70457107, 0, 0, 0, 0.7045709, 0, 0, 0, 0.70457107, 1.0969601, -0.6430273, -0.2718675) -visibility_range_end = 0.6 -visibility_range_end_margin = 0.3 -visibility_range_fade_mode = 1 -modulate = Color(1.8247963, 1.8247963, 1.8247963, 1) -no_depth_test = true -texture = ExtResource("24_ghmim") -region_enabled = true -region_rect = Rect2(735.5, 0, 995.5, 1024) - -[node name="HoverDetect" type="CollisionShape3D" parent="logic/CeilingMemento"] -transform = Transform3D(1, 0, -2.9802322e-08, 0, 1, 0, 2.9802322e-08, 0, 1, 0, 0.09362054, 0) -shape = SubResource("SphereShape3D_c7buh") - -[node name="MindBoard" type="Area3D" parent="logic" groups=["interactables"]] -unique_name_in_owner = true -transform = Transform3D(-4.37114e-08, 0, 0.999999, 0, 1, 0, -0.999999, 0, -4.37114e-08, -0.907206, 1.17661, 1.74337) -collision_layer = 16 -collision_mask = 0 -script = ExtResource("11_6fwv8") - -[node name="collectable_particles" parent="logic/MindBoard" instance=ExtResource("12_qxx2k")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00898492, -0.14171, 0.152755) - -[node name="UiWrapper" type="Area3D" parent="logic/MindBoard"] -transform = Transform3D(0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, 0, 0, 0) -script = ExtResource("11_7uxd8") -billboard = false - -[node name="UI_click_collider" type="CollisionShape3D" parent="logic/MindBoard/UiWrapper"] -transform = Transform3D(2.56, -5.96046e-08, 4.76837e-07, 1.78814e-07, 2.56, -4.17233e-07, -2.38419e-07, -5.96046e-08, 2.56, 0, 1.90735e-06, 0.238397) -shape = SubResource("BoxShape3D_cb3g8") - -[node name="UiSprite" type="Sprite3D" parent="logic/MindBoard/UiWrapper"] -transform = Transform3D(1, 0, 2.4869e-14, 0, 1, 0, -2.4869e-14, 0, 1, -1.0693e-14, 0, 0.180784) -modulate = Color(0.941183, 0.904347, 0.886647, 1) -pixel_size = 0.015 -shaded = true -texture = SubResource("ViewportTexture_hdmps") - -[node name="SubViewport" type="SubViewport" parent="logic/MindBoard/UiWrapper/UiSprite"] -transparent_bg = true -use_hdr_2d = true -size = Vector2i(400, 350) -render_target_update_mode = 4 - -[node name="CollectableUi" parent="logic/MindBoard/UiWrapper/UiSprite/SubViewport" instance=ExtResource("25_ghmim")] -is_board = true - -[node name="Frame" type="Sprite3D" parent="logic/MindBoard/UiWrapper"] -transform = Transform3D(0.70457107, 0, 0, 0, 0.7045709, 0, 0, 0, 0.70457107, 1.0969601, -0.6430273, -0.2718675) -visibility_range_end = 0.6 -visibility_range_end_margin = 0.3 -visibility_range_fade_mode = 1 -modulate = Color(1.8247963, 1.8247963, 1.8247963, 1) -no_depth_test = true -texture = ExtResource("24_ghmim") -region_enabled = true -region_rect = Rect2(735.5, 0, 995.5, 1024) - -[node name="HoverDetect" type="CollisionShape3D" parent="logic/MindBoard"] -transform = Transform3D(-4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0, 1, 0, 0, 0) -shape = SubResource("CapsuleShape3D_72g2i") - -[node name="Door" type="Area3D" parent="logic" groups=["interactables"]] -unique_name_in_owner = true -transform = Transform3D(0.999999, 0, 4.9738e-14, 0, 1, 0, -4.9738e-14, 0, 0.999999, 0.115203, 1.3931, -0.954428) -collision_layer = 16 -collision_mask = 0 -script = ExtResource("11_6fwv8") - -[node name="collectable_particles" parent="logic/Door" instance=ExtResource("12_qxx2k")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00898492, -0.14171, 0.152755) - -[node name="UiWrapper" type="Area3D" parent="logic/Door"] -transform = Transform3D(0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, 0, 0, 0) -script = ExtResource("11_7uxd8") -billboard = false - -[node name="UI_click_collider" type="CollisionShape3D" parent="logic/Door/UiWrapper"] -transform = Transform3D(2.56, -5.96046e-08, 4.76837e-07, 1.78814e-07, 2.56, -4.17233e-07, -2.38419e-07, -5.96046e-08, 2.56, 0, 1.90735e-06, 0.238397) -shape = SubResource("BoxShape3D_cb3g8") - -[node name="UiSprite" type="Sprite3D" parent="logic/Door/UiWrapper"] -transform = Transform3D(1, 0, 2.4869e-14, 0, 1, 0, -2.4869e-14, 0, 1, -1.0693e-14, 0, 0.180784) -material_override = SubResource("ShaderMaterial_5bsh1") -modulate = Color(0.5167205, 0.2787405, 0.482234, 1) -pixel_size = 0.015 -shaded = true -texture = SubResource("ViewportTexture_v3447") - -[node name="SubViewport" type="SubViewport" parent="logic/Door/UiWrapper/UiSprite"] -transparent_bg = true -use_hdr_2d = true -size = Vector2i(400, 350) -render_target_update_mode = 4 - -[node name="CollectableUi" parent="logic/Door/UiWrapper/UiSprite/SubViewport" instance=ExtResource("25_ghmim")] -scene = 4 -is_exit = true - -[node name="Frame" type="Sprite3D" parent="logic/Door/UiWrapper"] -transform = Transform3D(0.70457107, 0, 0, 0, 0.7045709, 0, 0, 0, 0.70457107, 1.0969601, -0.6430273, -0.2718675) -visibility_range_end = 0.6 -visibility_range_end_margin = 0.3 -visibility_range_fade_mode = 1 -modulate = Color(1.8247963, 1.8247963, 1.8247963, 1) -no_depth_test = true -texture = ExtResource("24_ghmim") -region_enabled = true -region_rect = Rect2(735.5, 0, 995.5, 1024) - -[node name="HoverDetect" type="CollisionShape3D" parent="logic/Door"] -transform = Transform3D(-4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0, 1, 0, 0, 0) -shape = SubResource("CapsuleShape3D_72g2i") +[node name="Door" parent="logic" instance=ExtResource("30_ypa88")] +transform = Transform3D(0.9999984, 0, 4.973797e-14, 0, 1, 0, -4.973797e-14, 0, 0.9999984, 0.115203, 1.3931, -0.954428) [node name="AnimationPlayer" type="AnimationPlayer" parent="."] libraries = { @@ -2578,15 +2250,5 @@ data = ExtResource("40_ea6x8") [connection signal="pressed" from="logic/UI/ending_button" to="logic/UI/ending_button" method="hide"] [connection signal="pressed" from="logic/UI/ending_button" to="logic/UI/ending" method="show"] [connection signal="emit_thunder" from="logic/ScenePlayer/JuiJutsu" to="AnimationPlayer" method="play" binds= ["lighting_and_thunder"]] -[connection signal="input_event" from="logic/MaskMemento/UiWrapper" to="logic/MaskMemento/UiWrapper" method="_on_input_event"] -[connection signal="scene_skipped" from="logic/MaskMemento/UiWrapper/UiSprite/SubViewport/CollectableUi" to="logic/UI/Board" method="on_scene_skipped"] -[connection signal="input_event" from="logic/ClothesMemento/UiWrapper" to="logic/ClothesMemento/UiWrapper" method="_on_input_event"] -[connection signal="scene_skipped" from="logic/ClothesMemento/UiWrapper/UiSprite/SubViewport/CollectableUi" to="logic/UI/Board" method="on_scene_skipped"] -[connection signal="input_event" from="logic/ComicMemento/UiWrapper" to="logic/ComicMemento/UiWrapper" method="_on_input_event"] -[connection signal="scene_skipped" from="logic/ComicMemento/UiWrapper/UiSprite/SubViewport/CollectableUi" to="logic/UI/Board" method="on_scene_skipped"] -[connection signal="input_event" from="logic/CeilingMemento/UiWrapper" to="logic/CeilingMemento/UiWrapper" method="_on_input_event"] -[connection signal="scene_skipped" from="logic/CeilingMemento/UiWrapper/UiSprite/SubViewport/CollectableUi" to="logic/UI/Board" method="on_scene_skipped"] -[connection signal="input_event" from="logic/MindBoard/UiWrapper" to="logic/MindBoard/UiWrapper" method="_on_input_event"] -[connection signal="open_board" from="logic/MindBoard/UiWrapper/UiSprite/SubViewport/CollectableUi" to="logic/UI/Board" method="claim_focus"] -[connection signal="input_event" from="logic/Door/UiWrapper" to="logic/Door/UiWrapper" method="_on_input_event"] -[connection signal="open_board" from="logic/Door/UiWrapper/UiSprite/SubViewport/CollectableUi" to="logic/UI/Board" method="claim_focus"] + +[editable path="logic/MindBoard"] diff --git a/src/base-environments/youth_room/youth_room_environment.gd b/src/base-environments/youth_room/youth_room_environment.gd index 0651126..afd8bed 100644 --- a/src/base-environments/youth_room/youth_room_environment.gd +++ b/src/base-environments/youth_room/youth_room_environment.gd @@ -19,6 +19,7 @@ func focus_object(): func scene_starting(id: int, _repeat: bool): if id == Scenes.id.YOUTH_VOICE_TRAINING: + #BUG: This await is dangerous and can lead to focus when the user has already moved on await get_tree().create_timer(10).timeout focus_object() diff --git a/src/base-environments/youth_room/youth_room_scene_player.gd b/src/base-environments/youth_room/youth_room_scene_player.gd index 2f7fec8..78c10d4 100644 --- a/src/base-environments/youth_room/youth_room_scene_player.gd +++ b/src/base-environments/youth_room/youth_room_scene_player.gd @@ -1,78 +1,53 @@ extends AnimationPlayer -var has_stage -var is_repeating = false +# This scene player now responds to scene signals to handle music and animations. +# The actual story playback is managed by CollectableUi directly. func _ready() -> void: - Scenes.scene_finished.connect(scene_finished) - - # FIXME: this needs to be made prettier. - $draven.finished.connect(on_draeven_done) - $childhood.finished.connect(on_childhood_done) - $JuiJutsu.finished.connect(on_jui_jutsu_done) - $voice_training.finished.connect(on_voice_training_done) - $draven.intro.connect(try_intro) - - Scenes.sign_up_for_sequence(play_scene, Scenes.id.YOUTH_DRAEVEN, 1) - Scenes.sign_up_for_sequence(play_scene, Scenes.id.YOUTH_CHILDHOOD, 0) - Scenes.sign_up_for_sequence(play_scene, Scenes.id.YOUTH_VOICE_TRAINING, 1) - Scenes.sign_up_for_sequence(play_scene, Scenes.id.YOUTH_JUI_JUTSU, 0) + Scenes.scene_starting.connect(_on_scene_starting) + Scenes.scene_finished.connect(_on_scene_finished) func start_soundtrack(): $Moving.play(70) $Childhood.play(70) $VoiceTraining.play(70) -func play_scene(id: int, repeat = false): - get_tree().call_group("interactables", "collapse") - is_repeating = repeat - Input.mouse_mode = Input.MOUSE_MODE_HIDDEN - match id: +func _on_scene_starting(scene_id: Scenes.id, _repeat: bool) -> void: + print_debug("YouthRoomScenePlayer._on_scene_starting(%s)" % Scenes.id.keys()[scene_id]) + + # Handle scene-specific setup (music, chest animation, etc.) + match scene_id: Scenes.id.YOUTH_CHILDHOOD: play("childhood_music") - $childhood.play() Scenes.id.YOUTH_VOICE_TRAINING: - $voice_training.play() play("voice_music") + _play_chest_animation() Scenes.id.YOUTH_JUI_JUTSU: play("jui_jutsu_music") - $JuiJutsu.play() Scenes.id.YOUTH_DRAEVEN: play("draeven") - $draven.play() - -func on_childhood_done(): - Scenes.continue_sequence(self) - $childhood.hide() - -func on_voice_training_done(): - Scenes.continue_sequence(self) - $"voice_training".hide() - -func on_jui_jutsu_done(): - Scenes.continue_sequence(self) - $JuiJutsu.hide() - if $JuiJutsu.was_skipped: - play("intro") - -func on_draeven_done(): - Scenes.continue_sequence(self) - await $draven.finished - $draven.hide() - -func try_intro(): - if $draven.was_skipped: - play("intro") - -func scene_finished(id: Scenes.id, _repeat: bool): - match id: +func _on_scene_finished(scene_id: Scenes.id, _repeat: bool) -> void: + print_debug("YouthRoomScenePlayer._on_scene_finished(%s)" % Scenes.id.keys()[scene_id]) + + match scene_id: Scenes.id.YOUTH_CHILDHOOD: play_backwards("childhood_music") Scenes.id.YOUTH_VOICE_TRAINING: play_backwards("voice_music") + queue("RESET") -func play(anin_name: StringName = "", a: float = -1, b: float = 1, c: bool = false) -> void: - print_debug("anim player accessed!") - super.play(anin_name, a, b, c) +func _play_chest_animation() -> void: + # Navigate up to youth_room to trigger chest reveal animation + var room = get_parent().get_parent() + if room and room.has_method("play_chest_reveal"): + room.play_chest_reveal() + +func try_intro(): + # Called from StoryPlayable for draven intro + play("intro") + +func play(anim_name: StringName = "", a: float = -1, b: float = 1, c: bool = false) -> void: + print_debug("YouthRoomScenePlayer.play(%s)" % anim_name) + super.play(anim_name, a, b, c) diff --git a/src/logic-scenes/card_burner/card_burner.gd b/src/logic-scenes/card_burner/card_burner.gd index aa6e819..d961f3b 100644 --- a/src/logic-scenes/card_burner/card_burner.gd +++ b/src/logic-scenes/card_burner/card_burner.gd @@ -21,10 +21,10 @@ var has_stage = false: @onready var ancors: Array[Control] = [%Ancor1, %Ancor2, %Ancor3, %Ancor4] func _ready(): - Scenes.sign_up_for_sequence(burn_cards, Scenes.id.TRANSITION, 0) + Scenes.register_scene_actor(Scenes.id.TRANSITION, burn_cards) %SkipButton.pressed.connect(card_burned.emit) -func burn_cards(_id): +func burn_cards(_id: int, _repeat: bool = false) -> void: var random_card_names: Array = State.save_game.board_state["randoms"] for card_name in random_card_names: @@ -47,9 +47,7 @@ func burn_cards(_id): $AnimationPlayer.play("vanish") await $AnimationPlayer.animation_finished - - #Scenes.continue_sequence(self) - Scenes.end_current_sequence() + Scenes.finish_sequence(self) signal card_burned diff --git a/src/logic-scenes/card_picker/card_picker.gd b/src/logic-scenes/card_picker/card_picker.gd index 0b7ed90..41efac0 100644 --- a/src/logic-scenes/card_picker/card_picker.gd +++ b/src/logic-scenes/card_picker/card_picker.gd @@ -250,7 +250,7 @@ func transition(): out_str.append(card.text if card.text != "" else "c_void") cards_picked.emit(out_str) selection_state = DONE - Scenes.end_current_sequence() + Scenes.finish_sequence(self) func show_posts(): for player:AnimationPlayer in anim_players: @@ -282,7 +282,7 @@ func pick_cards(id: int, repeat: bool): $Meaning.play() else: - Scenes.end_current_sequence() + Scenes.finish_sequence(self) func play_scene(_id, _repeat): pass diff --git a/src/logic-scenes/collectable/collectable_ui.gd b/src/logic-scenes/collectable/collectable_ui.gd index 4923cac..b980c2e 100644 --- a/src/logic-scenes/collectable/collectable_ui.gd +++ b/src/logic-scenes/collectable/collectable_ui.gd @@ -1,6 +1,10 @@ extends CenterContainer class_name CollectableUi +## The StoryPlayable to play when this memento is collected. +## Should be a child node (typically inside a CanvasLayer for full-screen display). +@export var story_playable: StoryPlayable + @export var has_stage: bool = false: set(focused): if has_stage == focused: return @@ -164,7 +168,7 @@ func _ready() -> void: update_state() -func _on_context_updated(): +func _on_context_updated() -> void: %SkipButton.visible = State.allow_skipping %SummaryButton.visible = State.provide_summaries %ReadStory.visible = is_collected @@ -172,7 +176,7 @@ func _on_context_updated(): %OptionsLabel.visible = State.allow_skipping or State.provide_summaries or is_collected and not is_board cn_label.visible = true if State.show_content_notes else false -func update_state(): +func update_state() -> void: scene = scene is_board = is_board is_exit = is_exit @@ -216,7 +220,7 @@ func _input(event: InputEvent) -> void: is_expanded = true get_viewport().set_input_as_handled() -func vanish(): +func vanish() -> void: if not visible: return if is_expanded: @@ -224,19 +228,38 @@ func vanish(): else: animation_player.play("vanish") -func collect_memento(): - Scenes.start_sequence(scene) +func collect_memento() -> void: + print_debug("CollectableUi.collect_memento() - scene: %s" % Scenes.id.keys()[scene]) + + # Hide the collectable UI + vanish() + + # Check if we have a story_playable to play + if story_playable == null: + push_warning("CollectableUi for scene %s has no story_playable assigned" % Scenes.id.keys()[scene]) + if was_skipped: + scene_skipped.emit(-1) + is_collected = true + return + + # Take stage and mark sequence as starting + State.take_stage(self) + Scenes.begin_sequence(scene) + + # Hide mouse and collapse other interactables + get_tree().call_group("interactables", "collapse") + Input.mouse_mode = Input.MOUSE_MODE_HIDDEN + + # Play the story (StoryPlayable handles its own visibility via animations) + await story_playable.play() + + # Restore mouse + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + + # Leave stage and mark sequence as finished State.leave_stage(self) - if scene == Scenes.id.TRANSITION: vanish() - #get_tree().call_group("scene_actors", "play_scene", scene, collected) - if was_skipped: scene_skipped.emit(-1) + Scenes.end_sequence(scene) + + if was_skipped: + scene_skipped.emit(-1) is_collected = true - -func _on_skip_pressed(): - print_debug("Scene skipped!") - if scene != null: - scene_skipped.emit(1) - was_skipped = true - $Panel/Content/Buttons/VBoxContainer/collect_or_listen.text = "collect (un-skip)" - - State.leave_stage(self) diff --git a/src/logic-scenes/collectable/collectable_ui.gd.uid b/src/logic-scenes/collectable/collectable_ui.gd.uid index 43448c3..9afdfd6 100644 --- a/src/logic-scenes/collectable/collectable_ui.gd.uid +++ b/src/logic-scenes/collectable/collectable_ui.gd.uid @@ -1 +1 @@ -uid://bd5p820vwiphe +uid://ct2503epxj4av diff --git a/src/logic-scenes/collectable/collectable_ui.tscn b/src/logic-scenes/collectable/collectable_ui.tscn index f40057b..a75373e 100644 --- a/src/logic-scenes/collectable/collectable_ui.tscn +++ b/src/logic-scenes/collectable/collectable_ui.tscn @@ -887,6 +887,7 @@ layout_mode = 2 alignment = 1 [node name="CollectPrompt" type="TextureRect" parent="VBoxContainer/HBoxContainer"] +unique_name_in_owner = true layout_mode = 2 texture = ExtResource("3_g0dpf") expand_mode = 2 @@ -982,3 +983,5 @@ libraries = { &"": SubResource("AnimationLibrary_6fedj") } autoplay = "init" + +[node name="CanvasLayer" type="CanvasLayer" parent="."] diff --git a/src/logic-scenes/interactive_sprite/interactive_sprite.tscn b/src/logic-scenes/interactive_sprite/interactive_sprite.tscn new file mode 100644 index 0000000..53fe377 --- /dev/null +++ b/src/logic-scenes/interactive_sprite/interactive_sprite.tscn @@ -0,0 +1,74 @@ +[gd_scene load_steps=11 format=3 uid="uid://cy4yesucptcr3"] + +[ext_resource type="Script" uid="uid://dr4wd80dobxjd" path="res://base-environments/youth_room/interactive_sprite.gd" id="1_v8gd7"] +[ext_resource type="PackedScene" uid="uid://bdnesuqroi7ss" path="res://vfx/collectable_particles.tscn" id="2_lqlgh"] +[ext_resource type="Script" uid="uid://dbdw3v7mbqscf" path="res://dev-util/click-trough-area.gd" id="3_1fk5i"] +[ext_resource type="Shader" uid="uid://ci37nlh06b5y2" path="res://logic-scenes/collectable/collectable.gdshader" id="4_64lfl"] +[ext_resource type="PackedScene" uid="uid://wfyna16xhlo0" path="res://logic-scenes/collectable/collectable_ui.tscn" id="5_kqyl2"] +[ext_resource type="Texture2D" uid="uid://d0ucjqi8tx6vt" path="res://import/interface-elements/frame.png" id="6_13pus"] + +[sub_resource type="BoxShape3D" id="BoxShape3D_v8gd7"] + +[sub_resource type="ViewportTexture" id="ViewportTexture_ghmim"] +viewport_path = NodePath("logic/MaskMemento/UiWrapper/UiSprite/SubViewport") + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_dqyng"] +resource_local_to_scene = true +render_priority = 0 +shader = ExtResource("4_64lfl") +shader_parameter/default_texture = SubResource("ViewportTexture_ghmim") + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_v8gd7"] +height = 1.5 + +[node name="Memento" type="Area3D" groups=["interactables"]] +transform = Transform3D(0.9999994, 0, 0, 0, 1, 0, 0, 0, 0.9999994, 0, 0, 0) +collision_layer = 16 +collision_mask = 0 +script = ExtResource("1_v8gd7") + +[node name="collectable_particles" parent="." instance=ExtResource("2_lqlgh")] + +[node name="UiWrapper" type="Area3D" parent="."] +transform = Transform3D(0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, 0, 0, 0) +script = ExtResource("3_1fk5i") + +[node name="UI_click_collider" type="CollisionShape3D" parent="UiWrapper"] +transform = Transform3D(1, -6.984922e-08, -1.908213e-15, 6.984922e-08, 1, 2.3283043e-08, 2.8191056e-16, -2.3283043e-08, 1, 0, 0, 0) +shape = SubResource("BoxShape3D_v8gd7") + +[node name="UiSprite" type="Sprite3D" parent="UiWrapper"] +transform = Transform3D(1, 0, -5.96046e-08, 0, 1, 0, 5.96046e-08, 0, 1, 0, 0, 0) +material_override = SubResource("ShaderMaterial_dqyng") +modulate = Color(0.52473676, 0.353479, 0.20148611, 1) +pixel_size = 0.015 +shaded = true +no_depth_test = true +texture = SubResource("ViewportTexture_ghmim") + +[node name="SubViewport" type="SubViewport" parent="UiWrapper/UiSprite"] +transparent_bg = true +size = Vector2i(400, 350) +render_target_update_mode = 4 + +[node name="CollectableUi" parent="UiWrapper/UiSprite/SubViewport" instance=ExtResource("5_kqyl2")] + +[node name="Frame" type="Sprite3D" parent="UiWrapper"] +transform = Transform3D(0.70457095, 0, -1.19208984e-07, 0, 0.704571, 0, 1.19208984e-07, 0, 0.70457095, 0, 0, 0) +visibility_range_end = 0.6 +visibility_range_end_margin = 0.3 +visibility_range_fade_mode = 1 +modulate = Color(1.8247963, 1.8247963, 1.8247963, 1) +no_depth_test = true +texture = ExtResource("6_13pus") +region_enabled = true +region_rect = Rect2(735.5, 0, 995.5, 1024) + +[node name="HoverDetect" type="CollisionShape3D" parent="."] +transform = Transform3D(-4.3711356e-08, -0.9999997, 0, 0.9999993, -4.3711374e-08, 0, 0, 0, 0.99999976, 0, 0, 0) +shape = SubResource("CapsuleShape3D_v8gd7") + +[node name="CanvasLayer" type="CanvasLayer" parent="."] +unique_name_in_owner = true + +[connection signal="input_event" from="UiWrapper" to="UiWrapper" method="_on_input_event"] diff --git a/src/logic-scenes/luna/playables/story_playable.gd b/src/logic-scenes/luna/playables/story_playable.gd index 4bd408a..ba2506b 100644 --- a/src/logic-scenes/luna/playables/story_playable.gd +++ b/src/logic-scenes/luna/playables/story_playable.gd @@ -119,6 +119,10 @@ func try_scroll(): func play(): print_debug("StoryPlayable.gd: %s.play()" % self.name) + + # Show ourselves before playing + show() + scroll_target = 0 # FIXME: find out why this needs to be set to prevent scenes from being fully revealed diff --git a/src/logic-scenes/player_controller/player_controller.gd b/src/logic-scenes/player_controller/player_controller.gd index 22061e0..1df69be 100644 --- a/src/logic-scenes/player_controller/player_controller.gd +++ b/src/logic-scenes/player_controller/player_controller.gd @@ -274,7 +274,7 @@ func play_scene(_id: int, _repeat: bool): func scene_finished(_id, repeat: bool): if repeat: - State.take_stage(self, true) + State.take_stage(self) func _on_bed_enter(_body): if not (crouched or on_crouch_cooldown): diff --git a/src/singletons/global_state.gd b/src/singletons/global_state.gd index 980811c..ee69e73 100644 --- a/src/singletons/global_state.gd +++ b/src/singletons/global_state.gd @@ -251,90 +251,134 @@ func _ready(): #TODO: make this a bit more clean maybe? save_game = ResourceLoader.load("res://dev-util/debug_save.tres") if "has_stage" in child: - pass_stage_to(child) + take_stage(child) break music_volume = music_volume #region focus handling (called staging to avoid name colisions) -# CAUTION: scene_reference directly accesses stage list to play sequences. +# Stage list is a stack. Only the front (top) element "has" the stage. +# The stage manager sets has_stage on actors when they take/leave stage. -var stage_list:Array = [] +var stage_list: Array = [] var focus_locked: bool = false -# Intented for use when an actor wants focus for itself, can reclaim focus, thus dropping the stack that focused. -func take_stage(actor: Object, _reclaim: bool = false) -> bool: - print_debug("DEPRECATED: take_stage ", actor); - return false - #if focus_locked or Scenes.current_sequence != -1: return false - #if reclaim: - # stage_list.front().has_stage = false - # if stage_list.has(actor): - # while stage_list.pop_front() != actor: break - # actor.has_stage = true - # stage_list.push_front(actor) - # return actor.has_stage - # push_warning(actor, " wanted to reclaim focus, but was not on list.") - #return pass_stage_to(actor) -# Element no longer wants focus, if Element itself is also dropped, this option can be chosen aswell. -func leave_stage(actor:Object) -> bool: - print_debug("DEPRECATED: leave_stage ", actor); - return false - #if stage_list[0] == actor: - # actor.has_stage = false - # focus_locked = false - #stage_list.erase(actor) +# Helper to safely set has_stage on an actor +func _set_actor_stage(actor: Object, value: bool) -> void: + if is_instance_valid(actor) and "has_stage" in actor: + actor.has_stage = value - #if stage_list != []: - # stage_list.front().has_stage = true - #else: - # get_tree().quit() - #return false -# Used to put a new target on top of the Focus Stack. -func pass_stage_to(target:Object, force = false, lock_focus = false) -> bool: - if "pass_to_actor" in target: - return pass_stage_to(target.pass_to_actor) - if (focus_locked or get_tree().paused) and not force: - push_error(target, " requested focus while it was locked or tree is paused.") - elif !is_instance_valid(target): - push_error("Focus instance not valid") - elif !"has_stage" in target: - push_error(target, " has no has focus method.") - else: - if stage_list.size() > 0: - if stage_list.front() == target: - push_warning(target, " is already target. Abort passing focus.") - return false - if not stage_list.size() == 0: stage_list.front().has_stage = false - target.has_stage = true - if target.has_stage: - stage_list.push_front(target) - assert(stage_list.size() < 100) - focus_locked = lock_focus - return true - return false - -# Currently focused element loses focus, but remains in stack. -func free_focus(): - if focus_locked: return false - if stage_list.size() > 0: stage_list.front().has_stage = false - -func reset_focus(): - stage_list = [stage_list[-1]] - -func transition_stage_to(thief: Object, lock_focus = false): - focus_locked = lock_focus +# Actor takes the stage (pushes to front of stack) +func take_stage(actor: Object) -> void: + print_debug(">>> take_stage(", actor, ")") + assert(not focus_locked, "Focus is locked, %s cannot take focus." % actor) + assert(is_instance_valid(actor), "Cannot take stage with invalid actor") + + # Remove actor if already in list (to re-add at front) + if actor in stage_list: + stage_list.erase(actor) + + # Remove stage from current front if stage_list.size() > 0: - if stage_list.front().has_stage: - stage_list.pop_front().has_stage = false - return pass_stage_to(thief, true) + _set_actor_stage(stage_list.front(), false) + + # Add new actor to front and give it stage + stage_list.push_front(actor) + _set_actor_stage(actor, true) -func queue_for_stage(target: Object, index: int = 1): + +# Actor leaves the stage (removes from stack) +func leave_stage(actor: Object) -> void: + print_debug("<<< leave_stage(", actor, ")") + if not (actor in stage_list): + push_warning("Actor %s not in stage list, ignoring leave_stage call." % actor) + return + + var was_front = false + if stage_list.size() > 0: + if stage_list.front() == actor: + was_front = true + + # Remove stage from actor and remove from list + _set_actor_stage(actor, false) + stage_list.erase(actor) + + # If actor was at front, give stage to new front + if was_front: + if stage_list.size() > 0: + _set_actor_stage(stage_list.front(), true) + + +# Pass stage to a new target (pushes target to front) +func pass_stage_to(target: Object, force: bool = false) -> void: + print_debug(">>> pass_stage_to(", target, ")") + + if not is_instance_valid(target): + push_error("Cannot pass stage to invalid target") + return + + if not "has_stage" in target: + push_error(target, " has no has_stage property") + return + + if (focus_locked or get_tree().paused) and not force: + push_error(target, " requested focus while it was locked or tree is paused") + return + + # If target is already at front, nothing to do + if stage_list.size() > 0 and stage_list.front() == target: + push_warning(target, " is already at front of stage. Ignoring.") + return + + take_stage(target) + + +# Queue an actor for stage at a specific position (does not give it stage yet) +func queue_for_stage(target: Object, index: int = 1) -> void: + print_debug(">>> queue_for_stage(", target, ") at index ", index) + if target in stage_list: + stage_list.erase(target) stage_list.insert(index, target) + +# Currently focused element loses stage but remains in stack +func free_focus() -> void: + if focus_locked: + return + if stage_list.size() > 0: + _set_actor_stage(stage_list.front(), false) + + +# Reset stack to only contain the bottom element (original/root) +func reset_focus() -> void: + # Remove stage from current front + if stage_list.size() > 0: + _set_actor_stage(stage_list.front(), false) + + # Keep only the last element + if stage_list.size() > 0: + var root = stage_list[-1] + stage_list = [root] + _set_actor_stage(root, true) + + +# Transfer stage from current front to a new actor (removes current front) +func transition_stage_to(target: Object, lock: bool = false) -> void: + print_debug(">>> transition_stage_to(", target, ")") + + # Remove current front from stack entirely + if stage_list.size() > 0: + var old_front = stage_list.pop_front() + _set_actor_stage(old_front, false) + + # Add new target + stage_list.push_front(target) + _set_actor_stage(target, true) + focus_locked = lock + #endregion #region play state diff --git a/src/singletons/scene_reference.gd b/src/singletons/scene_reference.gd index bf0d575..daf4d7c 100644 --- a/src/singletons/scene_reference.gd +++ b/src/singletons/scene_reference.gd @@ -1,13 +1,12 @@ extends Node class_name SceneReference -var sequence_actors:Array[Array] = [] +# State tracking var started_sequences: int = 0 var completed_sequences: int = 0 var enabled_sequences: int = 255: set(stuff): pass var current_sequence: int = -1 -var current_sequence_index: int = 0 enum id { YOUTH_DRAEVEN, @@ -25,58 +24,68 @@ enum id { } signal scene_starting(scene_id: id, is_repeating: bool) -signal scene_continuing(scene_id: id, scene_index: int, is_repeating: bool) signal scene_finished(scene_id: id, is_repeating: bool) func _ready() -> void: - for i in range(id.keys().size()): - sequence_actors.append([null, null]) + pass -func sign_up_for_sequence(callable: Callable, sequence_id: id, index: int): - if sequence_actors[sequence_id].size() <= index: - sequence_actors[sequence_id].resize(index+1) - # if this assertion fails, two objects tried to sign up for the same sequence. - assert(sequence_actors[sequence_id][index] == null) - sequence_actors[sequence_id][index] = callable +# Called by CollectableUi when it starts playing a scene +func begin_sequence(scene_id: id) -> void: + print_debug(">>> Scenes.begin_sequence(%s)" % id.keys()[scene_id]) + + current_sequence = scene_id + started_sequences = started_sequences | (1 << scene_id) + + # Emit signal for other systems (music, animations, etc.) + scene_starting.emit(scene_id, is_sequence_repeating(scene_id)) -func start_sequence(index: id): - if State.pass_stage_to(sequence_actors[index][0].get_object()): - sequence_actors[index][0].call(index) - current_sequence = index - started_sequences = started_sequences | (1 << index) - scene_starting.emit(current_sequence, is_sequence_repeating(index)) - else: - push_error("Sequence could not be started.") +# Called by CollectableUi when it finishes playing a scene +func end_sequence(scene_id: id) -> void: + print_debug(">>> Scenes.end_sequence(%s)" % id.keys()[scene_id]) + + # Emit signal before clearing state + scene_finished.emit(scene_id, is_sequence_repeating(scene_id)) + + # Mark as completed + completed_sequences = completed_sequences | (1 << scene_id) + + # Clear current sequence + if current_sequence == scene_id: + current_sequence = -1 -# Leaves stage to pass it to the next element wanting to catch focus. -func continue_sequence(former_actor: Object): - # if this fails, pass next was called without a sequencce having been started. - assert(current_sequence != -1) +# Legacy support - redirects to begin_sequence +func start_sequence(scene_id: id) -> void: + push_warning("start_sequence is deprecated. CollectableUi should call begin_sequence directly.") + begin_sequence(scene_id) - if former_actor == State.stage_list[0] and former_actor == sequence_actors[current_sequence][current_sequence_index].get_object(): - former_actor.has_stage = false +# Legacy support - redirects to end_sequence +func finish_sequence(_actor: Object) -> void: + push_warning("finish_sequence is deprecated. CollectableUi should call end_sequence directly.") + if current_sequence != -1 and current_sequence < id.size(): + end_sequence(id.values()[current_sequence]) - current_sequence_index += 1 +# Legacy alias +func end_current_sequence() -> void: + if current_sequence != -1 and current_sequence < id.size(): + end_sequence(id.values()[current_sequence]) - State.stage_list[0] = sequence_actors[current_sequence][current_sequence_index].get_object() - print_debug(sequence_actors[current_sequence][current_sequence_index].get_object().name) +# Legacy support - no longer needed +func continue_sequence(_former_actor: Object) -> void: + push_warning("continue_sequence is deprecated and does nothing.") - State.stage_list[0].has_stage = true +# Legacy support - no longer needed +func sign_up_for_sequence(_callable: Callable, _sequence_id: id, _index: int = 0) -> void: + push_warning("sign_up_for_sequence is deprecated. CollectableUi now manages playback directly.") - sequence_actors[current_sequence][current_sequence_index].call(current_sequence, is_sequence_repeating(current_sequence)) +# Legacy support - no longer needed +func register_scene_actor(_scene_id: id, _callable: Callable) -> void: + push_warning("register_scene_actor is deprecated. CollectableUi now manages playback directly.") - scene_continuing.emit(current_sequence, current_sequence_index, is_sequence_repeating(current_sequence)) +func is_sequence_repeating(index: int) -> bool: + return completed_sequences & (1 << index) > 0 -func end_current_sequence(): - State.leave_stage(State.stage_list[0]) - scene_finished.emit(current_sequence, is_sequence_repeating(current_sequence)) - completed_sequences = completed_sequences | (1 << current_sequence) - current_sequence = -1 - current_sequence_index = 0 - -func is_sequence_repeating(index: int) -> bool: return completed_sequences & (1 << index) > 0 - -func is_sequence_unlocked(index: id) -> bool: return (1 << int(index)) & enabled_sequences > 0 +func is_sequence_unlocked(index: id) -> bool: + return (1 << int(index)) & enabled_sequences > 0 func get_completed_total() -> int: var i: int = completed_sequences - ((completed_sequences >> 1) & 0x55555555); From 465b00cbd4d5a97b0d8989b4add5d25afbdab2fd Mon Sep 17 00:00:00 2001 From: Tiger Jove Date: Mon, 5 Jan 2026 16:11:16 +0100 Subject: [PATCH 2/8] chore: re-added new playable child scenes to their actual mementoes --- .../youth_room/youth_room.tscn | 72 ++++++++++++++++++- .../interactive_sprite.tscn | 1 + 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/src/base-environments/youth_room/youth_room.tscn b/src/base-environments/youth_room/youth_room.tscn index ab628ea..27e91d3 100644 --- a/src/base-environments/youth_room/youth_room.tscn +++ b/src/base-environments/youth_room/youth_room.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=120 format=4 uid="uid://b3b0gyvklqn50"] +[gd_scene load_steps=128 format=4 uid="uid://b3b0gyvklqn50"] [ext_resource type="Script" uid="uid://bsop46tqngddc" path="res://base-environments/youth_room/youth_room.gd" id="1_aitp0"] [ext_resource type="AudioStream" uid="uid://1h6k2d8q1kw3" path="res://base-environments/youth_room/import/sounds/rain_on_window.mp3" id="2_3haaq"] @@ -926,6 +926,42 @@ _surfaces = [{ blend_shape_mode = 0 shadow_mesh = SubResource("ArrayMesh_lag5h") +[sub_resource type="ViewportTexture" id="ViewportTexture_dqyng"] +viewport_path = NodePath("logic/MaskMemento/UiWrapper/UiSprite/SubViewport") + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_xbjb2"] +resource_local_to_scene = true +render_priority = 0 +shader = ExtResource("25_dqyng") +shader_parameter/default_texture = SubResource("ViewportTexture_dqyng") + +[sub_resource type="ViewportTexture" id="ViewportTexture_e5y1q"] +viewport_path = NodePath("logic/MaskMemento/UiWrapper/UiSprite/SubViewport") + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_5bsh1"] +resource_local_to_scene = true +render_priority = 0 +shader = ExtResource("25_dqyng") +shader_parameter/default_texture = SubResource("ViewportTexture_e5y1q") + +[sub_resource type="ViewportTexture" id="ViewportTexture_ks23q"] +viewport_path = NodePath("logic/MaskMemento/UiWrapper/UiSprite/SubViewport") + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_e5y1q"] +resource_local_to_scene = true +render_priority = 0 +shader = ExtResource("25_dqyng") +shader_parameter/default_texture = SubResource("ViewportTexture_ks23q") + +[sub_resource type="ViewportTexture" id="ViewportTexture_5bsh1"] +viewport_path = NodePath("logic/MaskMemento/UiWrapper/UiSprite/SubViewport") + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_ypa88"] +resource_local_to_scene = true +render_priority = 0 +shader = ExtResource("25_dqyng") +shader_parameter/default_texture = SubResource("ViewportTexture_5bsh1") + [sub_resource type="ViewportTexture" id="ViewportTexture_ypa88"] viewport_path = NodePath("logic/MaskMemento/UiWrapper/UiSprite/SubViewport") @@ -1972,15 +2008,43 @@ omni_range = 16.8518 [node name="MaskMemento" parent="logic" instance=ExtResource("30_ypa88")] transform = Transform3D(-0.8630245, 0, 0.5051597, 0, 1, 0, -0.5051597, 0, -0.8630245, 0.0754588, 0.948372, 2.42068) +[node name="UiSprite" parent="logic/MaskMemento/UiWrapper" index="1"] +material_override = SubResource("ShaderMaterial_xbjb2") +texture = SubResource("ViewportTexture_dqyng") + +[node name="childhood" parent="logic/MaskMemento/CanvasLayer" index="0" instance=ExtResource("12_viwxf")] + [node name="ClothesMemento" parent="logic" instance=ExtResource("30_ypa88")] transform = Transform3D(0.8604294, 0, -0.5095667, 0, 1, 0, 0.5095667, 0, 0.8604294, 1.3658599, 1.17096, -0.6365988) +[node name="UiSprite" parent="logic/ClothesMemento/UiWrapper" index="1"] +material_override = SubResource("ShaderMaterial_5bsh1") +texture = SubResource("ViewportTexture_e5y1q") + +[node name="JuiJutsu" parent="logic/ClothesMemento/CanvasLayer" index="0" instance=ExtResource("12_x3dlb")] + [node name="ComicMemento" parent="logic" instance=ExtResource("30_ypa88")] transform = Transform3D(0.9699434, 0, 0.24332686, 0, 1, 0, -0.24332686, 0, 0.9699434, 2.91664, 0.595014, -0.75655603) +[node name="UiSprite" parent="logic/ComicMemento/UiWrapper" index="1"] +material_override = SubResource("ShaderMaterial_e5y1q") +texture = SubResource("ViewportTexture_ks23q") + +[node name="voice_training" parent="logic/ComicMemento/CanvasLayer" index="0" instance=ExtResource("13_v3447")] +story_array = [] +paragraph_lengths = [1] + [node name="CeilingMemento" parent="logic" instance=ExtResource("30_ypa88")] transform = Transform3D(0.71489924, 0, 0.6992255, 0, 1, 0, -0.6992255, 0, 0.71489924, -0.13478619, 2.0720484, -0.42032808) +[node name="UiSprite" parent="logic/CeilingMemento/UiWrapper" index="1"] +material_override = SubResource("ShaderMaterial_ypa88") +texture = SubResource("ViewportTexture_5bsh1") + +[node name="draven" parent="logic/CeilingMemento/CanvasLayer" index="0" instance=ExtResource("19_d3c7p")] +story_array = [] +paragraph_lengths = [1] + [node name="MindBoard" parent="logic" instance=ExtResource("30_ypa88")] transform = Transform3D(-4.3711374e-08, 0, 0.9999984, 0, 1, 0, -0.9999984, 0, -4.3711374e-08, -0.907206, 1.17661, 1.74337) @@ -1988,6 +2052,8 @@ transform = Transform3D(-4.3711374e-08, 0, 0.9999984, 0, 1, 0, -0.9999984, 0, -4 material_override = SubResource("ShaderMaterial_mhuct") texture = SubResource("ViewportTexture_ypa88") +[node name="board" parent="logic/MindBoard/CanvasLayer" index="0" instance=ExtResource("4_gyjxx")] + [node name="Door" parent="logic" instance=ExtResource("30_ypa88")] transform = Transform3D(0.9999984, 0, 4.973797e-14, 0, 1, 0, -4.973797e-14, 0, 0.9999984, 0.115203, 1.3931, -0.954428) @@ -2251,4 +2317,8 @@ data = ExtResource("40_ea6x8") [connection signal="pressed" from="logic/UI/ending_button" to="logic/UI/ending" method="show"] [connection signal="emit_thunder" from="logic/ScenePlayer/JuiJutsu" to="AnimationPlayer" method="play" binds= ["lighting_and_thunder"]] +[editable path="logic/MaskMemento"] +[editable path="logic/ClothesMemento"] +[editable path="logic/ComicMemento"] +[editable path="logic/CeilingMemento"] [editable path="logic/MindBoard"] diff --git a/src/logic-scenes/interactive_sprite/interactive_sprite.tscn b/src/logic-scenes/interactive_sprite/interactive_sprite.tscn index 53fe377..9721068 100644 --- a/src/logic-scenes/interactive_sprite/interactive_sprite.tscn +++ b/src/logic-scenes/interactive_sprite/interactive_sprite.tscn @@ -70,5 +70,6 @@ shape = SubResource("CapsuleShape3D_v8gd7") [node name="CanvasLayer" type="CanvasLayer" parent="."] unique_name_in_owner = true +visible = false [connection signal="input_event" from="UiWrapper" to="UiWrapper" method="_on_input_event"] From 8dfbf4ef23a46fb1e4650d8a858a877bc12d9949 Mon Sep 17 00:00:00 2001 From: Tiger Jove Date: Mon, 5 Jan 2026 16:19:21 +0100 Subject: [PATCH 3/8] chore: hook up new direct interactable system --- .../youth_room/interactive_sprite.gd | 11 ++++++ .../collectable/collectable_ui.gd | 37 +++++++++++++++---- src/singletons/scene_reference.gd | 4 ++ 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/base-environments/youth_room/interactive_sprite.gd b/src/base-environments/youth_room/interactive_sprite.gd index 6299d78..80c86a1 100644 --- a/src/base-environments/youth_room/interactive_sprite.gd +++ b/src/base-environments/youth_room/interactive_sprite.gd @@ -31,6 +31,17 @@ var has_mouse: bool = false # Called when the node enters the scene tree for the first time. func _ready(): mouse_entered.connect(_on_mouse_entered) + + # Wire up the CollectableUi with the CanvasLayer for story playback + var canvas = get_node_or_null("%CanvasLayer") + if canvas and ui: + ui.canvas_layer = canvas + # Find and wire the StoryPlayable if not already set + if ui.story_playable == null: + for child in canvas.get_children(): + if child is StoryPlayable: + ui.story_playable = child + break func _on_mouse_entered(): if not State.focus_locked: diff --git a/src/logic-scenes/collectable/collectable_ui.gd b/src/logic-scenes/collectable/collectable_ui.gd index b980c2e..102ec91 100644 --- a/src/logic-scenes/collectable/collectable_ui.gd +++ b/src/logic-scenes/collectable/collectable_ui.gd @@ -2,9 +2,13 @@ extends CenterContainer class_name CollectableUi ## The StoryPlayable to play when this memento is collected. -## Should be a child node (typically inside a CanvasLayer for full-screen display). +## Auto-discovered from the owner's %CanvasLayer, or can be set manually. @export var story_playable: StoryPlayable +## Reference to the CanvasLayer containing the story_playable. +## Auto-discovered in _ready() if not set. +var canvas_layer: CanvasLayer + @export var has_stage: bool = false: set(focused): if has_stage == focused: return @@ -165,9 +169,22 @@ func _ready() -> void: State.settings_changed.connect(_on_context_updated) %CollectButton.pressed.connect(collect_memento) ##TODO: add functions for remaining buttons + + # Auto-discover story_playable and canvas_layer from scene hierarchy + _discover_story_playable() update_state() + +## Ensure canvas_layer is set if story_playable was set via export. +## InteractiveSprite._ready() handles the main wiring for inherited scenes. +func _discover_story_playable() -> void: + if story_playable != null and canvas_layer == null: + # story_playable set via export, find its parent CanvasLayer + var parent = story_playable.get_parent() + if parent is CanvasLayer: + canvas_layer = parent + func _on_context_updated() -> void: %SkipButton.visible = State.allow_skipping %SummaryButton.visible = State.provide_summaries @@ -242,22 +259,28 @@ func collect_memento() -> void: is_collected = true return - # Take stage and mark sequence as starting - State.take_stage(self) + # Signal that a scene is starting (for music, etc.) Scenes.begin_sequence(scene) - # Hide mouse and collapse other interactables + # Hide mouse and collapse other interactables BEFORE showing canvas get_tree().call_group("interactables", "collapse") Input.mouse_mode = Input.MOUSE_MODE_HIDDEN - # Play the story (StoryPlayable handles its own visibility via animations) + # Show the CanvasLayer so the story is visible full-screen + if canvas_layer: + canvas_layer.show() + + # Play the story await story_playable.play() + # Hide the CanvasLayer when done + if canvas_layer: + canvas_layer.hide() + # Restore mouse Input.mouse_mode = Input.MOUSE_MODE_VISIBLE - # Leave stage and mark sequence as finished - State.leave_stage(self) + # Signal that the scene is finished Scenes.end_sequence(scene) if was_skipped: diff --git a/src/singletons/scene_reference.gd b/src/singletons/scene_reference.gd index daf4d7c..c91cee6 100644 --- a/src/singletons/scene_reference.gd +++ b/src/singletons/scene_reference.gd @@ -8,6 +8,10 @@ var enabled_sequences: int = 255: set(stuff): pass var current_sequence: int = -1 +## Returns true if a scene is currently playing. +var is_playing: bool: + get: return current_sequence != -1 + enum id { YOUTH_DRAEVEN, YOUTH_CHILDHOOD, From dbde200416eb3de02bfa967b461a841c7c58ac75 Mon Sep 17 00:00:00 2001 From: Tiger Jove Date: Mon, 5 Jan 2026 16:28:45 +0100 Subject: [PATCH 4/8] chore: refactor stage system, clear dead code --- .../transition/subway_sequence.gd | 2 +- .../volunteer_room/shared_flat.gd | 2 +- .../youth_room/interactive_sprite.gd | 2 +- .../youth_room/youth_room.gd | 7 +- src/dev-util/bug_button.gd | 2 +- src/dev-util/click-trough-area.gd | 2 +- src/logic-scenes/board/card-board.gd | 4 +- src/logic-scenes/card_picker/card_picker.gd | 25 ---- .../collectable/collectable_ui.gd | 17 --- .../player_controller/player_controller.gd | 8 +- src/singletons/global_state.gd | 128 ------------------ src/singletons/main/main.gd | 108 --------------- src/tab_container.gd | 13 +- src/ui/menu_main/accessibility_settings.gd | 4 +- src/ui/menu_main/audio_settings.gd | 3 +- src/ui/menu_main/content_settings.gd | 3 +- src/ui/menu_main/gameplay_settings.gd | 3 +- src/ui/menu_main/privacy_settings.gd | 3 +- src/ui/menu_main/video_settings.gd | 2 - 19 files changed, 28 insertions(+), 310 deletions(-) diff --git a/src/base-environments/transition/subway_sequence.gd b/src/base-environments/transition/subway_sequence.gd index 3f9becf..1a25e1a 100644 --- a/src/base-environments/transition/subway_sequence.gd +++ b/src/base-environments/transition/subway_sequence.gd @@ -15,7 +15,7 @@ func _ready() -> void: func start_room(): save_game = State.save_game - State.pass_stage_to(%PlayerController) + %PlayerController.has_stage = true on_first_station() var left_first_station: bool = false diff --git a/src/base-environments/volunteer_room/shared_flat.gd b/src/base-environments/volunteer_room/shared_flat.gd index 4ede5d0..26d536d 100644 --- a/src/base-environments/volunteer_room/shared_flat.gd +++ b/src/base-environments/volunteer_room/shared_flat.gd @@ -19,7 +19,7 @@ func start_room(): save_room()) %PlayerController.process_mode = Node.PROCESS_MODE_INHERIT ini_room.emit() - State.pass_stage_to(%PlayerController) + %PlayerController.has_stage = true func _ready(): id = State.rooms.ADULTHOOD diff --git a/src/base-environments/youth_room/interactive_sprite.gd b/src/base-environments/youth_room/interactive_sprite.gd index 80c86a1..0d22825 100644 --- a/src/base-environments/youth_room/interactive_sprite.gd +++ b/src/base-environments/youth_room/interactive_sprite.gd @@ -44,7 +44,7 @@ func _ready(): break func _on_mouse_entered(): - if not State.focus_locked: + if not Scenes.is_playing: input_ray_pickable = false ui.is_collapsed = false has_mouse = true diff --git a/src/base-environments/youth_room/youth_room.gd b/src/base-environments/youth_room/youth_room.gd index 5b0b56f..a95a306 100644 --- a/src/base-environments/youth_room/youth_room.gd +++ b/src/base-environments/youth_room/youth_room.gd @@ -19,17 +19,17 @@ func start_room(): if not Scenes.is_sequence_repeating(Scenes.id.YOUTH_DRAEVEN): # Play intro scene directly (not triggered by CollectableUi) await _play_intro_scene() - State.pass_stage_to(%PlayerController) else: - State.pass_stage_to(%PlayerController) %LightAnimation.lights_on() + + # Give player control after intro (or immediately if repeating) + %PlayerController.has_stage = true func _play_intro_scene() -> void: # The intro scene is auto-played, not triggered by CollectableUi var intro_playable: StoryPlayable = $logic/ScenePlayer/draven - State.take_stage(self) Scenes.begin_sequence(Scenes.id.YOUTH_DRAEVEN) Input.mouse_mode = Input.MOUSE_MODE_HIDDEN @@ -39,7 +39,6 @@ func _play_intro_scene() -> void: Input.mouse_mode = Input.MOUSE_MODE_VISIBLE - State.leave_stage(self) Scenes.end_sequence(Scenes.id.YOUTH_DRAEVEN) diff --git a/src/dev-util/bug_button.gd b/src/dev-util/bug_button.gd index 20d0318..63e3616 100644 --- a/src/dev-util/bug_button.gd +++ b/src/dev-util/bug_button.gd @@ -19,7 +19,7 @@ func create_bug_report(): Current Focus: %s Current Scene: %s Mementos: %s - """ % [OS.get_name(), OS.get_video_adapter_driver_info(), State.stage_list, State.current_room, Scenes.completed_sequences] + """ % [OS.get_name(), OS.get_video_adapter_driver_info(), Scenes.current_sequence, State.current_room, Scenes.completed_sequences] #debug_text = debug_text.replace(" ", "%20").replace("\n", "%0A").replace("\t", "") diff --git a/src/dev-util/click-trough-area.gd b/src/dev-util/click-trough-area.gd index 42014ad..ddaf9dd 100644 --- a/src/dev-util/click-trough-area.gd +++ b/src/dev-util/click-trough-area.gd @@ -22,7 +22,7 @@ func _input(event: InputEvent) -> void: # viewport.push_input(event) func _on_input_event(_camera: Camera3D, event: InputEvent, pos: Vector3, _normal: Vector3, _shape_idx: int): - if not State.focus_locked: + if not Scenes.is_playing: # Position of the event in Sprite3D local coordinates. var texture_3d_position := sprite.get_global_transform().affine_inverse() * pos #if !is_zero_approx(texture_3d_position.z): diff --git a/src/logic-scenes/board/card-board.gd b/src/logic-scenes/board/card-board.gd index aa7cb2f..8545981 100644 --- a/src/logic-scenes/board/card-board.gd +++ b/src/logic-scenes/board/card-board.gd @@ -408,7 +408,7 @@ func _input(event) -> void: if not has_stage or not is_instance_valid(currently_active_node): return if event.is_action_pressed("ui_cancel"): - State.leave_stage(self) + has_stage = false get_viewport().set_input_as_handled() if event is InputEventMouse: @@ -568,7 +568,7 @@ func on_scene_skipped(i: int): mementos_collected += i # FIXME: sometimes -1 is passed here, why? func claim_focus(): - State.pass_stage_to(self) + has_stage = true func find_first_free_card() -> int: for i in range(dropzone.get_child_count()): diff --git a/src/logic-scenes/card_picker/card_picker.gd b/src/logic-scenes/card_picker/card_picker.gd index 41efac0..402a9dc 100644 --- a/src/logic-scenes/card_picker/card_picker.gd +++ b/src/logic-scenes/card_picker/card_picker.gd @@ -59,30 +59,6 @@ signal cards_picked(cardnames: Array[String]) # Called when the node enters the scene tree for the first time. func _ready() -> void: reset() - return -# -# #FIXME: can I make this less annoying somehow? -# if State.onready_room == State.rooms.YOUTH: -# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.YOUTH_DRAEVEN, 2) -# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.YOUTH_CHILDHOOD, 1) -# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.YOUTH_VOICE_TRAINING, 2) -# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.YOUTH_JUI_JUTSU, 1) -# elif State.onready_room == State.rooms.ADULTHOOD: -# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.ADULT_DND, 1) -# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.ADULT_VOLUNTARY, 1) -# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.ADULT_CHRISTMAS, 1) -# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.ADULT_EATING, 1) -# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.ADULT_UNI, 1) -# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.ADULT_THERAPY, 1) -# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.ADULT_BURNOUT, 1) -# else: -# assert(false, "Not Implemented") -# -# if get_tree().root == self.get_parent(): -# pick_cards(3, false) -# State.take_stage(self) -# -# reset() func reset(): card_anim_skipped = false @@ -276,7 +252,6 @@ func pick_cards(id: int, repeat: bool): if not repeat: Input.mouse_mode = Input.MOUSE_MODE_VISIBLE fill_card_slots(id) - #State.transition_stage_to(self, true) selection_state = CARDS if id == Scenes.id.YOUTH_DRAEVEN and not repeat: $Meaning.play() diff --git a/src/logic-scenes/collectable/collectable_ui.gd b/src/logic-scenes/collectable/collectable_ui.gd index 102ec91..54ee609 100644 --- a/src/logic-scenes/collectable/collectable_ui.gd +++ b/src/logic-scenes/collectable/collectable_ui.gd @@ -22,23 +22,6 @@ var canvas_layer: CanvasLayer get_viewport().gui_release_focus() is_collapsed = true -#@export var collapsed = true: -# set(collapse): -# if is_inside_tree() and not Engine.is_editor_hint(): -# if State.reduce_motion: -# collapsed = false -# return -# if collapse and not collapsed: -# if is_inside_tree(): -# _hide_buttons() -# collapsed = collapse -# elif not collapse and collapsed: -# if is_inside_tree(): -# _show_buttons() -# collapsed = collapse -# -# if collapse and has_stage: State.leave_stage(self) - @export var scene: Scenes.id = Scenes.id.YOUTH_DRAEVEN: set(id): scene = id diff --git a/src/logic-scenes/player_controller/player_controller.gd b/src/logic-scenes/player_controller/player_controller.gd index 1df69be..6d4f930 100644 --- a/src/logic-scenes/player_controller/player_controller.gd +++ b/src/logic-scenes/player_controller/player_controller.gd @@ -116,7 +116,11 @@ func _process(_delta): #emit_signal("ui_exited") #dhas_entered = false if Input.is_action_just_pressed("ui_accept"): - State.pass_stage_to(focus_ray.get_collider()) + # Pass focus to the collider if it has has_stage property + var collider = focus_ray.get_collider() + if collider and "has_stage" in collider: + has_stage = false + collider.has_stage = true else: camera.fov = base_fov / (1 + Input.get_action_raw_strength("zoom_in_controller")) @@ -274,7 +278,7 @@ func play_scene(_id: int, _repeat: bool): func scene_finished(_id, repeat: bool): if repeat: - State.take_stage(self) + has_stage = true func _on_bed_enter(_body): if not (crouched or on_crouch_cooldown): diff --git a/src/singletons/global_state.gd b/src/singletons/global_state.gd index ee69e73..4780aeb 100644 --- a/src/singletons/global_state.gd +++ b/src/singletons/global_state.gd @@ -250,137 +250,9 @@ func _ready(): push_warning("Room initialised without a SaveGame. Creating proxy save.") #TODO: make this a bit more clean maybe? save_game = ResourceLoader.load("res://dev-util/debug_save.tres") - if "has_stage" in child: - take_stage(child) - break music_volume = music_volume -#region focus handling (called staging to avoid name colisions) - -# Stage list is a stack. Only the front (top) element "has" the stage. -# The stage manager sets has_stage on actors when they take/leave stage. - -var stage_list: Array = [] -var focus_locked: bool = false - - -# Helper to safely set has_stage on an actor -func _set_actor_stage(actor: Object, value: bool) -> void: - if is_instance_valid(actor) and "has_stage" in actor: - actor.has_stage = value - - -# Actor takes the stage (pushes to front of stack) -func take_stage(actor: Object) -> void: - print_debug(">>> take_stage(", actor, ")") - assert(not focus_locked, "Focus is locked, %s cannot take focus." % actor) - assert(is_instance_valid(actor), "Cannot take stage with invalid actor") - - # Remove actor if already in list (to re-add at front) - if actor in stage_list: - stage_list.erase(actor) - - # Remove stage from current front - if stage_list.size() > 0: - _set_actor_stage(stage_list.front(), false) - - # Add new actor to front and give it stage - stage_list.push_front(actor) - _set_actor_stage(actor, true) - - -# Actor leaves the stage (removes from stack) -func leave_stage(actor: Object) -> void: - print_debug("<<< leave_stage(", actor, ")") - if not (actor in stage_list): - push_warning("Actor %s not in stage list, ignoring leave_stage call." % actor) - return - - var was_front = false - if stage_list.size() > 0: - if stage_list.front() == actor: - was_front = true - - # Remove stage from actor and remove from list - _set_actor_stage(actor, false) - stage_list.erase(actor) - - # If actor was at front, give stage to new front - if was_front: - if stage_list.size() > 0: - _set_actor_stage(stage_list.front(), true) - - -# Pass stage to a new target (pushes target to front) -func pass_stage_to(target: Object, force: bool = false) -> void: - print_debug(">>> pass_stage_to(", target, ")") - - if not is_instance_valid(target): - push_error("Cannot pass stage to invalid target") - return - - if not "has_stage" in target: - push_error(target, " has no has_stage property") - return - - if (focus_locked or get_tree().paused) and not force: - push_error(target, " requested focus while it was locked or tree is paused") - return - - # If target is already at front, nothing to do - if stage_list.size() > 0 and stage_list.front() == target: - push_warning(target, " is already at front of stage. Ignoring.") - return - - take_stage(target) - - -# Queue an actor for stage at a specific position (does not give it stage yet) -func queue_for_stage(target: Object, index: int = 1) -> void: - print_debug(">>> queue_for_stage(", target, ") at index ", index) - if target in stage_list: - stage_list.erase(target) - stage_list.insert(index, target) - - -# Currently focused element loses stage but remains in stack -func free_focus() -> void: - if focus_locked: - return - if stage_list.size() > 0: - _set_actor_stage(stage_list.front(), false) - - -# Reset stack to only contain the bottom element (original/root) -func reset_focus() -> void: - # Remove stage from current front - if stage_list.size() > 0: - _set_actor_stage(stage_list.front(), false) - - # Keep only the last element - if stage_list.size() > 0: - var root = stage_list[-1] - stage_list = [root] - _set_actor_stage(root, true) - - -# Transfer stage from current front to a new actor (removes current front) -func transition_stage_to(target: Object, lock: bool = false) -> void: - print_debug(">>> transition_stage_to(", target, ")") - - # Remove current front from stack entirely - if stage_list.size() > 0: - var old_front = stage_list.pop_front() - _set_actor_stage(old_front, false) - - # Add new target - stage_list.push_front(target) - _set_actor_stage(target, true) - focus_locked = lock - -#endregion - #region play state enum rooms { diff --git a/src/singletons/main/main.gd b/src/singletons/main/main.gd index 31463aa..8d4b796 100644 --- a/src/singletons/main/main.gd +++ b/src/singletons/main/main.gd @@ -116,112 +116,4 @@ func _unhandled_input(event: InputEvent) -> void: if event.is_action_pressed("ui_menu"): app_state = AppState.PLAY -# if not get_tree().paused: -# get_tree().paused = true -# var state_machine := menu_animation["parameters/playback"] -# state_machine.travel("reveal_pause_menu") -# Input.mouse_mode = Input.MOUSE_MODE_VISIBLE -# else: -# get_tree().paused = false -# var state_machine := menu_animation["parameters/playback"] -# state_machine.travel("start_game") -# -# if State.stage_list[0] is Player: -# Input.mouse_mode = Input.MOUSE_MODE_CAPTURED -#func debug_youth(): -# get_child(1).hide() -# get_child(2).hide() -# get_child(3).hide() -# get_child(0).get_ready() -# get_child(0).start() -# -#func _return_to_menu(): -# State.active_save_game = null -# -# menu_animation["parameters/conditions/start_game"] = false -# -# State.pass_stage_to(main_menu) -# -# currently_loading_room = get_room_path_from_id(main_menu.save_game_handle.get_most_recent_save().current_room) -# -# menu_animation["parameters/conditions/return_to_menu"] = true -# await(get_tree().create_timer(0.5).timeout) -# menu_animation["parameters/conditions/return_to_menu"] = false -# _on_ready_to_unload() -# -#func load_save(save: SaveGame): -# -# if currently_loading_room != "": -# await(room_loaded) -# -# if save.current_room != current_room.id: -# # TODO Prevent race condition from appearing when save is loaded while room is still loading. -# currently_loading_room = get_room_path_from_id(save.current_room) -# await(room_loaded) -# -# menu_animation["parameters/conditions/start_game"] = true -# -# State.active_save_game = save -# in_game = true -# current_room.start_room() -# -#func _on_ready_to_unload(): -# if get_child(0) is Node3D: -# get_child(0).free() -# -#func get_room_path_from_id(id: State.rooms) -> String: -# match id: -# State.rooms.YOUTH, State.rooms.NULL: -# return youth_room_path -# State.rooms.TRANSITION: -# return transition_room_path -# State.rooms.ADULTHOOD: -# return adulthood_room_path -# _: -# return ending_path -# -#func get_room_id_from_path(path: String) -> State.rooms: -# match path: -# youth_room_path: -# return State.rooms.YOUTH -# transition_room_path: -# return State.rooms.TRANSITION -# adulthood_room_path: -# return State.rooms.ADULTHOOD -# _: -# return State.rooms.NULL -# -# -#func start_demo(): -# #FIXME this causes the room to reload -# #load_save(SaveGame.new()) -# current_room.start_room() -# in_game = true -# -#func pause_mode_changed(): -# print_debug(get_tree().paused) -# -#var await_swap: bool = false -#func prepare_transition(scene_id: Scenes.id, _repeat): -# if scene_id == Scenes.id.TRANSITION: -# await_swap = true -# #FIXME: this does not need to be part of the sequence -# await(get_tree().process_frame) -# current_room.prepare_transition() -# if not _repeat: -# currently_loading_room = get_room_path_from_id(State.rooms.TRANSITION) -# else: -# -# currently_loading_room = get_room_path_from_id(State.rooms.ADULTHOOD) -# -#func transition(scene_id: Scenes.id, _repeat): -# if scene_id == Scenes.id.TRANSITION: -# State.reset_focus() -# await_swap = false -# await room_loaded -# if not _repeat: -# State.queue_for_stage(current_room) -# Scenes.end_current_sequence() -# else: -# State.pass_stage_to(current_room) diff --git a/src/tab_container.gd b/src/tab_container.gd index 98f3bb0..c753b5f 100644 --- a/src/tab_container.gd +++ b/src/tab_container.gd @@ -10,15 +10,16 @@ func _ready() -> void: pass_to_actor = get_child(current_tab) func _on_tab_changed(tab_id: int): - var child_has_stage:bool = false + # Transfer has_stage to the new tab's child for child in get_children(): if "has_stage" in child: - if child.has_stage: - child_has_stage = true - if child_has_stage: - State.transition_stage_to(get_child(tab_id)) + child.has_stage = false - pass_to_actor = get_child(tab_id) + var new_child = get_child(tab_id) + if "has_stage" in new_child: + new_child.has_stage = true + + pass_to_actor = new_child func _on_stage_left(): await get_tree().process_frame diff --git a/src/ui/menu_main/accessibility_settings.gd b/src/ui/menu_main/accessibility_settings.gd index 0579dd4..027878e 100644 --- a/src/ui/menu_main/accessibility_settings.gd +++ b/src/ui/menu_main/accessibility_settings.gd @@ -15,9 +15,7 @@ var is_active:bool = false: if is_node_ready() and active: screenreader_check.grab_focus() if not active and is_active: - if has_stage: - State.leave_stage(self) - leave_stage.emit() + leave_stage.emit() is_active = active if (is_active and not has_stage) and not get_tree().paused: diff --git a/src/ui/menu_main/audio_settings.gd b/src/ui/menu_main/audio_settings.gd index a406f26..44508f7 100644 --- a/src/ui/menu_main/audio_settings.gd +++ b/src/ui/menu_main/audio_settings.gd @@ -84,8 +84,7 @@ func update_ui_from_state(): func _on_exit_button_pressed() -> void: leave_stage.emit() State.save_settings() - State.leave_stage(self) func _input(event: InputEvent) -> void: if event.is_action_pressed("ui_cancel") and has_stage: - State.leave_stage(self) + leave_stage.emit() diff --git a/src/ui/menu_main/content_settings.gd b/src/ui/menu_main/content_settings.gd index 3e1e85c..069e3fc 100644 --- a/src/ui/menu_main/content_settings.gd +++ b/src/ui/menu_main/content_settings.gd @@ -45,8 +45,7 @@ func _on_exit_button_pressed() -> void: State.save_settings() has_unsaved_changes = false leave_stage.emit() - State.leave_stage(self) func _input(event: InputEvent) -> void: if event.is_action_pressed("ui_cancel") and has_stage: - State.leave_stage(self) + leave_stage.emit() diff --git a/src/ui/menu_main/gameplay_settings.gd b/src/ui/menu_main/gameplay_settings.gd index 97ca362..71fe6b7 100644 --- a/src/ui/menu_main/gameplay_settings.gd +++ b/src/ui/menu_main/gameplay_settings.gd @@ -37,8 +37,7 @@ func update_ui_from_state(): func _on_exit_button_pressed() -> void: leave_stage.emit() State.save_settings() - State.leave_stage(self) func _input(event: InputEvent) -> void: if event.is_action_pressed("ui_cancel") and has_stage: - State.leave_stage(self) + leave_stage.emit() diff --git a/src/ui/menu_main/privacy_settings.gd b/src/ui/menu_main/privacy_settings.gd index ba15105..daea4ff 100644 --- a/src/ui/menu_main/privacy_settings.gd +++ b/src/ui/menu_main/privacy_settings.gd @@ -39,11 +39,10 @@ func update_ui_from_state(): func _on_exit_button_pressed() -> void: leave_stage.emit() State.save_settings() - State.leave_stage(self) func _input(event: InputEvent) -> void: if event.is_action_pressed("ui_cancel") and has_stage: - State.leave_stage(self) + leave_stage.emit() func reset_all_stats(): Steam.resetAllStats(true) diff --git a/src/ui/menu_main/video_settings.gd b/src/ui/menu_main/video_settings.gd index 17d1d91..8944795 100644 --- a/src/ui/menu_main/video_settings.gd +++ b/src/ui/menu_main/video_settings.gd @@ -175,14 +175,12 @@ func save_settings(): func _on_exit_confirmed() -> void: leave_stage.emit() - State.leave_stage(self) func _on_exit_button_pressed() -> void: if has_changed: $Popup.show() else: leave_stage.emit() - State.leave_stage(self) func _on_confirm_button_pressed() -> void: ProjectSettings.set_setting("display/window/size/mode", window_mode) From 218febb4f4e1b99f26593147e28de7ebc5c7d9ec Mon Sep 17 00:00:00 2001 From: Tiger Jove Date: Mon, 5 Jan 2026 18:18:48 +0100 Subject: [PATCH 5/8] wip: trying to fix broken subviewports --- .../youth_room/interactive_sprite.gd | 18 +- .../youth_room/youth_room.gd | 8 +- .../youth_room/youth_room.tscn | 165 +++++++----------- src/dev-util/room_template.gd | 6 +- src/logic-scenes/card_burner/card_burner.gd | 2 +- .../collectable/collectable_ui.gd | 9 +- .../interactive_sprite.tscn | 24 +-- src/singletons/main/main.gd | 3 +- 8 files changed, 105 insertions(+), 130 deletions(-) diff --git a/src/base-environments/youth_room/interactive_sprite.gd b/src/base-environments/youth_room/interactive_sprite.gd index 0d22825..db2eede 100644 --- a/src/base-environments/youth_room/interactive_sprite.gd +++ b/src/base-environments/youth_room/interactive_sprite.gd @@ -33,15 +33,16 @@ func _ready(): mouse_entered.connect(_on_mouse_entered) # Wire up the CollectableUi with the CanvasLayer for story playback - var canvas = get_node_or_null("%CanvasLayer") - if canvas and ui: - ui.canvas_layer = canvas + if ui: + ui.canvas_layer = %CanvasLayer # Find and wire the StoryPlayable if not already set if ui.story_playable == null: - for child in canvas.get_children(): + for child in %CanvasLayer.get_children(): if child is StoryPlayable: ui.story_playable = child break + # Connect playback_finished to restore player control + ui.playback_finished.connect(_on_playback_finished) func _on_mouse_entered(): if not Scenes.is_playing: @@ -69,5 +70,14 @@ func collapse(): _on_mouse_exited() revealed = false +func _on_playback_finished(): + # Restore player controller control using the room's unique node reference + var player_controller = owner.get_node_or_null("%PlayerController") + if player_controller and "has_stage" in player_controller: + player_controller.has_stage = true + else: + # Fallback: ensure mouse is visible if we can't find player controller + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + func handle(event: InputEvent): viewport.push_input(event) diff --git a/src/base-environments/youth_room/youth_room.gd b/src/base-environments/youth_room/youth_room.gd index a95a306..cd629ce 100644 --- a/src/base-environments/youth_room/youth_room.gd +++ b/src/base-environments/youth_room/youth_room.gd @@ -2,7 +2,7 @@ class_name YouthRoom extends RoomTemplate ## Used by the stage system when this room takes stage for intro playback -var has_stage: bool = false +# var has_stage: bool = false # Reminder, do not uncomment, this field is inherited from RoomTemplate! @onready var board_trigger: InteractiveSprite = %MindBoard @onready var door_trigger: InteractiveSprite = %Door @@ -96,3 +96,9 @@ func play_chest_reveal() -> void: func unload(): $visuals.queue_free() + + +func play_chest_animation(_id): + $AnimationPlayer.play("intro") + await $AnimationPlayer.animation_finished + Scenes.continue_sequence(self) diff --git a/src/base-environments/youth_room/youth_room.tscn b/src/base-environments/youth_room/youth_room.tscn index 27e91d3..09578dc 100644 --- a/src/base-environments/youth_room/youth_room.tscn +++ b/src/base-environments/youth_room/youth_room.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=128 format=4 uid="uid://b3b0gyvklqn50"] +[gd_scene load_steps=136 format=4 uid="uid://b3b0gyvklqn50"] [ext_resource type="Script" uid="uid://bsop46tqngddc" path="res://base-environments/youth_room/youth_room.gd" id="1_aitp0"] [ext_resource type="AudioStream" uid="uid://1h6k2d8q1kw3" path="res://base-environments/youth_room/import/sounds/rain_on_window.mp3" id="2_3haaq"] @@ -161,14 +161,6 @@ func show(): script/source = "extends CenterContainer var has_stage - -func _ready() -> void: - Scenes.sign_up_for_sequence(play_chest_animation, Scenes.id.YOUTH_DRAEVEN, 0) - -func play_chest_animation(_id): - $AnimationPlayer.play(\"intro\") - await $AnimationPlayer.animation_finished - Scenes.continue_sequence(self) " [sub_resource type="Animation" id="Animation_ks23q"] @@ -264,192 +256,144 @@ tracks/2/keys = { tracks/3/type = "value" tracks/3/imported = false tracks/3/enabled = true -tracks/3/path = NodePath("ScenePlayer/childhood/PanelContainer:self_modulate") +tracks/3/path = NodePath("ScenePlayer/OmniLight3D:light_energy") tracks/3/interp = 1 tracks/3/loop_wrap = true tracks/3/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), "update": 0, -"values": [Color(1, 1, 1, 1)] +"values": [0.0] } tracks/4/type = "value" tracks/4/imported = false tracks/4/enabled = true -tracks/4/path = NodePath("ScenePlayer/childhood:visible") +tracks/4/path = NodePath("ScenePlayer/starlight_mesh/starlight_ambient:light_energy") tracks/4/interp = 1 tracks/4/loop_wrap = true tracks/4/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), -"update": 1, -"values": [false] +"update": 0, +"values": [0.2] } tracks/5/type = "value" tracks/5/imported = false tracks/5/enabled = true -tracks/5/path = NodePath("ScenePlayer/OmniLight3D:light_energy") +tracks/5/path = NodePath("ScenePlayer/starlight_mesh:visible") tracks/5/interp = 1 tracks/5/loop_wrap = true tracks/5/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), "update": 0, -"values": [0.0] +"values": [true] } tracks/6/type = "value" tracks/6/imported = false tracks/6/enabled = true -tracks/6/path = NodePath("ScenePlayer/starlight_mesh/starlight_ambient:light_energy") +tracks/6/path = NodePath("ScenePlayer/starlight_mesh/starlight_lamp_dynamic:light_energy") tracks/6/interp = 1 tracks/6/loop_wrap = true tracks/6/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), "update": 0, -"values": [0.2] +"values": [2.0] } tracks/7/type = "value" tracks/7/imported = false tracks/7/enabled = true -tracks/7/path = NodePath("ScenePlayer/starlight_mesh:visible") +tracks/7/path = NodePath("ScenePlayer/Luna_frame-of-mind:visible") tracks/7/interp = 1 tracks/7/loop_wrap = true tracks/7/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), "update": 0, -"values": [true] +"values": [false] } tracks/8/type = "value" tracks/8/imported = false tracks/8/enabled = true -tracks/8/path = NodePath("ScenePlayer/starlight_mesh/starlight_lamp_dynamic:light_energy") +tracks/8/path = NodePath("ScenePlayer/Luna_frame-of-mind:rotation") tracks/8/interp = 1 tracks/8/loop_wrap = true tracks/8/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), "update": 0, -"values": [2.0] +"values": [Vector3(0, 0.2877, 0)] } tracks/9/type = "value" tracks/9/imported = false tracks/9/enabled = true -tracks/9/path = NodePath("ScenePlayer/Luna_frame-of-mind:visible") +tracks/9/path = NodePath("ScenePlayer/Luna_frame-of-mind:position") tracks/9/interp = 1 tracks/9/loop_wrap = true tracks/9/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), "update": 0, -"values": [false] +"values": [Vector3(-10.1552, 14.9384, -16.2182)] } tracks/10/type = "value" tracks/10/imported = false tracks/10/enabled = true -tracks/10/path = NodePath("ScenePlayer/Luna_frame-of-mind:rotation") +tracks/10/path = NodePath("ScenePlayer/material_handle:material:shader_parameter/alpha_scissor_threshold") tracks/10/interp = 1 tracks/10/loop_wrap = true tracks/10/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), "update": 0, -"values": [Vector3(0, 0.2877, 0)] +"values": [-0.3] } tracks/11/type = "value" tracks/11/imported = false tracks/11/enabled = true -tracks/11/path = NodePath("ScenePlayer/Luna_frame-of-mind:position") +tracks/11/path = NodePath("ScenePlayer/material_handle:material:shader_parameter/alpha_offset") tracks/11/interp = 1 tracks/11/loop_wrap = true tracks/11/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), "update": 0, -"values": [Vector3(-10.1552, 14.9384, -16.2182)] +"values": [-1.0] } tracks/12/type = "value" tracks/12/imported = false tracks/12/enabled = true -tracks/12/path = NodePath("ScenePlayer/material_handle:material:shader_parameter/alpha_scissor_threshold") +tracks/12/path = NodePath("ScenePlayer/Jui_Jutsu:volume_db") tracks/12/interp = 1 tracks/12/loop_wrap = true tracks/12/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), "update": 0, -"values": [-0.3] +"values": [0.0] } tracks/13/type = "value" tracks/13/imported = false tracks/13/enabled = true -tracks/13/path = NodePath("ScenePlayer/material_handle:material:shader_parameter/alpha_offset") +tracks/13/path = NodePath("%ScenePlayer/Moving:volume_db") tracks/13/interp = 1 tracks/13/loop_wrap = true tracks/13/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), "update": 0, -"values": [-1.0] +"values": [0.0] } tracks/14/type = "value" tracks/14/imported = false tracks/14/enabled = true -tracks/14/path = NodePath("ScenePlayer/Jui_Jutsu:volume_db") +tracks/14/path = NodePath("%ScenePlayer/OmniLight3D:visible") tracks/14/interp = 1 tracks/14/loop_wrap = true tracks/14/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), -"update": 0, -"values": [0.0] -} -tracks/15/type = "value" -tracks/15/imported = false -tracks/15/enabled = true -tracks/15/path = NodePath("%ScenePlayer/JuiJutsu:visible") -tracks/15/interp = 1 -tracks/15/loop_wrap = true -tracks/15/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 1, -"values": [false] -} -tracks/16/type = "value" -tracks/16/imported = false -tracks/16/enabled = true -tracks/16/path = NodePath("%ScenePlayer/childhood:visible") -tracks/16/interp = 1 -tracks/16/loop_wrap = true -tracks/16/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 1, -"values": [false] -} -tracks/17/type = "value" -tracks/17/imported = false -tracks/17/enabled = true -tracks/17/path = NodePath("%ScenePlayer/Moving:volume_db") -tracks/17/interp = 1 -tracks/17/loop_wrap = true -tracks/17/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 0, -"values": [0.0] -} -tracks/18/type = "value" -tracks/18/imported = false -tracks/18/enabled = true -tracks/18/path = NodePath("%ScenePlayer/OmniLight3D:visible") -tracks/18/interp = 1 -tracks/18/loop_wrap = true -tracks/18/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), "update": 1, "values": [false] } @@ -935,6 +879,9 @@ render_priority = 0 shader = ExtResource("25_dqyng") shader_parameter/default_texture = SubResource("ViewportTexture_dqyng") +[sub_resource type="ViewportTexture" id="ViewportTexture_mhuct"] +viewport_path = NodePath("UiWrapper/UiSprite/SubViewport") + [sub_resource type="ViewportTexture" id="ViewportTexture_e5y1q"] viewport_path = NodePath("logic/MaskMemento/UiWrapper/UiSprite/SubViewport") @@ -944,6 +891,9 @@ render_priority = 0 shader = ExtResource("25_dqyng") shader_parameter/default_texture = SubResource("ViewportTexture_e5y1q") +[sub_resource type="ViewportTexture" id="ViewportTexture_wc1hp"] +viewport_path = NodePath("UiWrapper/UiSprite/SubViewport") + [sub_resource type="ViewportTexture" id="ViewportTexture_ks23q"] viewport_path = NodePath("logic/MaskMemento/UiWrapper/UiSprite/SubViewport") @@ -953,6 +903,9 @@ render_priority = 0 shader = ExtResource("25_dqyng") shader_parameter/default_texture = SubResource("ViewportTexture_ks23q") +[sub_resource type="ViewportTexture" id="ViewportTexture_murax"] +viewport_path = NodePath("UiWrapper/UiSprite/SubViewport") + [sub_resource type="ViewportTexture" id="ViewportTexture_5bsh1"] viewport_path = NodePath("logic/MaskMemento/UiWrapper/UiSprite/SubViewport") @@ -962,6 +915,9 @@ render_priority = 0 shader = ExtResource("25_dqyng") shader_parameter/default_texture = SubResource("ViewportTexture_5bsh1") +[sub_resource type="ViewportTexture" id="ViewportTexture_culng"] +viewport_path = NodePath("UiWrapper/UiSprite/SubViewport") + [sub_resource type="ViewportTexture" id="ViewportTexture_ypa88"] viewport_path = NodePath("logic/MaskMemento/UiWrapper/UiSprite/SubViewport") @@ -971,6 +927,21 @@ render_priority = 0 shader = ExtResource("25_dqyng") shader_parameter/default_texture = SubResource("ViewportTexture_ypa88") +[sub_resource type="ViewportTexture" id="ViewportTexture_5ovnq"] +viewport_path = NodePath("UiWrapper/UiSprite/SubViewport") + +[sub_resource type="ViewportTexture" id="ViewportTexture_xbjb2"] +viewport_path = NodePath("UiWrapper/UiSprite/SubViewport") + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_wc1hp"] +resource_local_to_scene = true +render_priority = 0 +shader = ExtResource("25_dqyng") +shader_parameter/default_texture = SubResource("ViewportTexture_xbjb2") + +[sub_resource type="ViewportTexture" id="ViewportTexture_qkj5t"] +viewport_path = NodePath("UiWrapper/UiSprite/SubViewport") + [sub_resource type="Animation" id="Animation_xum02"] length = 0.001 tracks/0/type = "value" @@ -1620,7 +1591,7 @@ func show(): visible = true var vis_tween = create_tween() vis_tween.tween_property(self, \"modulate\", Color(1, 1, 1, 1), 0.1) - + func hide(): var vis_tween = create_tween() vis_tween.tween_property(self, \"modulate\", Color(1, 1, 1, 0), 0.1) @@ -1911,26 +1882,14 @@ stream = ExtResource("9_i8mqk") volume_db = -80.0 bus = &"music" -[node name="childhood" parent="logic/ScenePlayer" instance=ExtResource("12_viwxf")] - [node name="VoiceTraining" type="AudioStreamPlayer" parent="logic/ScenePlayer"] stream = ExtResource("10_wwwdq") volume_db = -80.0 bus = &"music" -[node name="JuiJutsu" parent="logic/ScenePlayer" instance=ExtResource("12_x3dlb")] - -[node name="voice_training" parent="logic/ScenePlayer" instance=ExtResource("13_v3447")] -story_array = [] -paragraph_lengths = [1] - [node name="Jui_Jutsu" type="AudioStreamPlayer" parent="logic/ScenePlayer"] bus = &"music" -[node name="draven" parent="logic/ScenePlayer" instance=ExtResource("19_d3c7p")] -story_array = [] -paragraph_lengths = [1] - [node name="starlight_mesh" type="MeshInstance3D" parent="logic/ScenePlayer"] transform = Transform3D(0.999, 0, 0, 0, 0.999, 0, 0, 0, 0.999, 0, 0, 0) layers = 2 @@ -2010,7 +1969,7 @@ transform = Transform3D(-0.8630245, 0, 0.5051597, 0, 1, 0, -0.5051597, 0, -0.863 [node name="UiSprite" parent="logic/MaskMemento/UiWrapper" index="1"] material_override = SubResource("ShaderMaterial_xbjb2") -texture = SubResource("ViewportTexture_dqyng") +texture = SubResource("ViewportTexture_mhuct") [node name="childhood" parent="logic/MaskMemento/CanvasLayer" index="0" instance=ExtResource("12_viwxf")] @@ -2019,7 +1978,7 @@ transform = Transform3D(0.8604294, 0, -0.5095667, 0, 1, 0, 0.5095667, 0, 0.86042 [node name="UiSprite" parent="logic/ClothesMemento/UiWrapper" index="1"] material_override = SubResource("ShaderMaterial_5bsh1") -texture = SubResource("ViewportTexture_e5y1q") +texture = SubResource("ViewportTexture_wc1hp") [node name="JuiJutsu" parent="logic/ClothesMemento/CanvasLayer" index="0" instance=ExtResource("12_x3dlb")] @@ -2028,7 +1987,7 @@ transform = Transform3D(0.9699434, 0, 0.24332686, 0, 1, 0, -0.24332686, 0, 0.969 [node name="UiSprite" parent="logic/ComicMemento/UiWrapper" index="1"] material_override = SubResource("ShaderMaterial_e5y1q") -texture = SubResource("ViewportTexture_ks23q") +texture = SubResource("ViewportTexture_murax") [node name="voice_training" parent="logic/ComicMemento/CanvasLayer" index="0" instance=ExtResource("13_v3447")] story_array = [] @@ -2039,24 +1998,30 @@ transform = Transform3D(0.71489924, 0, 0.6992255, 0, 1, 0, -0.6992255, 0, 0.7148 [node name="UiSprite" parent="logic/CeilingMemento/UiWrapper" index="1"] material_override = SubResource("ShaderMaterial_ypa88") -texture = SubResource("ViewportTexture_5bsh1") +texture = SubResource("ViewportTexture_culng") [node name="draven" parent="logic/CeilingMemento/CanvasLayer" index="0" instance=ExtResource("19_d3c7p")] story_array = [] paragraph_lengths = [1] [node name="MindBoard" parent="logic" instance=ExtResource("30_ypa88")] +unique_name_in_owner = true transform = Transform3D(-4.3711374e-08, 0, 0.9999984, 0, 1, 0, -0.9999984, 0, -4.3711374e-08, -0.907206, 1.17661, 1.74337) [node name="UiSprite" parent="logic/MindBoard/UiWrapper" index="1"] material_override = SubResource("ShaderMaterial_mhuct") -texture = SubResource("ViewportTexture_ypa88") +texture = SubResource("ViewportTexture_5ovnq") [node name="board" parent="logic/MindBoard/CanvasLayer" index="0" instance=ExtResource("4_gyjxx")] [node name="Door" parent="logic" instance=ExtResource("30_ypa88")] +unique_name_in_owner = true transform = Transform3D(0.9999984, 0, 4.973797e-14, 0, 1, 0, -4.973797e-14, 0, 0.9999984, 0.115203, 1.3931, -0.954428) +[node name="UiSprite" parent="logic/Door/UiWrapper" index="1"] +material_override = SubResource("ShaderMaterial_wc1hp") +texture = SubResource("ViewportTexture_qkj5t") + [node name="AnimationPlayer" type="AnimationPlayer" parent="."] libraries = { &"": SubResource("AnimationLibrary_vwrt1") @@ -2315,10 +2280,10 @@ data = ExtResource("40_ea6x8") [connection signal="body_exited" from="logic/Bed and Ladders/reset_failover" to="logic/PlayerController" method="_on_bed_exit"] [connection signal="pressed" from="logic/UI/ending_button" to="logic/UI/ending_button" method="hide"] [connection signal="pressed" from="logic/UI/ending_button" to="logic/UI/ending" method="show"] -[connection signal="emit_thunder" from="logic/ScenePlayer/JuiJutsu" to="AnimationPlayer" method="play" binds= ["lighting_and_thunder"]] [editable path="logic/MaskMemento"] [editable path="logic/ClothesMemento"] [editable path="logic/ComicMemento"] [editable path="logic/CeilingMemento"] [editable path="logic/MindBoard"] +[editable path="logic/Door"] diff --git a/src/dev-util/room_template.gd b/src/dev-util/room_template.gd index 16a3693..9bd6819 100644 --- a/src/dev-util/room_template.gd +++ b/src/dev-util/room_template.gd @@ -23,6 +23,9 @@ func disable()-> void: set_process_input(false) set_process(false) +func get_ready(): + pass + func load(): # Override this function to load the state of the chapter from State.save_game pass @@ -32,9 +35,6 @@ func play() -> String: return await proceed -func get_ready(): - pass - func start_room(): pass diff --git a/src/logic-scenes/card_burner/card_burner.gd b/src/logic-scenes/card_burner/card_burner.gd index d961f3b..865e5bc 100644 --- a/src/logic-scenes/card_burner/card_burner.gd +++ b/src/logic-scenes/card_burner/card_burner.gd @@ -21,7 +21,7 @@ var has_stage = false: @onready var ancors: Array[Control] = [%Ancor1, %Ancor2, %Ancor3, %Ancor4] func _ready(): - Scenes.register_scene_actor(Scenes.id.TRANSITION, burn_cards) + # Note: burn_cards is now called directly by the transition system, not via register_scene_actor %SkipButton.pressed.connect(card_burned.emit) func burn_cards(_id: int, _repeat: bool = false) -> void: diff --git a/src/logic-scenes/collectable/collectable_ui.gd b/src/logic-scenes/collectable/collectable_ui.gd index 54ee609..7f77290 100644 --- a/src/logic-scenes/collectable/collectable_ui.gd +++ b/src/logic-scenes/collectable/collectable_ui.gd @@ -144,6 +144,7 @@ var canvas_layer: CanvasLayer signal open_board signal exit_room +signal playback_finished #TODO implement proper scene skipping signal scene_skipped(i: int) @@ -240,6 +241,7 @@ func collect_memento() -> void: if was_skipped: scene_skipped.emit(-1) is_collected = true + playback_finished.emit() return # Signal that a scene is starting (for music, etc.) @@ -260,8 +262,8 @@ func collect_memento() -> void: if canvas_layer: canvas_layer.hide() - # Restore mouse - Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + # Restore mouse to captured mode (player controller will be given back control) + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED # Signal that the scene is finished Scenes.end_sequence(scene) @@ -269,3 +271,6 @@ func collect_memento() -> void: if was_skipped: scene_skipped.emit(-1) is_collected = true + + # Signal that playback is finished so the InteractiveSprite can restore player control + playback_finished.emit() diff --git a/src/logic-scenes/interactive_sprite/interactive_sprite.tscn b/src/logic-scenes/interactive_sprite/interactive_sprite.tscn index 9721068..7146f48 100644 --- a/src/logic-scenes/interactive_sprite/interactive_sprite.tscn +++ b/src/logic-scenes/interactive_sprite/interactive_sprite.tscn @@ -1,22 +1,15 @@ -[gd_scene load_steps=11 format=3 uid="uid://cy4yesucptcr3"] +[gd_scene load_steps=9 format=3 uid="uid://cy4yesucptcr3"] [ext_resource type="Script" uid="uid://dr4wd80dobxjd" path="res://base-environments/youth_room/interactive_sprite.gd" id="1_v8gd7"] [ext_resource type="PackedScene" uid="uid://bdnesuqroi7ss" path="res://vfx/collectable_particles.tscn" id="2_lqlgh"] [ext_resource type="Script" uid="uid://dbdw3v7mbqscf" path="res://dev-util/click-trough-area.gd" id="3_1fk5i"] -[ext_resource type="Shader" uid="uid://ci37nlh06b5y2" path="res://logic-scenes/collectable/collectable.gdshader" id="4_64lfl"] [ext_resource type="PackedScene" uid="uid://wfyna16xhlo0" path="res://logic-scenes/collectable/collectable_ui.tscn" id="5_kqyl2"] [ext_resource type="Texture2D" uid="uid://d0ucjqi8tx6vt" path="res://import/interface-elements/frame.png" id="6_13pus"] [sub_resource type="BoxShape3D" id="BoxShape3D_v8gd7"] -[sub_resource type="ViewportTexture" id="ViewportTexture_ghmim"] -viewport_path = NodePath("logic/MaskMemento/UiWrapper/UiSprite/SubViewport") - -[sub_resource type="ShaderMaterial" id="ShaderMaterial_dqyng"] -resource_local_to_scene = true -render_priority = 0 -shader = ExtResource("4_64lfl") -shader_parameter/default_texture = SubResource("ViewportTexture_ghmim") +[sub_resource type="ViewportTexture" id="ViewportTexture_bc0j1"] +viewport_path = NodePath("UiWrapper/UiSprite/SubViewport") [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_v8gd7"] height = 1.5 @@ -38,23 +31,20 @@ transform = Transform3D(1, -6.984922e-08, -1.908213e-15, 6.984922e-08, 1, 2.3283 shape = SubResource("BoxShape3D_v8gd7") [node name="UiSprite" type="Sprite3D" parent="UiWrapper"] -transform = Transform3D(1, 0, -5.96046e-08, 0, 1, 0, 5.96046e-08, 0, 1, 0, 0, 0) -material_override = SubResource("ShaderMaterial_dqyng") -modulate = Color(0.52473676, 0.353479, 0.20148611, 1) +gi_mode = 0 +modulate = Color(0.9999996, 0.96863645, 0.88173, 1) pixel_size = 0.015 -shaded = true no_depth_test = true -texture = SubResource("ViewportTexture_ghmim") +texture = SubResource("ViewportTexture_bc0j1") [node name="SubViewport" type="SubViewport" parent="UiWrapper/UiSprite"] transparent_bg = true size = Vector2i(400, 350) -render_target_update_mode = 4 [node name="CollectableUi" parent="UiWrapper/UiSprite/SubViewport" instance=ExtResource("5_kqyl2")] [node name="Frame" type="Sprite3D" parent="UiWrapper"] -transform = Transform3D(0.70457095, 0, -1.19208984e-07, 0, 0.704571, 0, 1.19208984e-07, 0, 0.70457095, 0, 0, 0) +transform = Transform3D(0.7045709, 0, -1.1920898e-07, 0, 0.704571, 0, 1.1920898e-07, 0, 0.7045709, 0, -1, 0) visibility_range_end = 0.6 visibility_range_end_margin = 0.3 visibility_range_fade_mode = 1 diff --git a/src/singletons/main/main.gd b/src/singletons/main/main.gd index 8d4b796..31abb4c 100644 --- a/src/singletons/main/main.gd +++ b/src/singletons/main/main.gd @@ -91,6 +91,7 @@ func _load_room(next_path: String) -> bool: ResourceLoader.THREAD_LOAD_LOADED: var next_scene := ResourceLoader.load_threaded_get(youth_room_path) as PackedScene State.room = next_scene.instantiate() as RoomTemplate + await get_tree().process_frame get_tree().root.add_child(State.room) await State.room.get_ready() %Loading.stop() @@ -115,5 +116,3 @@ func _unhandled_input(event: InputEvent) -> void: AppState.PAUSE: if event.is_action_pressed("ui_menu"): app_state = AppState.PLAY - - From b3d82de85043c83f2e05e7df02bd82cf0d0a72ca Mon Sep 17 00:00:00 2001 From: Tiger Jove Date: Mon, 5 Jan 2026 18:42:27 +0100 Subject: [PATCH 6/8] chore: found many broken / orphaned viewports in youth room --- .../youth_room/youth_room.gd | 2 - .../youth_room/youth_room.tscn | 99 +------------------ .../interactive_sprite.tscn | 10 +- .../interactive_sprite/ui_sprite.gd | 4 + .../interactive_sprite/ui_sprite.gd.uid | 1 + 5 files changed, 13 insertions(+), 103 deletions(-) create mode 100644 src/logic-scenes/interactive_sprite/ui_sprite.gd create mode 100644 src/logic-scenes/interactive_sprite/ui_sprite.gd.uid diff --git a/src/base-environments/youth_room/youth_room.gd b/src/base-environments/youth_room/youth_room.gd index cd629ce..f55897d 100644 --- a/src/base-environments/youth_room/youth_room.gd +++ b/src/base-environments/youth_room/youth_room.gd @@ -10,8 +10,6 @@ extends RoomTemplate @onready var card_picker: CardPicker = %Picker @onready var ui: Control = %UI -signal interaction(interactable: Object) - func start_room(): %UI.show() $logic/PlayerController.process_mode = Node.PROCESS_MODE_INHERIT diff --git a/src/base-environments/youth_room/youth_room.tscn b/src/base-environments/youth_room/youth_room.tscn index 09578dc..a4f6191 100644 --- a/src/base-environments/youth_room/youth_room.tscn +++ b/src/base-environments/youth_room/youth_room.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=136 format=4 uid="uid://b3b0gyvklqn50"] +[gd_scene load_steps=117 format=4 uid="uid://b3b0gyvklqn50"] [ext_resource type="Script" uid="uid://bsop46tqngddc" path="res://base-environments/youth_room/youth_room.gd" id="1_aitp0"] [ext_resource type="AudioStream" uid="uid://1h6k2d8q1kw3" path="res://base-environments/youth_room/import/sounds/rain_on_window.mp3" id="2_3haaq"] @@ -27,7 +27,6 @@ [ext_resource type="ArrayMesh" uid="uid://bfc3d4g40n0wy" path="res://logic-scenes/collectable/import/old-mask.res" id="19_jr2bb"] [ext_resource type="PackedScene" uid="uid://dwtxjvprjyx8p" path="res://base-environments/youth_room/lava-lamp.tscn" id="21_0k2gr"] [ext_resource type="AudioStream" uid="uid://bghjiqkyehs1p" path="res://base-environments/youth_room/import/sounds/rain and thunder.mp3" id="22_xrkbj"] -[ext_resource type="Shader" uid="uid://ci37nlh06b5y2" path="res://logic-scenes/collectable/collectable.gdshader" id="25_dqyng"] [ext_resource type="PackedScene" uid="uid://bpjympn3ps3wo" path="res://logic-scenes/luna/luna_imported.tscn" id="27_pb1jl"] [ext_resource type="Material" uid="uid://ct7uc5i5yp5qf" path="res://base-environments/youth_room/import/materials/wall.tres" id="28_oiweb"] [ext_resource type="PackedScene" uid="uid://bw47g00bi710i" path="res://base-environments/youth_room/youth_room_visuals.tscn" id="30_dqyng"] @@ -870,78 +869,6 @@ _surfaces = [{ blend_shape_mode = 0 shadow_mesh = SubResource("ArrayMesh_lag5h") -[sub_resource type="ViewportTexture" id="ViewportTexture_dqyng"] -viewport_path = NodePath("logic/MaskMemento/UiWrapper/UiSprite/SubViewport") - -[sub_resource type="ShaderMaterial" id="ShaderMaterial_xbjb2"] -resource_local_to_scene = true -render_priority = 0 -shader = ExtResource("25_dqyng") -shader_parameter/default_texture = SubResource("ViewportTexture_dqyng") - -[sub_resource type="ViewportTexture" id="ViewportTexture_mhuct"] -viewport_path = NodePath("UiWrapper/UiSprite/SubViewport") - -[sub_resource type="ViewportTexture" id="ViewportTexture_e5y1q"] -viewport_path = NodePath("logic/MaskMemento/UiWrapper/UiSprite/SubViewport") - -[sub_resource type="ShaderMaterial" id="ShaderMaterial_5bsh1"] -resource_local_to_scene = true -render_priority = 0 -shader = ExtResource("25_dqyng") -shader_parameter/default_texture = SubResource("ViewportTexture_e5y1q") - -[sub_resource type="ViewportTexture" id="ViewportTexture_wc1hp"] -viewport_path = NodePath("UiWrapper/UiSprite/SubViewport") - -[sub_resource type="ViewportTexture" id="ViewportTexture_ks23q"] -viewport_path = NodePath("logic/MaskMemento/UiWrapper/UiSprite/SubViewport") - -[sub_resource type="ShaderMaterial" id="ShaderMaterial_e5y1q"] -resource_local_to_scene = true -render_priority = 0 -shader = ExtResource("25_dqyng") -shader_parameter/default_texture = SubResource("ViewportTexture_ks23q") - -[sub_resource type="ViewportTexture" id="ViewportTexture_murax"] -viewport_path = NodePath("UiWrapper/UiSprite/SubViewport") - -[sub_resource type="ViewportTexture" id="ViewportTexture_5bsh1"] -viewport_path = NodePath("logic/MaskMemento/UiWrapper/UiSprite/SubViewport") - -[sub_resource type="ShaderMaterial" id="ShaderMaterial_ypa88"] -resource_local_to_scene = true -render_priority = 0 -shader = ExtResource("25_dqyng") -shader_parameter/default_texture = SubResource("ViewportTexture_5bsh1") - -[sub_resource type="ViewportTexture" id="ViewportTexture_culng"] -viewport_path = NodePath("UiWrapper/UiSprite/SubViewport") - -[sub_resource type="ViewportTexture" id="ViewportTexture_ypa88"] -viewport_path = NodePath("logic/MaskMemento/UiWrapper/UiSprite/SubViewport") - -[sub_resource type="ShaderMaterial" id="ShaderMaterial_mhuct"] -resource_local_to_scene = true -render_priority = 0 -shader = ExtResource("25_dqyng") -shader_parameter/default_texture = SubResource("ViewportTexture_ypa88") - -[sub_resource type="ViewportTexture" id="ViewportTexture_5ovnq"] -viewport_path = NodePath("UiWrapper/UiSprite/SubViewport") - -[sub_resource type="ViewportTexture" id="ViewportTexture_xbjb2"] -viewport_path = NodePath("UiWrapper/UiSprite/SubViewport") - -[sub_resource type="ShaderMaterial" id="ShaderMaterial_wc1hp"] -resource_local_to_scene = true -render_priority = 0 -shader = ExtResource("25_dqyng") -shader_parameter/default_texture = SubResource("ViewportTexture_xbjb2") - -[sub_resource type="ViewportTexture" id="ViewportTexture_qkj5t"] -viewport_path = NodePath("UiWrapper/UiSprite/SubViewport") - [sub_resource type="Animation" id="Animation_xum02"] length = 0.001 tracks/0/type = "value" @@ -1967,28 +1894,16 @@ omni_range = 16.8518 [node name="MaskMemento" parent="logic" instance=ExtResource("30_ypa88")] transform = Transform3D(-0.8630245, 0, 0.5051597, 0, 1, 0, -0.5051597, 0, -0.8630245, 0.0754588, 0.948372, 2.42068) -[node name="UiSprite" parent="logic/MaskMemento/UiWrapper" index="1"] -material_override = SubResource("ShaderMaterial_xbjb2") -texture = SubResource("ViewportTexture_mhuct") - [node name="childhood" parent="logic/MaskMemento/CanvasLayer" index="0" instance=ExtResource("12_viwxf")] [node name="ClothesMemento" parent="logic" instance=ExtResource("30_ypa88")] transform = Transform3D(0.8604294, 0, -0.5095667, 0, 1, 0, 0.5095667, 0, 0.8604294, 1.3658599, 1.17096, -0.6365988) -[node name="UiSprite" parent="logic/ClothesMemento/UiWrapper" index="1"] -material_override = SubResource("ShaderMaterial_5bsh1") -texture = SubResource("ViewportTexture_wc1hp") - [node name="JuiJutsu" parent="logic/ClothesMemento/CanvasLayer" index="0" instance=ExtResource("12_x3dlb")] [node name="ComicMemento" parent="logic" instance=ExtResource("30_ypa88")] transform = Transform3D(0.9699434, 0, 0.24332686, 0, 1, 0, -0.24332686, 0, 0.9699434, 2.91664, 0.595014, -0.75655603) -[node name="UiSprite" parent="logic/ComicMemento/UiWrapper" index="1"] -material_override = SubResource("ShaderMaterial_e5y1q") -texture = SubResource("ViewportTexture_murax") - [node name="voice_training" parent="logic/ComicMemento/CanvasLayer" index="0" instance=ExtResource("13_v3447")] story_array = [] paragraph_lengths = [1] @@ -1996,10 +1911,6 @@ paragraph_lengths = [1] [node name="CeilingMemento" parent="logic" instance=ExtResource("30_ypa88")] transform = Transform3D(0.71489924, 0, 0.6992255, 0, 1, 0, -0.6992255, 0, 0.71489924, -0.13478619, 2.0720484, -0.42032808) -[node name="UiSprite" parent="logic/CeilingMemento/UiWrapper" index="1"] -material_override = SubResource("ShaderMaterial_ypa88") -texture = SubResource("ViewportTexture_culng") - [node name="draven" parent="logic/CeilingMemento/CanvasLayer" index="0" instance=ExtResource("19_d3c7p")] story_array = [] paragraph_lengths = [1] @@ -2008,20 +1919,12 @@ paragraph_lengths = [1] unique_name_in_owner = true transform = Transform3D(-4.3711374e-08, 0, 0.9999984, 0, 1, 0, -0.9999984, 0, -4.3711374e-08, -0.907206, 1.17661, 1.74337) -[node name="UiSprite" parent="logic/MindBoard/UiWrapper" index="1"] -material_override = SubResource("ShaderMaterial_mhuct") -texture = SubResource("ViewportTexture_5ovnq") - [node name="board" parent="logic/MindBoard/CanvasLayer" index="0" instance=ExtResource("4_gyjxx")] [node name="Door" parent="logic" instance=ExtResource("30_ypa88")] unique_name_in_owner = true transform = Transform3D(0.9999984, 0, 4.973797e-14, 0, 1, 0, -4.973797e-14, 0, 0.9999984, 0.115203, 1.3931, -0.954428) -[node name="UiSprite" parent="logic/Door/UiWrapper" index="1"] -material_override = SubResource("ShaderMaterial_wc1hp") -texture = SubResource("ViewportTexture_qkj5t") - [node name="AnimationPlayer" type="AnimationPlayer" parent="."] libraries = { &"": SubResource("AnimationLibrary_vwrt1") diff --git a/src/logic-scenes/interactive_sprite/interactive_sprite.tscn b/src/logic-scenes/interactive_sprite/interactive_sprite.tscn index 7146f48..92b291d 100644 --- a/src/logic-scenes/interactive_sprite/interactive_sprite.tscn +++ b/src/logic-scenes/interactive_sprite/interactive_sprite.tscn @@ -1,14 +1,15 @@ -[gd_scene load_steps=9 format=3 uid="uid://cy4yesucptcr3"] +[gd_scene load_steps=10 format=3 uid="uid://cy4yesucptcr3"] [ext_resource type="Script" uid="uid://dr4wd80dobxjd" path="res://base-environments/youth_room/interactive_sprite.gd" id="1_v8gd7"] [ext_resource type="PackedScene" uid="uid://bdnesuqroi7ss" path="res://vfx/collectable_particles.tscn" id="2_lqlgh"] [ext_resource type="Script" uid="uid://dbdw3v7mbqscf" path="res://dev-util/click-trough-area.gd" id="3_1fk5i"] +[ext_resource type="Script" uid="uid://cdjjn1jx1fdeb" path="res://logic-scenes/interactive_sprite/ui_sprite.gd" id="4_uwc8q"] [ext_resource type="PackedScene" uid="uid://wfyna16xhlo0" path="res://logic-scenes/collectable/collectable_ui.tscn" id="5_kqyl2"] [ext_resource type="Texture2D" uid="uid://d0ucjqi8tx6vt" path="res://import/interface-elements/frame.png" id="6_13pus"] [sub_resource type="BoxShape3D" id="BoxShape3D_v8gd7"] -[sub_resource type="ViewportTexture" id="ViewportTexture_bc0j1"] +[sub_resource type="ViewportTexture" id="ViewportTexture_uwc8q"] viewport_path = NodePath("UiWrapper/UiSprite/SubViewport") [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_v8gd7"] @@ -35,11 +36,14 @@ gi_mode = 0 modulate = Color(0.9999996, 0.96863645, 0.88173, 1) pixel_size = 0.015 no_depth_test = true -texture = SubResource("ViewportTexture_bc0j1") +texture = SubResource("ViewportTexture_uwc8q") +script = ExtResource("4_uwc8q") [node name="SubViewport" type="SubViewport" parent="UiWrapper/UiSprite"] +unique_name_in_owner = true transparent_bg = true size = Vector2i(400, 350) +render_target_update_mode = 4 [node name="CollectableUi" parent="UiWrapper/UiSprite/SubViewport" instance=ExtResource("5_kqyl2")] diff --git a/src/logic-scenes/interactive_sprite/ui_sprite.gd b/src/logic-scenes/interactive_sprite/ui_sprite.gd new file mode 100644 index 0000000..eec39dc --- /dev/null +++ b/src/logic-scenes/interactive_sprite/ui_sprite.gd @@ -0,0 +1,4 @@ +extends Sprite3D + +func _ready() -> void: + pass diff --git a/src/logic-scenes/interactive_sprite/ui_sprite.gd.uid b/src/logic-scenes/interactive_sprite/ui_sprite.gd.uid new file mode 100644 index 0000000..b91d31a --- /dev/null +++ b/src/logic-scenes/interactive_sprite/ui_sprite.gd.uid @@ -0,0 +1 @@ +uid://cdjjn1jx1fdeb From 9da3692b60a5aa3626a3f514248ec1bc6a15919d Mon Sep 17 00:00:00 2001 From: Tiger Jove Date: Mon, 5 Jan 2026 21:39:16 +0100 Subject: [PATCH 7/8] fix: viewport children no longer break. --- .../youth_room/interactive_sprite.gd | 27 ++++++++++--------- .../youth_room/youth_room.gd | 14 +++++----- .../youth_room/youth_room.tscn | 26 ++++-------------- .../collectable/collectable_ui.gd | 26 ++++-------------- .../interactive_sprite.tscn | 8 +++--- 5 files changed, 35 insertions(+), 66 deletions(-) diff --git a/src/base-environments/youth_room/interactive_sprite.gd b/src/base-environments/youth_room/interactive_sprite.gd index db2eede..97f4c78 100644 --- a/src/base-environments/youth_room/interactive_sprite.gd +++ b/src/base-environments/youth_room/interactive_sprite.gd @@ -1,5 +1,7 @@ class_name InteractiveSprite extends Area3D +@export var interaction_ui: PackedScene = null + @onready var pass_to_actor: = $UiWrapper/UiSprite/SubViewport/CollectableUi @onready var wrapper := $UiWrapper @onready var ui: CollectableUi = $UiWrapper/UiSprite/SubViewport.get_child(0) @@ -30,19 +32,18 @@ var has_mouse: bool = false # Called when the node enters the scene tree for the first time. func _ready(): - mouse_entered.connect(_on_mouse_entered) - - # Wire up the CollectableUi with the CanvasLayer for story playback - if ui: - ui.canvas_layer = %CanvasLayer - # Find and wire the StoryPlayable if not already set - if ui.story_playable == null: - for child in %CanvasLayer.get_children(): - if child is StoryPlayable: - ui.story_playable = child - break - # Connect playback_finished to restore player control - ui.playback_finished.connect(_on_playback_finished) + if interaction_ui: + %CanvasLayer.add_child(interaction_ui.instantiate()) + + ui.canvas_layer = %CanvasLayer + # Find and wire the StoryPlayable if not already set + if ui.story_playable == null: + for child in %CanvasLayer.get_children(): + if child is StoryPlayable: + ui.story_playable = child + break + # Connect playback_finished to restore player control + ui.playback_finished.connect(_on_playback_finished) func _on_mouse_entered(): if not Scenes.is_playing: diff --git a/src/base-environments/youth_room/youth_room.gd b/src/base-environments/youth_room/youth_room.gd index f55897d..387f5ba 100644 --- a/src/base-environments/youth_room/youth_room.gd +++ b/src/base-environments/youth_room/youth_room.gd @@ -13,13 +13,13 @@ extends RoomTemplate func start_room(): %UI.show() $logic/PlayerController.process_mode = Node.PROCESS_MODE_INHERIT - + if not Scenes.is_sequence_repeating(Scenes.id.YOUTH_DRAEVEN): # Play intro scene directly (not triggered by CollectableUi) await _play_intro_scene() else: %LightAnimation.lights_on() - + # Give player control after intro (or immediately if repeating) %PlayerController.has_stage = true @@ -27,16 +27,16 @@ func start_room(): func _play_intro_scene() -> void: # The intro scene is auto-played, not triggered by CollectableUi var intro_playable: StoryPlayable = $logic/ScenePlayer/draven - + Scenes.begin_sequence(Scenes.id.YOUTH_DRAEVEN) - + Input.mouse_mode = Input.MOUSE_MODE_HIDDEN - + # Play the story (StoryPlayable handles its own visibility via animations) await intro_playable.play() - + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE - + Scenes.end_sequence(Scenes.id.YOUTH_DRAEVEN) diff --git a/src/base-environments/youth_room/youth_room.tscn b/src/base-environments/youth_room/youth_room.tscn index a4f6191..0eda798 100644 --- a/src/base-environments/youth_room/youth_room.tscn +++ b/src/base-environments/youth_room/youth_room.tscn @@ -1893,33 +1893,24 @@ omni_range = 16.8518 [node name="MaskMemento" parent="logic" instance=ExtResource("30_ypa88")] transform = Transform3D(-0.8630245, 0, 0.5051597, 0, 1, 0, -0.5051597, 0, -0.8630245, 0.0754588, 0.948372, 2.42068) - -[node name="childhood" parent="logic/MaskMemento/CanvasLayer" index="0" instance=ExtResource("12_viwxf")] +interaction_ui = ExtResource("12_viwxf") [node name="ClothesMemento" parent="logic" instance=ExtResource("30_ypa88")] transform = Transform3D(0.8604294, 0, -0.5095667, 0, 1, 0, 0.5095667, 0, 0.8604294, 1.3658599, 1.17096, -0.6365988) - -[node name="JuiJutsu" parent="logic/ClothesMemento/CanvasLayer" index="0" instance=ExtResource("12_x3dlb")] +interaction_ui = ExtResource("12_x3dlb") [node name="ComicMemento" parent="logic" instance=ExtResource("30_ypa88")] transform = Transform3D(0.9699434, 0, 0.24332686, 0, 1, 0, -0.24332686, 0, 0.9699434, 2.91664, 0.595014, -0.75655603) - -[node name="voice_training" parent="logic/ComicMemento/CanvasLayer" index="0" instance=ExtResource("13_v3447")] -story_array = [] -paragraph_lengths = [1] +interaction_ui = ExtResource("13_v3447") [node name="CeilingMemento" parent="logic" instance=ExtResource("30_ypa88")] transform = Transform3D(0.71489924, 0, 0.6992255, 0, 1, 0, -0.6992255, 0, 0.71489924, -0.13478619, 2.0720484, -0.42032808) - -[node name="draven" parent="logic/CeilingMemento/CanvasLayer" index="0" instance=ExtResource("19_d3c7p")] -story_array = [] -paragraph_lengths = [1] +interaction_ui = ExtResource("19_d3c7p") [node name="MindBoard" parent="logic" instance=ExtResource("30_ypa88")] unique_name_in_owner = true transform = Transform3D(-4.3711374e-08, 0, 0.9999984, 0, 1, 0, -0.9999984, 0, -4.3711374e-08, -0.907206, 1.17661, 1.74337) - -[node name="board" parent="logic/MindBoard/CanvasLayer" index="0" instance=ExtResource("4_gyjxx")] +interaction_ui = ExtResource("4_gyjxx") [node name="Door" parent="logic" instance=ExtResource("30_ypa88")] unique_name_in_owner = true @@ -2183,10 +2174,3 @@ data = ExtResource("40_ea6x8") [connection signal="body_exited" from="logic/Bed and Ladders/reset_failover" to="logic/PlayerController" method="_on_bed_exit"] [connection signal="pressed" from="logic/UI/ending_button" to="logic/UI/ending_button" method="hide"] [connection signal="pressed" from="logic/UI/ending_button" to="logic/UI/ending" method="show"] - -[editable path="logic/MaskMemento"] -[editable path="logic/ClothesMemento"] -[editable path="logic/ComicMemento"] -[editable path="logic/CeilingMemento"] -[editable path="logic/MindBoard"] -[editable path="logic/Door"] diff --git a/src/logic-scenes/collectable/collectable_ui.gd b/src/logic-scenes/collectable/collectable_ui.gd index 7f77290..0153d17 100644 --- a/src/logic-scenes/collectable/collectable_ui.gd +++ b/src/logic-scenes/collectable/collectable_ui.gd @@ -1,13 +1,11 @@ extends CenterContainer class_name CollectableUi +@onready var canvas_layer: CanvasLayer = %CanvasLayer + ## The StoryPlayable to play when this memento is collected. ## Auto-discovered from the owner's %CanvasLayer, or can be set manually. -@export var story_playable: StoryPlayable - -## Reference to the CanvasLayer containing the story_playable. -## Auto-discovered in _ready() if not set. -var canvas_layer: CanvasLayer +var story_playable: StoryPlayable @export var has_stage: bool = false: set(focused): @@ -154,21 +152,9 @@ func _ready() -> void: %CollectButton.pressed.connect(collect_memento) ##TODO: add functions for remaining buttons - # Auto-discover story_playable and canvas_layer from scene hierarchy - _discover_story_playable() - update_state() -## Ensure canvas_layer is set if story_playable was set via export. -## InteractiveSprite._ready() handles the main wiring for inherited scenes. -func _discover_story_playable() -> void: - if story_playable != null and canvas_layer == null: - # story_playable set via export, find its parent CanvasLayer - var parent = story_playable.get_parent() - if parent is CanvasLayer: - canvas_layer = parent - func _on_context_updated() -> void: %SkipButton.visible = State.allow_skipping %SummaryButton.visible = State.provide_summaries @@ -252,15 +238,13 @@ func collect_memento() -> void: Input.mouse_mode = Input.MOUSE_MODE_HIDDEN # Show the CanvasLayer so the story is visible full-screen - if canvas_layer: - canvas_layer.show() + canvas_layer.show() # Play the story await story_playable.play() # Hide the CanvasLayer when done - if canvas_layer: - canvas_layer.hide() + canvas_layer.hide() # Restore mouse to captured mode (player controller will be given back control) Input.mouse_mode = Input.MOUSE_MODE_CAPTURED diff --git a/src/logic-scenes/interactive_sprite/interactive_sprite.tscn b/src/logic-scenes/interactive_sprite/interactive_sprite.tscn index 92b291d..e4d1ce5 100644 --- a/src/logic-scenes/interactive_sprite/interactive_sprite.tscn +++ b/src/logic-scenes/interactive_sprite/interactive_sprite.tscn @@ -12,8 +12,8 @@ [sub_resource type="ViewportTexture" id="ViewportTexture_uwc8q"] viewport_path = NodePath("UiWrapper/UiSprite/SubViewport") -[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_v8gd7"] -height = 1.5 +[sub_resource type="BoxShape3D" id="BoxShape3D_uwc8q"] +size = Vector3(1, 1, 0.14892578) [node name="Memento" type="Area3D" groups=["interactables"]] transform = Transform3D(0.9999994, 0, 0, 0, 1, 0, 0, 0, 0.9999994, 0, 0, 0) @@ -59,8 +59,8 @@ region_enabled = true region_rect = Rect2(735.5, 0, 995.5, 1024) [node name="HoverDetect" type="CollisionShape3D" parent="."] -transform = Transform3D(-4.3711356e-08, -0.9999997, 0, 0.9999993, -4.3711374e-08, 0, 0, 0, 0.99999976, 0, 0, 0) -shape = SubResource("CapsuleShape3D_v8gd7") +transform = Transform3D(-4.3711356e-08, -0.9999997, 0, 0.9999993, -4.3711374e-08, 0, 0, 0, 0.99999976, 0, 0, 0.060790993) +shape = SubResource("BoxShape3D_uwc8q") [node name="CanvasLayer" type="CanvasLayer" parent="."] unique_name_in_owner = true From 31977a731c01842637fbc2ecba24628516f9d475 Mon Sep 17 00:00:00 2001 From: Tiger Jove Date: Mon, 5 Jan 2026 21:52:20 +0100 Subject: [PATCH 8/8] fix: board now knows it's board --- .../youth_room/interactive_sprite.gd | 14 +++++--- src/logic-scenes/board/card-board.gd | 2 ++ .../collectable/collectable_ui.gd | 33 ++++++++++--------- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/base-environments/youth_room/interactive_sprite.gd b/src/base-environments/youth_room/interactive_sprite.gd index 97f4c78..d45934f 100644 --- a/src/base-environments/youth_room/interactive_sprite.gd +++ b/src/base-environments/youth_room/interactive_sprite.gd @@ -1,6 +1,7 @@ class_name InteractiveSprite extends Area3D @export var interaction_ui: PackedScene = null +@export var is_board: bool = false @onready var pass_to_actor: = $UiWrapper/UiSprite/SubViewport/CollectableUi @onready var wrapper := $UiWrapper @@ -9,6 +10,7 @@ class_name InteractiveSprite extends Area3D @onready var distance_tween: Tween + var revealed: bool = false: set(reveal): revealed = reveal @@ -37,11 +39,13 @@ func _ready(): ui.canvas_layer = %CanvasLayer # Find and wire the StoryPlayable if not already set - if ui.story_playable == null: - for child in %CanvasLayer.get_children(): - if child is StoryPlayable: - ui.story_playable = child - break + for child in %CanvasLayer.get_children(): + if child is StoryPlayable: + ui.story_playable = child + break + if child is CardBoard: + ui.is_board = true + # Connect playback_finished to restore player control ui.playback_finished.connect(_on_playback_finished) diff --git a/src/logic-scenes/board/card-board.gd b/src/logic-scenes/board/card-board.gd index 8545981..f180b7e 100644 --- a/src/logic-scenes/board/card-board.gd +++ b/src/logic-scenes/board/card-board.gd @@ -8,6 +8,8 @@ enum Error { MISSING } +const is_board := true + var focus_stickies:bool = true: set(stickies): if not is_node_ready(): return diff --git a/src/logic-scenes/collectable/collectable_ui.gd b/src/logic-scenes/collectable/collectable_ui.gd index 0153d17..7b87c25 100644 --- a/src/logic-scenes/collectable/collectable_ui.gd +++ b/src/logic-scenes/collectable/collectable_ui.gd @@ -1,7 +1,7 @@ extends CenterContainer -class_name CollectableUi +class_name CollectableUi -@onready var canvas_layer: CanvasLayer = %CanvasLayer +@onready var canvas_layer: CanvasLayer = %CanvasLayer ## The StoryPlayable to play when this memento is collected. ## Auto-discovered from the owner's %CanvasLayer, or can be set manually. @@ -127,6 +127,7 @@ var story_playable: StoryPlayable else: scene = scene collected_box.show() + @export var is_exit:bool = false: set(exit): is_exit = exit @@ -151,7 +152,7 @@ func _ready() -> void: State.settings_changed.connect(_on_context_updated) %CollectButton.pressed.connect(collect_memento) ##TODO: add functions for remaining buttons - + update_state() @@ -217,44 +218,44 @@ func vanish() -> void: func collect_memento() -> void: print_debug("CollectableUi.collect_memento() - scene: %s" % Scenes.id.keys()[scene]) - + # Hide the collectable UI vanish() - + # Check if we have a story_playable to play if story_playable == null: push_warning("CollectableUi for scene %s has no story_playable assigned" % Scenes.id.keys()[scene]) - if was_skipped: + if was_skipped: scene_skipped.emit(-1) is_collected = true playback_finished.emit() return - + # Signal that a scene is starting (for music, etc.) Scenes.begin_sequence(scene) - + # Hide mouse and collapse other interactables BEFORE showing canvas get_tree().call_group("interactables", "collapse") Input.mouse_mode = Input.MOUSE_MODE_HIDDEN - + # Show the CanvasLayer so the story is visible full-screen canvas_layer.show() - + # Play the story await story_playable.play() - + # Hide the CanvasLayer when done canvas_layer.hide() - + # Restore mouse to captured mode (player controller will be given back control) Input.mouse_mode = Input.MOUSE_MODE_CAPTURED - + # Signal that the scene is finished Scenes.end_sequence(scene) - - if was_skipped: + + if was_skipped: scene_skipped.emit(-1) is_collected = true - + # Signal that playback is finished so the InteractiveSprite can restore player control playback_finished.emit()