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()