SchildDerStaerke/scripts/unit.gd

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()