2024-10-06 09:31:47 +00:00
class_name CardBoard extends PanelContainer
2023-06-27 11:51:23 +00:00
2023-10-15 11:27:02 +00:00
enum { NAVIGATE , ASSIGN , DRAG }
2025-03-31 19:31:09 +00:00
enum Error {
OK ,
OUT_OF_BOUNDS ,
ILLEGAL_STATE ,
MISSING
}
2023-10-15 11:27:02 +00:00
2023-11-01 22:19:47 +00:00
var focus_stickies : bool = true :
2024-09-15 09:30:31 +00:00
set ( stickies ) :
2025-05-16 21:50:19 +00:00
if not is_node_ready ( ) : return
2024-09-15 09:30:31 +00:00
if stickies and sticky_note_container . get_child_count ( ) == 0 : return
2025-01-31 02:22:07 +00:00
# this messes things up if called unneeded.
if focus_stickies != stickies :
focus_stickies = stickies
if not current_context == ASSIGN :
if stickies :
current_sticky_note_id = current_sticky_note_id
else :
current_dropzone_id = current_dropzone_id
2023-07-02 13:10:33 +00:00
2023-07-11 13:27:44 +00:00
var has_stage = false :
2024-09-15 09:30:31 +00:00
set ( focus ) :
if focus :
has_stage = true
get_tree ( ) . call_group ( " interactables " , " collapse " )
2025-05-16 11:16:19 +00:00
current_dropzone_id = 0
current_sticky_note_id = 0
focus_stickies = true
2024-09-15 09:30:31 +00:00
else :
has_stage = false
if is_node_ready ( ) :
if focus :
process_mode = Node . PROCESS_MODE_INHERIT
else :
process_mode = Node . PROCESS_MODE_DISABLED
2025-01-31 02:22:07 +00:00
for sticky in dropzone . get_children ( ) :
if sticky is StickyNote :
sticky . is_dragged = false
2024-09-15 09:30:31 +00:00
visible = has_stage
2023-07-11 13:04:46 +00:00
2023-07-01 11:43:27 +00:00
@ onready var dropzone = $ HBoxContainer / dropzone
2023-08-01 08:59:24 +00:00
var dropzone_size : Vector2
2025-03-23 14:43:04 +00:00
@ export var dropzone_padding : int = 100
2023-10-12 16:25:21 +00:00
@ onready var sticky_note_container = $ HBoxContainer / ScrollContainer / VBoxContainer
2023-10-15 11:27:02 +00:00
@ onready var current_context : int = NAVIGATE :
2024-09-15 09:30:31 +00:00
set ( context ) :
if current_context == ASSIGN and ! context == ASSIGN :
sticky_note_container . get_child ( current_sticky_note_id ) . clear_if_empty ( )
#match context:
# NAVIGATE:
# _return_sticky_notes_to_panels()
# DRAG:
# pass
# ASSIGN:
# pass
current_context = context
2023-07-17 22:15:04 +00:00
@ onready var instructions = $ instructions_panel / HBoxContainer / cards_remaining
2025-03-31 19:31:09 +00:00
@ onready var timer : Timer = $ Timer
2023-07-17 22:15:04 +00:00
var mementos_collected : int = 0 :
2024-09-15 09:30:31 +00:00
set ( mementos ) :
mementos_collected = mementos
match mementos :
1 :
instructions . text = " There are three Mementos left to find. "
2 :
instructions . text = " You have collected half of the mementos. "
3 :
instructions . text = " Find the last Memento to complete the Board. "
4 :
instructions . text = " Combine cards to order your thoughts. "
2023-06-27 11:51:23 +00:00
2023-10-12 16:25:21 +00:00
@ onready var currently_active_node : Area2D = null :
2024-09-15 09:30:31 +00:00
set ( new_node ) :
2025-01-31 02:22:07 +00:00
# this makes sure no accidental context switches can happen while a card is being dragged.
2025-02-24 15:14:08 +00:00
if not ( current_context == DRAG ) :
2025-01-31 02:22:07 +00:00
if not currently_active_node == null :
currently_active_node . highlighted = false
currently_active_node = new_node
if not currently_active_node == null :
currently_active_node . highlighted = true
2023-07-01 13:19:54 +00:00
2023-09-23 14:19:58 +00:00
@ onready var current_dropzone_id : int = 0 :
2024-09-15 09:30:31 +00:00
set ( new_id ) :
2025-05-16 21:50:19 +00:00
if is_node_ready ( ) :
if new_id > dropzone . get_child_count ( ) - 1 : current_dropzone_id = 0
elif new_id < 0 : current_dropzone_id = dropzone . get_child_count ( ) - 1
else : current_dropzone_id = new_id
if current_context == ASSIGN and not focus_stickies :
while not dropzone . get_child ( current_dropzone_id ) is Card : current_dropzone_id = ( current_dropzone_id + 1 ) % dropzone . get_child_count ( )
dropzone . get_child ( current_dropzone_id ) . preview_sticky_note ( currently_active_node )
elif not focus_stickies :
currently_active_node = dropzone . get_child ( current_dropzone_id )
2024-09-15 09:30:31 +00:00
2023-10-12 16:25:21 +00:00
@ onready var current_sticky_note_id : int = 0 :
2024-09-15 09:30:31 +00:00
set ( new_id ) :
2025-05-16 21:50:19 +00:00
if is_node_ready ( ) :
if sticky_note_container . get_child_count ( ) < = 1 : return
elif new_id > sticky_note_container . get_child_count ( ) - 1 : current_sticky_note_id = 0
elif new_id < 0 : current_sticky_note_id = sticky_note_container . get_child_count ( ) - 1
else : current_sticky_note_id = new_id
if current_context == ASSIGN :
_return_sticky_notes_to_panels ( )
currently_active_node . preview_sticky_note ( sticky_note_container . get_child ( current_sticky_note_id ) . attached_sticky_note )
2025-02-24 15:14:08 +00:00
else :
2025-05-16 21:50:19 +00:00
if sticky_note_container . get_child ( current_sticky_note_id ) . get_child_count ( ) == 1 :
currently_active_node = sticky_note_container . get_child ( current_sticky_note_id ) . get_child ( 0 )
else :
for i in range ( sticky_note_container . 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 )
2023-07-02 13:10:33 +00:00
2025-03-31 19:31:09 +00:00
var last_save_dict : Dictionary
var text_recovery : Dictionary
2023-07-19 11:52:01 +00:00
signal board_completed
2023-06-27 11:51:23 +00:00
# Called when the node enters the scene tree for the first time.
func _ready ( ) :
2025-02-24 15:14:08 +00:00
var size_reference = StickyNotePanel . new ( )
2024-09-15 09:30:31 +00:00
2025-02-24 15:14:08 +00:00
dropzone_size = get_viewport_rect ( ) . size - Vector2 ( dropzone_padding + size_reference . minimum_size . x , dropzone_padding )
2024-09-15 09:30:31 +00:00
if get_parent ( ) == get_tree ( ) . root :
2025-05-16 21:50:19 +00:00
populate_board ( [ " c_void " , ' c_joy ' , " p_wet " , " p_effort " ] )
populate_board ( [ " c_jui_jutsu " , ' c_hit ' , " p_girly " , " p_vent " ] )
populate_board ( [ " c_comic_heroes " , ' c_teasing ' , " p_agent_q " , " p_good_intended " ] )
populate_board ( [ " c_out_of_world " , ' c_confusion ' , " p_outer_conflict " , " p_unique " ] )
2024-09-15 09:30:31 +00:00
mementos_collected = 2
2023-09-23 14:19:58 +00:00
2024-09-15 09:30:31 +00:00
has_stage = has_stage
2025-02-24 15:14:08 +00:00
get_viewport ( ) . gui_focus_changed . connect ( reclaim_lost_focus )
2025-03-25 21:34:13 +00:00
2025-04-13 17:31:39 +00:00
#FIXME properly implement board recovery
#timer.timeout.connect(validate_board)
#timer.start()
2025-03-31 19:31:09 +00:00
2025-04-13 17:31:39 +00:00
#await get_tree().process_frame
#last_save_dict = get_save_dict()
2025-02-24 15:14:08 +00:00
func reclaim_lost_focus ( ) :
if has_stage :
grab_focus ( )
2023-09-23 14:19:58 +00:00
2023-10-15 11:27:02 +00:00
#func _process(delta):
2025-05-21 17:42:45 +00:00
# # drops dragged area when Mouse is no longer pressed.
# if has_stage and !Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT) and current_context == DRAG:
# currently_active_node.is_dragged = false
2023-07-02 13:10:33 +00:00
2023-07-02 08:11:54 +00:00
# Will be used later to spawn Cards and Post-Its and remember them in the dictionary
2025-04-13 17:07:31 +00:00
func populate_board ( card_names : Array [ StringName ] ) :
2024-09-15 09:30:31 +00:00
mementos_collected += 1
2025-04-13 17:07:31 +00:00
var all_new : Dictionary = HardCards . get_cards_by_name_array ( card_names )
2024-09-15 09:30:31 +00:00
# spawning the cards and adding them to the dictionary
for new_card in all_new [ " cards " ] :
2025-04-13 17:07:31 +00:00
add_card ( new_card , false )
2024-09-15 09:30:31 +00:00
for new_sticky_note in all_new [ " sticky_notes " ] : # spawning a sticky note
2025-04-13 17:07:31 +00:00
add_sticky_note ( new_sticky_note , false )
2024-09-15 09:30:31 +00:00
#currently_active_node = area_dict["dropzone_content"][0] # set first Card as currently selected node by default
currently_active_node = dropzone . get_child ( 0 )
2023-11-01 22:19:47 +00:00
2025-04-13 17:07:31 +00:00
func add_card ( card : Card , reparent : bool = true ) :
if reparent :
card . reparent ( self )
else :
add_child ( card )
2024-09-15 09:30:31 +00:00
card . position = Vector2 ( randi_range ( dropzone_padding , dropzone_size . x ) , randi_range ( dropzone_padding , dropzone_size . y ) )
insert_area ( dropzone , card )
card . set_owner ( self )
card . is_dragable = true
2025-04-13 17:07:31 +00:00
func add_sticky_note ( sticky : StickyNote , reparent : bool = true ) :
2025-02-24 15:14:08 +00:00
var new_panel = StickyNotePanel . new ( )
2025-03-23 13:31:00 +00:00
sticky_note_container . add_child ( new_panel , true , Node . INTERNAL_MODE_DISABLED )
2025-02-24 15:14:08 +00:00
#WARNING this for some reason would break the tweens
2024-09-15 09:30:31 +00:00
new_panel . set_owner ( self )
2025-02-24 15:14:08 +00:00
sticky . current_handle = self
2025-04-13 17:07:31 +00:00
new_panel . attatch_sticky_note ( sticky , self , false , reparent )
2024-09-15 09:30:31 +00:00
2023-07-01 13:19:54 +00:00
# Checks if a Node is currently inside the dropzone
func is_in_dropzone ( to_check : Node ) - > bool :
2024-09-15 09:30:31 +00:00
return dropzone . get_rect ( ) . has_point ( to_check . global_position )
2023-07-01 13:19:54 +00:00
2025-01-31 02:22:07 +00:00
# Called by notes when a mouse event needs handling
func handle_mouse_button ( input : InputEventMouseButton , to_handle = currently_active_node ) :
# Makes sure that only the same area is dragged.
2024-09-15 09:30:31 +00:00
# Otherwise overlapping areas are dragged at the same time.
if current_context == DRAG and to_handle != currently_active_node :
return
2025-01-31 02:22:07 +00:00
if input . button_index == MOUSE_BUTTON_MASK_LEFT and input . pressed :
currently_active_node = to_handle
2024-09-15 09:30:31 +00:00
to_handle . is_dragged = true
if to_handle is StickyNote :
if not to_handle . on_board :
to_handle . reparent ( dropzone )
to_handle . on_board = true
2025-02-24 15:14:08 +00:00
to_handle . attached_to = self
2024-09-15 09:30:31 +00:00
current_context = DRAG
2025-05-21 17:42:45 +00:00
2024-09-15 09:30:31 +00:00
# when Drag stops ...
2025-01-31 02:22:07 +00:00
if input . button_index == MOUSE_BUTTON_MASK_LEFT and not input . pressed :
2024-09-15 09:30:31 +00:00
to_handle . is_dragged = false
if to_handle is StickyNote :
if is_in_dropzone ( to_handle ) :
if to_handle . has_overlapping_areas ( ) :
for area in to_handle . get_overlapping_areas ( ) :
if area is Card :
focus_stickies = false
if area . has_sticky_note_attached ( ) :
to_handle = area . exchange_sticky_note_with ( to_handle )
to_handle . reparent ( dropzone )
to_handle . on_board = true
2025-02-24 15:14:08 +00:00
# FIXME: this caused an error when all stickies were attatched ...
2024-09-15 09:30:31 +00:00
sticky_note_container . get_child ( current_sticky_note_id ) . attached_sticky_note = to_handle
to_handle . attached_to = sticky_note_container . get_child ( current_sticky_note_id )
to_handle . reset_drag ( )
current_context = NAVIGATE
2025-04-30 14:34:00 +00:00
_return_sticky_notes_to_panels ( )
2024-09-15 09:30:31 +00:00
return
else :
area . attach_sticky_note ( to_handle )
2025-05-08 19:53:53 +00:00
to_handle . z_index = 0
2025-03-31 19:31:09 +00:00
if sticky_note_container . get_child_count ( ) > 0 :
sticky_note_container . get_child ( current_sticky_note_id ) . clear_if_empty ( )
2024-09-15 09:30:31 +00:00
current_context = NAVIGATE
2025-03-31 19:31:09 +00:00
if is_board_complete ( ) : board_completed . emit ( )
2024-09-15 09:30:31 +00:00
return
else :
2025-02-24 15:14:08 +00:00
var i : int = 0
for panel : StickyNotePanel in sticky_note_container . get_children ( ) :
i += 1
if panel . is_gapped or i == sticky_note_container . get_child_count ( ) :
panel . collapse_gap ( )
var new_panel = StickyNotePanel . new ( )
sticky_note_container . add_child ( new_panel )
sticky_note_container . move_child ( new_panel , i )
new_panel . attatch_sticky_note ( to_handle , self )
new_panel . owner = self
panel . clear_if_empty ( )
2024-09-15 09:30:31 +00:00
_return_sticky_notes_to_panels ( )
2025-02-24 15:14:08 +00:00
current_context = NAVIGATE
2024-09-15 09:30:31 +00:00
return
## Dropping Cards and Sticky Notes not causing a return condition above.
2025-02-24 15:14:08 +00:00
if not ( to_handle is StickyNote and to_handle . is_sticky_note_attached ( ) ) :
2025-03-31 19:31:09 +00:00
if to_handle . get_parent ( ) is Card :
insert_area ( to_handle . get_parent ( ) . remove_sticky_note ( ) , to_handle )
else :
insert_area ( dropzone , to_handle )
2024-09-15 09:30:31 +00:00
current_context = NAVIGATE
focus_stickies = false
current_dropzone_id = dropzone . get_children ( ) . find ( to_handle )
if to_handle is StickyNote :
to_handle . rotation = to_handle . base_rotation
to_handle . scale = to_handle . base_scale
2023-11-01 22:19:47 +00:00
2024-09-15 09:30:31 +00:00
if input . is_action_pressed ( " mouse_right " ) and current_context == DRAG :
to_handle . reset_drag ( )
2023-07-01 13:19:54 +00:00
2025-01-31 02:22:07 +00:00
2023-10-12 16:25:21 +00:00
func _return_sticky_notes_to_panels ( ) :
2025-02-24 15:14:08 +00:00
for panel : StickyNotePanel in sticky_note_container . get_children ( ) :
2024-09-15 09:30:31 +00:00
panel . reclaim_sticky_note ( )
2025-04-30 14:34:00 +00:00
for node in dropzone . get_children ( ) :
if node is StickyNote :
node . is_dragable = true
2024-09-15 09:30:31 +00:00
2023-08-30 11:23:37 +00:00
func is_board_complete ( ) - > bool :
2024-09-15 09:30:31 +00:00
if mementos_collected == 4 :
for card in dropzone . get_children ( ) :
if card is Card :
if not card . has_sticky_note_attached ( ) :
return false
return true
return false
2023-08-30 09:07:22 +00:00
func is_board_lore ( ) - > bool :
2024-09-15 09:30:31 +00:00
for card in dropzone . get_children ( ) :
2025-04-13 17:07:31 +00:00
if card is Card :
if card . has_sticky_note_attached ( ) :
if not card . current_sticky_note . sticky_id . contains ( card . card_id ) : return false
2024-09-15 09:30:31 +00:00
return true
2023-07-02 13:10:33 +00:00
# Mark area that was hovered over as currently selected
2023-07-01 14:59:13 +00:00
func handle_hover ( to_handle : Area2D ) :
2024-09-15 09:30:31 +00:00
if Input . is_mouse_button_pressed ( MOUSE_BUTTON_LEFT ) : return
currently_active_node = to_handle
if is_in_dropzone ( to_handle ) or to_handle is Card :
if not ( to_handle is StickyNote and ! to_handle . on_board ) :
current_dropzone_id = dropzone . get_children ( ) . find ( to_handle )
focus_stickies = false
else :
current_sticky_note_id = sticky_note_container . get_children ( ) . find ( to_handle . attached_to )
focus_stickies = true
2023-09-23 14:19:58 +00:00
# Adds a child at the correct child indext in an area
func insert_area ( parent : Control , node : Area2D ) :
2024-09-15 09:30:31 +00:00
var children : Array = parent . get_children ( )
var i = 0
if not node in parent . get_children ( ) :
node . reparent ( parent )
if node is StickyNote :
node . on_board = true
node . owner = self
if children . size ( ) > 0 :
children . erase ( node )
while children [ i ] . global_position . y < node . global_position . y and i + 1 < children . size ( ) :
i += 1
parent . move_child ( node , i )
2025-03-31 19:31:09 +00:00
if node is StickyNote :
node . attached_to = self
2025-04-30 14:34:00 +00:00
node . is_dragable = true
2024-09-15 09:30:31 +00:00
2023-07-02 13:10:33 +00:00
# Takes the inputs for control inputs
func _input ( event ) :
2024-09-15 09:30:31 +00:00
2025-01-31 02:22:07 +00:00
if not has_stage or not is_instance_valid ( currently_active_node ) : return
2025-05-16 11:19:22 +00:00
if event . is_action_pressed ( " ui_cancel " ) :
State . leave_stage ( self )
get_viewport ( ) . set_input_as_handled ( )
2025-01-31 02:22:07 +00:00
2025-05-21 17:42:45 +00:00
if event is InputEventMouse :
# makes sure to pass release events so notes do not get attached to the mouse while the cursor leaves the area.
if event is InputEventMouseButton and current_context == DRAG :
if event . button_index == MOUSE_BUTTON_LEFT and not event . pressed :
handle_mouse_button ( event )
get_viewport ( ) . set_input_as_handled ( )
else :
return
2025-02-24 15:14:08 +00:00
if current_context != DRAG :
2024-09-15 09:30:31 +00:00
if event . is_action_pressed ( " ui_up " ) :
if focus_stickies :
current_sticky_note_id -= 1
else :
current_dropzone_id -= 1
2025-05-16 11:19:22 +00:00
get_viewport ( ) . set_input_as_handled ( )
2024-09-15 09:30:31 +00:00
elif event . is_action_pressed ( " ui_down " ) : # down to select an element beneath
if focus_stickies :
current_sticky_note_id += 1
else :
current_dropzone_id += 1
2025-05-16 11:19:22 +00:00
get_viewport ( ) . set_input_as_handled ( )
2024-09-15 09:30:31 +00:00
elif event . is_action_pressed ( " ui_right " ) : # left to switch context to the left
if not focus_stickies :
if current_context == NAVIGATE :
focus_stickies = true
elif current_context == ASSIGN :
current_context = NAVIGATE
2025-05-16 11:19:22 +00:00
get_viewport ( ) . set_input_as_handled ( )
2024-09-15 09:30:31 +00:00
elif event . is_action_pressed ( " ui_left " ) : # right to switch context to the right
if focus_stickies :
if current_context == NAVIGATE :
focus_stickies = false
elif current_context == ASSIGN :
current_context = NAVIGATE
2025-05-16 11:19:22 +00:00
get_viewport ( ) . set_input_as_handled ( )
2024-09-15 09:30:31 +00:00
elif event . is_action_pressed ( " ui_accept " ) : # select the selected note it
if dropzone . get_child ( current_dropzone_id ) is Card :
2025-05-08 19:53:53 +00:00
var card : Card = dropzone . get_child ( current_dropzone_id )
if current_context == ASSIGN : # to assign it to a card
if card . has_sticky_note_attached ( ) :
currently_active_node = card . exchange_sticky_note_with ( currently_active_node )
current_dropzone_id = find_first_free_card ( )
else :
card . attach_sticky_note ( sticky_note_container . get_child ( current_sticky_note_id ) . attached_sticky_note )
current_context = NAVIGATE
current_sticky_note_id += 1
current_dropzone_id = find_first_free_card ( )
if is_board_complete ( ) : emit_signal ( " board_completed " )
2024-09-15 09:30:31 +00:00
else :
2025-05-08 19:53:53 +00:00
if ! focus_stickies and card . has_sticky_note_attached ( ) :
currently_active_node = card . remove_sticky_note ( )
add_sticky_note ( currently_active_node )
current_dropzone_id = - 1
else : current_dropzone_id = find_first_free_card ( )
current_context = ASSIGN
focus_stickies = ! focus_stickies
if focus_stickies :
current_sticky_note_id = current_sticky_note_id
else :
current_dropzone_id = current_dropzone_id
elif dropzone . get_child ( current_dropzone_id ) is StickyNote :
if currently_active_node is StickyNote :
currently_active_node = dropzone . get_child ( current_dropzone_id )
focus_stickies = false
current_context = ASSIGN
current_dropzone_id += 1
currently_active_node . is_dragable = false
currently_active_node . z_index = 1
2025-05-16 11:19:22 +00:00
get_viewport ( ) . set_input_as_handled ( )
2023-07-02 13:10:33 +00:00
2023-10-12 16:25:21 +00:00
# move the note it so it floats next to the card where it should be attached
func _select_card_for_assigning ( sticky_note : Area2D , card : Area2D ) :
2024-09-15 09:30:31 +00:00
sticky_note . tween_transform_to ( card . get_child ( 3 ) . global_position )
2023-07-15 13:26:14 +00:00
2023-07-19 11:52:01 +00:00
func on_scene_skipped ( i : int ) :
2024-09-15 09:30:31 +00:00
mementos_collected += i
2023-07-01 13:19:54 +00:00
2023-07-19 11:52:01 +00:00
func claim_focus ( ) :
2024-09-15 09:30:31 +00:00
State . pass_stage_to ( self )
2023-10-15 11:27:02 +00:00
func find_first_free_card ( ) - > int :
2024-09-15 09:30:31 +00:00
for i in range ( dropzone . get_child_count ( ) ) :
# start searching at the current location, use modulo to avoid getting out of array bounds
if ! dropzone . get_child ( ( i + current_dropzone_id ) % dropzone . get_child_count ( ) ) . has_sticky_note_attached ( ) :
return ( i + current_dropzone_id ) % dropzone . get_child_count ( )
return - 1
2023-11-01 22:19:47 +00:00
func on_sticky_panel_cleared ( ) :
2024-09-15 09:30:31 +00:00
if current_sticky_note_id == sticky_note_container . get_child_count ( ) - 1 :
current_sticky_note_id -= 1
2024-10-02 23:12:24 +00:00
func get_save_dict ( ) - > Dictionary :
var cards : Dictionary = { }
var stickies : Dictionary = { }
for child in dropzone . get_children ( ) :
if child is Card :
2025-03-25 21:34:13 +00:00
# Save position of Card.
cards [ child . name ] = child . transform . origin
2024-10-02 23:12:24 +00:00
if child . has_sticky_note_attached ( ) :
2025-03-25 21:34:13 +00:00
# Saves Card Name as position of it's children.
2024-10-02 23:12:24 +00:00
stickies [ child . get_attached_sticky_note ( ) . name ] = child . name
2025-03-25 21:34:13 +00:00
2024-10-02 23:12:24 +00:00
elif child is StickyNote :
2025-03-25 21:34:13 +00:00
# Save position of StickyNote.
2024-10-02 23:12:24 +00:00
cards [ child . name ] = child . transform . origin
for child in sticky_note_container . get_children ( ) :
2025-02-24 15:14:08 +00:00
if child is StickyNotePanel :
2025-03-25 21:34:13 +00:00
# Saves all collected Stickies that are not on board.
2024-10-02 23:12:24 +00:00
stickies [ child . attached_sticky_note . name ] = - 1
return {
" cards " : cards ,
" stickies " : stickies
2025-03-25 21:34:13 +00:00
}
2024-10-02 23:12:24 +00:00
2025-03-31 19:31:09 +00:00
2024-10-02 23:12:24 +00:00
func initialise_from_save ( savegame : SaveGame ) :
2025-03-31 19:31:09 +00:00
last_save_dict = savegame . board_state . duplicate ( )
2024-10-06 09:31:47 +00:00
if savegame . board_state == { } : return
2025-03-31 19:31:09 +00:00
rebuild_from_savedict ( savegame . board_state )
func rebuild_from_savedict ( board_state : Dictionary ) :
2025-05-16 23:53:09 +00:00
var cards : Dictionary [ StringName , Variant ]
if board_state [ " cards " ] != { } :
cards = board_state [ " cards " ]
var stickies : Dictionary [ StringName , Variant ]
if board_state [ " stickies " ] != { } :
stickies = board_state [ " stickies " ]
if cards == null and stickies == null : return
2024-10-02 23:12:24 +00:00
2025-04-13 17:07:31 +00:00
var card_pile = HardCards . get_cards_by_name_array ( cards . keys ( ) + ( stickies . keys ( ) ) )
2024-10-02 23:12:24 +00:00
for card : Card in card_pile [ " cards " ] :
2025-05-16 21:50:19 +00:00
add_card ( card , false )
card . transform . origin = cards [ card . name ] # Replacing position reference with card reference! Needed in next loop.
2024-10-02 23:12:24 +00:00
cards [ card . name ] = card
2025-03-31 19:31:09 +00:00
text_recovery [ card . name ] = card . text
2024-10-02 23:12:24 +00:00
for sticky : StickyNote in card_pile [ " sticky_notes " ] :
2025-03-31 19:31:09 +00:00
text_recovery [ sticky . name ] = sticky . text
2024-10-02 23:12:24 +00:00
if stickies [ sticky . name ] == - 1 :
2025-05-16 21:50:19 +00:00
add_sticky_note ( sticky , false )
2025-03-25 21:34:13 +00:00
elif stickies [ sticky . name ] is String :
2024-10-02 23:12:24 +00:00
cards [ stickies [ sticky . name ] ] . attach_sticky_note ( sticky )
else :
insert_area ( dropzone , sticky )
sticky . transform . origin = stickies [ sticky . name ]
2025-03-31 19:31:09 +00:00
func validate_board ( ) :
2025-04-28 13:46:50 +00:00
return
2025-03-31 19:31:09 +00:00
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 :
for child in dropzone . get_children ( ) : child . free ( )
for child in sticky_note_container . get_children ( ) : child . free ( )
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