From bbcf9abfc00d497c696ea1beb5858569a454ede1 Mon Sep 17 00:00:00 2001 From: Tiger Jove Date: Mon, 15 Dec 2025 23:13:40 +0100 Subject: [PATCH] feat: basic room start logic, WIP --- .../youth_room/youth_room.gd | 25 ++-- src/logic-scenes/board/card-board.gd | 136 +++++++++--------- 2 files changed, 81 insertions(+), 80 deletions(-) diff --git a/src/base-environments/youth_room/youth_room.gd b/src/base-environments/youth_room/youth_room.gd index 010f5c4..4174ed5 100644 --- a/src/base-environments/youth_room/youth_room.gd +++ b/src/base-environments/youth_room/youth_room.gd @@ -9,15 +9,7 @@ signal ini_room @onready var card_picker: CardPicker = %Picker func start_room(): - $UI.show() - save_game = State.save_game - save_game.current_room = State.rooms.YOUTH - Scenes.completed_sequences = save_game.mementos_complete - Scenes.started_sequences = save_game.mementos_complete - card_board.initialise_from_save(save_game) - card_board.board_completed.connect(func(): - save_game.is_childhood_board_complete = true - save_room()) + %UI.show() $logic/PlayerController.process_mode = Node.PROCESS_MODE_INHERIT ini_room.emit() if not Scenes.is_sequence_repeating(Scenes.id.YOUTH_DRAEVEN): @@ -28,15 +20,24 @@ func start_room(): %LightAnimation.lights_on() func get_ready(): - id = State.rooms.YOUTH + save_game = State.save_game + save_game.current_room = State.rooms.YOUTH + Scenes.completed_sequences = save_game.mementos_complete + Scenes.started_sequences = save_game.mementos_complete + card_board.initialise_from_save(save_game) + ini_room.emit() + card_board.board_completed.connect(func(): + save_game.is_childhood_board_complete = true + save_room()) + %UI.hide() - self.show() $sfx/distant_rain.play() $"sfx/rain on window".play() - await get_tree().process_frame #TODO: this was 0.1s, not sure if needed at all + self.show() func _ready(): super._ready() + id = State.rooms.YOUTH Scenes.scene_finished.connect(_on_scene_finished) card_picker.cards_picked.connect(card_board.populate_board) diff --git a/src/logic-scenes/board/card-board.gd b/src/logic-scenes/board/card-board.gd index b32c70e..f51e0fe 100644 --- a/src/logic-scenes/board/card-board.gd +++ b/src/logic-scenes/board/card-board.gd @@ -12,16 +12,16 @@ var focus_stickies:bool = true: set(stickies): if not is_node_ready(): return if stickies and sticky_note_container.get_child_count() == 0: return - + # 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 + current_dropzone_id = current_dropzone_id var has_stage := false: set(focus): @@ -98,7 +98,7 @@ var mementos_collected: int = 0: elif not focus_stickies: currently_active_node = dropzone.get_child(current_dropzone_id) - + @onready var current_sticky_note_id: int = 0: set(new_id): if is_node_ready(): @@ -132,9 +132,9 @@ signal board_completed # Called when the node enters the scene tree for the first time. func _ready(): var size_reference = StickyNotePanel.new() - + dropzone_size = get_viewport_rect().size - Vector2(dropzone_padding + size_reference.minimum_size.x, dropzone_padding) - + if get_parent() == get_tree().root: populate_board(["c_void", 'c_gifted', "p_wet", "p_joy"]) populate_board(["c_jui_jutsu", 'c_hit', "p_girly", "p_vent"]) @@ -142,13 +142,13 @@ func _ready(): populate_board(["c_out_of_world", 'c_confusion', "p_outer_conflict", "p_unique"]) has_stage = has_stage - + get_viewport().gui_focus_changed.connect(reclaim_lost_focus) - + #FIXME properly implement board recovery #timer.timeout.connect(validate_board) #timer.start() - + #await get_tree().process_frame #last_save_dict = get_save_dict() @@ -162,12 +162,12 @@ func reclaim_lost_focus(_thief): # if has_stage and !Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT) and current_context == DRAG: # currently_active_node.is_dragged = false -## Will be used later to spawn Cards and Post-Its and remember them in the dictionary +## Will be used later to spawn Cards and Post-Its and remember them in the dictionary func populate_board(card_names: Array[StringName]): mementos_collected += 1 - + var all_new:Dictionary = HardCards.get_cards_by_name_array(card_names) - + # spawning the cards and adding them to the dictionary for new_card: Card in all_new["cards"]: add_card(new_card, false) @@ -177,7 +177,7 @@ func populate_board(card_names: Array[StringName]): add_sticky_note(new_sticky_note, false) # marking the first sticky as random picks new_sticky_note.picked_random = new_sticky_note.name == card_names[3] - + #currently_active_node = area_dict["dropzone_content"][0] # set first Card as currently selected node by default currently_active_node = dropzone.get_child(0) @@ -190,7 +190,7 @@ func add_card(card: Card, re_parent:bool = true): insert_area(dropzone, card) card.set_owner(self) card.is_dragable = true - + func add_sticky_note(sticky: StickyNote, re_parent:bool = true): var new_panel := StickyNotePanel.new() sticky_note_container.add_child(new_panel, true, Node.INTERNAL_MODE_DISABLED) @@ -198,19 +198,19 @@ func add_sticky_note(sticky: StickyNote, re_parent:bool = true): new_panel.set_owner(self) sticky.current_handle = self new_panel.attatch_sticky_note(sticky, self, false, re_parent) - + # Checks if a Node is currently inside the dropzone func is_in_dropzone(to_check: Node) -> bool: return dropzone.get_rect().has_point(to_check.global_position) # 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. - # Otherwise overlapping areas are dragged at the same time. + # Otherwise overlapping areas are dragged at the same time. if current_context == DRAG and to_handle != currently_active_node: return - + if input.button_index == MOUSE_BUTTON_MASK_LEFT and input.pressed: currently_active_node = to_handle to_handle.is_dragged = true @@ -220,7 +220,7 @@ func handle_mouse_button(input: InputEventMouseButton, to_handle = currently_act to_handle.on_board = true to_handle.attached_to = self current_context = DRAG - + # when Drag stops ... if input.button_index == MOUSE_BUTTON_MASK_LEFT and not input.pressed: @@ -274,7 +274,7 @@ func handle_mouse_button(input: InputEventMouseButton, to_handle = currently_act _return_sticky_notes_to_panels() current_context = NAVIGATE return - + ## 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 to_handle.get_parent() is Card: @@ -296,7 +296,7 @@ func _return_sticky_notes_to_panels(): if not (current_context == ASSIGN and focus_stickies): return #FIXME this is an early return to prevent race conditions. Check if it is save to be removed. for panel:StickyNotePanel in sticky_note_container.get_children(): panel.reclaim_sticky_note() - + for node in dropzone.get_children(): if node is StickyNote: node.is_dragable = true @@ -327,13 +327,13 @@ var complete: bool = false func give_lore_feedback(): var fitting_card_count: int = 0 var total_card_count: int = 0 - + for child in dropzone.get_children(): if child is Card: if child.has_sticky_note_attached(): fitting_card_count += int(child.card_id == child.get_attached_sticky_note().parent_id) total_card_count += 1 - + if float(fitting_card_count) / float(total_card_count) < 0.2: instructions.text = "You can move on, but you may not have understood Lisa." if not unfitting: @@ -366,12 +366,12 @@ func is_board_lore() -> bool: if card.has_sticky_note_attached(): if not card.current_sticky_note.sticky_id.contains(card.card_id): return false return true - + # Mark area that was hovered over as currently selected func handle_hover(to_handle: Area2D): 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 (current_context == ASSIGN and not currently_active_node.is_dragged): #Prevent Mouse input from messing up directional control selections if not (to_handle is StickyNote and !to_handle.on_board): @@ -380,37 +380,37 @@ func handle_hover(to_handle: Area2D): else: current_sticky_note_id = sticky_note_container.get_children().find(to_handle.attached_to) focus_stickies = true - + # Adds a child at the correct child indext in an area func insert_area(parent: Control, node: Area2D): - var children:Array = parent.get_children() + 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 + i+=1 parent.move_child(node, i) - + if node is StickyNote: node.attached_to = self node.is_dragable = true - + # Takes the inputs for control inputs func _input(event): - + if not has_stage or not is_instance_valid(currently_active_node): return if event.is_action_pressed("ui_cancel"): State.leave_stage(self) get_viewport().set_input_as_handled() - + 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: @@ -426,7 +426,7 @@ func _input(event): selection_position = dropzone.get_child( current_dropzone_id ).global_position else: selection_position = currently_active_node.global_position - + if event.is_action_pressed("ui_up"): if focus_stickies: current_sticky_note_id -= 1 @@ -434,7 +434,7 @@ func _input(event): if not try_select_nearest_card(selection_position, Vector2.UP): current_dropzone_id -= 1 get_viewport().set_input_as_handled() - + elif event.is_action_pressed("ui_down"): # down to select an element beneath if focus_stickies: current_sticky_note_id += 1 @@ -442,7 +442,7 @@ func _input(event): if not try_select_nearest_card(selection_position, Vector2.DOWN): current_dropzone_id += 1 get_viewport().set_input_as_handled() - + elif event.is_action_pressed("ui_right"): # left to switch context to the left if not try_select_nearest_card(selection_position, Vector2.RIGHT, true): if not focus_stickies: @@ -452,7 +452,7 @@ func _input(event): sticky_note_container.get_children()[current_sticky_note_id].reclaim_sticky_note() current_context = NAVIGATE get_viewport().set_input_as_handled() - + elif event.is_action_pressed("ui_left"): # right to switch context to the right print_debug(try_select_nearest_card(selection_position, Vector2.LEFT)) if focus_stickies: @@ -461,13 +461,13 @@ func _input(event): elif current_context == ASSIGN: current_context = NAVIGATE get_viewport().set_input_as_handled() - + elif event.is_action_pressed("ui_accept"): # select the selected note it if current_context == ASSIGN: if not dropzone.get_child(current_dropzone_id) is Card: return var card:Card = dropzone.get_child(current_dropzone_id) var sticky: StickyNote = currently_active_node if not focus_stickies else sticky_note_container.get_child(current_sticky_note_id).attached_sticky_note - + if card.has_sticky_note_attached(): currently_active_node = card.exchange_sticky_note_with(sticky) focus_stickies = false @@ -487,7 +487,7 @@ func _input(event): else: focus_stickies = true current_sticky_note_id -= 1 - + elif current_context == NAVIGATE: if focus_stickies: # this is kind of redundant, but a safety feature to avoid active node and index misaligning. @@ -514,12 +514,12 @@ func _input(event): focus_stickies = true current_sticky_note_id = current_sticky_note_id -# +# # else: # if current_context == ASSIGN: # if not dropzone.get_child(current_dropzone_id) is Card: return # var card:Card = dropzone.get_child(current_dropzone_id) -# +# # if dropzone.get_child(current_dropzone_id) is Card: # var card:Card = dropzone.get_child(current_dropzone_id) # if current_context == ASSIGN: # to assign it to a card @@ -543,7 +543,7 @@ func _input(event): # else: # if not try_select_nearest_empty_card(currently_active_node.global_position): # current_dropzone_id = find_first_free_card() -# +# # current_context = ASSIGN # focus_stickies = !focus_stickies # if focus_stickies: @@ -590,24 +590,24 @@ func get_save_dict() -> Dictionary: var cards: Dictionary = {} var stickies: Dictionary = {} var randoms: Array[StringName] - + for child in dropzone.get_children(): if child is Card: # Save position of Card. cards[child.name] = child.transform.origin if child.picked_random: randoms.append(child.name) - + if child.has_sticky_note_attached(): # Saves Card Name as position of it's children. stickies[child.get_attached_sticky_note().name] = child.name if child.get_attached_sticky_note().picked_random: randoms.append(child.get_attached_sticky_note().name) - + elif child is StickyNote: # Save position of StickyNote. cards[child.name] = child.transform.origin - + for child in sticky_note_container.get_children(): if child is StickyNotePanel: # Saves all collected Stickies that are not on board. @@ -623,27 +623,27 @@ func initialise_from_save(savegame: SaveGame): last_save_dict = savegame.board_state.duplicate() if savegame.board_state == {}: return rebuild_from_savedict(savegame.board_state) - + func rebuild_from_savedict(board_state:Dictionary): var cards: Dictionary - if board_state["cards"] != {} : + if board_state["cards"] != {} : cards = board_state["cards"] var stickies: Dictionary - if board_state["stickies"] != {} : + if board_state["stickies"] != {} : stickies = board_state["stickies"] var randoms: Array[StringName] - if board_state["randoms"] != [] : + if board_state["randoms"] != [] : randoms = board_state["randoms"] - + if cards == null and stickies == null: return - + var all_cards: Array[StringName] for card_name: StringName in cards.keys(): all_cards.append(card_name) for card_name: StringName in stickies.keys(): all_cards.append(card_name) var card_pile = HardCards.get_cards_by_name_array(all_cards) - + for card:Card in card_pile["cards"]: add_card(card, false) card.transform.origin = cards[card.name]# Replacing position reference with card reference! Needed in next loop. @@ -664,7 +664,7 @@ func rebuild_from_savedict(board_state:Dictionary): func validate_board(): if current_context == NAVIGATE: - + var needs_rebuild := false for node in dropzone.get_children(): if node is Card: @@ -689,12 +689,12 @@ func validate_board(): # 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 @@ -712,7 +712,7 @@ func validate_sticky(note: StickyNote) -> CardBoard.Error: 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: @@ -728,14 +728,14 @@ func validate_card(card: Card) -> CardBoard.Error: func try_select_nearest_card(from: Vector2, towards: Vector2, include_stickies: bool = false) -> bool: var selection_transform = Transform2D(0, from).looking_at(from+towards) - + var scores: Dictionary[int, Area2D] = {-1: null} for child:Area2D in dropzone.get_children(): if not (child is StickyNote and current_context == ASSIGN): scores[get_distance_score(child.global_position, selection_transform)] = child scores.erase(-1) scores.sort() - + if include_stickies: var panel_scores: Dictionary[int, StickyNotePanel] = {-1: null} for child:StickyNotePanel in sticky_note_container.get_children(): @@ -743,7 +743,7 @@ func try_select_nearest_card(from: Vector2, towards: Vector2, include_stickies: panel_scores[get_distance_score(child.attached_sticky_note.global_position, selection_transform)] = child panel_scores.erase(-1) panel_scores.sort() - + if panel_scores != {}: if scores != {}: if panel_scores.keys()[0] < scores.keys()[0]: @@ -756,8 +756,8 @@ func try_select_nearest_card(from: Vector2, towards: Vector2, include_stickies: current_sticky_note_id = sticky_note_container.get_children().find(panel_scores.values()[0]) focus_stickies = true return true - - + + if scores != {}: current_dropzone_id = dropzone.get_children().find(scores.values()[0]) return true @@ -765,14 +765,14 @@ func try_select_nearest_card(from: Vector2, towards: Vector2, include_stickies: func try_select_nearest_empty_card(from: Vector2) -> bool: var scores: Dictionary[int, Area2D] = {} - + for card in dropzone.get_children(): if card is Card: if not card.has_sticky_note_attached(): scores[int((from-card.global_position).length())] = card - + scores.sort() - + if scores != {}: current_dropzone_id = dropzone.get_children().find(scores.values()[0]) return true