132 lines
5 KiB
GDScript3
132 lines
5 KiB
GDScript3
|
|
extends SceneTree
|
||
|
|
|
||
|
|
# A player who is short of research data is told where it comes from.
|
||
|
|
#
|
||
|
|
# It is the one currency with a non-obvious source: ore and gas are visibly
|
||
|
|
# mined, but data comes off conquered worlds and nothing said so at the point
|
||
|
|
# it mattered. The skill tree refused the node in SILENCE, and the ship lab
|
||
|
|
# refused with "Research is already queued or complete" - which is not why it
|
||
|
|
# refused, and sends the player looking at the wrong thing.
|
||
|
|
#
|
||
|
|
# Covers:
|
||
|
|
# A. a doctrine that costs data the player has not got opens the explainer,
|
||
|
|
# naming what was wanted and what they hold
|
||
|
|
# B. the same from the ship lab, instead of blaming the queue
|
||
|
|
# C. with the data in hand, the research goes through and no popup appears
|
||
|
|
|
||
|
|
var game_state: Node
|
||
|
|
var scene: Node
|
||
|
|
var controller: Node
|
||
|
|
var popup: Control
|
||
|
|
var elapsed: float = 0.0
|
||
|
|
var stage: int = 0
|
||
|
|
|
||
|
|
|
||
|
|
func _initialize() -> void:
|
||
|
|
game_state = root.get_node("GameState")
|
||
|
|
game_state.buildings.clear()
|
||
|
|
game_state.extractors.clear()
|
||
|
|
game_state.reset_progression()
|
||
|
|
game_state.reset_new_game()
|
||
|
|
game_state.intro_active = false
|
||
|
|
game_state.reset_quests()
|
||
|
|
game_state.rocks = 5000
|
||
|
|
game_state.bank_inventory.set_amount(GameState.RESOURCE_GAS, 5000)
|
||
|
|
game_state.bank_inventory.set_amount(GameState.RESOURCE_ENERGY, 5000)
|
||
|
|
game_state.research_points = 0
|
||
|
|
game_state.unlocked = ["shipyards"]
|
||
|
|
scene = load("res://world/Main.tscn").instantiate()
|
||
|
|
root.add_child(scene)
|
||
|
|
current_scene = scene
|
||
|
|
controller = scene.get_node("BuildController")
|
||
|
|
popup = scene.get_node("UI/ResearchPointsMenu")
|
||
|
|
|
||
|
|
|
||
|
|
func _costly_doctrine() -> String:
|
||
|
|
for node in GameState.SKILL_TREE:
|
||
|
|
if int(node.get("research_points", 0)) > 0:
|
||
|
|
return String(node.id)
|
||
|
|
return ""
|
||
|
|
|
||
|
|
|
||
|
|
func _process(delta: float) -> bool:
|
||
|
|
elapsed += delta
|
||
|
|
if elapsed < 0.4:
|
||
|
|
return false
|
||
|
|
match stage:
|
||
|
|
0:
|
||
|
|
var doctrine: String = _costly_doctrine()
|
||
|
|
if doctrine == "":
|
||
|
|
return _fail("no doctrine costs research data, so this proves nothing")
|
||
|
|
# Everything but the data: the prerequisite met and the ore paid,
|
||
|
|
# so data is unambiguously the thing that is missing.
|
||
|
|
game_state.unlocked = ["shipyards"]
|
||
|
|
var requires: String = String(game_state.skill_node(doctrine).get("requires", ""))
|
||
|
|
if requires != "" and not game_state.is_unlocked(requires):
|
||
|
|
game_state.unlocked.append(requires)
|
||
|
|
game_state.research_points = 0
|
||
|
|
|
||
|
|
var mothership_id: int = game_state.add_building(
|
||
|
|
GameState.BUILDING_MOTHERSHIP, Vector2.ZERO)
|
||
|
|
controller.skill_menu.building_id = mothership_id
|
||
|
|
if popup.visible:
|
||
|
|
return _fail("the explainer was open before anything was refused")
|
||
|
|
controller._on_unlock_requested(doctrine)
|
||
|
|
if not popup.visible:
|
||
|
|
return _fail("a doctrine costing data was refused with no explanation")
|
||
|
|
if game_state.is_unlocked(doctrine):
|
||
|
|
return _fail("the doctrine was researched with no data at all")
|
||
|
|
var said: String = popup.have_label.text
|
||
|
|
if not said.contains("YOU HAVE 0"):
|
||
|
|
return _fail("the explainer does not say what the player holds: '%s'" % said)
|
||
|
|
if not popup.detail_label.text.to_lower().contains("scanner"):
|
||
|
|
return _fail("the explainer never mentions how to find a lab world")
|
||
|
|
print("skill tree: refused and explained - '%s'" % said)
|
||
|
|
popup.close_menu()
|
||
|
|
|
||
|
|
# --- C. with the data, it goes through, quietly ---------------
|
||
|
|
game_state.research_points = 20
|
||
|
|
controller._on_unlock_requested(doctrine)
|
||
|
|
if not game_state.is_unlocked(doctrine):
|
||
|
|
return _fail("the doctrine was refused with data in hand")
|
||
|
|
if popup.visible:
|
||
|
|
return _fail("the explainer opened on a research that succeeded")
|
||
|
|
print("with data in hand it goes through, and says nothing")
|
||
|
|
elapsed = 0.0
|
||
|
|
stage = 1
|
||
|
|
return false
|
||
|
|
1:
|
||
|
|
# --- B. the lab explains too, rather than blaming the queue ---
|
||
|
|
game_state.research_points = 0
|
||
|
|
var lab_id: int = game_state.add_building(GameState.BUILDING_SHIP_LAB,
|
||
|
|
Vector2(600.0, 0.0))
|
||
|
|
controller.lab_building_id = lab_id
|
||
|
|
controller.lab_vessel = GameState.VESSEL_INTERCEPTOR
|
||
|
|
controller.lab_choice = 0
|
||
|
|
var options: Array = controller._lab_options()
|
||
|
|
if options.is_empty():
|
||
|
|
return _fail("the lab offers nothing, so this proves nothing")
|
||
|
|
# Pick an option that actually costs data.
|
||
|
|
for i in range(options.size()):
|
||
|
|
if game_state.research_point_cost(String(options[i].id)) > 0:
|
||
|
|
controller.lab_choice = i
|
||
|
|
break
|
||
|
|
if game_state.research_point_cost(String(options[controller.lab_choice].id)) <= 0:
|
||
|
|
return _fail("no lab option costs research data, so this proves nothing")
|
||
|
|
controller._on_lab_buy()
|
||
|
|
if not popup.visible:
|
||
|
|
return _fail("the lab refused for want of data with no explanation")
|
||
|
|
if controller.lab_menu.status.text.contains("already queued"):
|
||
|
|
return _fail("the lab still blames the queue: '%s'" % controller.lab_menu.status.text)
|
||
|
|
print("ship lab: refused and explained, not blamed on the queue")
|
||
|
|
|
||
|
|
print("TEST_RESEARCH_POINTS_EXPLAINER: PASS")
|
||
|
|
quit(0)
|
||
|
|
return true
|
||
|
|
return false
|
||
|
|
|
||
|
|
|
||
|
|
func _fail(message: String) -> bool:
|
||
|
|
print("TEST_RESEARCH_POINTS_EXPLAINER: FAIL (%s)" % message)
|
||
|
|
quit(1)
|
||
|
|
return true
|