54 lines
1.8 KiB
GDScript3
54 lines
1.8 KiB
GDScript3
|
|
class_name EnemyRangedWeaponComponent
|
||
|
|
extends Node
|
||
|
|
|
||
|
|
# Same shape as VesselWeaponComponent, mirrored for an enemy: fires an
|
||
|
|
# EnemyProjectile at the nearest player ship's CURRENT position, not led,
|
||
|
|
# so a moving ship can dodge it.
|
||
|
|
|
||
|
|
var capability_id: String = "ranged_weapon"
|
||
|
|
|
||
|
|
@export var fire_range: float = 700.0
|
||
|
|
@export var fire_cooldown: float = 2.2
|
||
|
|
@export var projectile_speed: float = 260.0
|
||
|
|
@export var damage: int = 1
|
||
|
|
|
||
|
|
var fire_timer: float = 0.0
|
||
|
|
var projectile_scene: PackedScene = preload("res://EnemyProjectile.tscn")
|
||
|
|
|
||
|
|
|
||
|
|
func tick(delta: float) -> void:
|
||
|
|
fire_timer -= delta
|
||
|
|
if fire_timer > 0.0:
|
||
|
|
return
|
||
|
|
var enemy: Node2D = get_parent()
|
||
|
|
var target: Node2D = _nearest_ship_in_range(enemy)
|
||
|
|
if target == null:
|
||
|
|
fire_timer = 0.25
|
||
|
|
return
|
||
|
|
var projectile: Area2D = projectile_scene.instantiate()
|
||
|
|
# global_position: the projectile is reparented to root, a different
|
||
|
|
# node than the enemy's own (possibly nested) parent, so local
|
||
|
|
# position would be wrong the moment an enemy isn't a direct root
|
||
|
|
# child - exactly the case #44 introduced (planet-surface hosting).
|
||
|
|
projectile.position = enemy.global_position
|
||
|
|
projectile.damage = damage
|
||
|
|
projectile.speed = projectile_speed
|
||
|
|
enemy.get_tree().root.add_child(projectile)
|
||
|
|
projectile.launch(target.global_position - enemy.global_position)
|
||
|
|
fire_timer = fire_cooldown
|
||
|
|
|
||
|
|
|
||
|
|
func _nearest_ship_in_range(enemy: Node2D) -> Node2D:
|
||
|
|
var fleet: Node2D = get_tree().get_first_node_in_group("player_fleet")
|
||
|
|
if fleet == null:
|
||
|
|
return null
|
||
|
|
var nearest: Node2D = null
|
||
|
|
var best_distance: float = fire_range
|
||
|
|
for ship in fleet.ships:
|
||
|
|
if not is_instance_valid(ship):
|
||
|
|
continue
|
||
|
|
var distance: float = enemy.global_position.distance_to(ship.global_position)
|
||
|
|
if distance <= best_distance:
|
||
|
|
best_distance = distance
|
||
|
|
nearest = ship
|
||
|
|
return nearest
|