diff --git a/src/logic-scenes/board/card-board.gd b/src/logic-scenes/board/card-board.gd index f174029..a0dd5d0 100644 --- a/src/logic-scenes/board/card-board.gd +++ b/src/logic-scenes/board/card-board.gd @@ -185,8 +185,8 @@ func add_card(card: Card, re_parent:bool = true): card.reparent(self) else: add_child(card) - card.position = _generate_random_position() insert_area(dropzone, card) + card.position = _generate_random_position() card.set_owner(self) card.is_dragable = true @@ -631,8 +631,9 @@ func initialise_from_save(savegame: SaveGame) -> void: print_debug(" Loading %d cards..." % card_pile["cards"].size()) for card: Card in card_pile["cards"]: add_child(card) + insert_area(dropzone, card) - # Set position from save, or generate random if missing + # Set position from save, or generate random if missing (must be after insert_area) if savegame.board_positions.has(card.name): card.position = savegame.board_positions[card.name] print_debug(" Card '%s' at %s" % [card.name, card.position]) @@ -640,7 +641,6 @@ func initialise_from_save(savegame: SaveGame) -> void: card.position = _generate_random_position() print_debug(" Card '%s' - generated random position: %s" % [card.name, card.position]) - insert_area(dropzone, card) card.set_owner(self) card.is_dragable = true cards_by_name[card.name] = card @@ -671,8 +671,9 @@ func initialise_from_save(savegame: SaveGame) -> void: # Sticky is loose on board else: add_child(sticky) + insert_area(dropzone, sticky) - # Set position from save, or generate random if missing + # Set position from save, or generate random if missing (must be after insert_area) 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]) @@ -680,7 +681,6 @@ func initialise_from_save(savegame: SaveGame) -> void: sticky.position = _generate_random_position() print_debug(" Loose sticky '%s' - generated random position: %s" % [sticky.name, sticky.position]) - insert_area(dropzone, sticky) sticky.set_owner(self) sticky.current_handle = self # Required for input handling sticky.on_board = true diff --git a/src/logic-scenes/board/card.gd b/src/logic-scenes/board/card.gd index 57f94f6..3916e4c 100644 --- a/src/logic-scenes/board/card.gd +++ b/src/logic-scenes/board/card.gd @@ -20,6 +20,7 @@ var wiggle_intensity: float = 0 var noise: Noise = FastNoiseLite.new() var wiggle_tween : Tween var scale_tween : Tween +var brightness_tween : Tween var transfor_arr: Array[Transform2D] = [ Transform2D(0.9, Vector2(-125, -83)), @@ -43,6 +44,7 @@ var transfor_arr: Array[Transform2D] = [ @export var wiggle_speed: float = 5 @export_range(1, 2) var scale_bump: float = 1.05 @export_range(1.0, 10.0) var bounce_speed: float = 5 +@export_range(1.0, 2.0) var highlight_brightness: float = 1.4 @export var highlighted: bool = false: set(highlight): if highlight != highlighted: @@ -51,23 +53,40 @@ var transfor_arr: Array[Transform2D] = [ if is_inside_tree() and is_node_ready(): if scale_tween: scale_tween.kill() if wiggle_tween: wiggle_tween.kill() + if brightness_tween: brightness_tween.kill() if highlighted: scale_tween = get_tree().create_tween() scale_tween.tween_property(self, "scale", Vector2(scale_bump, scale_bump), 0.1) wiggle_tween = get_tree().create_tween() wiggle_tween.tween_property(self, "wiggle_intensity", 1, 0.2) + brightness_tween = get_tree().create_tween() + brightness_tween.set_parallel(true) + brightness_tween.tween_property(background_sprite, "modulate", Color(highlight_brightness, highlight_brightness, highlight_brightness), 0.15) + brightness_tween.tween_property(label, "modulate", Color(highlight_brightness, highlight_brightness, highlight_brightness), 0.15) else: scale_tween = get_tree().create_tween() scale_tween.tween_property(self, "scale", Vector2(1, 1), 0.3) wiggle_tween = get_tree().create_tween() wiggle_tween.tween_property(self, "wiggle_intensity", 0, 0.5) + brightness_tween = get_tree().create_tween() + brightness_tween.set_parallel(true) + brightness_tween.tween_property(background_sprite, "modulate", Color.WHITE, 0.2) + brightness_tween.tween_property(label, "modulate", Color.WHITE, 0.2) else: if highlighted: scale = Vector2(scale_bump, scale_bump) wiggle_intensity = 1 + if background_sprite: + background_sprite.modulate = Color(highlight_brightness, highlight_brightness, highlight_brightness) + if label: + label.modulate = Color(highlight_brightness, highlight_brightness, highlight_brightness) else: scale = Vector2(1,1) wiggle_intensity = 0 + if background_sprite: + background_sprite.modulate = Color.WHITE + if label: + label.modulate = Color.WHITE @export var voice_line: AudioStream = null @export var is_dragable: bool = false @@ -127,7 +146,6 @@ var card_fire: Sprite2D = preload("res://logic-scenes/card_burner/card_fire.tscn var sticky_note_position: Vector2 = Vector2(-66, 83) -var is_mouse_entered: bool = false var mouse_offset: Vector2 func init(card_name: String = "card", own_id:StringName = "-1") -> void: @@ -196,38 +214,28 @@ func _input(event: InputEvent) -> void: is_dragged = false func _on_mouse_entered() -> void: - is_mouse_entered = true if not Input.is_action_pressed("mouse_left"): - # Do nothing if mouse hovers over sticky_note + # Do nothing if mouse hovers over sticky_note (it has higher priority) if has_sticky_note_attached(): if current_sticky_note and current_sticky_note.highlighted: return - highlighted = true if "handle_hover" in owner: owner.handle_hover(self) func _on_mouse_exited(): highlighted = false - is_mouse_entered = false if burn_state == burned.SINGED: burn_state = burned.NOT func _on_input_event(_viewport, event, _shape_idx): - - if event is InputEventMouseMotion: - _move_card() - - if event is InputEventMouseButton: - # Mouse Button Left is being handled by card_board to prevent events being missed when mouse moves outside card - if event.button_index == MOUSE_BUTTON_LEFT and event.pressed: - if "handle_mouse_button" in owner: - mouse_offset = (get_viewport().get_mouse_position() - position) - if highlighted: - owner.handle_mouse_button(event, self) + if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed: + if "handle_mouse_button" in owner and highlighted: + mouse_offset = get_viewport().get_mouse_position() - position + owner.handle_mouse_button(event, self) func _move_card(): if is_dragged: - position += (get_viewport().get_mouse_position() - position) - mouse_offset + position = get_viewport().get_mouse_position() - mouse_offset confine_to_screen() func has_sticky_note_attached() -> bool: @@ -279,8 +287,8 @@ func exchange_sticky_note_with(new_note: StickyNote) -> StickyNote: # This makes sure this node highlights itself when focus has left the sticky note. func check_hover(): - if is_mouse_entered: - _on_mouse_entered() + # Re-trigger hover handling - owner will decide if this should be highlighted + _on_mouse_entered() func reclaim_sticky_note(): current_sticky_note.on_board = false diff --git a/src/logic-scenes/board/sticky-note.gd b/src/logic-scenes/board/sticky-note.gd index 90dea41..c3c31ea 100644 --- a/src/logic-scenes/board/sticky-note.gd +++ b/src/logic-scenes/board/sticky-note.gd @@ -7,13 +7,10 @@ var parent_id var sibling: StickyNote var shift_tween: Tween var modulate_tween: Tween -var card_stick_tween: Tween -var hovering_cards: Array[Card] -var hover_pos_shift: float var attached_to: Node = null: set(new_attatchement): attached_to = new_attatchement -# cannot be explicitly typed, as this can be bnoth handled by picker and physics-board +# cannot be explicitly typed, as this can be both handled by picker and physics-board var current_handle: Node var position_locked: bool = false @@ -63,8 +60,7 @@ var label: Label @onready var base_rotation := rotation @onready var base_scale := scale -var initial_drag_position: Vector2 -var mouse_diff: Vector2 +var mouse_offset: Vector2 @onready var diameter := 312.0 @export_range(1.0, 10.0) var bounce_speed: float = 8 @@ -109,65 +105,36 @@ func _process(delta: float) -> void: _move_sticky_note() func _on_mouse_entered(): - if not Input.is_action_pressed("mouse_left"): - highlighted = true - if current_handle != null: - if "handle_hover" in current_handle: - current_handle.handle_hover(self) + if not Input.is_action_pressed("mouse_left") and "handle_hover" in current_handle: + current_handle.handle_hover(self) func _on_mouse_exited(): - if not is_dragged: - highlighted = false - + highlighted = false + # Let parent card re-check hover state if this sticky is attached to it if is_sticky_note_attached() and "check_hover" in attached_to: attached_to.check_hover() -func _on_area_enter(card: Area2D): - if card is Card: - if hovering_cards == []: - hovering_cards = [card] - card_stick_tween = get_tree().create_tween() - card_stick_tween.set_ease(Tween.EASE_IN_OUT) - card_stick_tween.tween_property(self, "hover_pos_shift", 0.3, 0.1) - else: - hovering_cards.append(card) - elif card is StickyNote and is_sticky_note_in_panel() and not is_dragged: +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: attached_to.create_gap() -func _on_area_exit(card: Area2D): - if hovering_cards != [] and card is Card: - if card in hovering_cards: - hovering_cards.erase(card) - card.highlighted = false - if hovering_cards == []: - hover_pos_shift = 0 - content.position = Vector2.ZERO - elif card is StickyNote and is_sticky_note_in_panel(): +func _on_area_exit(area: Area2D): + # Handle sticky note panel gap collapse + if area is StickyNote and is_sticky_note_in_panel(): attached_to.collapse_gap() func _on_input_event(_viewport, event, _shape_idx): - if event is InputEventMouseButton: + if event is InputEventMouseButton and "handle_mouse_button" in current_handle: if (event.button_index == MOUSE_BUTTON_LEFT and event.pressed) or event.button_index == MOUSE_BUTTON_RIGHT: - if "handle_hover" in current_handle: - mouse_diff = get_viewport().get_mouse_position() - initial_drag_position = global_position - current_handle.handle_mouse_button(event, self) + mouse_offset = get_viewport().get_mouse_position() - global_position + current_handle.handle_mouse_button(event, self) func _move_sticky_note(): if is_dragged: - #var old_position = position - position = initial_drag_position + get_viewport().get_mouse_position() - mouse_diff + global_position = get_viewport().get_mouse_position() - mouse_offset confine_to_screen() - if hovering_cards != []: - var closest: Card = hovering_cards[0] - for card in hovering_cards: - card.highlighted = false - if (closest.position - position).length() > (closest.position - position).length(): - card = closest - closest.highlighted = true - content.position = (closest.to_global(closest.sticky_note_position) - global_position) * hover_pos_shift - func is_sticky_note_attached() -> bool: # FIXME: this breaks if attatched to is previousely freed because GODOT IS FUCKING STUPID return attached_to is Card diff --git a/src/logic-scenes/card_picker/card_picker.gd b/src/logic-scenes/card_picker/card_picker.gd index dc68274..e686f9b 100644 --- a/src/logic-scenes/card_picker/card_picker.gd +++ b/src/logic-scenes/card_picker/card_picker.gd @@ -105,20 +105,20 @@ var on_cooldown: bool = false var card_anim_skipped:bool = false func _input(event): - if event is not InputEventAction: - return - if not _input_locked: if not on_cooldown: + # Navigation: keyboard arrows, gamepad D-pad, and analog stick if event.is_action_pressed("ui_up") or event.is_action_pressed("ui_left") or event.is_action_pressed("ui_focus_next"): curr_selection_id -= 1 + on_cooldown = true + get_tree().create_timer(0.15).timeout.connect(func(): on_cooldown = false, CONNECT_ONE_SHOT) elif event.is_action_pressed("ui_down") or event.is_action_pressed("ui_right") or event.is_action_pressed("ui_focus_prev"): curr_selection_id += 1 - on_cooldown = true - await get_tree().create_timer(0.1).timeout - on_cooldown = false + on_cooldown = true + get_tree().create_timer(0.15).timeout.connect(func(): on_cooldown = false, CONNECT_ONE_SHOT) - if event.is_action_pressed("ui_accept"): + # Selection: Enter/Space on keyboard, A button (Joy 0) on gamepad, or left click + if event.is_action_pressed("ui_accept") or event.is_action_pressed("collect_memento_ui"): pick(curr_selection_id) elif event.is_action_pressed("skip"): $Meaning.stop()