EnemyStandoffComponent holds a preferred distance from the nearest player ship instead of ramming (advance beyond it, retreat inside retreat_range_factor of it, drift laterally in the comfortable band between) - never paired with a pursuit component. EnemyRangedWeaponComponent mirrors VesselWeaponComponent for an enemy: fires an EnemyProjectile aimed at the target's CURRENT position rather than led, so a moving ship can dodge it (projectile_speed 260 vs the interceptor's 460 max_speed). Registered in EnemyDefinitions so it's placeable from a planet setup by enemy_id. test_sniper_enemy.gd went through a few iterations to get its own timing right: physics ticks can run ahead of a SceneTree test's own _process() clock under this device's load, so the cooldown-violation check reads the component's own fire_timer directly (a rising value means it refired) instead of comparing projectile counts against a wall-clock wait, and manually repositioned ships need their move_target re-pinned or Ship's own steering silently drives them back to the stale target. Part of the #40 conquest-mechanic breakdown.
20 lines
537 B
GDScript
20 lines
537 B
GDScript
class_name EnemyDefinitions
|
|
extends RefCounted
|
|
|
|
const DEFAULT_ID: String = "chaser"
|
|
const ORDER: PackedStringArray = ["chaser", "sniper"]
|
|
const DEFINITIONS: Dictionary = {
|
|
"chaser": preload("res://ChaserEnemyDefinition.tres"),
|
|
"sniper": preload("res://SniperEnemyDefinition.tres"),
|
|
}
|
|
|
|
|
|
static func get_definition(enemy_id: String) -> Resource:
|
|
return DEFINITIONS.get(enemy_id, DEFINITIONS[DEFAULT_ID])
|
|
|
|
|
|
static func all() -> Array:
|
|
var result: Array = []
|
|
for enemy_id in ORDER:
|
|
result.append(DEFINITIONS[enemy_id])
|
|
return result
|