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