133 lines
5.5 KiB
GDScript3
133 lines
5.5 KiB
GDScript3
|
|
extends SceneTree
|
||
|
|
|
||
|
|
# Forgejo #205: the Energy Propulser had no upgrades at all - it was the one
|
||
|
|
# fleet hull whose ship lab offered nothing. It now carries three, and this
|
||
|
|
# checks each of them reaches the thing it is supposed to change rather than
|
||
|
|
# only reading well in the menu.
|
||
|
|
#
|
||
|
|
# Covers:
|
||
|
|
# A. Warp Coils lengthen the dash, and the controller aims that far
|
||
|
|
# B. Surge Capacitor shortens the recharge, floored by minimum_stats
|
||
|
|
# C. Flux Regulator makes boosted cruise cheaper to sustain
|
||
|
|
# D. an unupgraded Propulser is exactly what it was before
|
||
|
|
|
||
|
|
const BASE_DASH_DISTANCE: float = 520.0
|
||
|
|
const BASE_DASH_COOLDOWN: float = 5.0
|
||
|
|
const BASE_BOOST_DRAIN: float = 2.0
|
||
|
|
const COOLDOWN_FLOOR: float = 2.0
|
||
|
|
# Where three Surge Capacitors actually land. Above the floor, deliberately:
|
||
|
|
# the floor is a guard on the definition, not a target the branch reaches.
|
||
|
|
const UPGRADED_COOLDOWN: float = 2.3
|
||
|
|
|
||
|
|
var state: Node
|
||
|
|
var main: Node
|
||
|
|
var fleet: Node
|
||
|
|
var dash: Node
|
||
|
|
var stage: int = 0
|
||
|
|
var elapsed: float = 0.0
|
||
|
|
|
||
|
|
|
||
|
|
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
|
||
|
|
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 _stat(name: String) -> float:
|
||
|
|
return state.vessel_stat(GameState.VESSEL_DISTORDER, name)
|
||
|
|
|
||
|
|
|
||
|
|
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)
|
||
|
|
|
||
|
|
# --- D. nothing researched, nothing changed -------------------
|
||
|
|
if not is_equal_approx(_stat("dash_distance"), BASE_DASH_DISTANCE) \
|
||
|
|
or not is_equal_approx(_stat("dash_cooldown"), BASE_DASH_COOLDOWN) \
|
||
|
|
or not is_equal_approx(_stat("boost_drain"), BASE_BOOST_DRAIN):
|
||
|
|
return _fail("an unresearched Propulser does not match its own definition")
|
||
|
|
print("unupgraded Propulser: %.0f dash, %.1fs recharge, %.1f energy/s" \
|
||
|
|
% [_stat("dash_distance"), _stat("dash_cooldown"), _stat("boost_drain")])
|
||
|
|
|
||
|
|
# --- A. Warp Coils --------------------------------------------
|
||
|
|
state.vessel_levels["dst_dash_range"] = 3
|
||
|
|
if not is_equal_approx(_stat("dash_distance"), BASE_DASH_DISTANCE + 420.0):
|
||
|
|
return _fail("three Warp Coils gave %.0f dash distance, expected %.0f" \
|
||
|
|
% [_stat("dash_distance"), BASE_DASH_DISTANCE + 420.0])
|
||
|
|
# The controller must aim as far as the fleet can actually surge,
|
||
|
|
# or the guide promises reach the dash does not have.
|
||
|
|
if not is_equal_approx(dash._aim_max_range(), _stat("dash_distance")):
|
||
|
|
return _fail("the dash guide reaches %.0f while the dash carries %.0f" \
|
||
|
|
% [dash._aim_max_range(), _stat("dash_distance")])
|
||
|
|
print("Warp Coils: dash and its guide both reach %.0f" % _stat("dash_distance"))
|
||
|
|
|
||
|
|
# --- C. Flux Regulator ----------------------------------------
|
||
|
|
state.vessel_levels["dst_drain"] = 3
|
||
|
|
var expected_drain: float = BASE_BOOST_DRAIN * pow(0.75, 3)
|
||
|
|
if not is_equal_approx(_stat("boost_drain"), expected_drain):
|
||
|
|
return _fail("three Flux Regulators drain %.3f/s, expected %.3f" \
|
||
|
|
% [_stat("boost_drain"), expected_drain])
|
||
|
|
print("Flux Regulator: sustained boost costs %.2f energy/s" % _stat("boost_drain"))
|
||
|
|
|
||
|
|
# --- B. Surge Capacitor, and its floor ------------------------
|
||
|
|
state.vessel_levels["dst_dash_cooldown"] = 2
|
||
|
|
if not is_equal_approx(_stat("dash_cooldown"), BASE_DASH_COOLDOWN - 1.8):
|
||
|
|
return _fail("two Surge Capacitors left a %.2fs recharge, expected %.2f" \
|
||
|
|
% [_stat("dash_cooldown"), BASE_DASH_COOLDOWN - 1.8])
|
||
|
|
state.vessel_levels["dst_dash_cooldown"] = 3
|
||
|
|
if not is_equal_approx(_stat("dash_cooldown"), UPGRADED_COOLDOWN):
|
||
|
|
return _fail("three Surge Capacitors left a %.2fs recharge, expected %.2f" \
|
||
|
|
% [_stat("dash_cooldown"), UPGRADED_COOLDOWN])
|
||
|
|
# Past the branch's own maximum, to prove minimum_stats actually
|
||
|
|
# holds. Nothing in the game can buy this level; raising max_level
|
||
|
|
# later would walk straight into the floor, and this says where it
|
||
|
|
# is rather than leaving it to be discovered.
|
||
|
|
state.vessel_levels["dst_dash_cooldown"] = 6
|
||
|
|
if not is_equal_approx(_stat("dash_cooldown"), COOLDOWN_FLOOR):
|
||
|
|
return _fail("the recharge passed its %.1fs floor, reaching %.2f" \
|
||
|
|
% [COOLDOWN_FLOOR, _stat("dash_cooldown")])
|
||
|
|
state.vessel_levels["dst_dash_cooldown"] = 3
|
||
|
|
print("Surge Capacitor: %.1fs recharge at full research, floored at %.1f" \
|
||
|
|
% [UPGRADED_COOLDOWN, COOLDOWN_FLOOR])
|
||
|
|
|
||
|
|
# A hull built AFTER the research carries the researched recharge:
|
||
|
|
# apply_stats() is what puts a definition on a component, and a
|
||
|
|
# stat that never reaches the component upgrades nothing.
|
||
|
|
fleet.spawn_ships(1, Vector2.ZERO,
|
||
|
|
PackedStringArray([GameState.VESSEL_DISTORDER]))
|
||
|
|
elapsed = 0.0
|
||
|
|
stage = 1
|
||
|
|
return false
|
||
|
|
1:
|
||
|
|
if elapsed < 0.3:
|
||
|
|
return false
|
||
|
|
var component: Node = fleet.ships[0].get_component("distorder")
|
||
|
|
if component == null:
|
||
|
|
return _fail("the spawned Propulser has no distorder component")
|
||
|
|
if not is_equal_approx(component.cooldown_duration, UPGRADED_COOLDOWN):
|
||
|
|
return _fail("the hull recharges in %.2fs while its definition says %.2f" \
|
||
|
|
% [component.cooldown_duration, UPGRADED_COOLDOWN])
|
||
|
|
print("the researched recharge reaches the hull itself")
|
||
|
|
print("TEST_PROPULSER_UPGRADES: PASS")
|
||
|
|
quit(0)
|
||
|
|
return true
|
||
|
|
return false
|
||
|
|
|
||
|
|
|
||
|
|
func _fail(message: String) -> bool:
|
||
|
|
print("TEST_PROPULSER_UPGRADES: FAIL (%s)" % message)
|
||
|
|
quit(1)
|
||
|
|
return true
|