WIP: adding recovery to cardboard

This commit is contained in:
betalars 2025-03-31 21:31:09 +02:00
parent 23eb1e3ed2
commit ff8145a097
4 changed files with 105 additions and 14 deletions

View File

@ -1,5 +1,6 @@
extends Control extends Control
# used to display cards during picking
func get_cards_by_scene_id(id: int) -> Array: func get_cards_by_scene_id(id: int) -> Array:
var output:Array var output:Array
@ -18,6 +19,7 @@ func get_cards_by_scene_id(id: int) -> Array:
return output return output
# used to put cards on the dev board
func get_cards_by_name_array(names: Array) -> Dictionary: func get_cards_by_name_array(names: Array) -> Dictionary:
var output:Dictionary = { var output:Dictionary = {
"cards": [], "cards": [],

View File

@ -1,12 +1,12 @@
class_name CardBoard extends PanelContainer class_name CardBoard extends PanelContainer
#var area_dict = {
# "dropzone_content": [],
# "cards": [],
# "sticky_notes_in_list": [],
# "sticky_note_panels": []
#}
enum {NAVIGATE, ASSIGN, DRAG} enum {NAVIGATE, ASSIGN, DRAG}
enum Error {
OK,
OUT_OF_BOUNDS,
ILLEGAL_STATE,
MISSING
}
var focus_stickies:bool = true: var focus_stickies:bool = true:
set(stickies): set(stickies):
@ -57,6 +57,7 @@ var dropzone_size: Vector2
# pass # pass
current_context = context current_context = context
@onready var instructions = $instructions_panel/HBoxContainer/cards_remaining @onready var instructions = $instructions_panel/HBoxContainer/cards_remaining
@onready var timer: Timer = $Timer
var mementos_collected: int = 0: var mementos_collected: int = 0:
set(mementos): set(mementos):
@ -110,7 +111,8 @@ var mementos_collected: int = 0:
if sticky_note_container.get_child(i).get_child_count() == 1: if sticky_note_container.get_child(i).get_child_count() == 1:
currently_active_node = sticky_note_container.get_child(i).get_child(0) currently_active_node = sticky_note_container.get_child(i).get_child(0)
var cache: Array = [] var last_save_dict: Dictionary
var text_recovery: Dictionary
signal board_completed signal board_completed
@ -129,6 +131,12 @@ func _ready():
get_viewport().gui_focus_changed.connect(reclaim_lost_focus) get_viewport().gui_focus_changed.connect(reclaim_lost_focus)
timer.timeout.connect(validate_board)
timer.start()
await get_tree().process_frame
last_save_dict = get_save_dict()
func reclaim_lost_focus(): func reclaim_lost_focus():
if has_stage: if has_stage:
@ -212,9 +220,10 @@ func handle_mouse_button(input: InputEventMouseButton, to_handle = currently_act
return return
else: else:
area.attach_sticky_note(to_handle) area.attach_sticky_note(to_handle)
sticky_note_container.get_child(current_sticky_note_id).clear_if_empty() if sticky_note_container.get_child_count() > 0:
sticky_note_container.get_child(current_sticky_note_id).clear_if_empty()
current_context = NAVIGATE current_context = NAVIGATE
if is_board_complete(): emit_signal("board_completed") if is_board_complete(): board_completed.emit()
return return
else: else:
var i: int = 0 var i: int = 0
@ -234,7 +243,10 @@ func handle_mouse_button(input: InputEventMouseButton, to_handle = currently_act
## Dropping Cards and Sticky Notes not causing a return condition above. ## Dropping Cards and Sticky Notes not causing a return condition above.
if not (to_handle is StickyNote and to_handle.is_sticky_note_attached()): if not (to_handle is StickyNote and to_handle.is_sticky_note_attached()):
insert_area(dropzone, to_handle) if to_handle.get_parent() is Card:
insert_area(to_handle.get_parent().remove_sticky_note(), to_handle)
else:
insert_area(dropzone, to_handle)
current_context = NAVIGATE current_context = NAVIGATE
focus_stickies = false focus_stickies = false
current_dropzone_id = dropzone.get_children().find(to_handle) current_dropzone_id = dropzone.get_children().find(to_handle)
@ -295,6 +307,9 @@ func insert_area(parent: Control, node: Area2D):
i+=1 i+=1
parent.move_child(node, i) parent.move_child(node, i)
if node is StickyNote:
node.attached_to = self
# Takes the inputs for control inputs # Takes the inputs for control inputs
func _input(event): func _input(event):
@ -389,7 +404,6 @@ func on_sticky_panel_cleared():
if current_sticky_note_id == sticky_note_container.get_child_count() - 1: if current_sticky_note_id == sticky_note_container.get_child_count() - 1:
current_sticky_note_id -= 1 current_sticky_note_id -= 1
func get_save_dict() -> Dictionary: func get_save_dict() -> Dictionary:
var cards: Dictionary = {} var cards: Dictionary = {}
var stickies: Dictionary = {} var stickies: Dictionary = {}
@ -410,10 +424,15 @@ func get_save_dict() -> Dictionary:
"stickies": stickies "stickies": stickies
} if cards != {} and stickies != {} else {} } if cards != {} and stickies != {} else {}
func initialise_from_save(savegame: SaveGame): func initialise_from_save(savegame: SaveGame):
last_save_dict = savegame.board_state.duplicate()
if savegame.board_state == {}: return if savegame.board_state == {}: return
var cards: Dictionary = savegame.board_state["cards"] rebuild_from_savedict(savegame.board_state)
var stickies: Dictionary = savegame.board_state["stickies"]
func rebuild_from_savedict(board_state:Dictionary):
var cards: Dictionary = board_state["cards"]
var stickies: Dictionary = board_state["stickies"]
var card_pile = board_of_devs.get_cards_by_name_array(cards.keys() + (stickies.keys())) var card_pile = board_of_devs.get_cards_by_name_array(cards.keys() + (stickies.keys()))
@ -421,7 +440,9 @@ func initialise_from_save(savegame: SaveGame):
add_card(card) add_card(card)
card.transform.origin = cards[card.name] card.transform.origin = cards[card.name]
cards[card.name] = card cards[card.name] = card
text_recovery[card.name] = card.text
for sticky:StickyNote in card_pile["sticky_notes"]: for sticky:StickyNote in card_pile["sticky_notes"]:
text_recovery[sticky.name] = sticky.text
if stickies[sticky.name] == -1: if stickies[sticky.name] == -1:
add_sticky_note(sticky) add_sticky_note(sticky)
if stickies[sticky.name] is String: if stickies[sticky.name] is String:
@ -429,3 +450,69 @@ func initialise_from_save(savegame: SaveGame):
else: else:
insert_area(dropzone, sticky) insert_area(dropzone, sticky)
sticky.transform.origin = stickies[sticky.name] sticky.transform.origin = stickies[sticky.name]
func validate_board():
if current_context == NAVIGATE:
var needs_rebuild = false
for node in dropzone.get_children():
if node is Card:
match validate_card(node):
Error.OUT_OF_BOUNDS:
node.position = last_save_dict[node.name]
Error.ILLEGAL_STATE:
needs_rebuild = true
if node is StickyNote:
match validate_sticky(node):
Error.OUT_OF_BOUNDS:
node.position = last_save_dict[node.name]
Error.ILLEGAL_STATE:
needs_rebuild = true
for panel:StickyNotePanel in sticky_note_container.get_children():
if panel.attached_sticky_note != null:
match validate_sticky(panel.attached_sticky_note):
Error.OUT_OF_BOUNDS:
panel.attached_sticky_note.position = panel.ancor_position
Error.ILLEGAL_STATE:
needs_rebuild = true
# FIXME: currently, illegal temporary state exists a lot and needs to be rectified before this can be trusted.
if needs_rebuild and false:
remove_child(board_of_devs)
for child in dropzone.get_children(): child.free()
for child in sticky_note_container.get_children(): child.free()
board_of_devs = preload("res://dev-util/board of devs.tscn").instantiate()
add_child(board_of_devs)
rebuild_from_savedict(last_save_dict)
current_dropzone_id = 0
current_sticky_note_id = 0
focus_stickies = false
current_context = NAVIGATE
else:
last_save_dict = get_save_dict()
func validate_sticky(note: StickyNote) -> CardBoard.Error:
if not get_viewport_rect().has_point(note.get_global_transform().origin):
return Error.OUT_OF_BOUNDS
if note.attached_to is StickyNotePanel:
if note.position != note.attached_to.ancor_position:
return Error.OUT_OF_BOUNDS
if (note.on_board and not is_in_dropzone(note)):
return Error.ILLEGAL_STATE
if not ((note.attached_to == self and dropzone.get_children().has(note)) or note.attached_to == note.get_parent()) or note.shift_tween != null:
return Error.ILLEGAL_STATE
return Error.OK
func validate_card(card: Card) -> CardBoard.Error:
if not is_in_dropzone(card):
return Error.OUT_OF_BOUNDS
if card.get_attached_sticky_note() != card.current_sticky_note:
#push_error("Card %s claims to have %s as current sticky note but has %s attached." % [card.name, card.current_sticky_note, card.get_attached_sticky_note()])
return Error.ILLEGAL_STATE
if not card.owner == self:
return Error.ILLEGAL_STATE
return CardBoard.Error.OK

View File

@ -212,7 +212,7 @@ func remove_sticky_note() -> StickyNote:
former_child.reparent(get_parent()) former_child.reparent(get_parent())
former_child.owner = self.owner former_child.owner = self.owner
former_child.on_board = true former_child.on_board = true
former_child.attached_to = null former_child.attached_to = owner
return former_child return former_child
func exchange_sticky_note_with(new_note: StickyNote) -> StickyNote: func exchange_sticky_note_with(new_note: StickyNote) -> StickyNote:

View File

@ -132,3 +132,5 @@ vertical_alignment = 1
[node name="VSeparator" type="VSeparator" parent="instructions_panel/HBoxContainer"] [node name="VSeparator" type="VSeparator" parent="instructions_panel/HBoxContainer"]
custom_minimum_size = Vector2(15, 0) custom_minimum_size = Vector2(15, 0)
layout_mode = 2 layout_mode = 2
[node name="Timer" type="Timer" parent="."]