frame-of-mind/src/logic-scenes/board/card-board.gd

275 lines
10 KiB
GDScript3
Raw Normal View History

extends PanelContainer
2023-08-30 11:23:37 +00:00
#var area_dict = {
# "dropzone_content": [],
# "cards": [],
# "post_its_in_list": [],
# "post_it_panels": []
#}
2023-09-23 14:19:58 +00:00
enum {DROPZONE, POST_IT_LIST, DRAGGING, ASSIGN_POST_IT}
2023-07-02 13:10:33 +00:00
var has_stage = false:
2023-07-11 13:04:46 +00:00
set(focus):
if focus:
has_stage = true
self.mouse_filter = Control.MOUSE_FILTER_PASS
2023-08-01 08:59:24 +00:00
get_tree().call_group("interactables", "collapse")
else:
has_stage = false
self.mouse_filter = Control.MOUSE_FILTER_IGNORE
if is_node_ready():
2023-08-30 11:23:37 +00:00
if focus:
process_mode = Node.PROCESS_MODE_INHERIT
else:
process_mode = Node.PROCESS_MODE_DISABLED
visible = has_stage
2023-07-11 13:04:46 +00:00
@onready var dropzone = $HBoxContainer/dropzone
2023-08-01 08:59:24 +00:00
var dropzone_size: Vector2
@export var dropzone_padding = 100
@onready var postit_container = $HBoxContainer/ScrollContainer/VBoxContainer
@onready var board_of_devs = $"board of devs"
2023-08-01 08:59:24 +00:00
var base_postit_panel: Panel
2023-09-23 14:19:58 +00:00
@onready var current_context = DROPZONE:
set(context):
match context:
DROPZONE:
pass
POST_IT_LIST:
pass
DRAGGING:
pass
ASSIGN_POST_IT:
pass
2023-07-17 22:15:04 +00:00
@onready var instructions = $instructions_panel/HBoxContainer/cards_remaining
var mementos_collected: int = 0:
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-09-23 14:19:58 +00:00
var currently_active_node: Area2D = null
2023-09-23 14:19:58 +00:00
@onready var current_dropzone_id: int = 0:
set(new_id):
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
var current_postIt_id: int = 0:
set(new_id):
if new_id > postit_container.get_child_count() - 1: current_postIt_id = 0
elif new_id < 0: current_postIt_id = postit_container.get_child_count() - 1
else: current_postIt_id = new_id
2023-07-02 13:10:33 +00:00
var cache: Array = []
signal board_completed
# Called when the node enters the scene tree for the first time.
func _ready():
2023-08-01 08:59:24 +00:00
base_postit_panel = $HBoxContainer/ScrollContainer/VBoxContainer/Panel
postit_container.remove_child(base_postit_panel)
2023-07-02 13:10:33 +00:00
2023-08-01 08:59:24 +00:00
dropzone_size = get_viewport_rect().size - Vector2(dropzone_padding + base_postit_panel.custom_minimum_size.x, dropzone_padding)
if get_parent() == get_tree().root:
populate_board(["c_void", 'c_joy', "p_wet", "p_thomas"])
populate_board(["c_fighting", 'c_hit', "p_girly", "p_vent"])
2023-09-23 14:19:58 +00:00
has_stage = has_stage
2023-09-23 14:19:58 +00:00
func _process(delta):
2023-09-23 14:19:58 +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 == DRAGGING:
currently_active_node.is_dragged = false
2023-07-02 13:10:33 +00:00
# Will be used later to spawn Cards and Post-Its and remember them in the dictionary
func populate_board(card_names: Array):
2023-07-17 22:15:04 +00:00
mementos_collected += 1
2023-08-01 08:59:24 +00:00
var all_new:Dictionary = board_of_devs.get_cards_by_name_array(card_names)
2023-08-01 08:59:24 +00:00
var new_cards:Array = all_new["cards"]
var new_postits:Array = all_new["postIts"]
2023-08-01 08:59:24 +00:00
# spawning the cards and adding them to the dictionary
for new_card in all_new["cards"]:
new_card.position = Vector2(randi_range(dropzone_padding, dropzone_size.x), randi_range(dropzone_padding, dropzone_size.y))
2023-09-23 14:19:58 +00:00
insert_area(dropzone, new_card)
2023-08-01 08:59:24 +00:00
new_card.set_owner(self)
new_card.is_dragable = true
for new_postit in all_new["postIts"]: # spawning a post-it
var new_panel = base_postit_panel.duplicate()
postit_container.add_child(new_panel)
new_panel.set_owner(self)
2023-08-01 08:59:24 +00:00
new_panel.add_child(new_postit)
new_postit.set_owner(self)
new_postit.position = new_panel.get_child(0).position
new_postit.is_dragable = true
2023-09-23 14:19:58 +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)
# Checks if a Node is currently inside the dropzone
func is_in_dropzone(to_check: Node) -> bool:
2023-08-30 11:23:37 +00:00
return dropzone.get_rect().has_point(to_check.global_position)
# called if a mouse button is pressed
func handle_mouse_button(to_handle: Area2D, input: InputEvent):
# No two areas can be dragged at the same time.
# Make sure that only the same area is dragged.
# Otherwise overlapping areas are dragged at the same time.
2023-09-23 14:19:58 +00:00
if current_context == DRAGGING:
return
2023-09-23 14:19:58 +00:00
currently_active_node = to_handle # update currently selected
to_handle.is_dragged = input.pressed
2023-09-23 14:19:58 +00:00
if input.pressed:
current_context = DRAGGING
# Check what is being dragged
if to_handle is Card:
2023-09-23 14:19:58 +00:00
current_context = DROPZONE
if !input.is_pressed():
insert_area(dropzone, to_handle)
current_context = dropzone
elif to_handle is PostIt:
if input.is_action_pressed("mouse_left"):
to_handle.reparent(dropzone)
to_handle.on_board = true
to_handle.set_owner(self) # needs to be here otherwise the owner disappears
elif input.is_action_pressed("mouse_right"):
_return_postit_to_panels(to_handle)
to_handle.is_dragged = false
is_area_dragged = false
currently_dragged_area = null
else:
if is_in_dropzone(to_handle):
if to_handle.has_overlapping_areas():
for area in to_handle.get_overlapping_areas():
if area is Card:
if !area.has_postit_attached():
attach_postit_to_card(to_handle, area)
else:
to_handle.rotation = to_handle.base_rotation
to_handle.scale = to_handle.base_scale
else:
2023-09-23 14:19:58 +00:00
current_context = POST_IT_LIST
_return_postit_to_panels(to_handle)
currently_dragged_area = null
2023-07-02 13:10:33 +00:00
# Logic for attaching a postit to a card. Also reset postit positions if the card cannot be attached
2023-08-30 11:23:37 +00:00
func attach_postit_to_card(postit: Area2D, card: Area2D, preview = false):
2023-08-30 09:07:22 +00:00
if card.has_postit_attached():
2023-09-23 14:19:58 +00:00
if current_context == ASSIGN_POST_IT:
2023-08-30 09:07:22 +00:00
_return_postit_to_panels(postit) # don't attach if card has already a post-it attached
return
2023-08-30 09:07:22 +00:00
postit.set_owner(self)
2023-08-30 11:23:37 +00:00
#if update_dict:
# area_dict["post_its_in_list"].erase(postit)
# area_dict["dropzone_content"].push_back(postit)
2023-08-30 09:07:22 +00:00
2023-08-30 11:23:37 +00:00
func is_board_complete() -> bool:
2023-08-30 09:07:22 +00:00
if mementos_collected == 4:
2023-08-30 11:23:37 +00:00
for card in dropzone.get_children():
if card is Card:
if not card.has_postit_attached():
return false
return true
return false
2023-08-30 09:07:22 +00:00
func is_board_lore() -> bool:
2023-08-30 11:23:37 +00:00
for card in dropzone.get_children():
if card.has_postit_attached():
if not card.current_post_it.is_in_group(card.name): return false
2023-08-30 09:07:22 +00:00
return true
2023-08-01 08:59:24 +00:00
2023-07-02 13:10:33 +00:00
# Mark area that was hovered over as currently selected
func handle_hover(to_handle: Area2D):
2023-09-23 14:19:58 +00:00
if to_handle != currently_active_node:
currently_active_node.highlighted = false
currently_active_node = to_handle
2023-07-02 13:10:33 +00:00
if is_in_dropzone(to_handle):
2023-09-23 14:19:58 +00:00
current_dropzone_id = area_dict["dropzone_content"].find(to_handle)
current_context = DROPZONE
2023-07-02 13:10:33 +00:00
else:
2023-09-23 14:19:58 +00:00
current_postIt_id = area_dict["post_its_in_list"].find(to_handle)
current_context = POST_IT_LIST
2023-07-02 13:10:33 +00:00
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):
var children = parent.get_children()
var i = 0
2023-09-23 14:19:58 +00:00
if children != []: while children[i].global_position.y > node.global_position.y: i+=1
2023-09-23 14:19:58 +00:00
if not node in get_children(): node.reparent(parent)
parent.move_child(node, i)
2023-07-02 13:10:33 +00:00
# Takes the inputs for control inputs
func _input(event):
if event.is_action_pressed("ui_cancel"):
State.leave_stage(self)
2023-07-02 13:10:33 +00:00
# Return, if the input is a mouse event (mouse events are handled separately)
2023-09-23 14:19:58 +00:00
if event is InputEventMouse or !has_stage or not is_instance_valid(currently_active_node): return
2023-07-02 13:10:33 +00:00
if event.is_action_pressed("ui_up"): # up to select an element above
2023-09-23 14:19:58 +00:00
if current_context == POST_IT_LIST:
current_postIt_id -= 1
else:
current_dropzone_id -= 1
2023-07-02 13:10:33 +00:00
elif event.is_action_pressed("ui_down"): # down to select an element beneath
2023-09-23 14:19:58 +00:00
if current_context == POST_IT_LIST:
current_postIt_id += 1
else:
current_dropzone_id += 1
2023-07-02 13:10:33 +00:00
elif event.is_action_pressed("ui_left"): # left to switch context to the left
2023-09-23 14:19:58 +00:00
if current_context == POST_IT_LIST:
current_context = DROPZONE
2023-07-02 13:10:33 +00:00
elif event.is_action_pressed("ui_right"): # right to switch context to the right
2023-09-23 14:19:58 +00:00
current_context = POST_IT_LIST
2023-07-02 13:10:33 +00:00
elif event.is_action_pressed("ui_accept"): # select the selected post it
2023-09-23 14:19:58 +00:00
var card:Card = dropzone.get_child(current_dropzone_id)
if current_context == ASSIGN_POST_IT: # to assign it to a card
if card.has_postit_attached():
currently_active_node = card.exchange_postIt_with(currently_active_node)
else:
card.attach_postit(currently_active_node)
current_context = DROPZONE
2023-07-02 13:10:33 +00:00
else:
2023-09-23 14:19:58 +00:00
if card.has_postit_attached():
currently_active_node = card.remove_postIt()
current_context == ASSIGN_POST_IT
2023-07-02 13:10:33 +00:00
# move the post it so it floats next to the card where it should be attached
func _select_card_for_assigning(post_it: Area2D, card: Area2D):
2023-08-30 09:07:22 +00:00
post_it.tween_transform_to(card.get_child(3).global_position)
func on_scene_skipped(i: int):
mementos_collected += i
func claim_focus():
State.pass_stage_to(self)