frame-of-mind/src/logic-scenes/card_picker/card_picker.gd

236 lines
6.0 KiB
GDScript3
Raw Normal View History

class_name CardPicker
extends Playable
#fixme INI is probably redundant.
enum {
2024-09-15 09:30:31 +00:00
INI,
CARDS,
CARDS_SELECTED,
TRANSITION,
POSTS,
POSTS_SELECTED,
DONE
}
2026-01-11 22:53:23 +00:00
@export var current_scene_id : Scenes.id = Scenes.id.NONE
2026-01-19 10:49:31 +00:00
var _input_locked: bool:
get: return (selection_state != CARDS and selection_state != POSTS) or not visible
2026-01-11 22:53:23 +00:00
var selection_state := INI:
2024-09-15 09:30:31 +00:00
set(state):
print("Setting picker state to %s" % ["INI","CARDS","CARDS_SELECTED","TRANSITION","POSTS","POSTS_SELECTED","DONE"][state])
2024-09-15 09:30:31 +00:00
selection_state = state
2024-09-15 09:30:31 +00:00
if state == CARDS_SELECTED:
var tween: Tween = get_tree().create_tween()
2024-09-15 09:30:31 +00:00
tween.tween_property($thought_prompt, "modulate", Color(1, 1, 1, 0), 0.5)
elif state == DONE:
reset()
var anim_players:Array[AnimationPlayer] = []
var curr_selection_id: int = -1:
2024-09-15 09:30:31 +00:00
set(new_id):
if selection_state == CARDS or selection_state == POSTS:
2026-01-19 10:49:31 +00:00
# Wrap around
curr_selection_id = new_id % options.size()
# Update all highlights
for i in range(options.size()):
options[i].highlighted = (i == curr_selection_id)
2024-09-15 09:30:31 +00:00
else:
curr_selection_id = new_id
2023-07-19 11:50:19 +00:00
var output:Array = []
var options:Array = []
2025-02-06 17:55:05 +00:00
signal cards_picked(cardnames: Array[String])
2026-01-19 10:49:31 +00:00
func play() -> void:
await pick_cards(Scenes.id.YOUTH_CHILDHOOD)
2023-07-19 11:50:19 +00:00
func reset():
card_anim_skipped = false
2024-09-15 09:30:31 +00:00
output = []
options = []
anim_players = []
var card_controls: Array[Node] = $cards.get_children()
2024-09-15 09:30:31 +00:00
for control in card_controls:
options.append(control.get_child(1))
anim_players.append(control.get_child(0))
curr_selection_id = 0
for player in anim_players: player.play("reveal")
func fill_card_slots(id: int):
var new_cards : Array[Card] = HardCards.get_cards_by_scene_id(id)
2024-09-15 09:30:31 +00:00
for i in range(new_cards.size()):
$cards.get_child(i).remove_child($cards.get_child(i).get_child(1))
2025-02-24 15:14:08 +00:00
var new_card:Card = new_cards[i]
$cards.get_child(i).add_child(new_card)
#new_card.owner = self
2025-02-24 15:14:08 +00:00
2026-01-19 10:49:31 +00:00
# No need to connect signals - Draggable base class handles this
2024-09-15 09:30:31 +00:00
options.append(new_card)
anim_players.append($cards.get_child(i).get_child(0))
func fill_post_slots():
2024-09-15 09:30:31 +00:00
var sticky_notes: Array[StickyNote] = []
for card: Card in output:
sticky_notes.append_array(HardCards.get_children_of(card.card_id))
2025-02-24 15:14:08 +00:00
for note:StickyNote in sticky_notes:
note.current_handle = self
2024-09-15 09:30:31 +00:00
sticky_notes.shuffle()
options = []
for ancor in $sticky_notes.get_children():
ancor.remove_child(ancor.get_child(1))
2024-09-15 09:30:31 +00:00
for i in range(sticky_notes.size()):
options.append(sticky_notes[i])
$sticky_notes.get_child(i).add_child(options[i], false)
#options[i].owner = self # TODO: I think this is not necessary.
var picked_player: AnimationPlayer
var random_player: AnimationPlayer
var card_anim_skipped:bool = false
func _input(event : InputEvent) -> void:
2026-01-19 10:49:31 +00:00
if _input_locked: return
# Navigation
if event.is_action_pressed("ui_up") or event.is_action_pressed("ui_left"):
curr_selection_id -= 1
elif event.is_action_pressed("ui_down") or event.is_action_pressed("ui_right"):
curr_selection_id += 1
# Selection
elif event.is_action_pressed("ui_accept"):
pick(curr_selection_id)
func pick(id: int) -> void:
print("%s picked card %s at id %d" % [name, options[id].text, id])
2024-09-15 09:30:31 +00:00
if id == -1:
curr_selection_id = 0
return
2024-09-15 09:30:31 +00:00
if selection_state == CARDS:
selection_state = CARDS_SELECTED
elif selection_state == POSTS:
selection_state = POSTS_SELECTED
2024-09-15 09:30:31 +00:00
anim_players[id].play("pick")
picked_player = anim_players[id]
var yield_to := anim_players[id].animation_finished
2024-09-15 09:30:31 +00:00
output.append(options[id])
2024-09-15 09:30:31 +00:00
options.remove_at(id)
anim_players.remove_at(id)
var parent_id:StringName
2024-09-15 09:30:31 +00:00
if selection_state == POSTS_SELECTED:
parent_id = output[-1].parent_id
var i:int = 0
for option:StickyNote in options:
if option.parent_id == parent_id:
options.erase(option)
anim_players[i].play("unshuffle")
anim_players.remove_at(i)
print("Removed StickyNote %s from options pool" % HardCards.get_obscure_name(option.name))
i += 1
var winning_id
print("Randomly selected card %s" % HardCards.get_obscure_name(options[1].name))
if not (current_scene_id == Scenes.id.YOUTH_JUI_JUTSU and selection_state == CARDS_SELECTED):
2024-09-15 09:30:31 +00:00
randomize()
winning_id = randi() % options.size() - ( 1 if selection_state == POSTS_SELECTED else 0)
2024-09-15 09:30:31 +00:00
else:
2025-05-12 17:05:13 +00:00
winning_id = 1 if id == 0 else 0
if Steamworks.has_initialized:
Steam.setAchievement("FIGHT_BACK")
Steam.storeStats()
2024-09-15 09:30:31 +00:00
output.append(options.pop_at(winning_id))
random_player = anim_players[winning_id]
2024-09-15 09:30:31 +00:00
anim_players.pop_at(winning_id).play("shuffle")
2024-09-15 09:30:31 +00:00
for anim in anim_players:
anim.play("unshuffle")
await yield_to
if not card_anim_skipped: transition()
2026-01-22 17:36:36 +00:00
func transition():
2024-09-15 09:30:31 +00:00
if selection_state == CARDS_SELECTED:
selection_state = TRANSITION
options = []
anim_players = []
for control in $sticky_notes.get_children():
options.append(control.get_child(1))
anim_players.append(control.get_child(0))
control.get_child(0).play("post")
curr_selection_id = -1
2024-09-15 09:30:31 +00:00
fill_post_slots()
2024-09-15 09:30:31 +00:00
await anim_players[0].animation_finished
if selection_state != POSTS:
show_posts()
2024-09-15 09:30:31 +00:00
elif selection_state == POSTS_SELECTED:
var out_str:Array[StringName] = []
2024-09-15 09:30:31 +00:00
for card in output:
out_str.append(card.name if card.name != "" else "c_void")
2024-09-19 10:29:35 +00:00
cards_picked.emit(out_str)
2024-09-15 09:30:31 +00:00
selection_state = DONE
2026-01-22 17:36:36 +00:00
func show_posts():
2024-09-15 09:30:31 +00:00
for player:AnimationPlayer in anim_players:
player.play("RESET")
2025-06-03 21:12:22 +00:00
selection_state = POSTS
2026-01-19 10:49:31 +00:00
func handle_hover(draggable: Draggable) -> void:
if _input_locked: return
draggable.highlighted = draggable.mouse_over
if draggable.mouse_over:
curr_selection_id = options.find(draggable)
2026-01-22 17:36:36 +00:00
2026-01-19 10:49:31 +00:00
func handle_mouse_button(event: InputEventMouseButton, draggable: Draggable) -> void:
if _input_locked: return
if event.button_index == MOUSE_BUTTON_LEFT and event.is_pressed() and not event.is_echo():
pick(options.find(draggable))
2025-05-10 13:59:52 +00:00
func pick_cards(id: Scenes.id):
2026-01-19 10:49:31 +00:00
prints("------------- PICKING CARDS -------------")
2025-05-10 13:59:52 +00:00
current_scene_id = id
hide()
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
fill_card_slots(id)
reset()
show()
selection_state = CARDS
if id == Scenes.id.YOUTH_DRAVEN:
$Meaning.play()
State.room.scene_player.play("intro")
await cards_picked
hide()