frame-of-mind/src/logic-scenes/collectable/collectable_ui.gd

277 lines
9.7 KiB
GDScript3
Raw Normal View History

extends CenterContainer
class_name CollectableUi
## The StoryPlayable to play when this memento is collected.
## Auto-discovered from the owner's %CanvasLayer, or can be set manually.
@export var story_playable: StoryPlayable
## Reference to the CanvasLayer containing the story_playable.
## Auto-discovered in _ready() if not set.
var canvas_layer: CanvasLayer
@export var has_stage: bool = false:
2024-09-15 09:30:31 +00:00
set(focused):
if has_stage == focused: return
2024-09-15 09:30:31 +00:00
if focused:
has_stage = true
is_collapsed = false
2024-09-15 09:30:31 +00:00
if not visible: show()
else:
2024-09-15 09:30:31 +00:00
has_stage = false
get_viewport().gui_release_focus()
is_collapsed = true
@export var scene: Scenes.id = Scenes.id.YOUTH_DRAEVEN:
set(id):
scene = id
if is_inside_tree() and not is_board:
match id:
Scenes.id.YOUTH_DRAEVEN:
# FIXME: this explicit translation should not be nessecary
if title_override == "": title_label.text = TranslationServer.translate("Starlight")
if subtitle_override == "": cn_label.text = "[b]%s[/b]: %s" % [TranslationServer.translate("MementoLabel_CN"), TranslationServer.translate("MementoLabel_DraevenCN")]
Scenes.id.YOUTH_CHILDHOOD:
if title_override == "": title_label.text = TranslationServer.translate("crafted Mask")
if subtitle_override == "": cn_label.text = "[b]%s[/b]: %s" % [TranslationServer.translate("MementoLabel_CN"), TranslationServer.translate("MementoLabel_ChildhoodCN")]
Scenes.id.YOUTH_VOICE_TRAINING:
if title_override == "": title_label.text = TranslationServer.translate("Comic Stash")
if subtitle_override == "": cn_label.text = "[b]%s[/b]: %s" % [TranslationServer.translate("MementoLabel_CN"), TranslationServer.translate("MementoLabel_VoiceCN")]
Scenes.id.YOUTH_JUI_JUTSU:
if title_override == "": title_label.text = TranslationServer.translate("Sports Clothes")
if subtitle_override == "": cn_label.text = "[b]%s[/b]: %s" % [TranslationServer.translate("MementoLabel_CN"), TranslationServer.translate("MementoLabel_Jui_JutsuCN")]
Scenes.id.TRANSITION:
if title_override == "": title_label.text = TranslationServer.translate("Move on")
if subtitle_override == "": cn_label.text = ""
Scenes.id.ADULT_DND:
if title_override == "": title_label.text = TranslationServer.translate("colorful Dice")
if subtitle_override == "": cn_label.text = ""
Scenes.id.ADULT_VOLUNTARY:
if title_override == "": title_label.text = TranslationServer.translate("Gemstone Art")
if subtitle_override == "": cn_label.text = ""
Scenes.id.ADULT_CHRISTMAS:
if title_override == "": title_label.text = TranslationServer.translate("Chat Messages")
if subtitle_override == "": cn_label.text = ""
Scenes.id.ADULT_EATING:
if title_override == "": title_label.text = TranslationServer.translate("Dishes")
if subtitle_override == "": cn_label.text = ""
Scenes.id.ADULT_UNI:
if title_override == "": title_label.text = TranslationServer.translate("Science Poster")
if subtitle_override == "": cn_label.text = ""
Scenes.id.ADULT_THERAPY:
if title_override == "": title_label.text = TranslationServer.translate("Doctors Note")
if subtitle_override == "": cn_label.text = ""
Scenes.id.ADULT_BURNOUT:
if title_override == "": title_label.text = TranslationServer.translate("Paperwork")
if subtitle_override == "": cn_label.text = ""
if not Engine.is_editor_hint():
is_collected = Scenes.is_sequence_repeating(scene)
@export var is_collected: bool = false:
set(value):
is_collected = value
if is_inside_tree():
collected_box.button_pressed = value
if is_collected and not is_board:
%CollectLabel.text = "listen again"
2024-09-15 09:30:31 +00:00
else:
if not is_board:
%CollectLabel.text = "MementoLabel_collect"
else:
%CollectLabel.text = "find connections"
@onready var collected_box: CheckBox = %CheckBox
@export var title_override: String = "":
set(value):
title_override = value
if is_inside_tree() and not is_board:
title_label.text = value
@onready var title_label: Label = %TitleLabel
@export var subtitle_override: String = "":
set(value):
subtitle_override = value
if is_inside_tree() and not is_board:
cn_label.text = value
@onready var cn_label: RichTextLabel = %ContentNoteLabel
@onready var animation_player: AnimationPlayer = %AnimationPlayer
@export var is_collapsed: bool = true
@export var is_expanded: bool = false:
set(expanded):
if expanded != is_expanded:
is_expanded = expanded
if is_inside_tree():
animation_player.play("expand")
await animation_player.animation_finished
for button:Button in [%ReadStory, %CollectButton, %SummaryButton, %SkipButton]:
if button.visible:
button.grab_focus()
return
@export var was_skipped: bool = false
@export var is_board:bool = false:
set(board):
is_board = board
2024-09-15 09:30:31 +00:00
if is_inside_tree():
if board:
if title_override == "": title_label.text = "Mind Board"
collected_box.hide()
# Not room agnostic yet!
if not Engine.is_editor_hint():
match Scenes.get_completed_total():
1:
if subtitle_override == "": cn_label.text = "Find all three Mementos to collect all thoughts."
2:
if subtitle_override == "": cn_label.text = "Find two more Mementos to get all cards."
3:
if subtitle_override == "": cn_label.text = "Find the last remaining Memento."
4:
if subtitle_override == "": cn_label.text = "Use this to find a Frame of Mind."
else:
scene = scene
collected_box.show()
@export var is_exit:bool = false:
set(exit):
is_exit = exit
2024-09-15 09:30:31 +00:00
if is_inside_tree():
if exit:
if title_override == "": title_label.text = "Move on"
if subtitle_override == "": %CollectLabel.text = "Leave room"
collected_box.hide()
else:
scene = scene
collected_box.show()
2023-07-19 11:51:26 +00:00
signal open_board
signal exit_room
2026-01-05 17:18:48 +00:00
signal playback_finished
#TODO implement proper scene skipping
2023-07-19 11:51:26 +00:00
signal scene_skipped(i: int)
func _ready() -> void:
State.settings_changed.connect(_on_context_updated)
%CollectButton.pressed.connect(collect_memento)
##TODO: add functions for remaining buttons
# Auto-discover story_playable and canvas_layer from scene hierarchy
_discover_story_playable()
update_state()
## Ensure canvas_layer is set if story_playable was set via export.
## InteractiveSprite._ready() handles the main wiring for inherited scenes.
func _discover_story_playable() -> void:
if story_playable != null and canvas_layer == null:
# story_playable set via export, find its parent CanvasLayer
var parent = story_playable.get_parent()
if parent is CanvasLayer:
canvas_layer = parent
func _on_context_updated() -> void:
%SkipButton.visible = State.allow_skipping
%SummaryButton.visible = State.provide_summaries
%ReadStory.visible = is_collected
%OptionPrompt.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
func update_state() -> void:
scene = scene
is_board = is_board
is_exit = is_exit
_on_context_updated()
func try_reveal() -> bool:
#if is_exit and not State.active_save_game.is_childhood_board_complete: return false
#if not is_board:
# if (not Scenes.is_sequence_unlocked( self.scene )) or false: #FIXME only for testing!!!
# return false
if not visible or animation_player.get_animation("vanish") or animation_player.get_animation("vanish_all"):
update_state()
visible = true
animation_player.play("reveal")
return true
return false
#func _process(_delta: float) -> void:
# if not visible or Engine.is_editor_hint(): return
# if Input.is_action_just_pressed("collect_memento_ui"):
# if not is_board:
# collect_memento()
# else:
# open_board.emit()
# elif Input.is_action_just_pressed("option_memento_ui"):
# is_expanded = true
#FIXME something was eating all my inputs, maybe I can use the more pretty pattern when I figure out the culprit
func _input(event: InputEvent) -> void:
if not visible: return
if event.is_action_pressed("collect_memento_ui"):
if not is_board:
collect_memento()
get_viewport().set_input_as_handled()
2024-09-15 09:30:31 +00:00
else:
if is_board:
open_board.emit()
if is_exit:
exit_room.emit()
elif event.is_action_pressed("option_memento_ui"):
is_expanded = true
get_viewport().set_input_as_handled()
func vanish() -> void:
if not visible: return
if is_expanded:
animation_player.play("vanish_all")
2024-09-15 09:30:31 +00:00
else:
animation_player.play("vanish")
2023-07-19 11:51:26 +00:00
func collect_memento() -> void:
print_debug("CollectableUi.collect_memento() - scene: %s" % Scenes.id.keys()[scene])
# Hide the collectable UI
vanish()
# Check if we have a story_playable to play
if story_playable == null:
push_warning("CollectableUi for scene %s has no story_playable assigned" % Scenes.id.keys()[scene])
if was_skipped:
scene_skipped.emit(-1)
is_collected = true
2026-01-05 17:18:48 +00:00
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
if canvas_layer:
canvas_layer.show()
# Play the story
await story_playable.play()
# Hide the CanvasLayer when done
if canvas_layer:
canvas_layer.hide()
2026-01-05 17:18:48 +00:00
# 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
2026-01-05 17:18:48 +00:00
# Signal that playback is finished so the InteractiveSprite can restore player control
playback_finished.emit()