refactor: stage 1, simplified board, now needs drag and drop
This commit is contained in:
parent
e86ce44583
commit
7cc50bb2e7
|
|
@ -7,9 +7,6 @@ extends RoomTemplate
|
|||
@onready var card_picker: CardPicker = %Picker
|
||||
@onready var ui: Control = %UI
|
||||
|
||||
# Is populated by child cardboard instead of onready.
|
||||
var card_board: CardBoard
|
||||
|
||||
func start_room():
|
||||
%UI.show()
|
||||
$logic/PlayerController.process_mode = Node.PROCESS_MODE_INHERIT
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
## Localization Utility class to move lists of keys out of difficult to read code
|
||||
extends Node
|
||||
|
||||
func get_memento_prompt(count: int) -> StringName:
|
||||
return TranslationServer.translate(_memento_prompts.get(count, ""))
|
||||
|
||||
func get_story_caption(id: Scenes.id) -> StringName:
|
||||
return TranslationServer.translate(_story_captions.get(id, ""))
|
||||
|
||||
|
||||
const _memento_prompts: Dictionary[int, StringName] = {
|
||||
1: "There are three Mementos left to find.",
|
||||
2: "You have collected half of the mementos.",
|
||||
3: "Find the last Memento to complete the Board.",
|
||||
4: "Combine cards to order your thoughts.",
|
||||
}
|
||||
|
||||
const _story_captions : Dictionary[Scenes.id, StringName] = {
|
||||
Scenes.id.YOUTH_DRAVEN: "Starlight",
|
||||
Scenes.id.YOUTH_CHILDHOOD: "crafted Mask",
|
||||
Scenes.id.YOUTH_VOICE_TRAINING: "Comic Stash",
|
||||
Scenes.id.YOUTH_JUI_JUTSU: "Sports Clothes",
|
||||
Scenes.id.TRANSITION: "Move on",
|
||||
Scenes.id.ADULT_DND: "colorful Dice",
|
||||
Scenes.id.ADULT_VOLUNTARY: "Gemstone Art",
|
||||
Scenes.id.ADULT_CHRISTMAS: "Chat Messages",
|
||||
Scenes.id.ADULT_EATING: "Dishes",
|
||||
Scenes.id.ADULT_UNI: "Science Poster",
|
||||
Scenes.id.ADULT_THERAPY: "Doctors Note",
|
||||
Scenes.id.ADULT_BURNOUT: "Paperwork",
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://26fa8xwylhxl
|
||||
|
|
@ -4,6 +4,7 @@ var initialised: bool = false
|
|||
var id: State.rooms = State.rooms.NULL
|
||||
|
||||
@onready var scene_player : AnimationPlayer = %ScenePlayer
|
||||
@onready var card_board : CardBoard # Optional Board, if present - set by the board in its own _ready()
|
||||
|
||||
var is_active: bool:
|
||||
set(value):
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -152,7 +152,7 @@ func init(card_name: String = "card", own_id:StringName = "-1") -> void:
|
|||
if card_name != "c_void":
|
||||
text = card_name
|
||||
if !card_name.begins_with("c"):
|
||||
push_error("Illegal card.")
|
||||
push_error("Illegal card!", card_name, own_id)
|
||||
card_id = own_id
|
||||
name = card_name
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ extends Area2D
|
|||
## Base class for draggable UI elements (Cards and StickyNotes)
|
||||
## Provides common dragging behavior and boundary protection
|
||||
|
||||
## Margin from screen edges when confining to screen bounds
|
||||
@export var screen_margin: float = 50.0
|
||||
|
||||
## Drop result codes for DropTarget pattern
|
||||
enum DropResult {
|
||||
ACCEPTED, # Drop successful, item is now owned by target
|
||||
|
|
@ -11,11 +14,6 @@ enum DropResult {
|
|||
EXCHANGED # Swap occurred, exchanged item needs handling
|
||||
}
|
||||
|
||||
## Static helper to check if a node implements DropTarget pattern
|
||||
## DropTarget pattern requires: can_accept_drop(draggable) and handle_drop(draggable)
|
||||
static func is_drop_target(node: Node) -> bool:
|
||||
return node != null and node.has_method("can_accept_drop") and node.has_method("handle_drop")
|
||||
|
||||
var is_dragged: bool = false:
|
||||
set(dragged):
|
||||
is_dragged = dragged
|
||||
|
|
@ -34,9 +32,6 @@ var highlighted: bool:
|
|||
func set_highlight(value: bool) -> void:
|
||||
_highlighted = value
|
||||
|
||||
## Margin from screen edges when confining to screen bounds
|
||||
@export var screen_margin: float = 50.0
|
||||
|
||||
## Drag state tracking
|
||||
var _drag_start_position: Vector2
|
||||
var _mouse_drag_offset: Vector2
|
||||
|
|
@ -69,27 +64,19 @@ func end_drag() -> void:
|
|||
is_dragged = false
|
||||
_drag_source = null
|
||||
|
||||
|
||||
## Confines this draggable element to stay within screen or container bounds
|
||||
## Skip this check if a sticky note is attached to a card
|
||||
func confine_to_screen() -> void:
|
||||
# Skip if this is a sticky note attached to a card
|
||||
if self is StickyNote:
|
||||
var sticky := self as StickyNote
|
||||
if sticky.attached_to is Card:
|
||||
return
|
||||
|
||||
# Try to get bounds from parent container
|
||||
var bounds := _get_container_bounds()
|
||||
|
||||
# If no container bounds, use viewport/screen bounds
|
||||
if bounds == Rect2():
|
||||
bounds = _get_viewport_bounds()
|
||||
|
||||
# If we have valid bounds, clamp position
|
||||
if bounds != Rect2():
|
||||
position.x = clampf(position.x, bounds.position.x, bounds.position.x + bounds.size.x)
|
||||
position.y = clampf(position.y, bounds.position.y, bounds.position.y + bounds.size.y)
|
||||
|
||||
|
||||
## Gets the bounds of the parent container if it exists and is a Control node
|
||||
func _get_container_bounds() -> Rect2:
|
||||
var parent := get_parent()
|
||||
|
|
@ -105,25 +92,19 @@ func _get_container_bounds() -> Rect2:
|
|||
control.size.y - screen_margin * 2
|
||||
)
|
||||
|
||||
# Check if parent is a Node2D with defined boundaries
|
||||
# (for future support of non-Control containers)
|
||||
if parent is Node2D:
|
||||
# For now, return empty rect - could be extended in the future
|
||||
# to check for custom boundary properties
|
||||
pass
|
||||
# Default: whole screen
|
||||
var viewport_size := get_viewport().get_visible_rect().size
|
||||
return Rect2(
|
||||
screen_margin,
|
||||
screen_margin,
|
||||
viewport_size.x - screen_margin * 2,
|
||||
viewport_size.y - screen_margin * 2
|
||||
)
|
||||
|
||||
return Rect2()
|
||||
|
||||
## Gets the viewport bounds as fallback
|
||||
func _get_viewport_bounds() -> Rect2:
|
||||
var viewport := get_viewport()
|
||||
if viewport:
|
||||
var viewport_size := viewport.get_visible_rect().size
|
||||
return Rect2(
|
||||
screen_margin,
|
||||
screen_margin,
|
||||
viewport_size.x - screen_margin * 2,
|
||||
viewport_size.y - screen_margin * 2
|
||||
)
|
||||
# === HELPERS ===
|
||||
## Static helper to check if a node implements DropTarget pattern
|
||||
## DropTarget pattern requires: can_accept_drop(draggable) and handle_drop(draggable)
|
||||
static func is_drop_target(node: Node) -> bool:
|
||||
return node != null and node.has_method("can_accept_drop") and node.has_method("handle_drop")
|
||||
|
||||
return Rect2()
|
||||
|
|
|
|||
|
|
@ -164,21 +164,17 @@ script = ExtResource("3_8v4c4")
|
|||
[node name="HBoxContainer" type="HBoxContainer" parent="."]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="dropzone" type="Panel" parent="HBoxContainer"]
|
||||
[node name="CardZone" type="Control" parent="HBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
self_modulate = Color(1, 1, 1, 0)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
mouse_filter = 1
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="HBoxContainer"]
|
||||
clip_contents = false
|
||||
[node name="NoteZone" type="Control" parent="HBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(400, 0)
|
||||
layout_mode = 2
|
||||
horizontal_scroll_mode = 0
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer/ScrollContainer"]
|
||||
z_index = 120
|
||||
layout_mode = 2
|
||||
|
||||
[node name="instructions_panel" type="PanelContainer" parent="."]
|
||||
layout_mode = 2
|
||||
|
|
|
|||
|
|
@ -13,10 +13,14 @@ var current_handle: Node
|
|||
|
||||
var position_locked: bool = false
|
||||
|
||||
## Computed property: Returns the current attachment (parent node)
|
||||
## Computed property: Is this currently attached to a card
|
||||
var is_attached : bool:
|
||||
get: return get_parent() is Card
|
||||
|
||||
## Replaces the need for tracking attached_to as state
|
||||
var attached_to: Node:
|
||||
get: return get_parent()
|
||||
var attached_to: Card:
|
||||
get: return get_parent() as Card if is_attached else null
|
||||
|
||||
|
||||
signal transform_tween_finished
|
||||
|
||||
|
|
@ -35,6 +39,7 @@ var label: Label
|
|||
@export var shift_by: Vector2 = Vector2(-32, 0)
|
||||
@export_color_no_alpha var highlight_color: Color = Color(1.5, 1.5, 1.5)
|
||||
|
||||
|
||||
## Override set_highlight to add visual feedback for sticky notes
|
||||
func set_highlight(value: bool) -> void:
|
||||
if value != _highlighted:
|
||||
|
|
@ -71,7 +76,7 @@ var mouse_offset: Vector2
|
|||
## Replaces on_board state tracking
|
||||
var on_board: bool:
|
||||
get:
|
||||
var parent = get_parent()
|
||||
var parent := get_parent()
|
||||
return parent != null and parent.name == "dropzone"
|
||||
|
||||
func init(sticky_name: String = "sticky_note", card_id: StringName = "-1") -> void:
|
||||
|
|
@ -101,14 +106,7 @@ func _on_text_updated():
|
|||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if get_overlapping_areas().size() > 0 and is_dragable and on_board:
|
||||
for area in get_overlapping_areas():
|
||||
if area is Card:
|
||||
if not area.highlighted or self.highlighted:
|
||||
var diff:Vector2 = position - area.position
|
||||
position -= diff.normalized() * ((diff.length()-diameter)/diameter) * bounce_speed * (delta/(1.0/60))
|
||||
|
||||
_move_sticky_note()
|
||||
_move_sticky_note(delta)
|
||||
|
||||
func _on_mouse_entered():
|
||||
if not Input.is_action_pressed("mouse_left") and current_handle and current_handle.has_method("handle_hover"):
|
||||
|
|
@ -116,25 +114,17 @@ func _on_mouse_entered():
|
|||
|
||||
func _on_mouse_exited():
|
||||
highlighted = false
|
||||
|
||||
# Let parent card re-check hover state if this sticky is attached to it
|
||||
if is_sticky_note_attached():
|
||||
var card = get_parent()
|
||||
if card and card.has_method("check_hover"):
|
||||
card.check_hover()
|
||||
var card := attached_to
|
||||
if card:
|
||||
card.check_hover()
|
||||
|
||||
func _on_area_enter(area: Area2D):
|
||||
# Handle sticky note panel gap creation
|
||||
if area is StickyNote and is_sticky_note_in_panel() and not is_dragged:
|
||||
var panel = get_parent() as StickyNotePanel
|
||||
if panel:
|
||||
panel.create_gap()
|
||||
func _on_area_enter(_area: Area2D):
|
||||
pass
|
||||
|
||||
func _on_area_exit(area: Area2D):
|
||||
# Handle sticky note panel gap collapse
|
||||
if area is StickyNote and is_sticky_note_in_panel():
|
||||
var panel = get_parent() as StickyNotePanel
|
||||
if panel:
|
||||
panel.collapse_gap()
|
||||
func _on_area_exit(_area: Area2D):
|
||||
pass
|
||||
|
||||
func _on_input_event(_viewport, event, _shape_idx):
|
||||
if event is InputEventMouseButton and current_handle and current_handle.has_method("handle_mouse_button"):
|
||||
|
|
@ -142,21 +132,27 @@ func _on_input_event(_viewport, event, _shape_idx):
|
|||
mouse_offset = get_viewport().get_mouse_position() - global_position
|
||||
current_handle.handle_mouse_button(event, self)
|
||||
|
||||
func _move_sticky_note():
|
||||
## frame rate independent FIR smoothing filter
|
||||
func _smooth(current: Vector2, goal: Vector2, delta: float) -> Vector2:
|
||||
var k := pow(0.1, 60.0 * delta)
|
||||
return (1.0-k) * current + k * goal
|
||||
|
||||
|
||||
func _move_sticky_note(delta: float) -> void:
|
||||
if is_dragged:
|
||||
update_drag_position(get_viewport().get_mouse_position())
|
||||
return
|
||||
|
||||
if is_attached:
|
||||
var card := attached_to
|
||||
position = _smooth(position, card.sticky_note_position, delta)
|
||||
|
||||
|
||||
func is_sticky_note_attached() -> bool:
|
||||
var parent = get_parent()
|
||||
return is_instance_valid(parent) and parent is Card
|
||||
|
||||
func is_sticky_note_in_panel() -> bool:
|
||||
var parent = get_parent()
|
||||
return is_instance_valid(parent) and parent is StickyNotePanel
|
||||
|
||||
var transform_tween: Tween
|
||||
|
||||
func tween_transform_to(target: Transform2D, duration: float = 0.25):
|
||||
func tween_transform_to(target: Transform2D, duration: float = 0.25) ->void:
|
||||
# Validate position to prevent teleporting
|
||||
if not is_finite(target.origin.x) or not is_finite(target.origin.y):
|
||||
push_warning("StickyNote.tween_transform_to: Invalid position, skipping tween")
|
||||
|
|
@ -175,28 +171,15 @@ func tween_transform_to(target: Transform2D, duration: float = 0.25):
|
|||
|
||||
# === DRAG LIFECYCLE OVERRIDES ===
|
||||
|
||||
## Track whether this sticky came from a panel (for exchange logic)
|
||||
var _came_from_panel: bool = false
|
||||
|
||||
## Start drag: if in panel, immediately move to board
|
||||
func start_drag(offset: Vector2) -> void:
|
||||
super.start_drag(offset)
|
||||
_came_from_panel = is_sticky_note_in_panel()
|
||||
|
||||
# If attached to a card, detach it first
|
||||
if is_sticky_note_attached():
|
||||
var card := get_parent() as Card
|
||||
if card and card.has_method("remove_sticky_note"):
|
||||
card.remove_sticky_note()
|
||||
var card := attached_to
|
||||
if card:
|
||||
card.remove_sticky_note()
|
||||
|
||||
# If in panel, immediately reparent to board dropzone for dragging
|
||||
if _came_from_panel and current_handle:
|
||||
var board := current_handle
|
||||
var dropzone := board.get_node_or_null("HBoxContainer/dropzone")
|
||||
if dropzone:
|
||||
reparent(dropzone)
|
||||
else:
|
||||
reparent(board)
|
||||
|
||||
## Find best drop target: Card > Panel > Board (in priority order)
|
||||
func find_drop_target() -> Node:
|
||||
|
|
@ -236,3 +219,6 @@ func _find_nearest_panel() -> StickyNotePanel:
|
|||
# No empty panels found - will need to create one (handled by board)
|
||||
return null
|
||||
|
||||
|
||||
func confine_to_screen() -> void:
|
||||
if attached_to is not Card: super.confine_to_screen()
|
||||
|
|
|
|||
|
|
@ -14,12 +14,19 @@ func _init(cstm_minimum_size: Vector2 = minimum_size, note_position: Vector2 = V
|
|||
mouse_filter = MOUSE_FILTER_PASS
|
||||
self_modulate = Color(1, 1, 1, 0)
|
||||
|
||||
@onready var board : CardBoard = get_parent().get_parent() as CardBoard
|
||||
|
||||
func _ready():
|
||||
custom_minimum_size = Vector2(custom_minimum_size.x, 0)
|
||||
|
||||
var is_attatching: bool = false
|
||||
func _process(delta: float) -> void:
|
||||
var child := get_child(0) as StickyNote
|
||||
if child and not child.is_dragged:
|
||||
var k := pow(0.1, 60.0 * delta)
|
||||
child.position = child.position * (1.0-k) + ancor_position * (k)
|
||||
|
||||
var is_attaching: bool = false
|
||||
func attatch_sticky_note(attatchment: StickyNote, custom_handle: Node, animate:bool = true):
|
||||
is_attatching = true
|
||||
attached_sticky_note = attatchment
|
||||
attatchment.current_handle = custom_handle
|
||||
|
||||
|
|
@ -56,74 +63,6 @@ func attatch_sticky_note(attatchment: StickyNote, custom_handle: Node, animate:b
|
|||
attatchment.rotation = 0.0
|
||||
attatchment.scale = Vector2.ONE
|
||||
|
||||
is_attatching = false
|
||||
|
||||
|
||||
var is_gapped: bool = false
|
||||
func create_gap():
|
||||
var self_id := get_parent().get_children().find(self)
|
||||
var next_id = min(self_id + 1, get_parent().get_child_count() - 1)
|
||||
var previous_id = max(self_id - 1, 0)
|
||||
|
||||
var board = _get_board()
|
||||
if not (is_gapped or get_parent().get_child(next_id).attached_sticky_note.is_dragged or get_parent().get_child(previous_id).attached_sticky_note.is_dragged) and board and board.current_context == CardBoard.DRAG:
|
||||
is_gapped = true
|
||||
var height_tween: Tween = create_tween()
|
||||
height_tween.tween_property(self, "custom_minimum_size", minimum_size*Vector2(1.0, 1.8), 0.1)
|
||||
|
||||
get_parent().get_child(next_id).collapse_gap()
|
||||
if not get_parent().get_children().find(self) == 0: get_parent().get_child(previous_id).collapse_gap()
|
||||
|
||||
func collapse_gap():
|
||||
if is_gapped:
|
||||
is_gapped = false
|
||||
var height_tween: Tween = create_tween()
|
||||
height_tween.tween_property(self, "custom_minimum_size", minimum_size, 0.1)
|
||||
|
||||
var invalid: bool = false
|
||||
func clear_if_empty():
|
||||
if !is_empty(): return
|
||||
invalid = true
|
||||
# No need to manually clear attached_to - reparenting handles it
|
||||
var height_tween: Tween = create_tween()
|
||||
height_tween.tween_property(self, "custom_minimum_size", Vector2.ZERO, 0.3)
|
||||
await height_tween.finished
|
||||
var board = _get_board()
|
||||
if board:
|
||||
board.on_sticky_panel_cleared(get_parent().get_children().find(self))
|
||||
self.queue_free()
|
||||
|
||||
func replace_sticky_note_with(new_sticky_note: StickyNote):
|
||||
if is_empty():
|
||||
attached_sticky_note = new_sticky_note
|
||||
|
||||
func is_empty() -> bool:
|
||||
return get_child_count() == 0 and not is_attatching
|
||||
return get_child_count() == 0
|
||||
|
||||
|
||||
# === DROP TARGET PATTERN IMPLEMENTATION ===
|
||||
|
||||
## Checks if this panel can accept the given draggable
|
||||
func can_accept_drop(draggable: Draggable) -> bool:
|
||||
return draggable is StickyNote and is_empty()
|
||||
|
||||
## Handles dropping a sticky note onto this panel
|
||||
func handle_drop(draggable: StickyNote) -> int:
|
||||
if not can_accept_drop(draggable):
|
||||
return Draggable.DropResult.REJECTED
|
||||
|
||||
# Attach sticky to this panel with animation
|
||||
var board = _get_board()
|
||||
if board:
|
||||
attatch_sticky_note(draggable, board, true)
|
||||
|
||||
# Clean up other empty panels
|
||||
for panel in get_parent().get_children():
|
||||
if panel is StickyNotePanel and panel != self:
|
||||
panel.clear_if_empty()
|
||||
|
||||
return Draggable.DropResult.ACCEPTED
|
||||
|
||||
|
||||
func _get_board() -> CardBoard:
|
||||
return get_parent().get_parent() as CardBoard
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
class_name CardPicker extends CenterContainer
|
||||
class_name CardPicker
|
||||
extends Playable
|
||||
|
||||
#fixme INI is probably redundant.
|
||||
enum {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
class_name Interactable extends Node3D
|
||||
|
||||
@export var interaction: PackedScene = null
|
||||
var interaction_ui : Control = null
|
||||
var interaction_ui : Playable = null
|
||||
|
||||
@onready var view: Node3D = $View
|
||||
@onready var frame: Sprite3D = $Frame
|
||||
|
|
@ -65,6 +65,7 @@ func expand() -> void:
|
|||
|
||||
|
||||
func collapse() -> void:
|
||||
if not shown: return #TODO: test
|
||||
shown = false
|
||||
if tween and tween.is_valid(): tween.kill()
|
||||
tween = create_tween().set_ease(Tween.EASE_IN).set_trans(Tween.TRANS_BACK)
|
||||
|
|
@ -143,7 +144,7 @@ func interact() -> void:
|
|||
shown = false
|
||||
await collapse()
|
||||
|
||||
# Hide mouse and collapse other interactables BEFORE showing canvas
|
||||
# collapse other interactables BEFORE showing canvas
|
||||
get_tree().call_group("interactables", "collapse")
|
||||
|
||||
# Show the CanvasLayer so the story is visible full-screen
|
||||
|
|
@ -164,33 +165,7 @@ func interact() -> void:
|
|||
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 = ""
|
||||
caption.text = I18n.get_story_caption(story.scene_id)
|
||||
elif interaction_ui is CardBoard:
|
||||
caption.text = TranslationServer.translate("Mind Board")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
extends CenterContainer
|
||||
class_name StoryPlayable
|
||||
extends Playable
|
||||
|
||||
signal text_finished
|
||||
signal finished
|
||||
|
|
@ -148,7 +148,7 @@ func play():
|
|||
show()
|
||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||
|
||||
# Don't know how to do this.
|
||||
# FIXME: Don't know how to do this.
|
||||
#%StoryScroll.grab_focus()
|
||||
|
||||
if name == "draven":
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
extends Control
|
||||
class_name Playable
|
||||
|
||||
## Awaitable that encapsulates the core interaction with this Playable
|
||||
func play() -> void:
|
||||
await get_tree().process_frame # Dummy wait so this is a coroutine
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://dbmkkouhc0euw
|
||||
|
|
@ -28,6 +28,7 @@ PromptManager="*res://addons/input_prompts/input_prompt_manager.gd"
|
|||
Steam="*res://dev-util/steam.gd"
|
||||
Main="*res://singletons/main/main.tscn"
|
||||
HardCards="*res://dev-util/hardcoded_cards.tscn"
|
||||
I18n="*res://dev-util/i18n.gd"
|
||||
|
||||
[debug]
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://b752f680edsnv"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://bnskiyx1sksww" path="res://logic-scenes/board/physics-board.tscn" id="1_b12jd"]
|
||||
|
||||
[node name="BoardTests" type="Node"]
|
||||
|
||||
[node name="board" parent="." instance=ExtResource("1_b12jd")]
|
||||
|
|
@ -55,7 +55,7 @@ func _load_games():
|
|||
|
||||
|
||||
func _sort_saves() -> void:
|
||||
saves.sort_custom(func(a: SaveGame, b: SaveGame) -> int:
|
||||
saves.sort_custom(func(a: SaveGame, b: SaveGame) -> bool:
|
||||
return a.last_saved > b.last_saved
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue