fuzzyworld

godot-shooter / files / actors / Enemy.gd

Enemy.gd

Blame: the commit that last changed each line · file · history

b856550a 2023-10-30 Pavel Safronov1extends KinematicBody2D
f398dcb9 2023-11-02 Pavel Safronov2class_name Enemy
b856550a 2023-10-30 Pavel Safronov3
cf2013fa 2023-11-02 Pavel Safronov4onready var damage_points = $DamagePoints
023ec2fb 2023-11-29 Pavel Safronov5onready var navigation_agent: NavigationAgent2D = $NavigationAgent2D
16938031 2023-11-17 Pavel Safronov6const Utils = preload("res://utils/Utils.gd")
7const Explosion = preload("res://effects/Explosion.tscn")
8const Smoke = preload("res://effects/Smoke.tscn")
2b4497bb 2023-11-27 Pavel Safronov9const Damage = preload("res://effects/Damage.tscn")
ee6296b3 2023-11-17 Pavel Safronov10const Constants = preload("res://utils/Constants.gd")
0f8974b8 2023-12-01 Pavel Safronov11const Weapons = preload("res://weapons/Weapons.gd")
b856550a 2023-10-30 Pavel Safronov12
ee6296b3 2023-11-17 Pavel Safronov13export var move_speed = Constants.SPEED * 1.05
4c85b9c3 2023-11-29 Pavel Safronov14export var turn_rate = 0.03
e9f8f8f2 2023-11-01 Pavel Safronov15export var health = -1
3fcb817e 2023-11-10 Pavel Safronov16export var max_health = 100
1d4ba5a6 2023-11-02 Pavel Safronov17export var is_targeted = false
52220002 2023-11-06 Pavel Safronov18export var is_invincible = false
4c85b9c3 2023-11-29 Pavel Safronov19export var target: Vector2
20export var follow_target = false
11ed9f7a 2023-11-08 Pavel Safronov21signal enemy_killed(position)
b856550a 2023-10-30 Pavel Safronov22
0f8974b8 2023-12-01 Pavel Safronov23var weapon: Weapon
b856550a 2023-10-30 Pavel Safronov24var velocity = Vector2.ZERO
25var dead = false
8adb41dc 2023-11-19 Pavel Safronov26var health_ratio
27var health_percentage
b856550a 2023-10-30 Pavel Safronov28
e9f8f8f2 2023-11-01 Pavel Safronov29func _ready() -> void:
0f8974b8 2023-12-01 Pavel Safronov30 weapon = Weapons.create_basic_enemy_gun()
6ad40cea 2023-12-01 Pavel Safronov31 navigation_agent.max_speed = move_speed
023ec2fb 2023-11-29 Pavel Safronov32 var _err = navigation_agent.connect("path_changed", self, "path_changed")
33 _err = navigation_agent.connect("velocity_computed", self, "velocity_computed")
34 _err = navigation_agent.connect("target_reached", self, "target_reached")
35
539576dd 2023-11-07 Pavel Safronov36 $AnimationPlayer.play("fade_in")
cf2013fa 2023-11-02 Pavel Safronov37 if health < 0 or health > max_health:
e9f8f8f2 2023-11-01 Pavel Safronov38 health = max_health
cf2013fa 2023-11-02 Pavel Safronov39 else:
40 var hurt_points = max_health - health
41 health = max_health
42 for i in hurt_points:
43 hurt()
e9f8f8f2 2023-11-01 Pavel Safronov44
023ec2fb 2023-11-29 Pavel Safronov45func path_changed() -> void:
638706e1 2023-11-30 Pavel Safronov46 pass
023ec2fb 2023-11-29 Pavel Safronov47
48func velocity_computed(new_vel: Vector2) -> void:
1702bad9 2023-11-30 Pavel Safronov49 velocity = move_and_slide(new_vel)
6ad40cea 2023-12-01 Pavel Safronov50 global_rotation = velocity.angle() + PI/2.0
638706e1 2023-11-30 Pavel Safronov51 pass
023ec2fb 2023-11-29 Pavel Safronov52
53func target_reached() -> void:
6ad40cea 2023-12-01 Pavel Safronov54 var players = get_tree().get_nodes_in_group("player")
55 var player = players[0]
56 player.hurt(25)
57 var explosion = Explosion.instance()
58 explosion.transform = transform
59 get_parent().add_child(explosion)
60 kill()
638706e1 2023-11-30 Pavel Safronov61 pass
023ec2fb 2023-11-29 Pavel Safronov62
236d1677 2023-11-01 Pavel Safronov63func _process(_delta: float) -> void:
8adb41dc 2023-11-19 Pavel Safronov64 var pb: ProgressBar = $Graphics/Alive/Container/ProgressBar
65 health_ratio = float(health) / float(max_health)
66 health_percentage = health_ratio * 100
67 pb.value = health_percentage
68 if health_percentage < 20:
69 pb.modulate = Color.red
70 elif health_percentage < 60:
71 pb.modulate = Color.yellow
72 else:
73 pb.modulate = Color.blue
614e7fb1 2023-10-31 Pavel Safronov74 $Graphics/Alive/Container.global_rotation = 0
8adb41dc 2023-11-19 Pavel Safronov75 $Graphics/Alive/Sprite/Target.visible = is_targeted
76 $Graphics/Alive/Sprite/Target.global_rotation = 0
77 $Graphics/Alive/Sprite/Trails.add_position(global_position)
0f8974b8 2023-12-01 Pavel Safronov78
79 var players = get_tree().get_nodes_in_group("player")
80 var player = players[0]
81 var dist_to_player = global_position.distance_to(player.global_position)
82
83 var should_shoot = dist_to_player < weapon.shooting_range
84 if should_shoot:
85 var space_state = get_world_2d().direct_space_state
86 var intersections = space_state.intersect_ray(global_position, player.global_position, [self])
87 var hits_player = intersections and intersections.collider == player
88 if hits_player:
89 weapon.try_shoot(self, player.global_position)
614e7fb1 2023-10-31 Pavel Safronov90
6ad40cea 2023-12-01 Pavel Safronov91func _physics_process(delta: float) -> void:
b856550a 2023-10-30 Pavel Safronov92 if dead:
93 return
023ec2fb 2023-11-29 Pavel Safronov94
95 # navigate to the next position
96 var current_pos = global_position
97 var next_pos = navigation_agent.get_next_location()
1702bad9 2023-11-30 Pavel Safronov98 var diff: Vector2 = next_pos - current_pos
99 var dir = diff.normalized()
6ad40cea 2023-12-01 Pavel Safronov100 var desired_vel = dir * navigation_agent.max_speed
101 var steering = (desired_vel - velocity) * delta * 4
102 var new_vel = velocity + steering
103 velocity = new_vel
104
1702bad9 2023-11-30 Pavel Safronov105 if navigation_agent.avoidance_enabled:
6ad40cea 2023-12-01 Pavel Safronov106 navigation_agent.set_velocity(velocity)
1702bad9 2023-11-30 Pavel Safronov107 else:
6ad40cea 2023-12-01 Pavel Safronov108 velocity_computed(velocity)
b856550a 2023-10-30 Pavel Safronov109
023ec2fb 2023-11-29 Pavel Safronov110func set_target(pos: Vector2):
111# var to_dir = (pos - global_position).normalized()
112# var curr_dir = velocity.normalized()
113# var dir_diff = to_dir - curr_dir
114# var change = dir_diff * turn_rate * move_speed
115# velocity = (velocity + change).normalized() * move_speed
1702bad9 2023-11-30 Pavel Safronov116# var nav_map = navigation_agent.get_navigation_map()
638706e1 2023-11-30 Pavel Safronov117# Utils.log("setting target location", pos, "map", nav_map)
023ec2fb 2023-11-29 Pavel Safronov118 navigation_agent.set_target_location(pos)
e496c548 2023-11-06 Pavel Safronov119
13440f93 2023-11-27 Pavel Safronov120func _ensure_smoke_exists() -> void:
121 var max_smoke_count = $DamagePoints.get_child_count()
122 var existing_smoke_count = $DamageObjects.get_child_count()
123 var expected_smoke_count = ceil(health_ratio * max_smoke_count)
124 var smoke_to_add_count = expected_smoke_count - existing_smoke_count
125 for i in smoke_to_add_count:
126 var smoke = Smoke.instance()
127 var smoke_pos = get_damage_point_on_body()
128 smoke.position = smoke_pos
129 $DamageObjects.add_child(smoke)
130
bd0825dd 2023-11-09 Pavel Safronov131func hurt(damage: int = 1):
52220002 2023-11-06 Pavel Safronov132 if dead || is_invincible:
b856550a 2023-10-30 Pavel Safronov133 return
bd0825dd 2023-11-09 Pavel Safronov134 health -= damage
2b4497bb 2023-11-27 Pavel Safronov135 add_damage_label(damage)
8adb41dc 2023-11-19 Pavel Safronov136# add_child(smoke)
13440f93 2023-11-27 Pavel Safronov137 _ensure_smoke_exists()
b856550a 2023-10-30 Pavel Safronov138 if health <= 0:
139 kill()
140
141func kill():
52220002 2023-11-06 Pavel Safronov142 if dead || is_invincible:
b856550a 2023-10-30 Pavel Safronov143 return
144 dead = true
145 $Graphics/Alive.hide()
969fd5af 2023-11-06 Pavel Safronov146 $CollisionPolygon2D.set_deferred("disabled", true)
c6faad15 2023-10-31 Pavel Safronov147 var explosion = Explosion.instance()
148 explosion.connect("explosion_done", self, "_on_death_explosion_finished")
149 $Graphics.add_child(explosion)
b856550a 2023-10-30 Pavel Safronov150 z_index = -1
11ed9f7a 2023-11-08 Pavel Safronov151 emit_signal("enemy_killed", global_position)
c6faad15 2023-10-31 Pavel Safronov152
2b4497bb 2023-11-27 Pavel Safronov153func add_damage_label(damage_amount: int = 5) -> void:
154 var damage_label: Damage = Damage.instance()
155 damage_label.value = -damage_amount
156 damage_label.position = self.position
157 get_tree().root.add_child(damage_label)
158
fc5de8ee 2023-11-09 Pavel Safronov159func teleport(dest: Vector2) -> void:
656778ea 2023-11-28 Pavel Safronov160 $Graphics/Alive/Sprite/Trails.clear()
fc5de8ee 2023-11-09 Pavel Safronov161 position = dest
162
c6faad15 2023-10-31 Pavel Safronov163func _on_death_explosion_finished():
cf2013fa 2023-11-02 Pavel Safronov164 $AnimationPlayer.play("fade_out")
165
166func get_damage_point_on_body() -> Vector2:
167 var child_count = damage_points.get_child_count()
168 var random_index = randi() % child_count
169 var random_child: Position2D = damage_points.get_child(random_index)
170 return random_child.position
969fd5af 2023-11-06 Pavel Safronov171
172func remove_thyself():
173 queue_free()
115aa5d1 2023-11-07 Pavel Safronov174
175func _on_Area2D_body_entered(body: Node) -> void:
176 var players = get_tree().get_nodes_in_group("player")
f6120dba 2023-11-08 Pavel Safronov177 var player = players[0]
115aa5d1 2023-11-07 Pavel Safronov178 var is_player = body == player
179 if is_player:
180 player.hurt(2)
181 var explosion = Explosion.instance()
182 explosion.transform = transform
183 get_parent().add_child(explosion)
184 kill()