Blobby/src/Actors/Enemies/Machines/Turret.gd

106 lines
3.1 KiB
GDScript3

extends KinematicBody2D
# Declare member variables here. Examples:
# var a: int = 2
# var b: String = "text"
onready var sightline: RayCast2D = $Sightline
onready var turret_state_machine = $TurretStateMachine
onready var lock_on_timer = $LockOnTimer
onready var sight_lost_timer = $SightLostTimer
onready var turret_animation = $AnimationPlayer.get_animation("Turret Rotation")
onready var Bullet = preload("res://src/HarmfulObjects/Bullet.tscn")
# Derives the freedom from the number of bald head eagles
onready var angle_of_freedom = deg2rad(
turret_animation.track_get_key_value(
0, turret_animation.track_get_key_count(0) - 1
)
)
onready var original_rotation = rotation
onready var rotation_speed_divider = 80
# TODO causes oscilation
onready var min_rotation_speed = deg2rad(0.3)
# TODO Bug when dying in the wrong state, missing prey instance
var prey_ref = weakref(null)
# Ray that goes from the turret to the target
var target_ray
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
$AnimationPlayer.play("Turret Rotation")
func prey():
return prey_ref.get_ref()
func searching():
$AnimationPlayer.play("Turret Rotation")
if sightline.is_colliding():
# The collider returns not the area or body it hit, but the parent of them
var collider = sightline.get_collider()
if collider.is_in_group("player"):
print_debug(is_tracking_prey())
prey_ref = weakref(collider)
print_debug(is_tracking_prey())
# TODO should this stand still?
func start_locking():
target_ray = RayCast2D.new()
add_child(target_ray)
target_ray.enabled = true
target_ray.exclude_parent = true
if(prey() != null):
target_ray.set_cast_to(to_local(prey().position))
$AnimationPlayer.stop(false)
lock_on_timer.start()
func is_locked_on_target():
return lock_on_timer.is_stopped()
func is_tracking_prey():
return true if(prey() != null) else false
# TODO simplify/split this method
func shooting():
var target_angle = target_ray.cast_to.angle_to(sightline.cast_to)
var rotation_speed = max(
min_rotation_speed, abs(target_angle / rotation_speed_divider)
)
if abs(target_angle) < min_rotation_speed:
rotation = rotation - target_angle
else:
rotation = rotation - rotation_speed * sign(target_angle)
rotation = clamp(
rotation, original_rotation, original_rotation + angle_of_freedom
)
if sightline.is_colliding():
# The collider returns not the area or body it hit, but the parent of them
# TODO Sight could be a cone instead of a ray
var collider = sightline.get_collider()
if collider.is_in_group("player"):
sight_lost_timer.stop()
target_ray.cast_to = to_local(prey().position)
else:
if (
sight_lost_timer.get_time_left() < 0.1
&& sight_lost_timer.get_time_left() > 0
):
prey_ref = weakref(null)
target_ray.queue_free()
return
if sight_lost_timer.is_stopped():
sight_lost_timer.start()
elif(prey() != null):
target_ray.cast_to = to_local(prey().position)
spawn_projectile()
func spawn_projectile():
var b = Bullet.instance()
owner.add_child(b)
b.set_collision_mask_bit(1, false)
b.transform = $Muzzle.global_transform