diff --git a/src/base-environments/youth_room/youth_room.tscn b/src/base-environments/youth_room/youth_room.tscn index cccade2..afb1642 100644 --- a/src/base-environments/youth_room/youth_room.tscn +++ b/src/base-environments/youth_room/youth_room.tscn @@ -1767,10 +1767,6 @@ mix_target = 2 bus = &"text" script = ExtResource("10_ypa88") -[node name="CardBurner" parent="logic/UI" instance=ExtResource("11_5bsh1")] -visible = false -layout_mode = 1 - [node name="ScenePlayer" type="AnimationPlayer" parent="logic" groups=["scene_actors"]] unique_name_in_owner = true libraries = { diff --git a/src/logic-scenes/board/card-board.gd b/src/logic-scenes/board/card-board.gd index 791605c..a5b59ee 100644 --- a/src/logic-scenes/board/card-board.gd +++ b/src/logic-scenes/board/card-board.gd @@ -69,6 +69,8 @@ func _navigate_prev(): # Called when the node enters the scene tree for the first time. func _ready() -> void: + print_debug("CardBoard.gd: %s._ready()" % self.name) + super._ready() # HACK: Lets us debug more easily if get_parent() == get_tree().root: _debug_mode() diff --git a/src/logic-scenes/board/card.gd b/src/logic-scenes/board/card.gd index 1bb02b5..5c56c2b 100644 --- a/src/logic-scenes/board/card.gd +++ b/src/logic-scenes/board/card.gd @@ -100,31 +100,33 @@ func set_highlight(value: bool) -> void: var burn_tween: Tween signal has_burned -@export var burn_state: burned = burned.NOT: + +var burn_state: burned = burned.NOT: set(burning): if burning != burn_state: - if burn_tween != null: - burn_tween.kill() + if burn_tween: burn_tween.kill() match burning: burned.NOT: burn_tween = get_tree().create_tween() burn_tween.tween_property(self, "burn_progress", 0, 0.5) + burn_state = burning burned.SINGED: burn_tween = get_tree().create_tween() burn_tween.set_ease(Tween.EASE_OUT) burn_tween.set_trans(Tween.TRANS_SINE) burn_tween.tween_property(self, "burn_progress", 0.5, 2) - burned.BURNING: - burn_tween = get_tree().create_tween() - burn_tween.tween_property(self, "burn_progress", 2.0, 2) - burn_tween.tween_callback(_torch).set_delay(1.0) + burn_state = burning burned.TORCHED: print_debug("Card %s has been burned." % HardCards.get_obscure_name(name)) has_burned.emit() - burn_state = burning + burn_state = burning -func _torch(): +func torch(): + if burn_tween: burn_tween.kill() burn_state = burned.TORCHED + burn_tween = create_tween() + burn_tween.tween_property(self, "burn_progress", 2.0, 2) + await burn_tween.finished var crumble_material: ShaderMaterial = preload("res://logic-scenes/card_burner/card_crumble.material") var card_fire: Sprite2D = preload("res://logic-scenes/card_burner/card_fire.tscn").instantiate() diff --git a/src/logic-scenes/card_burner/burner_gradient.tres b/src/logic-scenes/card_burner/burner_gradient.tres new file mode 100644 index 0000000..71796ca --- /dev/null +++ b/src/logic-scenes/card_burner/burner_gradient.tres @@ -0,0 +1,9 @@ +[gd_resource type="GradientTexture2D" load_steps=2 format=3 uid="uid://dwerd76p42ac"] + +[sub_resource type="Gradient" id="Gradient_ckmi5"] +colors = PackedColorArray(0, 0, 0, 1, 0, 0, 0, 1) + +[resource] +gradient = SubResource("Gradient_ckmi5") +width = 128 +height = 128 diff --git a/src/logic-scenes/card_burner/card_burner.gd b/src/logic-scenes/card_burner/card_burner.gd index 0b0a5d1..d74974d 100644 --- a/src/logic-scenes/card_burner/card_burner.gd +++ b/src/logic-scenes/card_burner/card_burner.gd @@ -1,28 +1,18 @@ class_name CardBurner extends Playable -var focused: bool = false: - set(focus): - if is_node_ready(): - if not focus == focused: - if focus: - process_mode = Node.PROCESS_MODE_INHERIT - self.show() - Input.mouse_mode = Input.MOUSE_MODE_HIDDEN - if not PromptManager.icons == InputPrompt.Icons.KEYBOARD or true: - handle_direction_input(Vector2.UP) - else: - self.hide() - process_mode = Node.PROCESS_MODE_DISABLED - focused = focus @onready var cursor: CandleCursor = %CandleCursor @onready var ancors: Array[Control] = [%Ancor1, %Ancor2, %Ancor3, %Ancor4] signal card_burned +var cards : Array[Card] = [] +var _submitted := false func _ready(): + print_debug("CardBurner.gd: %s._ready()" % self.name) + super._ready() %SkipButton.pressed.connect(card_burned.emit) @@ -39,19 +29,23 @@ func play() -> void: print_debug("CardBurner: Found %d cards to choose from" % card_names.size()) # 2. Get card instances and shuffle them - var random_cards: Array = HardCards.get_cards_by_name_array(card_names)["cards"] - random_cards.shuffle() + var stack : Array = HardCards.get_cards_by_name_array(card_names)["cards"] + stack.shuffle() + + cards = [] # 3. Populate the 4 anchor slots with random cards for ancor: Control in ancors: - var new_card: Card = random_cards.pop_front() - ancor.add_child(new_card) - new_card.owner = self - new_card.has_burned.connect(card_burned.emit) - print_debug("CardBurner: Added card '%s' to anchor" % new_card.name) + var card: Card = stack.pop_front() + cards.append(card) + ancor.add_child(card) + print_debug("CardBurner: Added card '%s' to anchor" % card.name) + + print("CardBurner: ", len(cards)) # 4. Wait for player to burn a card (or skip) print_debug("CardBurner: Waiting for player to burn a card...") + handle_direction_input(Vector2.UP) await card_burned # 5. Play vanish animation and wait for completion @@ -61,71 +55,82 @@ func play() -> void: print_debug("CardBurner: Sequence complete") -func handle_hover(card: Draggable): - if not card is Card: return - card.highlighted = card.mouse_over - card.burn_state = Card.burned.SINGED if card.mouse_over else Card.burned.NOT -func handle_mouse_button(event: InputEventMouseButton, card: Card): +func handle_hover(card: Draggable) -> void: + if not card is Card: return + selection = cards.find(card) + + +func handle_mouse_button(event: InputEventMouseButton, card: Card) -> void: if event.button_index == MOUSE_BUTTON_MASK_LEFT and event.is_pressed() and not event.is_echo(): - card.burn_state = Card.burned.BURNING + _submit(card) + +func _submit(card : Card): + _submitted = true + %SkipButton.visible = false + await card.torch() + card_burned.emit() + func _input(event: InputEvent) -> void: - if focused: - if event.is_action_pressed("ui_up"): - handle_direction_input(Vector2.UP) - elif event.is_action_pressed("ui_down"): - handle_direction_input(Vector2.DOWN) - elif event.is_action_pressed("ui_left"): - handle_direction_input(Vector2.LEFT) - elif event.is_action_pressed("ui_right"): - handle_direction_input(Vector2.RIGHT) - elif event is InputEventMouse: - cursor.gamepad_mode = false - ancors[card_index].get_child(0)._on_mouse_exited() - elif event.is_action_pressed("ui_accept"): - ancors[card_index].get_child(0).burn_state = Card.burned.BURNING + if _submitted: return + if event.is_action_pressed("ui_up"): + handle_direction_input(Vector2.UP) + elif event.is_action_pressed("ui_down"): + handle_direction_input(Vector2.DOWN) + elif event.is_action_pressed("ui_left"): + handle_direction_input(Vector2.LEFT) + elif event.is_action_pressed("ui_right"): + handle_direction_input(Vector2.RIGHT) + elif event.is_action_pressed("ui_accept"): + _submit(cards[selection]) var focus_cards: bool = false: set(focus): + if _submitted: return focus_cards = focus if focus_cards: cursor.visible = true %SkipButton.release_focus() - card_index = card_index else: cursor.visible = false %SkipButton.grab_focus() - ancors[card_index].get_child(0)._on_mouse_exited() -var card_index: int = 0: - set(index): - ancors[card_index].get_child(0)._on_mouse_exited() - card_index = index % 4 - handle_hover(ancors[card_index].get_child(0)) -func handle_direction_input(direction: Vector2): + +var selection: int: + set(value): + if _submitted: return + selection = value % len(cards) + for i in range(len(cards)): + var card := cards[i] + card.highlighted = (selection == i) + card.burn_state = Card.burned.SINGED if card.highlighted else Card.burned.NOT + if card.highlighted: + cursor.gamepad_target = card.global_position + Vector2(-120, 150) + + +func handle_direction_input(direction: Vector2) -> void: + if _submitted: return if not cursor.gamepad_mode: - for ancor in ancors: - ancor.get_child(0)._on_mouse_exited() cursor.gamepad_mode = true focus_cards = focus_cards + match direction: Vector2.UP: focus_cards = true cursor.visible = true %SkipButton.release_focus() - card_index = card_index + selection = selection Vector2.DOWN: focus_cards = false cursor.visible = false %SkipButton.grab_focus() - ancors[card_index].get_child(0)._on_mouse_exited() Vector2.LEFT: focus_cards = true - card_index -= 1 + selection -= 1 Vector2.RIGHT: focus_cards = true - card_index += 1 - cursor.gamepad_target = ancors[card_index].get_child(0).global_position + Vector2(-120, 150) + selection += 1 + if not focus_cards: cursor.gamepad_target += Vector2(0, 50) diff --git a/src/logic-scenes/card_burner/card_burner.tscn b/src/logic-scenes/card_burner/card_burner.tscn index ce6990b..6d03bfa 100644 --- a/src/logic-scenes/card_burner/card_burner.tscn +++ b/src/logic-scenes/card_burner/card_burner.tscn @@ -1,10 +1,10 @@ -[gd_scene load_steps=15 format=3 uid="uid://g2a27jwdapai"] +[gd_scene load_steps=13 format=3 uid="uid://g2a27jwdapai"] [ext_resource type="Script" uid="uid://bbia2hcdwctyn" path="res://logic-scenes/card_burner/card_burner.gd" id="1_copuj"] [ext_resource type="Texture2D" uid="uid://615hvpuiacvm" path="res://addons/input_prompts/icons/xbox/X.png" id="3_ckmi5"] [ext_resource type="PackedScene" uid="uid://uc6urpgv7n1y" path="res://logic-scenes/card_burner/cursor_candle.tscn" id="3_l4ogr"] +[ext_resource type="Texture2D" uid="uid://dwerd76p42ac" path="res://logic-scenes/card_burner/burner_gradient.tres" id="4_ckmi5"] [ext_resource type="Script" uid="uid://bbs1u7ojno7xo" path="res://addons/input_prompts/action_prompt/action_prompt.gd" id="4_x6cxt"] -[ext_resource type="PackedScene" uid="uid://dy5rd437h5hsw" path="res://logic-scenes/board/card.tscn" id="5_ckmi5"] [sub_resource type="InputEventKey" id="InputEventKey_ckmi5"] device = -1 @@ -22,20 +22,12 @@ action = &"skip" [sub_resource type="Shortcut" id="Shortcut_57mhv"] events = [SubResource("InputEventAction_23lqb")] -[sub_resource type="Gradient" id="Gradient_ckmi5"] -colors = PackedColorArray(0, 0, 0, 1, 0, 0, 0, 1) - -[sub_resource type="GradientTexture2D" id="GradientTexture2D_x6cxt"] -gradient = SubResource("Gradient_ckmi5") -width = 100 -height = 100 - [sub_resource type="Animation" id="Animation_57mhv"] length = 0.001 tracks/0/type = "value" tracks/0/imported = false tracks/0/enabled = true -tracks/0/path = NodePath("../Sprite2D:self_modulate") +tracks/0/path = NodePath("../../Sprite2D:self_modulate") tracks/0/interp = 1 tracks/0/loop_wrap = true tracks/0/keys = { @@ -62,7 +54,7 @@ resource_name = "vanish" tracks/0/type = "value" tracks/0/imported = false tracks/0/enabled = true -tracks/0/path = NodePath("../Sprite2D:self_modulate") +tracks/0/path = NodePath("../../Sprite2D:self_modulate") tracks/0/interp = 2 tracks/0/loop_wrap = true tracks/0/keys = { @@ -98,6 +90,12 @@ grow_horizontal = 2 grow_vertical = 2 script = ExtResource("1_copuj") +[node name="ColorRect" type="ColorRect" parent="."] +visible = false +custom_minimum_size = Vector2(8192, 8192) +layout_mode = 2 +color = Color(0, 0, 0, 0.3137255) + [node name="Control" type="Control" parent="."] layout_mode = 2 @@ -185,56 +183,18 @@ layout_mode = 2 shortcut = SubResource("Shortcut_57mhv") text = "Keep all thoughts" -[node name="Sprite2D" type="Sprite2D" parent="Control"] -self_modulate = Color(1, 1, 1, 0) -scale = Vector2(100, 100) -texture = SubResource("GradientTexture2D_x6cxt") - [node name="CandleCursor" parent="." instance=ExtResource("3_l4ogr")] unique_name_in_owner = true +position = Vector2(989, 1068) + +[node name="Sprite2D" type="Sprite2D" parent="."] +self_modulate = Color(1, 1, 1, 0) +position = Vector2(954.99994, 545) +scale = Vector2(100, 100) +texture = ExtResource("4_ckmi5") [node name="AnimationPlayer" type="AnimationPlayer" parent="."] root_node = NodePath("../Control/HSplitContainer") libraries = { &"": SubResource("AnimationLibrary_kaqqi") } - -[node name="Card1" parent="." instance=ExtResource("5_ckmi5")] -wiggle_strength = null -wiggle_speed = null -scale_bump = null -bounce_speed = null -is_dragable = null -diameter = null -burn_progress = null -burn_state = null - -[node name="Card2" parent="." instance=ExtResource("5_ckmi5")] -wiggle_strength = null -wiggle_speed = null -scale_bump = null -bounce_speed = null -is_dragable = null -diameter = null -burn_progress = null -burn_state = null - -[node name="Card3" parent="." instance=ExtResource("5_ckmi5")] -wiggle_strength = null -wiggle_speed = null -scale_bump = null -bounce_speed = null -is_dragable = null -diameter = null -burn_progress = null -burn_state = null - -[node name="Card4" parent="." instance=ExtResource("5_ckmi5")] -wiggle_strength = null -wiggle_speed = null -scale_bump = null -bounce_speed = null -is_dragable = null -diameter = null -burn_progress = null -burn_state = null diff --git a/src/logic-scenes/interactable/interactable.gd b/src/logic-scenes/interactable/interactable.gd index 158b996..27895d9 100644 --- a/src/logic-scenes/interactable/interactable.gd +++ b/src/logic-scenes/interactable/interactable.gd @@ -1,7 +1,7 @@ class_name Interactable extends Node3D @export var interaction: PackedScene = null -var interaction_ui : Playable = null +var playable : Playable = null @onready var view: Node3D = $View @onready var frame: Sprite3D = $Frame @@ -30,12 +30,12 @@ func _ready() -> void: view.scale = Vector3.ZERO frame.modulate.a = 0 if interaction: - interaction_ui = interaction.instantiate() as Control - canvas_layer.add_child(interaction_ui) + playable = interaction.instantiate() as Control + canvas_layer.add_child(playable) _update_caption() # Check if this scene was already completed (for re-entering rooms) - if interaction_ui is StoryPlayable: - var story := interaction_ui as StoryPlayable + if playable is StoryPlayable: + var story := playable as StoryPlayable collected = Scenes.is_sequence_repeating(story.scene_id) else: _update_prompt() @@ -106,19 +106,19 @@ func play_story() -> void: canvas_layer.show() # Allow room to prepare for scene (e.g., play animations) - await State.room.prepare_scene_start(interaction_ui.scene_id, repeat) + await State.room.prepare_scene_start(playable.scene_id, repeat) - Scenes.begin_sequence(interaction_ui.scene_id) + Scenes.begin_sequence(playable.scene_id) # Play the story - await interaction_ui.play() + await playable.play() # Pick the cards if not already picked if not repeat: var picker := State.room.get_node("%Picker") as CardPicker - await picker.pick_cards(interaction_ui.scene_id) + await picker.pick_cards(playable.scene_id) - Scenes.end_sequence(interaction_ui.scene_id) # todo: maybe later? + Scenes.end_sequence(playable.scene_id) # todo: maybe later? # Hide the CanvasLayer when done canvas_layer.hide() @@ -131,7 +131,7 @@ func play_board() -> void: canvas_layer.show() # Play the board (handles mouse visibility and waits for close) - await interaction_ui.play() + await playable.play() # Hide the CanvasLayer when done canvas_layer.hide() @@ -144,7 +144,7 @@ func play_burner() -> void: canvas_layer.show() # Play the board (handles mouse visibility and waits for close) - await interaction_ui.play() + await playable.play() # Hide the CanvasLayer when done canvas_layer.hide() @@ -159,32 +159,34 @@ func interact() -> void: # collapse other interactables BEFORE showing canvas get_tree().call_group("interactables", "collapse") - if interaction_ui is StoryPlayable: + + if playable is StoryPlayable: await play_story() - if interaction_ui is CardBoard: + if playable is CardBoard: await play_board() - if interaction_ui is CardBurner: + if playable is CardBurner: await play_burner() + ## Updates caption label based on the instantiated interaction_ui func _update_caption() -> void: - if interaction_ui is StoryPlayable: - var story := interaction_ui as StoryPlayable + if playable is StoryPlayable: + var story := playable as StoryPlayable caption.text = I18n.get_story_caption(story.scene_id) - if interaction_ui is CardBoard: + if playable is CardBoard: caption.text = TranslationServer.translate("Mind Board") - if interaction_ui is CardBurner: + if playable is CardBurner: caption.text = TranslationServer.translate("leave") ## Updates prompt label based on the interaction type and collected state func _update_prompt() -> void: - if interaction_ui is StoryPlayable: + if playable is StoryPlayable: if collected: prompt.text = TranslationServer.translate("read again") else: prompt.text = TranslationServer.translate("MementoLabel_collect") - elif interaction_ui is CardBoard: + elif playable is CardBoard: prompt.text = TranslationServer.translate("find connections") diff --git a/src/logic-scenes/luna/playables/story_playable.gd b/src/logic-scenes/luna/playables/story_playable.gd index 8137b83..3742376 100644 --- a/src/logic-scenes/luna/playables/story_playable.gd +++ b/src/logic-scenes/luna/playables/story_playable.gd @@ -70,7 +70,7 @@ var substring_sizes: Array[int] func _ready() -> void: print_debug("StoryPlayable.gd: %s._ready()" % self.name) - hide() + super._ready() animation_player.play("RESET") State.settings_changed.connect(func(): story_array = story_array) skip_control = %SkipControl diff --git a/src/logic-scenes/playable.gd b/src/logic-scenes/playable.gd index 81f343b..7bb791d 100644 --- a/src/logic-scenes/playable.gd +++ b/src/logic-scenes/playable.gd @@ -1,6 +1,9 @@ extends Control class_name Playable +func _ready() -> void: + pass + ## Awaitable that encapsulates the core interaction with this Playable func play() -> void: push_warning("Playeable[base].play() not overridden")