tiger-cleanup #1

Merged
tiger merged 97 commits from tiger-cleanup into development 2026-01-15 14:54:23 +00:00
14 changed files with 368 additions and 560 deletions
Showing only changes of commit 7ec7552d0a - Show all commits

View File

@ -1,6 +1,9 @@
class_name YouthRoom class_name YouthRoom
extends RoomTemplate 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 board_trigger: InteractiveSprite = %MindBoard
@onready var door_trigger: InteractiveSprite = %Door @onready var door_trigger: InteractiveSprite = %Door
@onready var card_board: CardBoard = %Board @onready var card_board: CardBoard = %Board
@ -12,19 +15,32 @@ signal interaction(interactable: Object)
func start_room(): func start_room():
%UI.show() %UI.show()
$logic/PlayerController.process_mode = Node.PROCESS_MODE_INHERIT $logic/PlayerController.process_mode = Node.PROCESS_MODE_INHERIT
if not Scenes.is_sequence_repeating(Scenes.id.YOUTH_DRAEVEN): if not Scenes.is_sequence_repeating(Scenes.id.YOUTH_DRAEVEN):
Scenes.start_sequence(Scenes.id.YOUTH_DRAEVEN) # Play intro scene directly (not triggered by CollectableUi)
State.queue_for_stage(%PlayerController) await _play_intro_scene()
State.pass_stage_to(%PlayerController)
else: else:
State.pass_stage_to(%PlayerController) State.pass_stage_to(%PlayerController)
%LightAnimation.lights_on() %LightAnimation.lights_on()
while true: # playing?
var interactable = await interaction func _play_intro_scene() -> void:
if interactable is StoryPlayable: # The intro scene is auto-played, not triggered by CollectableUi
await interactable.play() var intro_playable: StoryPlayable = $logic/ScenePlayer/draven
# check gamestate to quit?
pass 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_game.is_childhood_board_complete = true
save_room()) 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() ui.hide()
$sfx/distant_rain.play() $sfx/distant_rain.play()
@ -73,11 +89,10 @@ func prepare_transition():
unload() 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") $AnimationPlayer.play("chest_reveal")
$visuals/SecondaryAnimation.play("chest_reveal") $visuals/SecondaryAnimation.play("chest_reveal")
await $AnimationPlayer.animation_finished
Scenes.continue_sequence(self)
func unload(): func unload():

View File

@ -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="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"] [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="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="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="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://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="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"] [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="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="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="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="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="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="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://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="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="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"] [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 blend_shape_mode = 0
shadow_mesh = SubResource("ArrayMesh_lag5h") shadow_mesh = SubResource("ArrayMesh_lag5h")
[sub_resource type="BoxShape3D" id="BoxShape3D_cb3g8"] [sub_resource type="ViewportTexture" id="ViewportTexture_ypa88"]
size = Vector3(2.31545, 2.13395, 0.0774798)
[sub_resource type="ViewportTexture" id="ViewportTexture_ghmim"]
viewport_path = NodePath("logic/MaskMemento/UiWrapper/UiSprite/SubViewport") 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 resource_local_to_scene = true
render_priority = 0 render_priority = 0
shader = ExtResource("25_dqyng") shader = ExtResource("25_dqyng")
shader_parameter/default_texture = SubResource("ViewportTexture_ghmim") shader_parameter/default_texture = SubResource("ViewportTexture_ypa88")
[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")
[sub_resource type="Animation" id="Animation_xum02"] [sub_resource type="Animation" id="Animation_xum02"]
length = 0.001 length = 0.001
@ -2016,308 +1969,27 @@ light_energy = 100.0
light_size = 20.0 light_size = 20.0
omni_range = 16.8518 omni_range = 16.8518
[node name="MaskMemento" type="Area3D" parent="logic" groups=["interactables"]] [node name="MaskMemento" parent="logic" instance=ExtResource("30_ypa88")]
unique_name_in_owner = true transform = Transform3D(-0.8630245, 0, 0.5051597, 0, 1, 0, -0.5051597, 0, -0.8630245, 0.0754588, 0.948372, 2.42068)
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="collectable_particles" parent="logic/MaskMemento" instance=ExtResource("12_qxx2k")] [node name="ClothesMemento" parent="logic" instance=ExtResource("30_ypa88")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00898492, -0.14171, 0.152755) 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"] [node name="ComicMemento" parent="logic" instance=ExtResource("30_ypa88")]
transform = Transform3D(0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, -0.134171, -0.20001, -0.000299692) transform = Transform3D(0.9699434, 0, 0.24332686, 0, 1, 0, -0.24332686, 0, 0.9699434, 2.91664, 0.595014, -0.75655603)
script = ExtResource("11_7uxd8")
[node name="UI_click_collider" type="CollisionShape3D" parent="logic/MaskMemento/UiWrapper"] [node name="CeilingMemento" parent="logic" instance=ExtResource("30_ypa88")]
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) transform = Transform3D(0.71489924, 0, 0.6992255, 0, 1, 0, -0.6992255, 0, 0.71489924, -0.13478619, 2.0720484, -0.42032808)
shape = SubResource("BoxShape3D_cb3g8")
[node name="UiSprite" type="Sprite3D" parent="logic/MaskMemento/UiWrapper"] [node name="MindBoard" parent="logic" instance=ExtResource("30_ypa88")]
transform = Transform3D(1, 0, -5.96046e-08, 0, 1, 0, 5.96046e-08, 0, 1, -3.4386, -0.143253, 0.433798) transform = Transform3D(-4.3711374e-08, 0, 0.9999984, 0, 1, 0, -0.9999984, 0, -4.3711374e-08, -0.907206, 1.17661, 1.74337)
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="logic/MaskMemento/UiWrapper/UiSprite"] [node name="UiSprite" parent="logic/MindBoard/UiWrapper" index="1"]
transparent_bg = true material_override = SubResource("ShaderMaterial_mhuct")
size = Vector2i(400, 350) texture = SubResource("ViewportTexture_ypa88")
render_target_update_mode = 4
[node name="CollectableUi" parent="logic/MaskMemento/UiWrapper/UiSprite/SubViewport" instance=ExtResource("25_ghmim")] [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="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="AnimationPlayer" type="AnimationPlayer" parent="."] [node name="AnimationPlayer" type="AnimationPlayer" parent="."]
libraries = { 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_button" method="hide"]
[connection signal="pressed" from="logic/UI/ending_button" to="logic/UI/ending" method="show"] [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="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"] [editable path="logic/MindBoard"]
[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"]

View File

@ -19,6 +19,7 @@ func focus_object():
func scene_starting(id: int, _repeat: bool): func scene_starting(id: int, _repeat: bool):
if id == Scenes.id.YOUTH_VOICE_TRAINING: 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 await get_tree().create_timer(10).timeout
focus_object() focus_object()

View File

@ -1,78 +1,53 @@
extends AnimationPlayer extends AnimationPlayer
var has_stage # This scene player now responds to scene signals to handle music and animations.
var is_repeating = false # The actual story playback is managed by CollectableUi directly.
func _ready() -> void: func _ready() -> void:
Scenes.scene_finished.connect(scene_finished) Scenes.scene_starting.connect(_on_scene_starting)
Scenes.scene_finished.connect(_on_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)
func start_soundtrack(): func start_soundtrack():
$Moving.play(70) $Moving.play(70)
$Childhood.play(70) $Childhood.play(70)
$VoiceTraining.play(70) $VoiceTraining.play(70)
func play_scene(id: int, repeat = false): func _on_scene_starting(scene_id: Scenes.id, _repeat: bool) -> void:
get_tree().call_group("interactables", "collapse") print_debug("YouthRoomScenePlayer._on_scene_starting(%s)" % Scenes.id.keys()[scene_id])
is_repeating = repeat
Input.mouse_mode = Input.MOUSE_MODE_HIDDEN # Handle scene-specific setup (music, chest animation, etc.)
match id: match scene_id:
Scenes.id.YOUTH_CHILDHOOD: Scenes.id.YOUTH_CHILDHOOD:
play("childhood_music") play("childhood_music")
$childhood.play()
Scenes.id.YOUTH_VOICE_TRAINING: Scenes.id.YOUTH_VOICE_TRAINING:
$voice_training.play()
play("voice_music") play("voice_music")
_play_chest_animation()
Scenes.id.YOUTH_JUI_JUTSU: Scenes.id.YOUTH_JUI_JUTSU:
play("jui_jutsu_music") play("jui_jutsu_music")
$JuiJutsu.play()
Scenes.id.YOUTH_DRAEVEN: Scenes.id.YOUTH_DRAEVEN:
play("draeven") play("draeven")
$draven.play()
func _on_scene_finished(scene_id: Scenes.id, _repeat: bool) -> void:
func on_childhood_done(): print_debug("YouthRoomScenePlayer._on_scene_finished(%s)" % Scenes.id.keys()[scene_id])
Scenes.continue_sequence(self)
$childhood.hide() match scene_id:
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:
Scenes.id.YOUTH_CHILDHOOD: Scenes.id.YOUTH_CHILDHOOD:
play_backwards("childhood_music") play_backwards("childhood_music")
Scenes.id.YOUTH_VOICE_TRAINING: Scenes.id.YOUTH_VOICE_TRAINING:
play_backwards("voice_music") play_backwards("voice_music")
queue("RESET") queue("RESET")
func play(anin_name: StringName = "", a: float = -1, b: float = 1, c: bool = false) -> void: func _play_chest_animation() -> void:
print_debug("anim player accessed!") # Navigate up to youth_room to trigger chest reveal animation
super.play(anin_name, a, b, c) 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)

View File

@ -21,10 +21,10 @@ var has_stage = false:
@onready var ancors: Array[Control] = [%Ancor1, %Ancor2, %Ancor3, %Ancor4] @onready var ancors: Array[Control] = [%Ancor1, %Ancor2, %Ancor3, %Ancor4]
func _ready(): 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) %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"] var random_card_names: Array = State.save_game.board_state["randoms"]
for card_name in random_card_names: for card_name in random_card_names:
@ -47,9 +47,7 @@ func burn_cards(_id):
$AnimationPlayer.play("vanish") $AnimationPlayer.play("vanish")
await $AnimationPlayer.animation_finished await $AnimationPlayer.animation_finished
Scenes.finish_sequence(self)
#Scenes.continue_sequence(self)
Scenes.end_current_sequence()
signal card_burned signal card_burned

View File

@ -250,7 +250,7 @@ func transition():
out_str.append(card.text if card.text != "" else "c_void") out_str.append(card.text if card.text != "" else "c_void")
cards_picked.emit(out_str) cards_picked.emit(out_str)
selection_state = DONE selection_state = DONE
Scenes.end_current_sequence() Scenes.finish_sequence(self)
func show_posts(): func show_posts():
for player:AnimationPlayer in anim_players: for player:AnimationPlayer in anim_players:
@ -282,7 +282,7 @@ func pick_cards(id: int, repeat: bool):
$Meaning.play() $Meaning.play()
else: else:
Scenes.end_current_sequence() Scenes.finish_sequence(self)
func play_scene(_id, _repeat): func play_scene(_id, _repeat):
pass pass

View File

@ -1,6 +1,10 @@
extends CenterContainer extends CenterContainer
class_name CollectableUi 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: @export var has_stage: bool = false:
set(focused): set(focused):
if has_stage == focused: return if has_stage == focused: return
@ -164,7 +168,7 @@ func _ready() -> void:
update_state() update_state()
func _on_context_updated(): func _on_context_updated() -> void:
%SkipButton.visible = State.allow_skipping %SkipButton.visible = State.allow_skipping
%SummaryButton.visible = State.provide_summaries %SummaryButton.visible = State.provide_summaries
%ReadStory.visible = is_collected %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 %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 cn_label.visible = true if State.show_content_notes else false
func update_state(): func update_state() -> void:
scene = scene scene = scene
is_board = is_board is_board = is_board
is_exit = is_exit is_exit = is_exit
@ -216,7 +220,7 @@ func _input(event: InputEvent) -> void:
is_expanded = true is_expanded = true
get_viewport().set_input_as_handled() get_viewport().set_input_as_handled()
func vanish(): func vanish() -> void:
if not visible: return if not visible: return
if is_expanded: if is_expanded:
@ -224,19 +228,38 @@ func vanish():
else: else:
animation_player.play("vanish") animation_player.play("vanish")
func collect_memento(): func collect_memento() -> void:
Scenes.start_sequence(scene) 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) State.leave_stage(self)
if scene == Scenes.id.TRANSITION: vanish() Scenes.end_sequence(scene)
#get_tree().call_group("scene_actors", "play_scene", scene, collected)
if was_skipped: scene_skipped.emit(-1) if was_skipped:
scene_skipped.emit(-1)
is_collected = true 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)

View File

@ -1 +1 @@
uid://bd5p820vwiphe uid://ct2503epxj4av

View File

@ -887,6 +887,7 @@ layout_mode = 2
alignment = 1 alignment = 1
[node name="CollectPrompt" type="TextureRect" parent="VBoxContainer/HBoxContainer"] [node name="CollectPrompt" type="TextureRect" parent="VBoxContainer/HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2 layout_mode = 2
texture = ExtResource("3_g0dpf") texture = ExtResource("3_g0dpf")
expand_mode = 2 expand_mode = 2
@ -982,3 +983,5 @@ libraries = {
&"": SubResource("AnimationLibrary_6fedj") &"": SubResource("AnimationLibrary_6fedj")
} }
autoplay = "init" autoplay = "init"
[node name="CanvasLayer" type="CanvasLayer" parent="."]

View File

@ -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"]

View File

@ -119,6 +119,10 @@ func try_scroll():
func play(): func play():
print_debug("StoryPlayable.gd: %s.play()" % self.name) print_debug("StoryPlayable.gd: %s.play()" % self.name)
# Show ourselves before playing
show()
scroll_target = 0 scroll_target = 0
# FIXME: find out why this needs to be set to prevent scenes from being fully revealed # FIXME: find out why this needs to be set to prevent scenes from being fully revealed

View File

@ -274,7 +274,7 @@ func play_scene(_id: int, _repeat: bool):
func scene_finished(_id, repeat: bool): func scene_finished(_id, repeat: bool):
if repeat: if repeat:
State.take_stage(self, true) State.take_stage(self)
func _on_bed_enter(_body): func _on_bed_enter(_body):
if not (crouched or on_crouch_cooldown): if not (crouched or on_crouch_cooldown):

View File

@ -251,90 +251,134 @@ func _ready():
#TODO: make this a bit more clean maybe? #TODO: make this a bit more clean maybe?
save_game = ResourceLoader.load("res://dev-util/debug_save.tres") save_game = ResourceLoader.load("res://dev-util/debug_save.tres")
if "has_stage" in child: if "has_stage" in child:
pass_stage_to(child) take_stage(child)
break break
music_volume = music_volume music_volume = music_volume
#region focus handling (called staging to avoid name colisions) #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 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. # Helper to safely set has_stage on an actor
func leave_stage(actor:Object) -> bool: func _set_actor_stage(actor: Object, value: bool) -> void:
print_debug("DEPRECATED: leave_stage ", actor); if is_instance_valid(actor) and "has_stage" in actor:
return false actor.has_stage = value
#if stage_list[0] == actor:
# actor.has_stage = false
# focus_locked = false
#stage_list.erase(actor)
#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. # Actor takes the stage (pushes to front of stack)
func pass_stage_to(target:Object, force = false, lock_focus = false) -> bool: func take_stage(actor: Object) -> void:
if "pass_to_actor" in target: print_debug(">>> take_stage(", actor, ")")
return pass_stage_to(target.pass_to_actor) assert(not focus_locked, "Focus is locked, %s cannot take focus." % actor)
if (focus_locked or get_tree().paused) and not force: assert(is_instance_valid(actor), "Cannot take stage with invalid actor")
push_error(target, " requested focus while it was locked or tree is paused.")
elif !is_instance_valid(target): # Remove actor if already in list (to re-add at front)
push_error("Focus instance not valid") if actor in stage_list:
elif !"has_stage" in target: stage_list.erase(actor)
push_error(target, " has no has focus method.")
else: # Remove stage from current front
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
if stage_list.size() > 0: if stage_list.size() > 0:
if stage_list.front().has_stage: _set_actor_stage(stage_list.front(), false)
stage_list.pop_front().has_stage = false
return pass_stage_to(thief, true) # 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) 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 #endregion
#region play state #region play state

View File

@ -1,13 +1,12 @@
extends Node extends Node
class_name SceneReference class_name SceneReference
var sequence_actors:Array[Array] = [] # State tracking
var started_sequences: int = 0 var started_sequences: int = 0
var completed_sequences: int = 0 var completed_sequences: int = 0
var enabled_sequences: int = 255: var enabled_sequences: int = 255:
set(stuff): pass set(stuff): pass
var current_sequence: int = -1 var current_sequence: int = -1
var current_sequence_index: int = 0
enum id { enum id {
YOUTH_DRAEVEN, YOUTH_DRAEVEN,
@ -25,58 +24,68 @@ enum id {
} }
signal scene_starting(scene_id: id, is_repeating: bool) 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) signal scene_finished(scene_id: id, is_repeating: bool)
func _ready() -> void: func _ready() -> void:
for i in range(id.keys().size()): pass
sequence_actors.append([null, null])
func sign_up_for_sequence(callable: Callable, sequence_id: id, index: int): # Called by CollectableUi when it starts playing a scene
if sequence_actors[sequence_id].size() <= index: func begin_sequence(scene_id: id) -> void:
sequence_actors[sequence_id].resize(index+1) print_debug(">>> Scenes.begin_sequence(%s)" % id.keys()[scene_id])
# if this assertion fails, two objects tried to sign up for the same sequence.
assert(sequence_actors[sequence_id][index] == null) current_sequence = scene_id
sequence_actors[sequence_id][index] = callable 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): # Called by CollectableUi when it finishes playing a scene
if State.pass_stage_to(sequence_actors[index][0].get_object()): func end_sequence(scene_id: id) -> void:
sequence_actors[index][0].call(index) print_debug(">>> Scenes.end_sequence(%s)" % id.keys()[scene_id])
current_sequence = index
started_sequences = started_sequences | (1 << index) # Emit signal before clearing state
scene_starting.emit(current_sequence, is_sequence_repeating(index)) scene_finished.emit(scene_id, is_sequence_repeating(scene_id))
else:
push_error("Sequence could not be started.") # 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. # Legacy support - redirects to begin_sequence
func continue_sequence(former_actor: Object): func start_sequence(scene_id: id) -> void:
# if this fails, pass next was called without a sequencce having been started. push_warning("start_sequence is deprecated. CollectableUi should call begin_sequence directly.")
assert(current_sequence != -1) begin_sequence(scene_id)
if former_actor == State.stage_list[0] and former_actor == sequence_actors[current_sequence][current_sequence_index].get_object(): # Legacy support - redirects to end_sequence
former_actor.has_stage = false 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() # Legacy support - no longer needed
print_debug(sequence_actors[current_sequence][current_sequence_index].get_object().name) 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(): func is_sequence_unlocked(index: id) -> bool:
State.leave_stage(State.stage_list[0]) return (1 << int(index)) & enabled_sequences > 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 get_completed_total() -> int: func get_completed_total() -> int:
var i: int = completed_sequences - ((completed_sequences >> 1) & 0x55555555); var i: int = completed_sequences - ((completed_sequences >> 1) & 0x55555555);