From 5b034a9ce7e82da512b9f8850861849e785d7956 Mon Sep 17 00:00:00 2001 From: Tiger Jove Date: Sun, 18 Jan 2026 19:16:56 +0100 Subject: [PATCH] fix: board deserialization --- src/dev-util/savegame.gd | 2 - src/logic-scenes/board/card-board.gd | 143 +++++++++----------- src/logic-scenes/board/card.gd | 1 - src/logic-scenes/board/sticky-note.gd | 2 - src/logic-scenes/card_burner/card_burner.gd | 14 +- 5 files changed, 69 insertions(+), 93 deletions(-) diff --git a/src/dev-util/savegame.gd b/src/dev-util/savegame.gd index edf5014..a7ad307 100644 --- a/src/dev-util/savegame.gd +++ b/src/dev-util/savegame.gd @@ -14,8 +14,6 @@ class_name SaveGame extends Resource # Board state - properly typed fields @export var board_positions: Dictionary[StringName, Vector2] = {} # Position of all cards and stickies @export var board_attachments: Dictionary[StringName, StringName] = {} # Sticky name → Card name (if attached) -@export var board_in_panel: Array[StringName] = [] # Stickies currently in the side panel -@export var board_randoms: Array[StringName] = [] # Items picked randomly @export var is_childhood_board_complete: bool = false @export var player_position: Vector3 = Vector3.ZERO diff --git a/src/logic-scenes/board/card-board.gd b/src/logic-scenes/board/card-board.gd index f68a519..4df11a9 100644 --- a/src/logic-scenes/board/card-board.gd +++ b/src/logic-scenes/board/card-board.gd @@ -41,7 +41,7 @@ var mementos_collected: int = 0: var selection: Draggable = null: set(value): if selection == value: return - + # Select & highlight new if selection: selection.highlighted = false selection = value @@ -132,11 +132,9 @@ func populate_board(names: Array[StringName]): for new_card: Card in all_new["cards"]: add_card(new_card) - new_card.picked_random = new_card.name == names[1] #CAUTION: Hardcoded Index for new_sticky_note: StickyNote in all_new["sticky_notes"]: add_note(new_sticky_note) - new_sticky_note.picked_random = new_sticky_note.name == names[3] #CAUTION: Hardcoded Index # FIXME: This can be made even simpler. @@ -225,8 +223,8 @@ func _start_drag(draggable: Draggable) -> void: ## Ends a drag operation and handles the drop func _end_drag(draggable: Draggable) -> void: - selection = draggable - + selection = draggable + # Cleanup and state update current_context = NAVIGATE @@ -235,15 +233,15 @@ func _end_drag(draggable: Draggable) -> void: # Handle sticky note drops if draggable is StickyNote: var sticky := draggable as StickyNote - + # If dropped on a card, attach it if destination and destination is Card: var target_card := destination as Card - + # If sticky was previously attached to a different card, detach it first if sticky.is_attached and sticky.attached_to != target_card: sticky.attached_to.remove_sticky_note() - + # If target card already has a sticky, exchange them if target_card.has_sticky_note_attached(): var exchanged_sticky := target_card.exchange_sticky_note_with(sticky) @@ -254,17 +252,17 @@ func _end_drag(draggable: Draggable) -> void: # Simple attach sticky.reparent(target_card) target_card.attach_sticky_note(sticky) - + # If dropped on board (no destination), ensure it's a child of the board elif not destination: # If it was attached to a card, detach it first if sticky.is_attached: sticky.attached_to.remove_sticky_note() - + # Make sure sticky is parented to board if sticky.get_parent() != self: - sticky.reparent(self) - + sticky.reparent(self) + # Check win condition after any sticky movement check_board_completion() @@ -401,45 +399,28 @@ func _input(event) -> void: func save_to_resource(savegame: SaveGame) -> void: savegame.board_positions.clear() savegame.board_attachments.clear() - savegame.board_in_panel.clear() - savegame.board_randoms.clear() print_debug("CardBoard: Saving board state...") - for child in cards: - # Save card position (local to dropzone) - savegame.board_positions[child.name] = child.position - print_debug(" Card '%s' at %s" % [child.name, child.position]) - if child.picked_random: - savegame.board_randoms.append(child.name) + # Save all cards and their positions + for card in cards: + savegame.board_positions[card.name] = card.position + print_debug(" Card '%s' at %s" % [card.name, card.position]) - var note: StickyNote = child.get_attached_sticky_note() - if note: - # Save sticky attachment to card - savegame.board_attachments[note.name] = child.name - # Don't save position for attached stickies - it's determined by the card - print_debug(" Sticky '%s' attached to card '%s'" % [note.name, child.name]) - if note.picked_random: - savegame.board_randoms.append(note.name) + # Save sticky note attachment if present + var note: StickyNote = card.get_attached_sticky_note() + if note: + savegame.board_attachments[note.name] = card.name + print_debug(" Sticky '%s' attached to card '%s'" % [note.name, card.name]) + # Save loose sticky notes (not attached to cards) + for note in notes: + savegame.board_positions[note.name] = note.position + print_debug(" Loose sticky '%s' at %s" % [note.name, note.position]) - # Save position of loose sticky on board (local to dropzone) - for child in notes: - print_debug(" Loose sticky '%s' at %s" % [child.name, child.position]) - - savegame.board_positions[child.name] = child.position - savegame.board_in_panel.append(child.name) - - if child.picked_random: - savegame.board_randoms.append(child.name) - - if child.picked_random: - savegame.board_randoms.append(child.name) - - print_debug("CardBoard: Saved %d positions, %d attachments, %d in panel" % [ + print_debug("CardBoard: Saved %d positions, %d attachments" % [ savegame.board_positions.size(), - savegame.board_attachments.size(), - savegame.board_in_panel.size() + savegame.board_attachments.size() ]) @@ -451,73 +432,73 @@ func initialise_from_save(savegame: SaveGame) -> void: return print_debug("CardBoard: Loading board state from save...") - print_debug(" Positions: %d, Attachments: %d, In panel: %d" % [ + print_debug(" Positions: %d, Attachments: %d" % [ savegame.board_positions.size(), - savegame.board_attachments.size(), - savegame.board_in_panel.size() + savegame.board_attachments.size() ]) - # Clear & Collect all card/sticky names from all relevant dictionaries + # Collect all card/sticky names from positions and attachments all_names = [] # Names from positions (cards and loose stickies) for item_name: StringName in savegame.board_positions.keys(): all_names.append(item_name) - # Sticky names from attachments + # Sticky names from attachments (keys) for sticky_name: StringName in savegame.board_attachments.keys(): - all_names.append(sticky_name) + if sticky_name not in all_names: + all_names.append(sticky_name) - # Card names from attachments (the values) + # Card names from attachments (values) for card_name: StringName in savegame.board_attachments.values(): - all_names.append(card_name) - - # Sticky names from panel - for item_name: StringName in savegame.board_in_panel: - all_names.append(item_name) + if card_name not in all_names: + all_names.append(card_name) print_debug(" Collected %d unique card/sticky names to load" % all_names.size()) + # Create all cards and stickies populate_board(all_names) - # Track cards by name for sticky note attachment pass - var cards_by_name: Dictionary[StringName, Card] = {} - for card in cards: - cards_by_name[card.name] = card - # Calculate mementos collected (each memento gives 2 cards) mementos_collected = int(len(cards) / 2.0) + # Build lookup dictionary for cards + var cards_by_name: Dictionary[StringName, Card] = {} + for card in cards: + cards_by_name[card.name] = card + # Position all cards for card: Card in cards: - var target_position: Vector2 if savegame.board_positions.has(card.name): - target_position = savegame.board_positions[card.name] - print_debug(" Card '%s' loading at %s" % [card.name, target_position]) + card.position = savegame.board_positions[card.name] + print_debug(" Card '%s' at %s" % [card.name, card.position]) else: - target_position = _generate_random_position() - push_warning(" Card '%s' - generated random position: %s" % [card.name, target_position]) + card.position = _generate_random_position() + push_warning(" Card '%s' - no saved position, using random" % card.name) - card.position = target_position - card.picked_random = savegame.board_randoms.has(card.card_id) - - # Add all sticky notes + # Attach sticky notes to cards or position them loose for sticky: StickyNote in notes: - var card_name := savegame.board_attachments[sticky.name] - var card : Card = cards_by_name.get(card_name, null) - if card: - sticky.reparent(card) # was alrady added as our own child by populate_board - card.attach_sticky_note(sticky) - print_debug(" Sticky '%s' attached to card '%s'" % [sticky.name, card_name]) - else: - # Sticky is loose, this means it will be automatically moved - sticky.position = savegame.board_positions.get(sticky.name, position + size/2.0) + var card_name: StringName = savegame.board_attachments.get(sticky.name, &"") - sticky.picked_random = savegame.board_randoms.has(sticky.sticky_id) + if card_name and cards_by_name.has(card_name): + # Sticky is attached to a card + var card: Card = cards_by_name[card_name] + sticky.reparent(card) + card.attach_sticky_note(sticky) + print_debug(" Sticky '%s' attached to card '%s'" % [sticky.name, card_name]) + else: + # Sticky is loose on the board + if savegame.board_positions.has(sticky.name): + sticky.position = savegame.board_positions[sticky.name] + print_debug(" Loose sticky '%s' at %s" % [sticky.name, sticky.position]) + else: + # Fallback to center of board + sticky.position = position + size / 2.0 + push_warning(" Sticky '%s' - no saved position, using center" % sticky.name) print_debug("CardBoard: Load complete!") - # Re-sort dropzone children now that all positions are set correctly + # Re-sort by positions for correct z-ordering _sort_by_positions() diff --git a/src/logic-scenes/board/card.gd b/src/logic-scenes/board/card.gd index 70812f3..1bb02b5 100644 --- a/src/logic-scenes/board/card.gd +++ b/src/logic-scenes/board/card.gd @@ -37,7 +37,6 @@ var transfor_arr: Array[Transform2D] = [ @onready var label: Label = $Label @onready var background_sprite: AnimatedSprite2D = $AnimatedSprite2D -@export var picked_random: bool = false @export var wiggle_strength: float = 0.2 @export var wiggle_speed: float = 5 @export_range(1, 2) var scale_bump: float = 1.05 diff --git a/src/logic-scenes/board/sticky-note.gd b/src/logic-scenes/board/sticky-note.gd index cbc6bc1..edb0d2d 100644 --- a/src/logic-scenes/board/sticky-note.gd +++ b/src/logic-scenes/board/sticky-note.gd @@ -34,8 +34,6 @@ signal transform_tween_finished var content: Node2D var label: Label -@export var picked_random: bool = false - @export var shift_by: Vector2 = Vector2(-32, 0) @export_color_no_alpha var highlight_color: Color = Color(1.5, 1.5, 1.5) diff --git a/src/logic-scenes/card_burner/card_burner.gd b/src/logic-scenes/card_burner/card_burner.gd index 5b63714..6119d1f 100644 --- a/src/logic-scenes/card_burner/card_burner.gd +++ b/src/logic-scenes/card_burner/card_burner.gd @@ -23,14 +23,14 @@ func _ready(): %SkipButton.pressed.connect(card_burned.emit) func burn_cards(_id: int, _repeat: bool = false) -> void: - var random_card_names: Array = State.save_game.board_randoms.duplicate() - - for card_name in random_card_names: - if card_name.begins_with("p"): - random_card_names.erase(card_name) - - var random_cards: Array = HardCards.get_cards_by_name_array(random_card_names)["cards"] + # Get all card names from the board (excluding stickies which start with "p") + var card_names: Array[StringName] = [] + for item_name in State.save_game.board_positions.keys(): + if not item_name.begins_with("p"): + card_names.append(item_name) + # Get card instances and shuffle them + var random_cards: Array = HardCards.get_cards_by_name_array(card_names)["cards"] random_cards.shuffle() for ancor:Control in ancors: