106 lines
3.1 KiB
GDScript3
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
|