70 lines
2.1 KiB
GDScript3
70 lines
2.1 KiB
GDScript3
|
extends "res://scripts/Machine.gd"
|
||
|
|
||
|
@export var bullet_scene: PackedScene
|
||
|
@export var bullet_item: Item
|
||
|
@export var fire_period: float = 0.5
|
||
|
@export var detection_poll_time: float = 0.5
|
||
|
|
||
|
var detection_cooldown = 0.0
|
||
|
var fire_cooldown: float = 0.0
|
||
|
var current_target: Enemy = null
|
||
|
|
||
|
func _ready() -> void:
|
||
|
super()
|
||
|
detection_cooldown = randf() * detection_poll_time
|
||
|
|
||
|
func _process(delta: float) -> void:
|
||
|
# clear target if it's dead or gone
|
||
|
if current_target != null:
|
||
|
check_target_status()
|
||
|
|
||
|
# find a target if we don't have one
|
||
|
if current_target == null:
|
||
|
detection_cooldown -= delta
|
||
|
if detection_cooldown <= 0:
|
||
|
detection_cooldown += detection_poll_time
|
||
|
search_for_enemy()
|
||
|
|
||
|
# fire at the target if we have one
|
||
|
if current_target != null:
|
||
|
if fire_cooldown <= 0:
|
||
|
if fetch_item_from_storage(bullet_item, 1):
|
||
|
fire_at_target()
|
||
|
|
||
|
if fire_cooldown > 0:
|
||
|
fire_cooldown -= delta
|
||
|
|
||
|
func check_target_status() -> void:
|
||
|
if current_target.is_queued_for_deletion():
|
||
|
current_target = null
|
||
|
|
||
|
func search_for_enemy() -> void:
|
||
|
var enemies: Array[Node] = get_tree().get_nodes_in_group("Enemy")
|
||
|
var closest: float = 9999999999
|
||
|
for enemy in enemies:
|
||
|
if enemy is Enemy:
|
||
|
if !enemy.sighted:
|
||
|
continue
|
||
|
var distance_sqr = global_position.distance_squared_to(enemy.global_position)
|
||
|
if distance_sqr <= closest:
|
||
|
var params: PhysicsRayQueryParameters2D = PhysicsRayQueryParameters2D.new()
|
||
|
params.collision_mask = 0b11
|
||
|
params.from = global_position
|
||
|
params.to = enemy.global_position
|
||
|
var result: Dictionary = get_world_2d().direct_space_state.intersect_ray(params)
|
||
|
if result.has("collider"):
|
||
|
if !result["collider"] is PhysicsBody2D:
|
||
|
continue
|
||
|
var body: PhysicsBody2D = result["collider"]
|
||
|
if body is Enemy:
|
||
|
current_target = body
|
||
|
closest = body.global_position.distance_squared_to(global_position)
|
||
|
|
||
|
func fire_at_target() -> void:
|
||
|
fire_cooldown += fire_period
|
||
|
var bullet: RigidBody2D = bullet_scene.instantiate()
|
||
|
add_child(bullet)
|
||
|
var angle: float = global_position.angle_to_point(current_target.global_position)
|
||
|
bullet.rotation = angle
|
||
|
bullet.apply_impulse(Vector2(1000,0).rotated(angle))
|