Compare commits

...

8 Commits

31 changed files with 363 additions and 867 deletions

View File

@ -15,7 +15,7 @@ func _ready() -> void:
func start_room(): func start_room():
save_game = State.save_game save_game = State.save_game
State.pass_stage_to(%PlayerController) %PlayerController.has_stage = true
on_first_station() on_first_station()
var left_first_station: bool = false var left_first_station: bool = false

View File

@ -19,7 +19,7 @@ func start_room():
save_room()) save_room())
%PlayerController.process_mode = Node.PROCESS_MODE_INHERIT %PlayerController.process_mode = Node.PROCESS_MODE_INHERIT
ini_room.emit() ini_room.emit()
State.pass_stage_to(%PlayerController) %PlayerController.has_stage = true
func _ready(): func _ready():
id = State.rooms.ADULTHOOD id = State.rooms.ADULTHOOD

View File

@ -1,5 +1,8 @@
class_name InteractiveSprite extends Area3D class_name InteractiveSprite extends Area3D
@export var interaction_ui: PackedScene = null
@export var is_board: bool = false
@onready var pass_to_actor: = $UiWrapper/UiSprite/SubViewport/CollectableUi @onready var pass_to_actor: = $UiWrapper/UiSprite/SubViewport/CollectableUi
@onready var wrapper := $UiWrapper @onready var wrapper := $UiWrapper
@onready var ui: CollectableUi = $UiWrapper/UiSprite/SubViewport.get_child(0) @onready var ui: CollectableUi = $UiWrapper/UiSprite/SubViewport.get_child(0)
@ -7,6 +10,7 @@ class_name InteractiveSprite extends Area3D
@onready var distance_tween: Tween @onready var distance_tween: Tween
var revealed: bool = false: var revealed: bool = false:
set(reveal): set(reveal):
revealed = reveal revealed = reveal
@ -30,10 +34,23 @@ var has_mouse: bool = false
# Called when the node enters the scene tree for the first time. # Called when the node enters the scene tree for the first time.
func _ready(): func _ready():
mouse_entered.connect(_on_mouse_entered) if interaction_ui:
%CanvasLayer.add_child(interaction_ui.instantiate())
ui.canvas_layer = %CanvasLayer
# Find and wire the StoryPlayable if not already set
for child in %CanvasLayer.get_children():
if child is StoryPlayable:
ui.story_playable = child
break
if child is CardBoard:
ui.is_board = true
# Connect playback_finished to restore player control
ui.playback_finished.connect(_on_playback_finished)
func _on_mouse_entered(): func _on_mouse_entered():
if not State.focus_locked: if not Scenes.is_playing:
input_ray_pickable = false input_ray_pickable = false
ui.is_collapsed = false ui.is_collapsed = false
has_mouse = true has_mouse = true
@ -58,5 +75,14 @@ func collapse():
_on_mouse_exited() _on_mouse_exited()
revealed = false revealed = false
func _on_playback_finished():
# Restore player controller control using the room's unique node reference
var player_controller = owner.get_node_or_null("%PlayerController")
if player_controller and "has_stage" in player_controller:
player_controller.has_stage = true
else:
# Fallback: ensure mouse is visible if we can't find player controller
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
func handle(event: InputEvent): func handle(event: InputEvent):
viewport.push_input(event) viewport.push_input(event)

View File

@ -1,30 +1,43 @@
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 # Reminder, do not uncomment, this field is inherited from RoomTemplate!
@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
@onready var card_picker: CardPicker = %Picker @onready var card_picker: CardPicker = %Picker
@onready var ui: Control = %UI @onready var ui: Control = %UI
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()
else: else:
State.pass_stage_to(%PlayerController)
%LightAnimation.lights_on() %LightAnimation.lights_on()
while true: # playing? # Give player control after intro (or immediately if repeating)
var interactable = await interaction %PlayerController.has_stage = true
if interactable is StoryPlayable:
await interactable.play()
# check gamestate to quit? func _play_intro_scene() -> void:
pass # The intro scene is auto-played, not triggered by CollectableUi
var intro_playable: StoryPlayable = $logic/ScenePlayer/draven
Scenes.begin_sequence(Scenes.id.YOUTH_DRAEVEN)
Input.mouse_mode = Input.MOUSE_MODE_HIDDEN
# Play the story (StoryPlayable handles its own visibility via animations)
await intro_playable.play()
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
Scenes.end_sequence(Scenes.id.YOUTH_DRAEVEN)
@ -36,7 +49,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,12 +86,17 @@ 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():
$visuals.queue_free() $visuals.queue_free()
func play_chest_animation(_id):
$AnimationPlayer.play("intro")
await $AnimationPlayer.animation_finished
Scenes.continue_sequence(self)

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=135 format=4 uid="uid://b3b0gyvklqn50"] [gd_scene load_steps=117 format=4 uid="uid://b3b0gyvklqn50"]
[ext_resource type="Script" uid="uid://bsop46tqngddc" path="res://base-environments/youth_room/youth_room.gd" id="1_aitp0"] [ext_resource type="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,10 @@
[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="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"]
@ -165,14 +160,6 @@ func show():
script/source = "extends CenterContainer script/source = "extends CenterContainer
var has_stage var has_stage
func _ready() -> void:
Scenes.sign_up_for_sequence(play_chest_animation, Scenes.id.YOUTH_DRAEVEN, 0)
func play_chest_animation(_id):
$AnimationPlayer.play(\"intro\")
await $AnimationPlayer.animation_finished
Scenes.continue_sequence(self)
" "
[sub_resource type="Animation" id="Animation_ks23q"] [sub_resource type="Animation" id="Animation_ks23q"]
@ -268,192 +255,144 @@ tracks/2/keys = {
tracks/3/type = "value" tracks/3/type = "value"
tracks/3/imported = false tracks/3/imported = false
tracks/3/enabled = true tracks/3/enabled = true
tracks/3/path = NodePath("ScenePlayer/childhood/PanelContainer:self_modulate") tracks/3/path = NodePath("ScenePlayer/OmniLight3D:light_energy")
tracks/3/interp = 1 tracks/3/interp = 1
tracks/3/loop_wrap = true tracks/3/loop_wrap = true
tracks/3/keys = { tracks/3/keys = {
"times": PackedFloat32Array(0), "times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1), "transitions": PackedFloat32Array(1),
"update": 0, "update": 0,
"values": [Color(1, 1, 1, 1)] "values": [0.0]
} }
tracks/4/type = "value" tracks/4/type = "value"
tracks/4/imported = false tracks/4/imported = false
tracks/4/enabled = true tracks/4/enabled = true
tracks/4/path = NodePath("ScenePlayer/childhood:visible") tracks/4/path = NodePath("ScenePlayer/starlight_mesh/starlight_ambient:light_energy")
tracks/4/interp = 1 tracks/4/interp = 1
tracks/4/loop_wrap = true tracks/4/loop_wrap = true
tracks/4/keys = { tracks/4/keys = {
"times": PackedFloat32Array(0), "times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1), "transitions": PackedFloat32Array(1),
"update": 1, "update": 0,
"values": [false] "values": [0.2]
} }
tracks/5/type = "value" tracks/5/type = "value"
tracks/5/imported = false tracks/5/imported = false
tracks/5/enabled = true tracks/5/enabled = true
tracks/5/path = NodePath("ScenePlayer/OmniLight3D:light_energy") tracks/5/path = NodePath("ScenePlayer/starlight_mesh:visible")
tracks/5/interp = 1 tracks/5/interp = 1
tracks/5/loop_wrap = true tracks/5/loop_wrap = true
tracks/5/keys = { tracks/5/keys = {
"times": PackedFloat32Array(0), "times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1), "transitions": PackedFloat32Array(1),
"update": 0, "update": 0,
"values": [0.0] "values": [true]
} }
tracks/6/type = "value" tracks/6/type = "value"
tracks/6/imported = false tracks/6/imported = false
tracks/6/enabled = true tracks/6/enabled = true
tracks/6/path = NodePath("ScenePlayer/starlight_mesh/starlight_ambient:light_energy") tracks/6/path = NodePath("ScenePlayer/starlight_mesh/starlight_lamp_dynamic:light_energy")
tracks/6/interp = 1 tracks/6/interp = 1
tracks/6/loop_wrap = true tracks/6/loop_wrap = true
tracks/6/keys = { tracks/6/keys = {
"times": PackedFloat32Array(0), "times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1), "transitions": PackedFloat32Array(1),
"update": 0, "update": 0,
"values": [0.2] "values": [2.0]
} }
tracks/7/type = "value" tracks/7/type = "value"
tracks/7/imported = false tracks/7/imported = false
tracks/7/enabled = true tracks/7/enabled = true
tracks/7/path = NodePath("ScenePlayer/starlight_mesh:visible") tracks/7/path = NodePath("ScenePlayer/Luna_frame-of-mind:visible")
tracks/7/interp = 1 tracks/7/interp = 1
tracks/7/loop_wrap = true tracks/7/loop_wrap = true
tracks/7/keys = { tracks/7/keys = {
"times": PackedFloat32Array(0), "times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1), "transitions": PackedFloat32Array(1),
"update": 0, "update": 0,
"values": [true] "values": [false]
} }
tracks/8/type = "value" tracks/8/type = "value"
tracks/8/imported = false tracks/8/imported = false
tracks/8/enabled = true tracks/8/enabled = true
tracks/8/path = NodePath("ScenePlayer/starlight_mesh/starlight_lamp_dynamic:light_energy") tracks/8/path = NodePath("ScenePlayer/Luna_frame-of-mind:rotation")
tracks/8/interp = 1 tracks/8/interp = 1
tracks/8/loop_wrap = true tracks/8/loop_wrap = true
tracks/8/keys = { tracks/8/keys = {
"times": PackedFloat32Array(0), "times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1), "transitions": PackedFloat32Array(1),
"update": 0, "update": 0,
"values": [2.0] "values": [Vector3(0, 0.2877, 0)]
} }
tracks/9/type = "value" tracks/9/type = "value"
tracks/9/imported = false tracks/9/imported = false
tracks/9/enabled = true tracks/9/enabled = true
tracks/9/path = NodePath("ScenePlayer/Luna_frame-of-mind:visible") tracks/9/path = NodePath("ScenePlayer/Luna_frame-of-mind:position")
tracks/9/interp = 1 tracks/9/interp = 1
tracks/9/loop_wrap = true tracks/9/loop_wrap = true
tracks/9/keys = { tracks/9/keys = {
"times": PackedFloat32Array(0), "times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1), "transitions": PackedFloat32Array(1),
"update": 0, "update": 0,
"values": [false] "values": [Vector3(-10.1552, 14.9384, -16.2182)]
} }
tracks/10/type = "value" tracks/10/type = "value"
tracks/10/imported = false tracks/10/imported = false
tracks/10/enabled = true tracks/10/enabled = true
tracks/10/path = NodePath("ScenePlayer/Luna_frame-of-mind:rotation") tracks/10/path = NodePath("ScenePlayer/material_handle:material:shader_parameter/alpha_scissor_threshold")
tracks/10/interp = 1 tracks/10/interp = 1
tracks/10/loop_wrap = true tracks/10/loop_wrap = true
tracks/10/keys = { tracks/10/keys = {
"times": PackedFloat32Array(0), "times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1), "transitions": PackedFloat32Array(1),
"update": 0, "update": 0,
"values": [Vector3(0, 0.2877, 0)] "values": [-0.3]
} }
tracks/11/type = "value" tracks/11/type = "value"
tracks/11/imported = false tracks/11/imported = false
tracks/11/enabled = true tracks/11/enabled = true
tracks/11/path = NodePath("ScenePlayer/Luna_frame-of-mind:position") tracks/11/path = NodePath("ScenePlayer/material_handle:material:shader_parameter/alpha_offset")
tracks/11/interp = 1 tracks/11/interp = 1
tracks/11/loop_wrap = true tracks/11/loop_wrap = true
tracks/11/keys = { tracks/11/keys = {
"times": PackedFloat32Array(0), "times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1), "transitions": PackedFloat32Array(1),
"update": 0, "update": 0,
"values": [Vector3(-10.1552, 14.9384, -16.2182)] "values": [-1.0]
} }
tracks/12/type = "value" tracks/12/type = "value"
tracks/12/imported = false tracks/12/imported = false
tracks/12/enabled = true tracks/12/enabled = true
tracks/12/path = NodePath("ScenePlayer/material_handle:material:shader_parameter/alpha_scissor_threshold") tracks/12/path = NodePath("ScenePlayer/Jui_Jutsu:volume_db")
tracks/12/interp = 1 tracks/12/interp = 1
tracks/12/loop_wrap = true tracks/12/loop_wrap = true
tracks/12/keys = { tracks/12/keys = {
"times": PackedFloat32Array(0), "times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1), "transitions": PackedFloat32Array(1),
"update": 0, "update": 0,
"values": [-0.3] "values": [0.0]
} }
tracks/13/type = "value" tracks/13/type = "value"
tracks/13/imported = false tracks/13/imported = false
tracks/13/enabled = true tracks/13/enabled = true
tracks/13/path = NodePath("ScenePlayer/material_handle:material:shader_parameter/alpha_offset") tracks/13/path = NodePath("%ScenePlayer/Moving:volume_db")
tracks/13/interp = 1 tracks/13/interp = 1
tracks/13/loop_wrap = true tracks/13/loop_wrap = true
tracks/13/keys = { tracks/13/keys = {
"times": PackedFloat32Array(0), "times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1), "transitions": PackedFloat32Array(1),
"update": 0, "update": 0,
"values": [-1.0] "values": [0.0]
} }
tracks/14/type = "value" tracks/14/type = "value"
tracks/14/imported = false tracks/14/imported = false
tracks/14/enabled = true tracks/14/enabled = true
tracks/14/path = NodePath("ScenePlayer/Jui_Jutsu:volume_db") tracks/14/path = NodePath("%ScenePlayer/OmniLight3D:visible")
tracks/14/interp = 1 tracks/14/interp = 1
tracks/14/loop_wrap = true tracks/14/loop_wrap = true
tracks/14/keys = { tracks/14/keys = {
"times": PackedFloat32Array(0), "times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1), "transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.0]
}
tracks/15/type = "value"
tracks/15/imported = false
tracks/15/enabled = true
tracks/15/path = NodePath("%ScenePlayer/JuiJutsu:visible")
tracks/15/interp = 1
tracks/15/loop_wrap = true
tracks/15/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/16/type = "value"
tracks/16/imported = false
tracks/16/enabled = true
tracks/16/path = NodePath("%ScenePlayer/childhood:visible")
tracks/16/interp = 1
tracks/16/loop_wrap = true
tracks/16/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/17/type = "value"
tracks/17/imported = false
tracks/17/enabled = true
tracks/17/path = NodePath("%ScenePlayer/Moving:volume_db")
tracks/17/interp = 1
tracks/17/loop_wrap = true
tracks/17/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.0]
}
tracks/18/type = "value"
tracks/18/imported = false
tracks/18/enabled = true
tracks/18/path = NodePath("%ScenePlayer/OmniLight3D:visible")
tracks/18/interp = 1
tracks/18/loop_wrap = true
tracks/18/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1, "update": 1,
"values": [false] "values": [false]
} }
@ -930,58 +869,6 @@ _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"]
size = Vector3(2.31545, 2.13395, 0.0774798)
[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("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")
[sub_resource type="Animation" id="Animation_xum02"] [sub_resource type="Animation" id="Animation_xum02"]
length = 0.001 length = 0.001
tracks/0/type = "value" tracks/0/type = "value"
@ -1922,26 +1809,14 @@ stream = ExtResource("9_i8mqk")
volume_db = -80.0 volume_db = -80.0
bus = &"music" bus = &"music"
[node name="childhood" parent="logic/ScenePlayer" instance=ExtResource("12_viwxf")]
[node name="VoiceTraining" type="AudioStreamPlayer" parent="logic/ScenePlayer"] [node name="VoiceTraining" type="AudioStreamPlayer" parent="logic/ScenePlayer"]
stream = ExtResource("10_wwwdq") stream = ExtResource("10_wwwdq")
volume_db = -80.0 volume_db = -80.0
bus = &"music" bus = &"music"
[node name="JuiJutsu" parent="logic/ScenePlayer" instance=ExtResource("12_x3dlb")]
[node name="voice_training" parent="logic/ScenePlayer" instance=ExtResource("13_v3447")]
story_array = []
paragraph_lengths = [1]
[node name="Jui_Jutsu" type="AudioStreamPlayer" parent="logic/ScenePlayer"] [node name="Jui_Jutsu" type="AudioStreamPlayer" parent="logic/ScenePlayer"]
bus = &"music" bus = &"music"
[node name="draven" parent="logic/ScenePlayer" instance=ExtResource("19_d3c7p")]
story_array = []
paragraph_lengths = [1]
[node name="starlight_mesh" type="MeshInstance3D" parent="logic/ScenePlayer"] [node name="starlight_mesh" type="MeshInstance3D" parent="logic/ScenePlayer"]
transform = Transform3D(0.999, 0, 0, 0, 0.999, 0, 0, 0, 0.999, 0, 0, 0) transform = Transform3D(0.999, 0, 0, 0, 0.999, 0, 0, 0, 0.999, 0, 0, 0)
layers = 2 layers = 2
@ -2016,308 +1891,30 @@ 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")]
transform = Transform3D(-0.8630245, 0, 0.5051597, 0, 1, 0, -0.5051597, 0, -0.8630245, 0.0754588, 0.948372, 2.42068)
interaction_ui = ExtResource("12_viwxf")
[node name="ClothesMemento" parent="logic" instance=ExtResource("30_ypa88")]
transform = Transform3D(0.8604294, 0, -0.5095667, 0, 1, 0, 0.5095667, 0, 0.8604294, 1.3658599, 1.17096, -0.6365988)
interaction_ui = ExtResource("12_x3dlb")
[node name="ComicMemento" parent="logic" instance=ExtResource("30_ypa88")]
transform = Transform3D(0.9699434, 0, 0.24332686, 0, 1, 0, -0.24332686, 0, 0.9699434, 2.91664, 0.595014, -0.75655603)
interaction_ui = ExtResource("13_v3447")
[node name="CeilingMemento" parent="logic" instance=ExtResource("30_ypa88")]
transform = Transform3D(0.71489924, 0, 0.6992255, 0, 1, 0, -0.6992255, 0, 0.71489924, -0.13478619, 2.0720484, -0.42032808)
interaction_ui = ExtResource("19_d3c7p")
[node name="MindBoard" parent="logic" instance=ExtResource("30_ypa88")]
unique_name_in_owner = true 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) transform = Transform3D(-4.3711374e-08, 0, 0.9999984, 0, 1, 0, -0.9999984, 0, -4.3711374e-08, -0.907206, 1.17661, 1.74337)
collision_layer = 16 interaction_ui = ExtResource("4_gyjxx")
collision_mask = 0
script = ExtResource("11_6fwv8")
[node name="collectable_particles" parent="logic/MaskMemento" instance=ExtResource("12_qxx2k")] [node name="Door" parent="logic" instance=ExtResource("30_ypa88")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00898492, -0.14171, 0.152755)
[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="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="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="SubViewport" type="SubViewport" parent="logic/MaskMemento/UiWrapper/UiSprite"]
transparent_bg = true
size = Vector2i(400, 350)
render_target_update_mode = 4
[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 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) transform = Transform3D(0.9999984, 0, 4.973797e-14, 0, 1, 0, -4.973797e-14, 0, 0.9999984, 0.115203, 1.3931, -0.954428)
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 = {
@ -2577,16 +2174,3 @@ data = ExtResource("40_ea6x8")
[connection signal="body_exited" from="logic/Bed and Ladders/reset_failover" to="logic/PlayerController" method="_on_bed_exit"] [connection signal="body_exited" from="logic/Bed and Ladders/reset_failover" to="logic/PlayerController" method="_on_bed_exit"]
[connection signal="pressed" from="logic/UI/ending_button" to="logic/UI/ending_button" method="hide"] [connection signal="pressed" from="logic/UI/ending_button" to="logic/UI/ending_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="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"]

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:
print_debug("YouthRoomScenePlayer._on_scene_finished(%s)" % Scenes.id.keys()[scene_id])
func on_childhood_done(): match scene_id:
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:
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

@ -19,7 +19,7 @@ func create_bug_report():
Current Focus: %s Current Focus: %s
Current Scene: %s Current Scene: %s
Mementos: %s Mementos: %s
""" % [OS.get_name(), OS.get_video_adapter_driver_info(), State.stage_list, State.current_room, Scenes.completed_sequences] """ % [OS.get_name(), OS.get_video_adapter_driver_info(), Scenes.current_sequence, State.current_room, Scenes.completed_sequences]
#debug_text = debug_text.replace(" ", "%20").replace("\n", "%0A").replace("\t", "") #debug_text = debug_text.replace(" ", "%20").replace("\n", "%0A").replace("\t", "")

View File

@ -22,7 +22,7 @@ func _input(event: InputEvent) -> void:
# viewport.push_input(event) # viewport.push_input(event)
func _on_input_event(_camera: Camera3D, event: InputEvent, pos: Vector3, _normal: Vector3, _shape_idx: int): func _on_input_event(_camera: Camera3D, event: InputEvent, pos: Vector3, _normal: Vector3, _shape_idx: int):
if not State.focus_locked: if not Scenes.is_playing:
# Position of the event in Sprite3D local coordinates. # Position of the event in Sprite3D local coordinates.
var texture_3d_position := sprite.get_global_transform().affine_inverse() * pos var texture_3d_position := sprite.get_global_transform().affine_inverse() * pos
#if !is_zero_approx(texture_3d_position.z): #if !is_zero_approx(texture_3d_position.z):

View File

@ -23,6 +23,9 @@ func disable()-> void:
set_process_input(false) set_process_input(false)
set_process(false) set_process(false)
func get_ready():
pass
func load(): func load():
# Override this function to load the state of the chapter from State.save_game # Override this function to load the state of the chapter from State.save_game
pass pass
@ -32,9 +35,6 @@ func play() -> String:
return await proceed return await proceed
func get_ready():
pass
func start_room(): func start_room():
pass pass

View File

@ -8,6 +8,8 @@ enum Error {
MISSING MISSING
} }
const is_board := true
var focus_stickies:bool = true: var focus_stickies:bool = true:
set(stickies): set(stickies):
if not is_node_ready(): return if not is_node_ready(): return
@ -408,7 +410,7 @@ func _input(event) -> void:
if not has_stage or not is_instance_valid(currently_active_node): return if not has_stage or not is_instance_valid(currently_active_node): return
if event.is_action_pressed("ui_cancel"): if event.is_action_pressed("ui_cancel"):
State.leave_stage(self) has_stage = false
get_viewport().set_input_as_handled() get_viewport().set_input_as_handled()
if event is InputEventMouse: if event is InputEventMouse:
@ -568,7 +570,7 @@ func on_scene_skipped(i: int):
mementos_collected += i # FIXME: sometimes -1 is passed here, why? mementos_collected += i # FIXME: sometimes -1 is passed here, why?
func claim_focus(): func claim_focus():
State.pass_stage_to(self) has_stage = true
func find_first_free_card() -> int: func find_first_free_card() -> int:
for i in range(dropzone.get_child_count()): for i in range(dropzone.get_child_count()):

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) # Note: burn_cards is now called directly by the transition system, not via register_scene_actor
%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

@ -59,30 +59,6 @@ signal cards_picked(cardnames: Array[String])
# Called when the node enters the scene tree for the first time. # Called when the node enters the scene tree for the first time.
func _ready() -> void: func _ready() -> void:
reset() reset()
return
#
# #FIXME: can I make this less annoying somehow?
# if State.onready_room == State.rooms.YOUTH:
# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.YOUTH_DRAEVEN, 2)
# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.YOUTH_CHILDHOOD, 1)
# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.YOUTH_VOICE_TRAINING, 2)
# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.YOUTH_JUI_JUTSU, 1)
# elif State.onready_room == State.rooms.ADULTHOOD:
# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.ADULT_DND, 1)
# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.ADULT_VOLUNTARY, 1)
# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.ADULT_CHRISTMAS, 1)
# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.ADULT_EATING, 1)
# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.ADULT_UNI, 1)
# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.ADULT_THERAPY, 1)
# Scenes.sign_up_for_sequence(pick_cards, Scenes.id.ADULT_BURNOUT, 1)
# else:
# assert(false, "Not Implemented")
#
# if get_tree().root == self.get_parent():
# pick_cards(3, false)
# State.take_stage(self)
#
# reset()
func reset(): func reset():
card_anim_skipped = false card_anim_skipped = false
@ -250,7 +226,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:
@ -276,13 +252,12 @@ func pick_cards(id: int, repeat: bool):
if not repeat: if not repeat:
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
fill_card_slots(id) fill_card_slots(id)
#State.transition_stage_to(self, true)
selection_state = CARDS selection_state = CARDS
if id == Scenes.id.YOUTH_DRAEVEN and not repeat: if id == Scenes.id.YOUTH_DRAEVEN and not repeat:
$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,12 @@
extends CenterContainer extends CenterContainer
class_name CollectableUi class_name CollectableUi
@onready var canvas_layer: CanvasLayer = %CanvasLayer
## The StoryPlayable to play when this memento is collected.
## Auto-discovered from the owner's %CanvasLayer, or can be set manually.
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
@ -14,23 +20,6 @@ class_name CollectableUi
get_viewport().gui_release_focus() get_viewport().gui_release_focus()
is_collapsed = true is_collapsed = true
#@export var collapsed = true:
# set(collapse):
# if is_inside_tree() and not Engine.is_editor_hint():
# if State.reduce_motion:
# collapsed = false
# return
# if collapse and not collapsed:
# if is_inside_tree():
# _hide_buttons()
# collapsed = collapse
# elif not collapse and collapsed:
# if is_inside_tree():
# _show_buttons()
# collapsed = collapse
#
# if collapse and has_stage: State.leave_stage(self)
@export var scene: Scenes.id = Scenes.id.YOUTH_DRAEVEN: @export var scene: Scenes.id = Scenes.id.YOUTH_DRAEVEN:
set(id): set(id):
scene = id scene = id
@ -138,6 +127,7 @@ class_name CollectableUi
else: else:
scene = scene scene = scene
collected_box.show() collected_box.show()
@export var is_exit:bool = false: @export var is_exit:bool = false:
set(exit): set(exit):
is_exit = exit is_exit = exit
@ -153,6 +143,7 @@ class_name CollectableUi
signal open_board signal open_board
signal exit_room signal exit_room
signal playback_finished
#TODO implement proper scene skipping #TODO implement proper scene skipping
signal scene_skipped(i: int) signal scene_skipped(i: int)
@ -164,7 +155,8 @@ 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 +164,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 +208,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 +216,46 @@ 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])
State.leave_stage(self)
if scene == Scenes.id.TRANSITION: vanish() # Hide the collectable UI
#get_tree().call_group("scene_actors", "play_scene", scene, collected) vanish()
if was_skipped: scene_skipped.emit(-1)
# 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
playback_finished.emit()
return
# Signal that a scene is starting (for music, etc.)
Scenes.begin_sequence(scene)
# Hide mouse and collapse other interactables BEFORE showing canvas
get_tree().call_group("interactables", "collapse")
Input.mouse_mode = Input.MOUSE_MODE_HIDDEN
# Show the CanvasLayer so the story is visible full-screen
canvas_layer.show()
# Play the story
await story_playable.play()
# Hide the CanvasLayer when done
canvas_layer.hide()
# Restore mouse to captured mode (player controller will be given back control)
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
# Signal that the scene is finished
Scenes.end_sequence(scene)
if was_skipped:
scene_skipped.emit(-1)
is_collected = true is_collected = true
func _on_skip_pressed(): # Signal that playback is finished so the InteractiveSprite can restore player control
print_debug("Scene skipped!") playback_finished.emit()
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,69 @@
[gd_scene load_steps=10 format=3 uid="uid://cy4yesucptcr3"]
[ext_resource type="Script" uid="uid://dr4wd80dobxjd" path="res://base-environments/youth_room/interactive_sprite.gd" id="1_v8gd7"]
[ext_resource type="PackedScene" uid="uid://bdnesuqroi7ss" path="res://vfx/collectable_particles.tscn" id="2_lqlgh"]
[ext_resource type="Script" uid="uid://dbdw3v7mbqscf" path="res://dev-util/click-trough-area.gd" id="3_1fk5i"]
[ext_resource type="Script" uid="uid://cdjjn1jx1fdeb" path="res://logic-scenes/interactive_sprite/ui_sprite.gd" id="4_uwc8q"]
[ext_resource type="PackedScene" uid="uid://wfyna16xhlo0" path="res://logic-scenes/collectable/collectable_ui.tscn" id="5_kqyl2"]
[ext_resource type="Texture2D" uid="uid://d0ucjqi8tx6vt" path="res://import/interface-elements/frame.png" id="6_13pus"]
[sub_resource type="BoxShape3D" id="BoxShape3D_v8gd7"]
[sub_resource type="ViewportTexture" id="ViewportTexture_uwc8q"]
viewport_path = NodePath("UiWrapper/UiSprite/SubViewport")
[sub_resource type="BoxShape3D" id="BoxShape3D_uwc8q"]
size = Vector3(1, 1, 0.14892578)
[node name="Memento" type="Area3D" groups=["interactables"]]
transform = Transform3D(0.9999994, 0, 0, 0, 1, 0, 0, 0, 0.9999994, 0, 0, 0)
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"]
gi_mode = 0
modulate = Color(0.9999996, 0.96863645, 0.88173, 1)
pixel_size = 0.015
no_depth_test = true
texture = SubResource("ViewportTexture_uwc8q")
script = ExtResource("4_uwc8q")
[node name="SubViewport" type="SubViewport" parent="UiWrapper/UiSprite"]
unique_name_in_owner = true
transparent_bg = true
size = Vector2i(400, 350)
render_target_update_mode = 4
[node name="CollectableUi" parent="UiWrapper/UiSprite/SubViewport" instance=ExtResource("5_kqyl2")]
[node name="Frame" type="Sprite3D" parent="UiWrapper"]
transform = Transform3D(0.7045709, 0, -1.1920898e-07, 0, 0.704571, 0, 1.1920898e-07, 0, 0.7045709, 0, -1, 0)
visibility_range_end = 0.6
visibility_range_end_margin = 0.3
visibility_range_fade_mode = 1
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.060790993)
shape = SubResource("BoxShape3D_uwc8q")
[node name="CanvasLayer" type="CanvasLayer" parent="."]
unique_name_in_owner = true
visible = false
[connection signal="input_event" from="UiWrapper" to="UiWrapper" method="_on_input_event"]

View File

@ -0,0 +1,4 @@
extends Sprite3D
func _ready() -> void:
pass

View File

@ -0,0 +1 @@
uid://cdjjn1jx1fdeb

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

@ -116,7 +116,11 @@ func _process(_delta):
#emit_signal("ui_exited") #emit_signal("ui_exited")
#dhas_entered = false #dhas_entered = false
if Input.is_action_just_pressed("ui_accept"): if Input.is_action_just_pressed("ui_accept"):
State.pass_stage_to(focus_ray.get_collider()) # Pass focus to the collider if it has has_stage property
var collider = focus_ray.get_collider()
if collider and "has_stage" in collider:
has_stage = false
collider.has_stage = true
else: else:
camera.fov = base_fov / (1 + Input.get_action_raw_strength("zoom_in_controller")) camera.fov = base_fov / (1 + Input.get_action_raw_strength("zoom_in_controller"))
@ -274,7 +278,7 @@ func play_scene(_id: int, _repeat: bool):
func scene_finished(_id, repeat: bool): func scene_finished(_id, repeat: bool):
if repeat: if repeat:
State.take_stage(self, true) has_stage = true
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

@ -250,93 +250,9 @@ func _ready():
push_warning("Room initialised without a SaveGame. Creating proxy save.") push_warning("Room initialised without a SaveGame. Creating proxy save.")
#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:
pass_stage_to(child)
break
music_volume = music_volume music_volume = music_volume
#region focus handling (called staging to avoid name colisions)
# CAUTION: scene_reference directly accesses stage list to play sequences.
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)
#if stage_list != []:
# stage_list.front().has_stage = true
#else:
# get_tree().quit()
#return false
# Used to put a new target on top of the Focus Stack.
func pass_stage_to(target:Object, force = false, lock_focus = false) -> bool:
if "pass_to_actor" in target:
return pass_stage_to(target.pass_to_actor)
if (focus_locked or get_tree().paused) and not force:
push_error(target, " requested focus while it was locked or tree is paused.")
elif !is_instance_valid(target):
push_error("Focus instance not valid")
elif !"has_stage" in target:
push_error(target, " has no has focus method.")
else:
if stage_list.size() > 0:
if stage_list.front() == target:
push_warning(target, " is already target. Abort passing focus.")
return false
if not stage_list.size() == 0: stage_list.front().has_stage = false
target.has_stage = true
if target.has_stage:
stage_list.push_front(target)
assert(stage_list.size() < 100)
focus_locked = lock_focus
return true
return false
# Currently focused element loses focus, but remains in stack.
func free_focus():
if focus_locked: return false
if stage_list.size() > 0: stage_list.front().has_stage = false
func reset_focus():
stage_list = [stage_list[-1]]
func transition_stage_to(thief: Object, lock_focus = false):
focus_locked = lock_focus
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):
stage_list.insert(index, target)
#endregion
#region play state #region play state
enum rooms { enum rooms {

View File

@ -91,6 +91,7 @@ func _load_room(next_path: String) -> bool:
ResourceLoader.THREAD_LOAD_LOADED: ResourceLoader.THREAD_LOAD_LOADED:
var next_scene := ResourceLoader.load_threaded_get(youth_room_path) as PackedScene var next_scene := ResourceLoader.load_threaded_get(youth_room_path) as PackedScene
State.room = next_scene.instantiate() as RoomTemplate State.room = next_scene.instantiate() as RoomTemplate
await get_tree().process_frame
get_tree().root.add_child(State.room) get_tree().root.add_child(State.room)
await State.room.get_ready() await State.room.get_ready()
%Loading.stop() %Loading.stop()
@ -115,113 +116,3 @@ func _unhandled_input(event: InputEvent) -> void:
AppState.PAUSE: AppState.PAUSE:
if event.is_action_pressed("ui_menu"): if event.is_action_pressed("ui_menu"):
app_state = AppState.PLAY app_state = AppState.PLAY
# if not get_tree().paused:
# get_tree().paused = true
# var state_machine := menu_animation["parameters/playback"]
# state_machine.travel("reveal_pause_menu")
# Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
# else:
# get_tree().paused = false
# var state_machine := menu_animation["parameters/playback"]
# state_machine.travel("start_game")
#
# if State.stage_list[0] is Player:
# Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
#func debug_youth():
# get_child(1).hide()
# get_child(2).hide()
# get_child(3).hide()
# get_child(0).get_ready()
# get_child(0).start()
#
#func _return_to_menu():
# State.active_save_game = null
#
# menu_animation["parameters/conditions/start_game"] = false
#
# State.pass_stage_to(main_menu)
#
# currently_loading_room = get_room_path_from_id(main_menu.save_game_handle.get_most_recent_save().current_room)
#
# menu_animation["parameters/conditions/return_to_menu"] = true
# await(get_tree().create_timer(0.5).timeout)
# menu_animation["parameters/conditions/return_to_menu"] = false
# _on_ready_to_unload()
#
#func load_save(save: SaveGame):
#
# if currently_loading_room != "":
# await(room_loaded)
#
# if save.current_room != current_room.id:
# # TODO Prevent race condition from appearing when save is loaded while room is still loading.
# currently_loading_room = get_room_path_from_id(save.current_room)
# await(room_loaded)
#
# menu_animation["parameters/conditions/start_game"] = true
#
# State.active_save_game = save
# in_game = true
# current_room.start_room()
#
#func _on_ready_to_unload():
# if get_child(0) is Node3D:
# get_child(0).free()
#
#func get_room_path_from_id(id: State.rooms) -> String:
# match id:
# State.rooms.YOUTH, State.rooms.NULL:
# return youth_room_path
# State.rooms.TRANSITION:
# return transition_room_path
# State.rooms.ADULTHOOD:
# return adulthood_room_path
# _:
# return ending_path
#
#func get_room_id_from_path(path: String) -> State.rooms:
# match path:
# youth_room_path:
# return State.rooms.YOUTH
# transition_room_path:
# return State.rooms.TRANSITION
# adulthood_room_path:
# return State.rooms.ADULTHOOD
# _:
# return State.rooms.NULL
#
#
#func start_demo():
# #FIXME this causes the room to reload
# #load_save(SaveGame.new())
# current_room.start_room()
# in_game = true
#
#func pause_mode_changed():
# print_debug(get_tree().paused)
#
#var await_swap: bool = false
#func prepare_transition(scene_id: Scenes.id, _repeat):
# if scene_id == Scenes.id.TRANSITION:
# await_swap = true
# #FIXME: this does not need to be part of the sequence
# await(get_tree().process_frame)
# current_room.prepare_transition()
# if not _repeat:
# currently_loading_room = get_room_path_from_id(State.rooms.TRANSITION)
# else:
#
# currently_loading_room = get_room_path_from_id(State.rooms.ADULTHOOD)
#
#func transition(scene_id: Scenes.id, _repeat):
# if scene_id == Scenes.id.TRANSITION:
# State.reset_focus()
# await_swap = false
# await room_loaded
# if not _repeat:
# State.queue_for_stage(current_room)
# Scenes.end_current_sequence()
# else:
# State.pass_stage_to(current_room)

View File

@ -1,13 +1,16 @@
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
## Returns true if a scene is currently playing.
var is_playing: bool:
get: return current_sequence != -1
enum id { enum id {
YOUTH_DRAEVEN, YOUTH_DRAEVEN,
@ -25,58 +28,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)
sequence_actors[sequence_id][index] = callable
func start_sequence(index: id): current_sequence = scene_id
if State.pass_stage_to(sequence_actors[index][0].get_object()): started_sequences = started_sequences | (1 << scene_id)
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.")
# Leaves stage to pass it to the next element wanting to catch focus. # Emit signal for other systems (music, animations, etc.)
func continue_sequence(former_actor: Object): scene_starting.emit(scene_id, is_sequence_repeating(scene_id))
# if this fails, pass next was called without a sequencce having been started.
assert(current_sequence != -1)
if former_actor == State.stage_list[0] and former_actor == sequence_actors[current_sequence][current_sequence_index].get_object(): # Called by CollectableUi when it finishes playing a scene
former_actor.has_stage = false 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() # Mark as completed
print_debug(sequence_actors[current_sequence][current_sequence_index].get_object().name) completed_sequences = completed_sequences | (1 << scene_id)
State.stage_list[0].has_stage = true # Clear current sequence
if current_sequence == scene_id:
current_sequence = -1
sequence_actors[current_sequence][current_sequence_index].call(current_sequence, is_sequence_repeating(current_sequence)) # 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)
scene_continuing.emit(current_sequence, current_sequence_index, is_sequence_repeating(current_sequence)) # 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])
func end_current_sequence(): # Legacy alias
State.leave_stage(State.stage_list[0]) func end_current_sequence() -> void:
scene_finished.emit(current_sequence, is_sequence_repeating(current_sequence)) if current_sequence != -1 and current_sequence < id.size():
completed_sequences = completed_sequences | (1 << current_sequence) end_sequence(id.values()[current_sequence])
current_sequence = -1
current_sequence_index = 0
func is_sequence_repeating(index: int) -> bool: return completed_sequences & (1 << index) > 0 # Legacy support - no longer needed
func continue_sequence(_former_actor: Object) -> void:
push_warning("continue_sequence is deprecated and does nothing.")
func is_sequence_unlocked(index: id) -> bool: return (1 << int(index)) & enabled_sequences > 0 # 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: func get_completed_total() -> int:
var i: int = completed_sequences - ((completed_sequences >> 1) & 0x55555555); var i: int = completed_sequences - ((completed_sequences >> 1) & 0x55555555);

View File

@ -10,15 +10,16 @@ func _ready() -> void:
pass_to_actor = get_child(current_tab) pass_to_actor = get_child(current_tab)
func _on_tab_changed(tab_id: int): func _on_tab_changed(tab_id: int):
var child_has_stage:bool = false # Transfer has_stage to the new tab's child
for child in get_children(): for child in get_children():
if "has_stage" in child: if "has_stage" in child:
if child.has_stage: child.has_stage = false
child_has_stage = true
if child_has_stage:
State.transition_stage_to(get_child(tab_id))
pass_to_actor = get_child(tab_id) var new_child = get_child(tab_id)
if "has_stage" in new_child:
new_child.has_stage = true
pass_to_actor = new_child
func _on_stage_left(): func _on_stage_left():
await get_tree().process_frame await get_tree().process_frame

View File

@ -15,9 +15,7 @@ var is_active:bool = false:
if is_node_ready() and active: if is_node_ready() and active:
screenreader_check.grab_focus() screenreader_check.grab_focus()
if not active and is_active: if not active and is_active:
if has_stage: leave_stage.emit()
State.leave_stage(self)
leave_stage.emit()
is_active = active is_active = active
if (is_active and not has_stage) and not get_tree().paused: if (is_active and not has_stage) and not get_tree().paused:

View File

@ -84,8 +84,7 @@ func update_ui_from_state():
func _on_exit_button_pressed() -> void: func _on_exit_button_pressed() -> void:
leave_stage.emit() leave_stage.emit()
State.save_settings() State.save_settings()
State.leave_stage(self)
func _input(event: InputEvent) -> void: func _input(event: InputEvent) -> void:
if event.is_action_pressed("ui_cancel") and has_stage: if event.is_action_pressed("ui_cancel") and has_stage:
State.leave_stage(self) leave_stage.emit()

View File

@ -45,8 +45,7 @@ func _on_exit_button_pressed() -> void:
State.save_settings() State.save_settings()
has_unsaved_changes = false has_unsaved_changes = false
leave_stage.emit() leave_stage.emit()
State.leave_stage(self)
func _input(event: InputEvent) -> void: func _input(event: InputEvent) -> void:
if event.is_action_pressed("ui_cancel") and has_stage: if event.is_action_pressed("ui_cancel") and has_stage:
State.leave_stage(self) leave_stage.emit()

View File

@ -37,8 +37,7 @@ func update_ui_from_state():
func _on_exit_button_pressed() -> void: func _on_exit_button_pressed() -> void:
leave_stage.emit() leave_stage.emit()
State.save_settings() State.save_settings()
State.leave_stage(self)
func _input(event: InputEvent) -> void: func _input(event: InputEvent) -> void:
if event.is_action_pressed("ui_cancel") and has_stage: if event.is_action_pressed("ui_cancel") and has_stage:
State.leave_stage(self) leave_stage.emit()

View File

@ -39,11 +39,10 @@ func update_ui_from_state():
func _on_exit_button_pressed() -> void: func _on_exit_button_pressed() -> void:
leave_stage.emit() leave_stage.emit()
State.save_settings() State.save_settings()
State.leave_stage(self)
func _input(event: InputEvent) -> void: func _input(event: InputEvent) -> void:
if event.is_action_pressed("ui_cancel") and has_stage: if event.is_action_pressed("ui_cancel") and has_stage:
State.leave_stage(self) leave_stage.emit()
func reset_all_stats(): func reset_all_stats():
Steam.resetAllStats(true) Steam.resetAllStats(true)

View File

@ -175,14 +175,12 @@ func save_settings():
func _on_exit_confirmed() -> void: func _on_exit_confirmed() -> void:
leave_stage.emit() leave_stage.emit()
State.leave_stage(self)
func _on_exit_button_pressed() -> void: func _on_exit_button_pressed() -> void:
if has_changed: if has_changed:
$Popup.show() $Popup.show()
else: else:
leave_stage.emit() leave_stage.emit()
State.leave_stage(self)
func _on_confirm_button_pressed() -> void: func _on_confirm_button_pressed() -> void:
ProjectSettings.set_setting("display/window/size/mode", window_mode) ProjectSettings.set_setting("display/window/size/mode", window_mode)