115 lines
2.7 KiB
GDScript
115 lines
2.7 KiB
GDScript
class_name Unit extends CharacterBody3D
|
|
|
|
@export var maximum_health := 10
|
|
@export var maximum_stamina := 50
|
|
@export var stamina_regeneration_rate := 2
|
|
@export var speed := 4.0
|
|
@export var acceleration := 4.0
|
|
@export var jump_speed := 8.0
|
|
@export var jump_cost := 20
|
|
@export var attack_cost := 10
|
|
@export var damage := 1
|
|
|
|
@export var model: Node3D
|
|
@onready var anim_tree := $AnimationTree
|
|
@onready var anim_state = $AnimationTree.get("parameters/playback")
|
|
|
|
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
|
|
var last_floor := true
|
|
var stamina_timer: float
|
|
var stamina_timer_max := 0.1
|
|
@export var hits := ["Hit_A", "Hit_B"]
|
|
@export var deaths := ["Death_A", "Death_B"]
|
|
|
|
enum States {
|
|
idle,
|
|
walking,
|
|
running,
|
|
chasing,
|
|
jumping,
|
|
attacking,
|
|
blocking,
|
|
dead,
|
|
aiming
|
|
}
|
|
|
|
var state = States.idle:
|
|
get:
|
|
return state
|
|
set(value):
|
|
state_changed.emit(state, value)
|
|
state = value
|
|
|
|
@export var unit_name: String:
|
|
get:
|
|
return unit_name
|
|
set(value):
|
|
unit_name = value
|
|
name_changed.emit(unit_name, str(state))
|
|
|
|
var health : int:
|
|
get:
|
|
return health
|
|
set(value):
|
|
if state == States.dead:
|
|
print("Error in health handling. Unit dead!")
|
|
else:
|
|
health = clampi(value, 0, maximum_health)
|
|
health_changed.emit(health, maximum_health)
|
|
if hits.size() > 0:
|
|
anim_state.travel(hits.pick_random())
|
|
if health <= 0:
|
|
die()
|
|
|
|
var stamina : int:
|
|
get:
|
|
return stamina
|
|
set(value):
|
|
stamina = clampi(value, 0, maximum_stamina)
|
|
stamina_changed.emit(stamina, maximum_stamina)
|
|
|
|
signal name_changed(unit_name: String)
|
|
signal health_changed(current_health: int, maximum_health: int)
|
|
signal stamina_changed(current_stamina: int, maximum_stamina: int)
|
|
signal state_changed(old_state: States, new_state: States)
|
|
signal unit_died(unit: Unit)
|
|
|
|
func _process(delta: float) -> void:
|
|
stamina_timer += delta
|
|
if stamina_timer > stamina_timer_max:
|
|
stamina += stamina_regeneration_rate
|
|
stamina_timer = 0
|
|
|
|
func take_damage(damage_amount: int) -> void:
|
|
if state == States.dead:
|
|
print(unit_name + " cannot take damage -> is already dead!")
|
|
elif state == States.blocking:
|
|
anim_state.travel("Block_Hit")
|
|
else:
|
|
health -= damage_amount
|
|
health_changed.emit(health, maximum_health)
|
|
if health <= 0:
|
|
die()
|
|
|
|
func enough_stamina_available(stamina_needed: int) -> bool:
|
|
return stamina_needed <= stamina
|
|
|
|
func use_stamina(stamina_needed: int) -> void:
|
|
stamina -= stamina_needed
|
|
|
|
func die() -> void:
|
|
if state != States.dead:
|
|
state = States.dead
|
|
unit_died.emit(self)
|
|
if deaths.size() > 0:
|
|
anim_state.travel(deaths.pick_random())
|
|
else:
|
|
print(unit_name + " can't die -> is already dead!")
|
|
|
|
func remove_unit() -> void:
|
|
if self is Player:
|
|
var player = self as Player
|
|
player.player_game_over()
|
|
else:
|
|
queue_free()
|