Resolve pending gameplay tickets
This commit is contained in:
parent
ec20778215
commit
c2ebbfaa2d
28 changed files with 618 additions and 188 deletions
137
tests/test_energy_propulser_dash.gd
Normal file
137
tests/test_energy_propulser_dash.gd
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
extends SceneTree
|
||||
|
||||
# Forgejo #179: an Energy Propulser in the fleet grants a hold-aim-release
|
||||
# dash. Covers visibility, aimed movement, energy cost, formation integrity,
|
||||
# and one cooldown per Propulser.
|
||||
|
||||
const DASH_COST: int = 15
|
||||
const DASH_DISTANCE: float = 520.0
|
||||
|
||||
var state: Node
|
||||
var main: Node
|
||||
var fleet: Node
|
||||
var dash: Node
|
||||
var stage: int = 0
|
||||
var elapsed: float = 0.0
|
||||
var first_origin: Vector2
|
||||
var second_origin: Vector2
|
||||
var offsets_before: Array = []
|
||||
var first_component: Node
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
state = root.get_node("GameState")
|
||||
state.reset_new_game()
|
||||
state.intro_active = false
|
||||
state.reset_quests()
|
||||
state.vessel_levels["unlock_distorder"] = 1
|
||||
state.fleet_inventory.total_capacity = -1
|
||||
state.deposit_fleet_resource(GameState.RESOURCE_ENERGY, DASH_COST * 3)
|
||||
main = load("res://world/Main.tscn").instantiate()
|
||||
root.add_child(main)
|
||||
current_scene = main
|
||||
fleet = main.get_node("Fleet")
|
||||
dash = main.get_node("DashController")
|
||||
|
||||
|
||||
func _process(delta: float) -> bool:
|
||||
elapsed += delta
|
||||
match stage:
|
||||
0:
|
||||
if elapsed < 0.3:
|
||||
return false
|
||||
main.get_node("EnemySpawner").set_process(false)
|
||||
main.get_node("AsteroidField").set_process(false)
|
||||
if main.get_node("UI/DashButton").visible:
|
||||
return _fail("dash button appeared without an Energy Propulser")
|
||||
# The carrier keeps enough hold capacity for both dashes. Two
|
||||
# Propulsers prove that cooldown belongs to a vessel, not the fleet.
|
||||
fleet.spawn_ships(3, Vector2.ZERO, PackedStringArray([
|
||||
GameState.VESSEL_CARRIER, GameState.VESSEL_DISTORDER,
|
||||
GameState.VESSEL_DISTORDER,
|
||||
]))
|
||||
dash._process(0.0)
|
||||
if not main.get_node("UI/DashButton").visible:
|
||||
return _fail("an Energy Propulser did not reveal the dash button")
|
||||
first_component = dash._next_ready_ship().get_component("distorder")
|
||||
first_origin = fleet.get_centroid()
|
||||
for ship in fleet.ships:
|
||||
offsets_before.append(ship.position - first_origin)
|
||||
_aim_and_release(Vector2.RIGHT, 11)
|
||||
if not fleet.is_dashing():
|
||||
return _fail("releasing a rightward aim did not begin a dash")
|
||||
if state.fleet_resource(GameState.RESOURCE_ENERGY) != DASH_COST * 2:
|
||||
return _fail("first dash did not consume %d energy" % DASH_COST)
|
||||
if first_component.is_ready():
|
||||
return _fail("the Propulser that dashed did not enter cooldown")
|
||||
dash._process(0.0)
|
||||
if not main.get_node("UI/DashButton").enabled:
|
||||
return _fail("one cooling Propulser disabled a second ready one")
|
||||
stage = 1
|
||||
elapsed = 0.0
|
||||
return false
|
||||
1:
|
||||
if elapsed < 0.7:
|
||||
return false
|
||||
var moved: Vector2 = fleet.get_centroid() - first_origin
|
||||
if absf(moved.x - DASH_DISTANCE) > 8.0 or absf(moved.y) > 8.0:
|
||||
return _fail("rightward aim moved the fleet by %s" % moved)
|
||||
for i in range(fleet.ships.size()):
|
||||
var offset: Vector2 = fleet.ships[i].position - fleet.get_centroid()
|
||||
if offset.distance_to(offsets_before[i]) > 1.0:
|
||||
return _fail("dash distorted formation slot %d by %.2f" \
|
||||
% [i, offset.distance_to(offsets_before[i])])
|
||||
second_origin = fleet.get_centroid()
|
||||
_aim_and_release(Vector2.UP, 12)
|
||||
if state.fleet_resource(GameState.RESOURCE_ENERGY) != DASH_COST:
|
||||
return _fail("second Propulser did not pay for its own dash")
|
||||
dash._process(0.0)
|
||||
if main.get_node("UI/DashButton").enabled:
|
||||
return _fail("dash remained enabled after both Propulsers fired")
|
||||
stage = 2
|
||||
elapsed = 0.0
|
||||
return false
|
||||
2:
|
||||
if elapsed < 0.7:
|
||||
return false
|
||||
var moved: Vector2 = fleet.get_centroid() - second_origin
|
||||
if absf(moved.y + DASH_DISTANCE) > 8.0 or absf(moved.x) > 8.0:
|
||||
return _fail("upward aim moved the fleet by %s" % moved)
|
||||
first_component.tick(first_component.DASH_COOLDOWN)
|
||||
dash._process(0.0)
|
||||
if not main.get_node("UI/DashButton").enabled:
|
||||
return _fail("button did not re-enable when one Propulser recharged")
|
||||
var surface: Node = load("res://surface/PlanetSurface.tscn").instantiate()
|
||||
if not surface.has_node("DashController") or not surface.has_node("UI/DashButton"):
|
||||
return _fail("planet surface does not carry the dash ability")
|
||||
surface.free()
|
||||
print("two aimed dashes moved %.0f units, preserved formation, and cooled down per Propulser" \
|
||||
% DASH_DISTANCE)
|
||||
print("TEST_ENERGY_PROPULSER_DASH: PASS")
|
||||
quit(0)
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
func _aim_and_release(direction: Vector2, touch_index: int) -> void:
|
||||
var button: Control = main.get_node("UI/DashButton")
|
||||
var press := InputEventScreenTouch.new()
|
||||
press.index = touch_index
|
||||
press.pressed = true
|
||||
press.position = button.global_position + button.size * 0.5
|
||||
main._handle_touch(press)
|
||||
var drag := InputEventScreenDrag.new()
|
||||
drag.index = touch_index
|
||||
drag.position = press.position + direction * 240.0
|
||||
main._handle_drag(drag)
|
||||
var release := InputEventScreenTouch.new()
|
||||
release.index = touch_index
|
||||
release.pressed = false
|
||||
release.position = drag.position
|
||||
main._handle_touch(release)
|
||||
|
||||
|
||||
func _fail(message: String) -> bool:
|
||||
print("TEST_ENERGY_PROPULSER_DASH: FAIL (%s)" % message)
|
||||
quit(1)
|
||||
return true
|
||||
Loading…
Reference in a new issue