chore: working towards a better inheritance and render order for mementos

This commit is contained in:
tiger tiger tiger 2026-01-05 16:04:59 +01:00
parent 1114f7f3c9
commit 7ec7552d0a
14 changed files with 368 additions and 560 deletions

View File

@ -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():

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

View File

@ -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()

View File

@ -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_scene_finished(scene_id: Scenes.id, _repeat: bool) -> void:
print_debug("YouthRoomScenePlayer._on_scene_finished(%s)" % Scenes.id.keys()[scene_id])
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:
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)

View File

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

View File

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

View File

@ -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)
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)
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
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)"
# 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)
Scenes.end_sequence(scene)
if was_skipped:
scene_skipped.emit(-1)
is_collected = true

View File

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

View File

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

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():
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

View File

@ -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):

View File

@ -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 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)
# 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.")
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
push_error(target, " requested focus while it was locked or tree is paused")
return
# 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
# 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
func reset_focus():
stage_list = [stage_list[-1]]
take_stage(target)
func transition_stage_to(thief: Object, lock_focus = false):
focus_locked = lock_focus
if stage_list.size() > 0:
if stage_list.front().has_stage:
stage_list.pop_front().has_stage = false
return pass_stage_to(thief, true)
func queue_for_stage(target: Object, index: int = 1):
# 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

View File

@ -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])
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.")
current_sequence = scene_id
started_sequences = started_sequences | (1 << scene_id)
# 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)
# Emit signal for other systems (music, animations, etc.)
scene_starting.emit(scene_id, is_sequence_repeating(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
# 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])
current_sequence_index += 1
# Emit signal before clearing state
scene_finished.emit(scene_id, is_sequence_repeating(scene_id))
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)
# Mark as completed
completed_sequences = completed_sequences | (1 << scene_id)
State.stage_list[0].has_stage = true
sequence_actors[current_sequence][current_sequence_index].call(current_sequence, is_sequence_repeating(current_sequence))
scene_continuing.emit(current_sequence, current_sequence_index, is_sequence_repeating(current_sequence))
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)
# Clear current sequence
if current_sequence == scene_id:
current_sequence = -1
current_sequence_index = 0
func is_sequence_repeating(index: int) -> bool: return completed_sequences & (1 << index) > 0
# 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)
func is_sequence_unlocked(index: id) -> bool: return (1 << int(index)) & enabled_sequences > 0
# 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])
# Legacy alias
func end_current_sequence() -> void:
if current_sequence != -1 and current_sequence < id.size():
end_sequence(id.values()[current_sequence])
# Legacy support - no longer needed
func continue_sequence(_former_actor: Object) -> void:
push_warning("continue_sequence is deprecated and does nothing.")
# 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.")
# 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.")
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:
var i: int = completed_sequences - ((completed_sequences >> 1) & 0x55555555);