1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
extends RigidBody2D

var alive = true
var asleep = false
var health = 15
var COOLDOWN = 1

var hovering

export var MAX_SPEED = 50
export var MAX_THRUST = 25


func _integrate_forces(state):
	if not alive:
		return

	if asleep:
		return

	var delta = state.get_step()

	# Check nearby objects with raycast
	var closest_collision = null
	$rays.rotation += delta * 11 * PI
	for ray in $rays.get_children():
		if ray.is_colliding():
			var collision_point = ray.get_collision_point() - global_position
			if closest_collision == null:
				closest_collision = collision_point
			if collision_point.length() < closest_collision.length():
				closest_collision = collision_point

	# Dodge
	if closest_collision:
		var normal = -closest_collision.normalized()
		var dodge_direction = 1
		if randf() < 0.5:
			dodge_direction = -1
		linear_velocity += normal * MAX_THRUST * 2 * delta
		linear_velocity += normal.rotated(PI / 2 * dodge_direction) * MAX_THRUST * delta

	# Steer towards player
	var distance_to_player = global_position.distance_to($"../../Ship".global_position)
	var vector_to_player = ($"../../Ship".global_position - global_position).normalized()

	# Rotate turret
	var start = $turret.rotation
	var angle_to_target = Vector2(1, 0).rotated(start).angle_to(vector_to_player)
	var end = start + angle_to_target
	$Tween.interpolate_property($turret, "rotation", start, end, 0.1, Tween.TRANS_QUAD, Tween.EASE_OUT)
	$Tween.start()

	if distance_to_player > 40:
		# Move towards player
		linear_velocity += vector_to_player * MAX_THRUST * delta
		hovering = false
	else:
		# Move away from player
		hovering = false
		linear_velocity += -vector_to_player * MAX_THRUST * delta

	# Clamp max speed
	if linear_velocity.length() > MAX_SPEED:
		linear_velocity = linear_velocity.normalized() * MAX_SPEED


func shoot():
	$shootCooldown.wait_time = COOLDOWN * (1 + rand_range(-0.25, 0.25))
	$shootCooldown.start()

	if not alive:
		return

	if asleep:
		return

	# Start firing animation
	$AnimationPlayer.play("firing")


const Laser = preload("res://bullets/scenes/EnemyLaser.tscn")


func spawn_bullet():
	var laser = Game.instance_scene_on_main(Laser, global_position)
	laser.apply_impulse(Vector2.ZERO, Vector2(-50, 0))


const ExplosionEffect = preload("res://effects/ExplosionEffect.tscn")
const HitEffect = preload("res://effects/HitEffect.tscn")


func create_hit_effect():
	Game.instance_scene_on_main(HitEffect, global_position)


func create_explosion():
	Game.instance_scene_on_main(ExplosionEffect, global_position)


func _exit_tree():
	create_explosion()


func _on_Drone_body_entered(body):
	if body.is_in_group("pbullet"):
		health -= 1
		if health <= 0:
			queue_free()