spaceship/tests/test_enemy_detection_range.gd

129 lines
4.6 KiB
GDScript3
Raw Normal View History

extends SceneTree
# Headless gameplay test: run with
# godot --headless -s res://tests/test_enemy_detection_range.gd
# Forgejo #69: enemies used to beeline toward the fleet from anywhere on the
# map the instant they spawned. Chasers (EnemyPursuitComponent) and snipers
# (EnemyStandoffComponent) now sit idle until the fleet is within their own
# detection_range; the enemy mothership deliberately keeps an (effectively)
# unlimited range instead, since it is meant to read as a persistent,
# unavoidable stalking threat rather than a local sentry.
#
# Covers:
# A. a chaser beyond detection_range does not move at all
# B. the same chaser, once the fleet is within range, closes in
# C. a sniper beyond detection_range does not move either
# D. the enemy mothership closes in even from far beyond a chaser's range
var game_state: Node
var main: Node
var fleet: Node
var chaser: Node
var sniper: Node
var mothership: Node
var chaser_start: Vector2
var sniper_start: Vector2
var mothership_start: Vector2
var stage: int = 0
var elapsed: float = 0.0
func _initialize() -> void:
game_state = root.get_node("GameState")
game_state.buildings.clear()
game_state.extractors.clear()
game_state.transporters.clear()
game_state.reset_progression()
main = load("res://Main.tscn").instantiate()
root.add_child(main)
fleet = main.get_node("Fleet")
func _process(delta: float) -> bool:
elapsed += delta
match stage:
0:
if elapsed < 0.2:
return false
main.get_node("EnemySpawner").set_process(false)
main.get_node("AsteroidField").set_process(false)
for a in get_nodes_in_group("asteroids"):
a.queue_free()
fleet.spawn_ships(1, Vector2.ZERO)
# --- A. beyond detection_range: no movement at all ---------------
chaser = load("res://Enemy.tscn").instantiate()
chaser.enemy_id = "chaser"
var pursuit: Node = null
main.add_child(chaser)
pursuit = chaser.get_component("pursuit")
chaser.position = fleet.get_centroid() + Vector2(pursuit.detection_range + 300.0, 0.0)
chaser_start = chaser.position
sniper = load("res://Enemy.tscn").instantiate()
sniper.enemy_id = "sniper"
main.add_child(sniper)
var standoff: Node = sniper.get_component("standoff")
sniper.position = fleet.get_centroid() + Vector2(0.0, standoff.detection_range + 300.0)
sniper_start = sniper.position
elapsed = 0.0
stage = 1
return false
1:
if elapsed < 1.0:
return false
var chaser_moved: float = chaser.position.distance_to(chaser_start)
var sniper_moved: float = sniper.position.distance_to(sniper_start)
print("beyond range for 1.0s: chaser moved %.1f, sniper moved %.1f" % [chaser_moved, sniper_moved])
if chaser_moved > 1.0:
return _fail("a chaser beyond detection_range moved %.1f - it should sit idle" % chaser_moved)
if sniper_moved > 1.0:
return _fail("a sniper beyond detection_range moved %.1f - it should sit idle" % sniper_moved)
# --- B. bring the chaser within range, it should now close in ----
var pursuit: Node = chaser.get_component("pursuit")
chaser.position = fleet.get_centroid() + Vector2(pursuit.detection_range * 0.5, 0.0)
chaser_start = chaser.position
elapsed = 0.0
stage = 2
return false
2:
if elapsed < 1.0:
return false
var chaser_moved: float = chaser.position.distance_to(chaser_start)
print("within range for 1.0s: chaser moved %.1f" % chaser_moved)
if chaser_moved < 20.0:
return _fail("a chaser within detection_range did not close in (moved %.1f)" % chaser_moved)
print("chaser correctly idle beyond range, closes in once inside it")
# --- D. the mothership closes in from far beyond a chaser's range -
mothership = load("res://Enemy.tscn").instantiate()
mothership.enemy_id = "enemy_mothership"
main.add_child(mothership)
var mother_pursuit: Node = mothership.get_component("pursuit")
if mother_pursuit.detection_range < 50000.0:
return _fail("the mothership's pursuit range is not effectively unlimited (%f)" \
% mother_pursuit.detection_range)
mothership.position = fleet.get_centroid() + Vector2(5000.0, 0.0)
mothership_start = mothership.position
elapsed = 0.0
stage = 3
return false
3:
if elapsed < 1.0:
return false
var mothership_moved: float = mothership.position.distance_to(mothership_start)
print("mothership 5000 units out, 1.0s: moved %.1f" % mothership_moved)
if mothership_moved < 5.0:
return _fail("the mothership did not close in from far away (moved %.1f)" % mothership_moved)
print("TEST_ENEMY_DETECTION_RANGE: PASS")
quit(0)
return true
return false
func _fail(message: String) -> bool:
print("TEST_ENEMY_DETECTION_RANGE: FAIL (%s)" % message)
quit(1)
return true