2026-02-11 03:11:28 +00:00
|
|
|
@icon("res://assets/icons/player.svg")
|
2026-02-11 03:01:44 +00:00
|
|
|
class_name Player
|
2026-02-13 16:35:50 +00:00
|
|
|
extends CharacterBody2D
|
2026-02-11 03:01:44 +00:00
|
|
|
|
2026-02-13 03:39:13 +00:00
|
|
|
## signals
|
|
|
|
|
signal turn_finished
|
|
|
|
|
|
2026-02-11 03:01:44 +00:00
|
|
|
## export variables
|
|
|
|
|
@export var attributes: PlayerAttributes ## The attributes resource that defines the player's abilities, vitals etc.
|
|
|
|
|
|
2026-02-13 03:39:13 +00:00
|
|
|
## regular variables
|
2026-02-15 03:17:23 +00:00
|
|
|
var is_active: bool = false: set = set_active
|
2026-02-13 03:39:13 +00:00
|
|
|
var player_label_offset: Vector2
|
|
|
|
|
|
2026-02-11 03:01:44 +00:00
|
|
|
## 'onready' variables
|
2026-02-13 03:39:13 +00:00
|
|
|
## child nodes
|
|
|
|
|
@onready var player_camera: Camera2D = $PlayerCamera
|
|
|
|
|
@onready var player_label: PlayerLabel = $PlayerLabel
|
2026-02-11 03:01:44 +00:00
|
|
|
@onready var player_nav: NavigationAgent2D = $PlayerNav
|
2026-02-15 03:17:23 +00:00
|
|
|
@onready var player_reach_area: Area2D = $PlayerReachArea
|
|
|
|
|
@onready var nav_target_sprite: Sprite2D = $NavTargetSprite
|
2026-02-11 03:01:44 +00:00
|
|
|
@onready var player_sprite: Sprite2D = $PlayerSprite
|
2026-02-13 03:39:13 +00:00
|
|
|
@onready var player_ui: CanvasLayer = $PlayerUI
|
2026-02-15 03:17:23 +00:00
|
|
|
#@onready var end_turn_button: Button = %EndTurnButton
|
2026-02-11 03:01:44 +00:00
|
|
|
|
2026-02-15 03:17:23 +00:00
|
|
|
## Overrides
|
2026-02-11 03:01:44 +00:00
|
|
|
func _ready() -> void:
|
2026-02-15 03:17:23 +00:00
|
|
|
_connect_signals()
|
|
|
|
|
#set_player_attributes(attributes)
|
2026-02-13 03:39:13 +00:00
|
|
|
|
2026-02-11 03:01:44 +00:00
|
|
|
if attributes:
|
2026-02-15 03:17:23 +00:00
|
|
|
_set_player_label_values(attributes)
|
|
|
|
|
_set_player_sprite(attributes.player_texture)
|
|
|
|
|
|
2026-02-13 03:39:13 +00:00
|
|
|
player_label_offset = player_label.position
|
|
|
|
|
|
|
|
|
|
func _process(_delta: float) -> void:
|
2026-02-15 03:17:23 +00:00
|
|
|
_set_player_label_position()
|
2026-02-13 03:39:13 +00:00
|
|
|
if is_active:
|
2026-02-15 03:17:23 +00:00
|
|
|
_set_nav_sprite_position()
|
2026-02-13 03:39:13 +00:00
|
|
|
|
2026-02-15 03:17:23 +00:00
|
|
|
func _physics_process(_delta: float) -> void:
|
|
|
|
|
_set_desired_velocity()
|
|
|
|
|
if get_last_slide_collision():
|
|
|
|
|
var collision = get_last_slide_collision()
|
|
|
|
|
var collider = collision.get_collider()
|
|
|
|
|
if collider is Ball:
|
|
|
|
|
collider.apply_central_impulse(collision.get_normal() * -2.0)
|
2026-02-13 03:39:13 +00:00
|
|
|
|
|
|
|
|
func _input(event: InputEvent) -> void:
|
|
|
|
|
if event.is_action_pressed("end_turn"):
|
|
|
|
|
end_turn()
|
|
|
|
|
if event is InputEventMouseButton and event.is_pressed() and event.button_index == 1:
|
|
|
|
|
var click_position_global = get_global_mouse_position()
|
|
|
|
|
print_debug("%s wants to navigate to %s" % [attributes.player_name, click_position_global])
|
|
|
|
|
player_nav.target_position = click_position_global
|
|
|
|
|
var target_distance = player_nav.distance_to_target()
|
|
|
|
|
print_debug("That's %s pixels/cm away" % target_distance)
|
|
|
|
|
|
|
|
|
|
## Setters
|
|
|
|
|
func set_active(active: bool) -> void:
|
|
|
|
|
is_active = active
|
|
|
|
|
if is_active:
|
|
|
|
|
print_debug("%s says: 'My turn!'" % attributes.player_name)
|
|
|
|
|
player_camera.enabled = true
|
|
|
|
|
player_camera.make_current()
|
2026-02-15 03:17:23 +00:00
|
|
|
nav_target_sprite.visible = true
|
2026-02-13 03:39:13 +00:00
|
|
|
set_process_input(true)
|
|
|
|
|
else:
|
|
|
|
|
print_debug("%s says: 'It's not my turn'" % attributes.player_name)
|
|
|
|
|
player_camera.enabled = false
|
2026-02-15 03:17:23 +00:00
|
|
|
nav_target_sprite.visible = false
|
2026-02-13 03:39:13 +00:00
|
|
|
set_process_input(false)
|
|
|
|
|
|
2026-02-15 03:17:23 +00:00
|
|
|
## Actions
|
2026-02-13 03:39:13 +00:00
|
|
|
func end_turn() -> void:
|
|
|
|
|
print_debug("%s says: I'd like my turn to end." % attributes.player_name)
|
|
|
|
|
is_active = false
|
|
|
|
|
turn_finished.emit()
|
2026-02-15 03:17:23 +00:00
|
|
|
|
|
|
|
|
## Helper functions
|
|
|
|
|
func _connect_signals() -> void:
|
|
|
|
|
player_nav.connect("velocity_computed", on_velocity_computed)
|
|
|
|
|
player_reach_area.connect("body_entered", on_player_reach_area_body_entered)
|
|
|
|
|
player_reach_area.connect("body_exited", on_player_reach_area_body_exited)
|
|
|
|
|
|
|
|
|
|
func _set_desired_velocity() -> void:
|
|
|
|
|
var desired_velocity: Vector2 = global_position.direction_to(player_nav.get_next_path_position()) * attributes.speed
|
|
|
|
|
player_nav.velocity = desired_velocity
|
|
|
|
|
|
|
|
|
|
func _set_player_label_position() -> void:
|
|
|
|
|
player_label.global_position = global_position + player_label_offset
|
|
|
|
|
|
|
|
|
|
func _set_nav_sprite_position() -> void:
|
|
|
|
|
nav_target_sprite.global_position = get_global_mouse_position()
|
|
|
|
|
|
|
|
|
|
func _set_player_label_values(attributes_resource: PlayerAttributes) -> void:
|
|
|
|
|
player_label.player_name = attributes_resource.player_name
|
|
|
|
|
player_label.player_number = attributes_resource.player_number
|
|
|
|
|
player_label.player_position = attributes_resource.player_position
|
|
|
|
|
|
|
|
|
|
func _set_player_sprite(texture: Texture2D) -> void:
|
|
|
|
|
player_sprite.texture = texture
|
|
|
|
|
|
|
|
|
|
## Signal handlers
|
|
|
|
|
func on_player_reach_area_body_entered(body: PhysicsBody2D) -> void:
|
|
|
|
|
if body is Player:
|
|
|
|
|
print_debug((body.attributes.player_name) + " has entered %s's reach area" % attributes.player_name)
|
|
|
|
|
elif body is Ball:
|
|
|
|
|
print_debug("The ball has entered %s's reach area" % attributes.player_name)
|
|
|
|
|
|
|
|
|
|
func on_player_reach_area_body_exited(body: PhysicsBody2D) -> void:
|
|
|
|
|
if body is Player:
|
|
|
|
|
print_debug((body.attributes.player_name) + " has exited %s's reach area" % attributes.player_name)
|
|
|
|
|
elif body is Ball:
|
|
|
|
|
print_debug("The ball has exited %s's reach area" % attributes.player_name)
|
2026-02-13 03:39:13 +00:00
|
|
|
|
|
|
|
|
func on_velocity_computed(safe_velocity: Vector2) -> void:
|
2026-02-15 03:17:23 +00:00
|
|
|
look_at(player_nav.get_next_path_position())
|
2026-02-13 16:35:50 +00:00
|
|
|
velocity = safe_velocity
|
|
|
|
|
move_and_slide()
|