182 lines
5.8 KiB
GDScript
182 lines
5.8 KiB
GDScript
extends SceneTree
|
|
|
|
# Headless gameplay test: run with
|
|
# godot --headless -s res://tests/test_shield_vessel.gd
|
|
# Forgejo #5: the shield vessel's shield absorbs a hit that would destroy any
|
|
# other ship, and is then down until it cycles back up.
|
|
#
|
|
# The shield is PERSONAL - it protects the vessel carrying it and nothing
|
|
# else. Ships have no health in this game: contact with an enemy or an
|
|
# asteroid destroys them outright, so "absorbs a hit" means surviving the
|
|
# collision that would otherwise have killed it.
|
|
#
|
|
# Verifies:
|
|
# 1. an ordinary interceptor still dies to a rock (so the shield result
|
|
# below means something)
|
|
# 2. a shield vessel survives the same rock, and the rock is destroyed
|
|
# 3. its shield is then DOWN - a second rock while it is cycling kills it,
|
|
# or the shield would be permanent invulnerability
|
|
# 4. the shield comes back on its own after the recharge time
|
|
# 5. researched capacity lets it take more than one hit
|
|
# 6. the recharge upgrade actually shortens the wait
|
|
|
|
var game_state: Node
|
|
var scene: Node
|
|
var fleet: Node
|
|
var interceptor: Node
|
|
var shield_ship: Node
|
|
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.stored_vessels.clear()
|
|
game_state.build_time_scale = 0.02
|
|
game_state.reset_progression()
|
|
game_state.rocks = 2000
|
|
scene = load("res://Main.tscn").instantiate()
|
|
root.add_child(scene)
|
|
fleet = scene.get_node("Fleet")
|
|
|
|
|
|
func _rock_onto(ship: Node) -> void:
|
|
var rock: Area2D = load("res://Asteroid.tscn").instantiate()
|
|
rock.velocity = Vector2.ZERO
|
|
rock.global_position = ship.global_position
|
|
scene.add_child(rock)
|
|
|
|
|
|
func _process(delta: float) -> bool:
|
|
elapsed += delta
|
|
match stage:
|
|
0:
|
|
scene.get_node("AsteroidField").set_process(false)
|
|
scene.get_node("EnemySpawner").set_process(false)
|
|
for a in get_nodes_in_group("asteroids"):
|
|
if is_instance_valid(a):
|
|
a.queue_free()
|
|
fleet.spawn_ships(1, Vector2.ZERO)
|
|
interceptor = fleet.ships[0]
|
|
# Well clear of the interceptor, or one rock hits both.
|
|
fleet.add_ship(GameState.VESSEL_SHIELD)
|
|
shield_ship = fleet.ships[1]
|
|
shield_ship.position = Vector2(2000.0, 0.0)
|
|
elapsed = 0.0
|
|
stage = 1
|
|
return false
|
|
1:
|
|
if elapsed < 0.2:
|
|
return false
|
|
if not shield_ship.has_shield():
|
|
print("TEST_SHIELD_VESSEL: FAIL (a fresh shield vessel has no shield)")
|
|
quit(1)
|
|
return true
|
|
# --- 1. the control: an interceptor dies --------------------
|
|
_rock_onto(interceptor)
|
|
elapsed = 0.0
|
|
stage = 2
|
|
return false
|
|
2:
|
|
if elapsed < 0.4:
|
|
return false
|
|
if is_instance_valid(interceptor):
|
|
print("TEST_SHIELD_VESSEL: FAIL (an ordinary interceptor survived a rock - the test proves nothing)")
|
|
quit(1)
|
|
return true
|
|
print("control: interceptor destroyed by a rock")
|
|
|
|
# --- 2. the shield vessel survives it -----------------------
|
|
_rock_onto(shield_ship)
|
|
elapsed = 0.0
|
|
stage = 3
|
|
return false
|
|
3:
|
|
if elapsed < 0.4:
|
|
return false
|
|
if not is_instance_valid(shield_ship):
|
|
print("TEST_SHIELD_VESSEL: FAIL (the shield did not absorb the hit)")
|
|
quit(1)
|
|
return true
|
|
if shield_ship.has_shield():
|
|
print("TEST_SHIELD_VESSEL: FAIL (shield still up after taking a hit - it never goes down)")
|
|
quit(1)
|
|
return true
|
|
print("shield vessel survived, shield now down")
|
|
|
|
# --- 3. defenceless while it cycles -------------------------
|
|
_rock_onto(shield_ship)
|
|
elapsed = 0.0
|
|
stage = 4
|
|
return false
|
|
4:
|
|
if elapsed < 0.4:
|
|
return false
|
|
if is_instance_valid(shield_ship):
|
|
print("TEST_SHIELD_VESSEL: FAIL (survived a second hit with the shield down - it is just invulnerable)")
|
|
quit(1)
|
|
return true
|
|
print("second hit while cycling destroyed it, as it should")
|
|
|
|
# --- 4 + 5. recharge, and researched capacity ---------------
|
|
game_state.vessel_levels["shd_hits"] = 1
|
|
fleet.add_ship(GameState.VESSEL_SHIELD)
|
|
shield_ship = fleet.ships[fleet.ships.size() - 1]
|
|
shield_ship.position = Vector2(-2000.0, 0.0)
|
|
elapsed = 0.0
|
|
stage = 5
|
|
return false
|
|
5:
|
|
if elapsed < 0.2:
|
|
return false
|
|
if shield_ship.shield_charges != game_state.shield_max_charges():
|
|
print("TEST_SHIELD_VESSEL: FAIL (researched capacity %d, vessel has %d)" % [
|
|
game_state.shield_max_charges(), shield_ship.shield_charges
|
|
])
|
|
quit(1)
|
|
return true
|
|
print("with Layered Emitters researched: %d charges" % shield_ship.shield_charges)
|
|
_rock_onto(shield_ship)
|
|
elapsed = 0.0
|
|
stage = 6
|
|
return false
|
|
6:
|
|
if elapsed < 0.4:
|
|
return false
|
|
if not is_instance_valid(shield_ship) or not shield_ship.has_shield():
|
|
print("TEST_SHIELD_VESSEL: FAIL (a two-charge shield did not survive one hit with a charge left)")
|
|
quit(1)
|
|
return true
|
|
print("two-charge shield took a hit and is still up (%d left)" % shield_ship.shield_charges)
|
|
|
|
# --- 6. the recharge upgrade shortens the wait --------------
|
|
var slow: float = game_state.shield_recharge_time()
|
|
game_state.vessel_levels["shd_recharge"] = 2
|
|
var fast: float = game_state.shield_recharge_time()
|
|
print("recharge %.1fs -> %.1fs with Fast Cycling" % [slow, fast])
|
|
if fast >= slow:
|
|
print("TEST_SHIELD_VESSEL: FAIL (the recharge upgrade did not shorten the wait)")
|
|
quit(1)
|
|
return true
|
|
|
|
# --- 4. it really does come back ----------------------------
|
|
shield_ship.shield_charges = 0
|
|
shield_ship.shield_recharge_left = 0.15
|
|
elapsed = 0.0
|
|
stage = 7
|
|
return false
|
|
7:
|
|
if elapsed < 0.6:
|
|
return false
|
|
if not shield_ship.has_shield():
|
|
print("TEST_SHIELD_VESSEL: FAIL (the shield never cycled back up)")
|
|
quit(1)
|
|
return true
|
|
print("shield cycled back up on its own")
|
|
print("TEST_SHIELD_VESSEL: PASS")
|
|
quit(0)
|
|
return true
|
|
return false
|