extends SceneTree # Forgejo #223: a Fleet Office is stocked to a bounded amount - enough that # its charge is always payable while the bank has anything, and no more. # # It used to declare a flat buffer (60 ore, 30 gas, 30 energy) whatever was # in its berth, so an office keeping an interceptor had transporters haul it # gas and energy it could never spend, and the amount had no relation to what # it was actually charged. Since #220 the charge also depends on how far down # the fleet the berth sits, which no definition can state. # # Covers: # A. an office asks for what its OWN berth is charged, not a flat figure # B. it asks for nothing of a resource that berth never spends # C. what it asks for covers at least one charge, so the tax is payable # D. the request is bounded - a stocked office stops asking # E. and a deeper berth, which #220 charges more, asks for more 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 offices: Array = [] for i in range(4): offices.append(state.add_building(GameState.BUILDING_FLEET_OFFICE, Vector2(600.0 * float(i + 1), 0.0))) # Berth 2 keeps an interceptor (ore only); berth 5 keeps a laser, which # is dearer both in kind and in depth. state.fleet_vessel_types = PackedStringArray([ GameState.VESSEL_INTERCEPTOR, GameState.VESSEL_INTERCEPTOR, GameState.VESSEL_LASER, GameState.VESSEL_LASER, GameState.VESSEL_LASER]) var first: int = int(offices[0]) var charge: Dictionary = state.fleet_office_upkeep( GameState.VESSEL_INTERCEPTOR, GameState.BASE_FLEET_SIZE) var ore_charge: int = int(charge.get(GameState.RESOURCE_ORE, 0)) if ore_charge <= 0: return _fail("an interceptor berth is charged no ore, so this proves nothing") # --- A + C. it asks for its own charge, several times over --------- var ore_wanted: int = state.building_requested_resource(first, GameState.RESOURCE_ORE) if ore_wanted < ore_charge: return _fail("an empty office asks for %d ore against a %d charge - it can starve with ore banked" \ % [ore_wanted, ore_charge]) if ore_wanted < ore_charge * GameState.FLEET_OFFICE_STOCK_CHARGES: return _fail("asks for %d ore, under the %d charges it is meant to hold" \ % [ore_wanted, GameState.FLEET_OFFICE_STOCK_CHARGES]) # A cheap hull's charges come to less than the small floor the definition # declares, and the floor wins - that floor is what keeps a berth payable # before its first delivery lands. The dynamic term is what matters for a # dear one, which is checked at berth 5 below. # --- B. and nothing it cannot spend -------------------------------- # An interceptor costs ore alone, so the gas request is the definition's # small floor rather than a buffer's worth of cargo it will never burn. var gas_wanted: int = state.building_requested_resource(first, GameState.RESOURCE_GAS) if gas_wanted >= ore_wanted: return _fail("an ore-only berth asks for %d gas against %d ore" % [gas_wanted, ore_wanted]) print("berth 2 (interceptor): %d ore wanted for a %d charge, %d gas" \ % [ore_wanted, ore_charge, gas_wanted]) # --- D. bounded: stocked, it stops asking --------------------------- state.deposit_resource_to_building(first, GameState.RESOURCE_ORE, ore_wanted) if state.building_requested_resource(first, GameState.RESOURCE_ORE) != 0: return _fail("a stocked office is still asking for ore - the fill is unbounded") state.deposit_resource_to_building(first, GameState.RESOURCE_ORE, 500) if state.building_requested_resource(first, GameState.RESOURCE_ORE) != 0: return _fail("an over-stocked office asks for still more") print("stocked, it asks for nothing further") # --- E. a deeper berth costs more, and asks for more ---------------- var deep: int = int(offices[3]) var deep_ore: int = state.building_requested_resource(deep, GameState.RESOURCE_ORE) var shallow_laser: Dictionary = state.fleet_office_upkeep( GameState.VESSEL_LASER, GameState.BASE_FLEET_SIZE) if deep_ore <= int(shallow_laser.get(GameState.RESOURCE_ORE, 0)) * GameState.FLEET_OFFICE_STOCK_CHARGES - 1: return _fail("berth 5 asks for %d ore, no more than the same hull would at berth 2" % deep_ore) # A laser burns energy too, so that berth asks for energy where the # interceptor's did not. if state.building_requested_resource(deep, GameState.RESOURCE_ENERGY) \ <= state.building_requested_resource(first, GameState.RESOURCE_ENERGY): return _fail("a laser berth asks for no more energy than an interceptor berth") print("berth 5 (laser, deeper): %d ore and energy on top" % deep_ore) print("TEST_FLEET_OFFICE_STOCK: PASS") quit(0) return true func _fail(message: String) -> bool: print("TEST_FLEET_OFFICE_STOCK: FAIL (%s)" % message) quit(1) return true