cabin-fever/Zombo.gd

106 lines
2.5 KiB
GDScript

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