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