86 lines
2.4 KiB
GDScript
86 lines
2.4 KiB
GDScript
extends CharacterBody2D
|
|
|
|
@export var speed: int = 900
|
|
@onready var navigation_agent_2d: NavigationAgent2D = $NavigationAgent2D
|
|
@onready var follow_update_timer: Timer = $FollowUpdateTimer
|
|
@onready var attack_timer: Timer = $AttackTimer
|
|
@onready var animated_sprite: AnimatedSprite2D = $AnimatedSprite2D
|
|
|
|
var idle: bool = true
|
|
const DAMAGE: int = 1
|
|
var health: int = 8
|
|
var target: Player = null
|
|
var in_attack_range: bool = false
|
|
var stop_distance: int = 20
|
|
var attack_cooldown_offset: float = 0.0
|
|
var flicker_time: float = 0.2
|
|
var flicker_timer: float = 0.0
|
|
|
|
func _ready() -> void:
|
|
navigation_agent_2d.avoidance_priority = randf_range(0.5, 1.0)
|
|
attack_cooldown_offset = randf_range(0.0, 0.5)
|
|
animated_sprite.speed_scale = randf_range(0.4, 1.2)
|
|
|
|
follow_update_timer.one_shot = false
|
|
follow_update_timer.autostart = false
|
|
|
|
func _process(delta: float) -> void:
|
|
if flicker_timer > 0.0:
|
|
flicker_timer -= delta
|
|
animated_sprite.modulate = Color(1, 0, 0)
|
|
if flicker_timer <= 0.0:
|
|
animated_sprite.modulate = Color(1, 1, 1)
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
if !idle and target:
|
|
if navigation_agent_2d.is_navigation_finished():
|
|
velocity = Vector2.ZERO
|
|
else:
|
|
var next_pos: Vector2 = navigation_agent_2d.get_next_path_position()
|
|
var direction: Vector2 = (next_pos - global_position).normalized()
|
|
velocity = direction * speed * delta
|
|
else:
|
|
velocity = Vector2.ZERO
|
|
|
|
move_and_slide()
|
|
|
|
func _on_area_body_entered(body: Node2D) -> void:
|
|
if body is Player:
|
|
idle = false
|
|
target = body
|
|
navigation_agent_2d.target_position = target.global_position
|
|
follow_update_timer.start()
|
|
animated_sprite.play()
|
|
|
|
func _on_area_body_exited(body: Node2D) -> void:
|
|
if body is Player:
|
|
idle = true
|
|
target = null
|
|
follow_update_timer.stop()
|
|
animated_sprite.frame = 0
|
|
animated_sprite.stop()
|
|
|
|
func _on_attack_area_body_entered(body: Node2D) -> void:
|
|
if body is Player:
|
|
in_attack_range = true
|
|
attack_timer.start(attack_timer.wait_time + attack_cooldown_offset)
|
|
|
|
func _on_attack_area_body_exited(body: Node2D) -> void:
|
|
if body is Player:
|
|
in_attack_range = false
|
|
attack_timer.stop()
|
|
|
|
func _on_follow_update_timer_timeout() -> void:
|
|
if target and !idle:
|
|
navigation_agent_2d.target_position = target.global_position
|
|
|
|
func _on_attack_timer_timeout() -> void:
|
|
if target and in_attack_range:
|
|
target.health -= DAMAGE
|
|
|
|
func _on_fightable_fought(player: Player) -> void:
|
|
health -= player.damage
|
|
flicker_timer = flicker_time
|
|
if health <= 0:
|
|
queue_free()
|