extends KinematicBody2D signal enemy_killed signal enemy_damaged var navi : Navigation2D onready var sprite : AnimatedSprite = $AnimatedSprite onready var aggro_area : Area2D = $AggroArea onready var look : RayCast2D = $Look onready var collision_shape : CollisionShape2D = $CollisionShape2D onready var aggro_collision : CollisionShape2D = $AggroArea/AggroRadius onready var attack_area : Area2D = $AttackArea onready var stun_timer : Timer = $StunTimer var target : Player var input_vec : Vector2 = Vector2.ZERO var player_seen : bool = false export var hp : int = 3 export var attack_speed : float = 3.0 var since_attack : float = 0 var stunned : bool = false func take_damage(damage : int): hp -= damage stun_timer.start() stunned = true if hp <= 0: emit_signal("enemy_killed") queue_free() return emit_signal("enemy_damaged") player_seen = true func _ready(): look.add_exception(collision_shape) look.add_exception(aggro_collision) func set_nav(nav : Navigation2D): navi = nav func search_player(): if target != null: var enemy_to_player = target.global_position - self.global_position look.cast_to = enemy_to_player if look.is_colliding(): var collider = look.get_collider() if collider == target: player_seen = true func try_attack() -> bool: if target == null: return false if !target.is_alive(): return true if attack_area.overlaps_body(target): if target.has_method("take_damage") and since_attack <= 0: target.take_damage(1) since_attack = attack_speed return true return false func _process(delta): since_attack -= delta if since_attack < 0: since_attack = 0 if target == null: return elif navi != null and player_seen: var path : PoolVector2Array = navi.get_simple_path(self.global_position, target.global_position) if path.size() >= 1: input_vec = (path[1] - position).normalized() var abs_y = abs(input_vec.y) var abs_x = abs(input_vec.x) if input_vec.x < 0: sprite.animation = "side" sprite.flip_h = true elif input_vec.x > 0: sprite.animation = "side" sprite.flip_h = false if input_vec.y < 0: sprite.animation = "up" elif input_vec.y > 0: sprite.animation = "down" if abs_y < abs_x: sprite.animation = "side" func _physics_process(delta): if !player_seen: search_player() elif try_attack(): return var speed = 80 if stunned: speed = 40 move_and_slide(input_vec.normalized() * speed, Vector2.UP) func _on_AggroArea_body_entered(body): if body.has_method("is_player") and body.is_player(): target = body func _on_StunTimer_timeout(): stunned = false