extends CharacterBody2D # ActionState should probably be expandable to enum ActionState {None, Cycling, Firing, Charging} enum MoveState {Still, Moving, Dashing, Knockback} @export var speed = 200 # How fast the player will move (pixels/sec). @export var dash_cooldown = 0.3 @export var hand_size = 3 @onready var camera: Camera2D = %PlayerCamera @onready var sprite: AnimatedSprite2D = $PlayerSprite var shield_active = true; var move_direction = Vector2.ZERO; var target = Vector2.ZERO # The position of the player's cursor. const drawpile = []; const hand = []; const discard_pile = []; var active_card_index = -1; var screen_size # Size of the game window. var action_state = ActionState.None var move_state = MoveState.Still var charge_level = 0; var charge_rate = 1; var charged = false; var dash_cooldown_timer = 0; var dash_on_cooldown = false; func update_move_direction(): move_direction = Vector2.ZERO if Input.is_action_pressed("move_right"): move_direction.x += 1 if Input.is_action_pressed("move_left"): move_direction.x -= 1 if Input.is_action_pressed("move_down"): move_direction.y += 1 if Input.is_action_pressed("move_up"): move_direction.y -= 1 move_direction = move_direction.normalized() func update_target_coords(): target = get_viewport().get_mouse_position() sprite.look_at(get_global_mouse_position()) func update_camera_position(): if not camera: return; var camera_target = (target - screen_size / 2) / 4 camera.position = camera.position.lerp(camera_target, 0.1) func charge(): # Charge attack if not charged and action_state == ActionState.Charging: charge_level += charge_rate; if charge_level >= 100: charged = false; charge_level = 0; elif charge_level > 0: # Gradual charge dropoff charge_level = max(charge_level - charge_rate * 2, 0); func dash(): var card = hand.get(active_card_index); if not card or dash_on_cooldown: return; card.discard(self); # Must set move_state at start and end of dash dash_on_cooldown = true; func play_card(): if active_card_index >= 0 and active_card_index < hand.size(): var card = hand[active_card_index]; card.play(self); func cycle_card(index_shift): if hand.size() > 0: active_card_index = (active_card_index + index_shift) % hand.size(); else: draw_card(); func discard_active_card(): if active_card_index >= 0 and active_card_index < hand.size(): var card = hand[active_card_index]; discard_pile.append(card); hand.remove_at(active_card_index); active_card_index = min(active_card_index, hand.size() - 1); draw_card(); func draw_card(): if drawpile.size() == 0: shuffle_deck(); if drawpile.size() > 0 and hand.size() < hand_size: var card = drawpile.pop_back(); hand.append(card); if active_card_index == -1: active_card_index = 0; # TODO: Reboot mechanics func shuffle_deck(): for card in discard_pile: drawpile.append(card); discard_pile.clear(); drawpile.shuffle(); active_card_index = 0; func _ready(): screen_size = get_viewport_rect().size while (hand.size() < hand_size and drawpile.size() > 0): draw_card(); func _process(delta): update_target_coords(); update_camera_position(); if (move_state != MoveState.Dashing): update_move_direction(); if (dash_on_cooldown): dash_cooldown_timer += delta; if (dash_cooldown_timer >= dash_cooldown): dash_on_cooldown = false; dash_cooldown_timer = 0; # handle move_state if move_state == MoveState.Knockback: pass elif Input.is_action_just_pressed("dash"): dash(); elif (move_state != MoveState.Dashing): velocity = move_direction * speed; if velocity.x || velocity.y: move_state = MoveState.Moving; else: move_state = MoveState.Still; move_and_slide(); # Handle action_state if Input.is_action_pressed("play_card"): play_card(); if Input.is_action_just_pressed("cycle_card_left"): action_state = ActionState.Cycling; cycle_card(-1); elif Input.is_action_just_pressed("cycle_card_right"): action_state = ActionState.Cycling; cycle_card(1);