You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
2.8 KiB
104 lines
2.8 KiB
2 years ago
|
extends Node2D
|
||
|
|
||
|
signal deal_damage(amount:int)
|
||
|
signal health_changed(old_value, new_value)
|
||
|
signal stamina_changed(old_value, new_value)
|
||
|
signal actions_done
|
||
|
|
||
|
@onready var _animation_player = $AnimationPlayer
|
||
|
@onready var _animation_sprite = $Sprite2D
|
||
|
@onready var _animation_damage_label = $DamageLabel
|
||
|
|
||
|
@export
|
||
|
var orientation:int = 1
|
||
|
@export
|
||
|
var health:int = 100
|
||
|
@export
|
||
|
var stamina:int = 100
|
||
|
@export
|
||
|
var descriptor:String = "Foo"
|
||
|
|
||
|
|
||
|
var _actions = []
|
||
|
var _action_queue = []
|
||
|
var _health = 0
|
||
|
var _stamina = 0
|
||
|
|
||
|
# Public methods
|
||
|
func init(actions):
|
||
|
_actions = actions.duplicate(true)
|
||
|
_health = health
|
||
|
_stamina = stamina
|
||
|
health_changed.emit(_health, _health)
|
||
|
stamina_changed.emit(_stamina, _stamina)
|
||
|
|
||
|
func is_animation_idle() -> bool:
|
||
|
return !_animation_player.is_playing() && _action_queue.is_empty()
|
||
|
|
||
|
func is_animation_done() -> bool:
|
||
|
return is_animation_idle() && _actions.is_empty()
|
||
|
|
||
|
# Called when the node enters the scene tree for the first time.
|
||
|
func _ready():
|
||
|
_animation_sprite.flip_h = orientation
|
||
|
_animation_player.play("RESET")
|
||
|
|
||
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||
|
func _process(_delta):
|
||
|
pass
|
||
|
|
||
|
func _take_damage(amount : int):
|
||
|
var old_health = _health
|
||
|
_health -= amount
|
||
|
if _animation_player.is_playing():
|
||
|
print_debug("%s -> %s: _take_damage -> skip current animation %s!" % [Time.get_ticks_msec(), descriptor,_animation_player.current_animation])
|
||
|
_animation_player.stop()
|
||
|
|
||
|
print_debug("%s -> %s: _take_damage -> play HIT animation!" % [Time.get_ticks_msec(), descriptor])
|
||
|
_animation_player.play("Hit")
|
||
|
_animation_damage_label.show_damage(amount)
|
||
|
|
||
|
health_changed.emit(old_health, _health)
|
||
|
|
||
|
func _alter_stamina(amount : int):
|
||
|
if _stamina <= stamina:
|
||
|
var old_stamina = _stamina
|
||
|
_stamina = min(stamina, _stamina + amount)
|
||
|
stamina_changed.emit(old_stamina, _stamina)
|
||
|
|
||
|
func _on_next_round():
|
||
|
print_debug("%s -> %s: _on_next_round" % [Time.get_ticks_msec(), descriptor])
|
||
|
if !_actions.is_empty():
|
||
|
_alter_stamina(5)
|
||
|
_action_queue = _actions.pop_front()
|
||
|
_schedule_next_action()
|
||
|
|
||
|
func _schedule_next_action():
|
||
|
if _animation_player.is_playing():
|
||
|
return
|
||
|
|
||
|
if _action_queue.is_empty():
|
||
|
_animation_sprite.frame = 0
|
||
|
actions_done.emit()
|
||
|
return
|
||
|
|
||
|
var action : String = _action_queue.pop_front()
|
||
|
_animation_player.play(action)
|
||
|
print_debug("%s -> %s: _schedule_next_action -> plays %s!" % [Time.get_ticks_msec(), descriptor, action])
|
||
|
|
||
|
if action.begins_with("Attack1"):
|
||
|
deal_damage.emit(5)
|
||
|
_alter_stamina(-10)
|
||
|
elif action.begins_with("Attack2"):
|
||
|
deal_damage.emit(15)
|
||
|
_alter_stamina(-20)
|
||
|
|
||
|
|
||
|
func _on_animation_finished(anim_name):
|
||
|
print_debug("%s -> %s: _on_animation_finished -> %s!" % [Time.get_ticks_msec(), descriptor, anim_name])
|
||
|
_schedule_next_action()
|
||
|
|
||
|
|
||
|
func _on_animation_started(anim_name):
|
||
|
print_debug("%s -> %s: _on_animation_started -> %s!" % [Time.get_ticks_msec(), descriptor, anim_name])
|