This repository has been archived on 2025-09-12. You can view files and clone it, but cannot push or open issues or pull requests.
ld48/character/Enemy.gd

166 lines
4.5 KiB
GDScript

extends KinematicBody2D
export var attack_hit_delay: float = 0.16
export var walk_sounds: Array
export var walk_sound_interval: float = 0.5
export var swing_sounds: Array
export var hit_sounds: Array
var health = 100.0
export var resist_base: float = 0.00
export var resist_fire: float = 0.00
export var resist_ice: float = 0.00
export var resist_wind: float = 0.00
var attack_range: float = 30.0
var basic_attack_dmg: float = 2.00
var basic_attack_multiplier: float = 3.00
var basic_attack_cooldown: float = 2.50
var attack_timer: float = 0.00
var run_speed: float = 70.0
var nearest_player = null
onready var home = self.position
onready var sprite = $AnimatedSprite
var walk_sound_timer: float = 0.0
var moving: bool = false
var last_movement_dir: Vector2 = Vector2.DOWN
var playing_action: bool = false
func _ready() -> void:
sprite.playing = true
func take_damage(dmg: float, fire_dmg: float, ice_dmg: float, wind_dmg: float):
health -= (1.0 - resist_base) * dmg
$FCTManager._show_value((1.0 - resist_base) * dmg)
health -= (1.0 - resist_fire) * fire_dmg
if ((1.0 - resist_fire) * fire_dmg) != 0:
$FCTManager._show_value((1.0 - resist_fire) * fire_dmg)
health -= (1.0 - resist_ice) * ice_dmg
if ((1.0 - resist_ice) * ice_dmg) != 0:
$FCTManager._show_value((1.0 - resist_ice) * ice_dmg)
health -= (1.0 - resist_wind) * wind_dmg
if ((1.0 - resist_wind) * wind_dmg) != 0:
$FCTManager._show_value((1.0 - resist_wind) * wind_dmg)
if health <= 0.0:
queue_free()
func set_target(player: KinematicBody2D):
nearest_player = player
func _physics_process(delta:float):
walk_sound_timer += delta
if nearest_player:
attack_timer += delta
var towardsplayer = ((nearest_player.global_position - self.global_position).normalized() * self.run_speed)
moving = true
move_and_slide(towardsplayer)
animate_movement(towardsplayer)
last_movement_dir = towardsplayer
try_play_walk_sound()
var collision = move_and_collide((nearest_player.global_position - self.global_position).normalized() * self.attack_range,true,true,true)
if collision && collision.collider.has_method("take_damage") && attack_timer >= basic_attack_cooldown :
attack_timer = 0.0
play_attack_anim(last_movement_dir)
if swing_sounds.size() > 0:
get_node(swing_sounds[randi() % swing_sounds.size()]).play()
hit(collision.collider)
else:
var towardshome = ((home - self.position).normalized() * self.run_speed)
if (home - self.position).length_squared() > 8.0:
moving = true
move_and_slide(towardshome)
animate_movement(towardshome)
last_movement_dir = towardshome
try_play_walk_sound()
else:
moving = false
animate_movement(last_movement_dir)
walk_sound_timer = 0.0
func hit(other: CollisionObject2D):
yield(get_tree().create_timer(attack_hit_delay), "timeout")
if !is_instance_valid(other):
return
if hit_sounds.size() > 0:
get_node(hit_sounds[randi() % hit_sounds.size()]).play()
other.take_damage(basic_attack_dmg * basic_attack_multiplier,0,0,0)
func animate_movement(dir: Vector2):
if playing_action:
return
var angle = dir.normalized().angle()
# right
if angle > -0.1875 * TAU && angle < 0.1875 * TAU:
if moving:
sprite.play("run_right")
else:
sprite.play("idle_right")
# left
elif angle < -0.3125 * TAU || angle > 0.3125 * TAU:
if moving:
sprite.play("run_left")
else:
sprite.play("idle_left")
# down
elif angle > 0.0:
if moving:
sprite.play("run_down")
else:
sprite.play("idle_down")
# up
else:
if moving:
sprite.play("run_up")
else:
sprite.play("idle_up")
func play_attack_anim(direction: Vector2):
playing_action = true
var angle = last_movement_dir.normalized().angle()
var anim: String
# right
if angle > -0.1875 * TAU && angle < 0.1875 * TAU:
anim = "slash_right"
# left
elif angle < -0.3125 * TAU || angle > 0.3125 * TAU:
anim = "slash_left"
# down
elif angle > 0.0:
anim = "slash_down"
# up
else:
anim = "slash_up"
sprite.play(anim)
$FxSprite.play(anim + "_red")
yield(sprite, "animation_finished")
playing_action = false
$FxSprite.play("idle")
func _process(delta:float):
# DebugLabel.display(self, last_movement_dir)
# if nearest_player:
# DebugLabel.display(self, nearest_player.position)
# DebugLabel.display(self, ((nearest_player.position - self.position).normalized() * self.run_speed))
# else:
# pass
pass
func try_play_walk_sound():
if walk_sound_timer > walk_sound_interval:
walk_sound_timer = 0.0
if walk_sounds.size() > 0:
get_node(walk_sounds[randi() % walk_sounds.size()]).play()