extends SceneTree # Forgejo #220: the fleet costs more per hull as it grows, and the Fleet # Office says so with the arithmetic shown. # # The interesting failure is not "the sum is wrong" - it is the readout and # the charging loop drifting apart, so the menu quotes a bill the game does # not take. So what is checked is that the SAME numbers come out of both. # # Covers: # A. the first paid berth pays the base rate, undialled # B. each berth past it pays more than the one before, compounding # C. the growth is slow - a mid-sized fleet is dearer, not ruinous # D. the breakdown's per-minute total matches its own per-berth charges # E. and the charges it quotes are the ones actually withdrawn # F. an empty berth is quoted nothing var state: Node func _initialize() -> void: state = root.get_node("GameState") state.buildings.clear() state.transporters.clear() state.reset_progression() state.reset_new_game() state.intro_active = false state.fleet_vessel_types = PackedStringArray() func _process(_delta: float) -> bool: var vessel: String = GameState.VESSEL_LASER var base: Dictionary = state.fleet_office_upkeep(vessel, GameState.BASE_FLEET_SIZE) if base.is_empty(): return _fail("a laser berth is charged nothing at all") # --- A. the first paid berth is the base rate ------------------- if not is_equal_approx(state.fleet_upkeep_scale(GameState.BASE_FLEET_SIZE), 1.0): return _fail("the first paid berth is already dialled up (x%.2f)" \ % state.fleet_upkeep_scale(GameState.BASE_FLEET_SIZE)) # --- B. and every berth after it costs more --------------------- var previous: float = 0.0 for slot in range(GameState.BASE_FLEET_SIZE, GameState.BASE_FLEET_SIZE + 12): var scale: float = state.fleet_upkeep_scale(slot) if scale < previous: return _fail("berth %d is cheaper than the one before it" % (slot + 1)) previous = scale var twelfth: float = state.fleet_upkeep_scale(GameState.BASE_FLEET_SIZE + 11) if twelfth <= 1.0: return _fail("twelve berths in, upkeep has not risen at all") # --- C. slowly, though ------------------------------------------ if twelfth > 6.0: return _fail("the twelfth berth costs x%.1f - that is not a slow exponential" % twelfth) print("berth scaling: 1.00 at the first paid berth, x%.2f twelve in" % twelfth) # --- D/E/F. the quoted bill IS the charged one ------------------ # Three offices, two of them crewed: the third berth stands empty and # must be quoted nothing. var office_ids: Array = [] for i in range(3): office_ids.append(state.add_building(GameState.BUILDING_FLEET_OFFICE, Vector2(500.0 * float(i + 1), 0.0))) state.fleet_vessel_types = PackedStringArray([ GameState.VESSEL_INTERCEPTOR, vessel, vessel]) var breakdown: Dictionary = state.fleet_upkeep_breakdown() var berths: Array = breakdown.berths if berths.size() != 2: return _fail("%d berths quoted for a fleet of 3 with 3 offices, expected 2 paying" \ % berths.size()) if int(berths[1].costs.get(GameState.RESOURCE_ORE, 0)) \ <= int(berths[0].costs.get(GameState.RESOURCE_ORE, 0)) - 1: return _fail("the second paid berth is quoted less than the first") # The per-minute figure has to be the per-berth charges, at the rate they # are actually taken - not a separate estimate. var charges: float = 60.0 / float(breakdown.charge_seconds) for resource_type in breakdown.per_minute: var summed: float = 0.0 for berth in berths: summed += float(berth.costs.get(resource_type, 0)) * charges if not is_equal_approx(float(breakdown.per_minute[resource_type]), summed): return _fail("%s quoted at %.2f/min, its own berths add to %.2f" % [ resource_type, float(breakdown.per_minute[resource_type]), summed]) print("bill: %s, from %d paying berths" % [breakdown.per_minute, berths.size()]) # And a charge actually taken matches what was quoted for that berth. var quoted: int = int(berths[0].costs.get(GameState.RESOURCE_ORE, 0)) var office: Dictionary = state.find_building(int(office_ids[0])) var store: RefCounted = state.building_inventory(int(office_ids[0])) store.set_amount(GameState.RESOURCE_ORE, 500) store.set_amount(GameState.RESOURCE_ENERGY, 500) var before: int = store.amount(GameState.RESOURCE_ORE) office.upkeep_progress = GameState.FLEET_OFFICE_UPKEEP_SECONDS state._advance_fleet_office_upkeep(0.1) var taken: int = before - store.amount(GameState.RESOURCE_ORE) if taken != quoted: return _fail("berth 2 was quoted %d ore and charged %d" % [quoted, taken]) print("what the menu quotes for a berth is what the office pays: %d ore" % taken) print("TEST_FLEET_UPKEEP_SCALING: PASS") quit(0) return true func _fail(message: String) -> bool: print("TEST_FLEET_UPKEEP_SCALING: FAIL (%s)" % message) quit(1) return true