140 lines
4 KiB
GDScript
140 lines
4 KiB
GDScript
class_name Enemy extends CharacterBody2D
|
|
|
|
@export_group("Combat Scenes")
|
|
@export var mask_drop : PackedScene
|
|
@export var death_explosion : PackedScene
|
|
@export var heart_attack : PackedScene
|
|
@export var scithe_attack : PackedScene
|
|
@export var spit_attack : PackedScene
|
|
|
|
var charge : float = 0.0
|
|
@export var charge_time : float = 0.7
|
|
|
|
@export var flee_range = 20
|
|
@export var aproach_range = 100
|
|
@export var health := 3
|
|
@export var current_mask : Types.mask_types
|
|
@export var movement_speed: float = 30.0
|
|
|
|
@onready var navigation_agent: NavigationAgent2D = $NavigationAgent2D
|
|
@onready var movement_target_position: Vector2 = global_position
|
|
@onready var sprite : AnimatedSprite2D = $Anim
|
|
|
|
@onready var player = get_tree().get_first_node_in_group("player")
|
|
|
|
func _ready():
|
|
navigation_agent.path_desired_distance = 4.0
|
|
navigation_agent.target_desired_distance = 4.0
|
|
|
|
navigation_agent.velocity_computed.connect(_on_velocity_computed)
|
|
call_deferred("_actor_setup")
|
|
|
|
func _actor_setup():
|
|
await get_tree().physics_frame
|
|
|
|
set_movement_target(movement_target_position)
|
|
|
|
func set_movement_target(movement_target: Vector2):
|
|
navigation_agent.target_position = movement_target
|
|
|
|
func _drop_mask():
|
|
var drop : MaskDrop = mask_drop.instantiate()
|
|
drop.mask_type = current_mask
|
|
get_parent().add_child(drop)
|
|
drop.global_position = global_position
|
|
|
|
func die():
|
|
EventBus.screenshake.emit(10)
|
|
var tween = create_tween()
|
|
var explo = death_explosion.instantiate()
|
|
get_parent().add_child(explo)
|
|
explo.global_position = global_position
|
|
explo.emitting = true
|
|
tween.tween_property(self, "modulate:a", 0, 0.2)
|
|
tween.tween_callback(_drop_mask)
|
|
tween.tween_callback(queue_free)
|
|
|
|
|
|
func launch_atk():
|
|
var atk = null
|
|
var target = navigation_agent.target_position
|
|
if (current_mask == Types.mask_types.Melee):
|
|
atk = scithe_attack.instantiate()
|
|
add_child(atk)
|
|
atk.look_at(target)
|
|
atk.modulate = Color.BLACK
|
|
elif (current_mask == Types.mask_types.Ranged):
|
|
atk = heart_attack.instantiate()
|
|
atk.global_position = global_position
|
|
atk.look_at(target)
|
|
atk.modulate = Color.BLACK
|
|
get_parent().add_child(atk)
|
|
elif (current_mask == Types.mask_types.Spit):
|
|
atk = spit_attack.instantiate()
|
|
atk.global_position = global_position
|
|
atk.start_position = global_position
|
|
get_parent().add_child(atk)
|
|
atk.target_position = global_position + global_position.direction_to(target) * 150
|
|
|
|
atk.set_from_player(false)
|
|
|
|
atk.global_position = atk.global_position.move_toward(target, 10 )
|
|
|
|
|
|
func _process(_delta: float) -> void:
|
|
queue_redraw()
|
|
if player:
|
|
set_movement_target(player.global_position)
|
|
if not current_mask == 2:
|
|
scale = Vector2.ONE * (1 + charge)
|
|
if (charge > charge_time):
|
|
launch_atk()
|
|
charge = 0
|
|
|
|
func hit():
|
|
health -= 1
|
|
SoundManager.play_sfx("death")
|
|
#charge = 0
|
|
if health == 0:
|
|
die()
|
|
|
|
EventBus.screenshake.emit(0.2)
|
|
var tween = create_tween()
|
|
tween.tween_property(self, "modulate", Color.CRIMSON, 0.1)
|
|
tween.tween_property(self, "modulate", Color.WHITE, 0.3)
|
|
|
|
func knockback():
|
|
EventBus.debug_print.emit("knocking back called!")
|
|
velocity += global_position.direction_to(navigation_agent.target_position).normalized() * -2000
|
|
|
|
func _dir_to_target():
|
|
if navigation_agent.is_navigation_finished():
|
|
return Vector2.ZERO
|
|
|
|
var next_path_position: Vector2 = navigation_agent.get_next_path_position()
|
|
return next_path_position
|
|
|
|
|
|
func _physics_process(delta : float):
|
|
var target_dist = navigation_agent.target_position.distance_to(global_position)
|
|
if (target_dist > aproach_range):
|
|
velocity += global_position.direction_to(_dir_to_target()) * movement_speed
|
|
sprite.flip_h = velocity.x > 0
|
|
charge = 0
|
|
elif (target_dist < flee_range):
|
|
velocity -= global_position.direction_to(_dir_to_target()) * movement_speed
|
|
sprite.flip_h = velocity.x > 0
|
|
charge = 0
|
|
else:
|
|
charge += delta
|
|
if player:
|
|
sprite.flip_h = player.global_position.x > global_position.x
|
|
|
|
velocity *= 0.6
|
|
|
|
navigation_agent.set_velocity(velocity)
|
|
move_and_slide()
|
|
|
|
func _on_velocity_computed(safe_velocity: Vector2):
|
|
velocity = safe_velocity
|
|
move_and_slide()
|