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