103 lines
4.8 KiB
GDScript3
103 lines
4.8 KiB
GDScript3
|
|
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
|