feat: added new interactables to youth room, and repositioned them

This commit is contained in:
tiger tiger tiger 2026-01-15 15:28:56 +01:00
parent d5b20eef6c
commit b21ba5e18f
6 changed files with 126 additions and 50 deletions

View File

@ -4,8 +4,6 @@ extends RoomTemplate
## Used by the room system when this room becomes active
# var is_active: bool = false # Reminder, do not uncomment, this field is inherited from RoomTemplate!
@onready var board_trigger: InteractiveSprite = %MindBoard
@onready var door_trigger: InteractiveSprite = %Door
@onready var card_picker: CardPicker = %Picker
@onready var ui: Control = %UI
@ -34,7 +32,7 @@ func _play_intro_scene() -> void:
# The intro scene is auto-played, not triggered by CollectableUi
var intro: InteractiveSprite = $logic/CeilingMemento
var intro: Interactable = $logic/CeilingInteractable
# Play the story (StoryPlayable handles its own visibility via animations)
await intro.play_story()

View File

@ -27,11 +27,11 @@
[ext_resource type="PackedScene" uid="uid://cgwuoc1jfi7w6" path="res://base-environments/youth_room/scenes/draven.tscn" id="19_d3c7p"]
[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://dreokijo757l1" path="res://logic-scenes/interactable/interactable.tscn" id="22_ks23q"]
[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="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"]
@ -1870,36 +1870,31 @@ light_energy = 100.0
light_size = 20.0
omni_range = 16.8518
[node name="MaskMemento" parent="logic" instance=ExtResource("30_ypa88")]
transform = Transform3D(-0.8630245, 0, 0.5051597, 0, 1, 0, -0.5051597, 0, -0.8630245, 0.0754588, 0.948372, 2.42068)
visible = false
interaction_ui = ExtResource("12_viwxf")
[node name="MaskInteractable" parent="logic" instance=ExtResource("22_ks23q")]
transform = Transform3D(0.8630244, 0, -0.50515974, 0, 1, 0, 0.50515974, 0, 0.8630244, 0.0754588, 0.8061602, 2.42068)
interaction = 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)
visible = false
interaction_ui = ExtResource("12_x3dlb")
[node name="MindBoardInteractable" parent="logic" instance=ExtResource("22_ks23q")]
transform = Transform3D(-4.371126e-08, 0, -0.9999984, 0, 1, 0, 0.9999984, 0, -4.371126e-08, -0.907206, 1.17661, 1.74337)
interaction = ExtResource("4_gyjxx")
[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)
visible = false
interaction_ui = ExtResource("13_v3447")
[node name="CeilingInteractable" parent="logic" instance=ExtResource("22_ks23q")]
transform = Transform3D(-0.7148993, 0, -0.6992254, 0, 1, 0, 0.6992254, 0, -0.7148993, -0.13478619, 2.0720484, -0.42032808)
interaction = ExtResource("19_d3c7p")
[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)
visible = false
interaction_ui = ExtResource("19_d3c7p")
[node name="ComicInteractable" parent="logic" instance=ExtResource("22_ks23q")]
transform = Transform3D(-0.9699434, 0, -0.24332677, 0, 1, 0, 0.24332677, 0, -0.9699434, 2.91664, 0.43768048, -0.75655603)
interaction = ExtResource("13_v3447")
[node name="MindBoard" parent="logic" instance=ExtResource("30_ypa88")]
unique_name_in_owner = true
transform = Transform3D(-4.3711374e-08, 0, 0.9999984, 0, 1, 0, -0.9999984, 0, -4.3711374e-08, -0.907206, 1.17661, 1.74337)
visible = false
interaction_ui = ExtResource("4_gyjxx")
[node name="ClothesInteractable" parent="logic" instance=ExtResource("22_ks23q")]
transform = Transform3D(-0.86042935, 0, 0.5095668, 0, 1, 0, -0.5095668, 0, -0.86042935, 1.5113667, 1.1907816, -0.597433)
interaction = ExtResource("12_x3dlb")
[node name="Door" parent="logic" instance=ExtResource("30_ypa88")]
unique_name_in_owner = true
transform = Transform3D(0.9999984, 0, 4.973797e-14, 0, 1, 0, -4.973797e-14, 0, 0.9999984, 0.115203, 1.3931, -0.954428)
visible = false
[node name="collectable_particles" parent="logic/ClothesInteractable" index="3"]
transform = Transform3D(0.99999976, 0, -2.9802322e-08, 0, 1, 0, 2.9802322e-08, 0, 0.99999976, -0.0057822466, -0.09358537, 0.2777158)
[node name="DoorInteractable" parent="logic" instance=ExtResource("22_ks23q")]
transform = Transform3D(-0.9999984, 0, 8.7422585e-08, 0, 1, 0, -8.7422585e-08, 0, -0.9999984, 0.115203, 1.3931, -0.954428)
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
libraries = {
@ -2160,3 +2155,5 @@ data = ExtResource("40_ea6x8")
[connection signal="body_exited" from="logic/Bed and Ladders/reset_failover" to="logic/PlayerController" method="_on_bed_exit"]
[connection signal="pressed" from="logic/UI/ending_button" to="logic/UI/ending_button" method="hide"]
[connection signal="pressed" from="logic/UI/ending_button" to="logic/UI/ending" method="show"]
[editable path="logic/ClothesInteractable"]

View File

@ -7,10 +7,17 @@ var interaction_ui : Control = null
@onready var frame: Sprite3D = $Frame
@onready var canvas_layer: CanvasLayer = $CanvasLayer
@onready var caption : Label3D = %Caption
@onready var prompt : Label3D = %Prompt
var active : bool = true
var shown : bool = false
var hover : bool = false
var collected : bool = false
var collected : bool = false:
set(value):
collected = value
if is_inside_tree():
_update_prompt()
var tween: Tween = null
@ -20,11 +27,28 @@ func _ready() -> void:
if interaction:
interaction_ui = interaction.instantiate() as Control
canvas_layer.add_child(interaction_ui)
_update_caption()
# Check if this scene was already completed (for re-entering rooms)
if interaction_ui is StoryPlayable:
var story := interaction_ui as StoryPlayable
collected = Scenes.is_sequence_repeating(story.scene_id)
else:
_update_prompt()
Scenes.player_enable.connect(_player_active) # TODO: do I have to clean this up?
func _player_active(value: bool) -> void:
active = value
func collapse() -> void:
hover = false
if shown:
shown = false
if tween: tween.kill()
tween = create_tween().set_ease(Tween.EASE_IN).set_trans(Tween.TRANS_BACK)
tween.parallel().tween_property(view, "scale", Vector3.ZERO, 0.3)
tween.parallel().tween_property(frame, "modulate:a", 0, 0.6)
func _process(_delta: float) -> void:
_process_hover()
_process_billboard()
@ -55,26 +79,13 @@ func _process_hover() -> void:
func _input(event: InputEvent) -> void:
if not active or not hover or not shown: return
print(event, event.is_action_pressed("ui_accept"))
var clicked : bool = (event.is_action_pressed("ui_accept")) or (event is InputEventMouseButton and event.pressed)
var clicked : bool = (event.is_action_pressed("ui_accept")) or (event is InputEventMouseButton and event.pressed)
if hover and shown and clicked:
collect_memento()
func collect_memento() -> void:
shown = false
collected = true
# Hide mouse and collapse other interactables BEFORE showing canvas
get_tree().call_group("interactables", "collapse")
# Show the CanvasLayer so the story is visible full-screen
canvas_layer.show()
if interaction_ui is StoryPlayable:
Input.mouse_mode = Input.MOUSE_MODE_HIDDEN
func play_story() -> void:
canvas_layer.show()
Scenes.begin_sequence(interaction_ui.scene_id)
@ -89,5 +100,75 @@ func collect_memento() -> void:
canvas_layer.hide()
Scenes.end_sequence(interaction_ui.scene_id) # todo: maybe later?
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
Scenes.player_enable.emit(true) # TODO: this may not be our job?
func play_board() -> void:
canvas_layer.show()
# Play the board (handles mouse visibility and waits for close)
await interaction_ui.play()
# Hide the CanvasLayer when done
canvas_layer.hide()
Scenes.player_enable.emit(true)
func collect_memento() -> void:
shown = false
collected = true
# Hide mouse and collapse other interactables BEFORE showing canvas
get_tree().call_group("interactables", "collapse")
# Show the CanvasLayer so the story is visible full-screen
canvas_layer.show()
if interaction_ui is StoryPlayable:
play_story()
if interaction_ui is CardBoard:
play_board()
## Updates caption label based on the instantiated interaction_ui
func _update_caption() -> void:
if interaction_ui is StoryPlayable:
var story := interaction_ui as StoryPlayable
match story.scene_id:
Scenes.id.YOUTH_DRAVEN:
caption.text = TranslationServer.translate("Starlight")
Scenes.id.YOUTH_CHILDHOOD:
caption.text = TranslationServer.translate("crafted Mask")
Scenes.id.YOUTH_VOICE_TRAINING:
caption.text = TranslationServer.translate("Comic Stash")
Scenes.id.YOUTH_JUI_JUTSU:
caption.text = TranslationServer.translate("Sports Clothes")
Scenes.id.TRANSITION:
caption.text = TranslationServer.translate("Move on")
Scenes.id.ADULT_DND:
caption.text = TranslationServer.translate("colorful Dice")
Scenes.id.ADULT_VOLUNTARY:
caption.text = TranslationServer.translate("Gemstone Art")
Scenes.id.ADULT_CHRISTMAS:
caption.text = TranslationServer.translate("Chat Messages")
Scenes.id.ADULT_EATING:
caption.text = TranslationServer.translate("Dishes")
Scenes.id.ADULT_UNI:
caption.text = TranslationServer.translate("Science Poster")
Scenes.id.ADULT_THERAPY:
caption.text = TranslationServer.translate("Doctors Note")
Scenes.id.ADULT_BURNOUT:
caption.text = TranslationServer.translate("Paperwork")
_:
caption.text = ""
elif interaction_ui is CardBoard:
caption.text = TranslationServer.translate("Mind Board")
## Updates prompt label based on the interaction type and collected state
func _update_prompt() -> void:
if interaction_ui is StoryPlayable:
if collected:
prompt.text = TranslationServer.translate("read again")
else:
prompt.text = TranslationServer.translate("MementoLabel_collect")
elif interaction_ui is CardBoard:
prompt.text = TranslationServer.translate("find connections")

View File

@ -32,6 +32,7 @@ render_priority = 50
texture = ExtResource("3_cjk23")
[node name="Caption" type="Label3D" parent="View"]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.03170359, 0)
double_sided = false
no_depth_test = true
@ -55,6 +56,7 @@ font_size = 10
outline_size = 0
[node name="Prompt" type="Label3D" parent="View/Icon"]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0353532, 0, 0)
double_sided = false
no_depth_test = true

View File

@ -152,13 +152,11 @@ func _on_ray_entered(_area):
assert(parent != null, "Ray entered non-interactable area!")
printt("ray entered", parent.name, parent)
parent.hover = true
Input.set_default_cursor_shape(Input.CURSOR_POINTING_HAND)
func _on_ray_exited(_area):
var parent := _area.get_parent() as Interactable
printt("ray exited", parent.name, parent)
parent.hover = false
Input.set_default_cursor_shape(Input.CURSOR_ARROW)
func _physics_process(delta: float):

View File

@ -41,7 +41,7 @@ func _load_games():
var filepaths: PackedStringArray = save_game_dir.get_files()
for path in filepaths:
if path.ends_with(".json"):
if path is String and path.ends_with(".json"):
saves.append(SaveGame.new("%s/%s" % [State.user_saves_path, path.get_basename()]))
_sort_saves()
@ -50,7 +50,7 @@ func _load_games():
func _sort_saves() -> void:
saves.sort_custom(func(a: SaveGame, b: SaveGame) -> int:
return a.last_saved < b.last_saved
return a.last_saved > b.last_saved
)
func _rebuild_buttons() -> void: