Pay for everything from the bank and the fleet hold, not just buildings
Construction already pooled the two; research, ship-lab upgrades and vessel unlocks still charged the bank alone. That split was arbitrary from the player's side - the resources are a couple of taps away from being banked either way, so refusing a purchase over where they happen to be sitting was ceremony. Worse, it was inconsistent: the same ore could buy a mothership and not a skill node. So the pooling moved down into can_afford/spend themselves, and the construction-specific pair is gone. can_afford_resources now pools per resource type, and a new spend_resources() charges bank first and hold for the shortfall, settling affordability in full before taking anything - a multi-resource price must not charge for the half it can cover and then fail. unlock_vessel goes through it instead of withdrawing from the bank directly. The skill menu's "you have %d" quoted the bank, which would have told the player they could not afford something they could. Ammo stays out of it. AimedFleetAbilityController reads the fleet hold directly, and should: a gas bomb is fired from what the ships are physically carrying, which is a fact about where the matter is rather than a convenience about where the money is. test_build_uses_fleet_hold became test_payments_use_fleet_hold and now walks every route - skill tree, ship lab, vessel research, multi-resource atomicity, and ammo staying unpooled. Two of its own setup steps were being silently clamped by the fleet hold's capacity, which is what made an affordable price look unaffordable; capacity is not what those checks are about, so it is taken out of the way explicitly. Full suite 106/106. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
f5a16a7b95
commit
821da05c9f
5 changed files with 341 additions and 215 deletions
|
|
@ -705,8 +705,8 @@ func _show_building_info(type: String) -> void:
|
|||
# The same pooled test the build itself uses. Asking the bank here while
|
||||
# charging bank-plus-hold below would hide the build button for something
|
||||
# the player can in fact afford.
|
||||
if can_build and not GameState.can_afford_construction(cost):
|
||||
lines.append("Not enough rocks - needs %d, you have %d." % [cost, GameState.construction_ore()])
|
||||
if can_build and not GameState.can_afford(cost):
|
||||
lines.append("Not enough rocks - needs %d, you have %d." % [cost, GameState.available_ore()])
|
||||
can_build = false
|
||||
|
||||
info_title.text = definition.display_name
|
||||
|
|
@ -753,17 +753,17 @@ func _confirm_build() -> void:
|
|||
# glyph/HUD rendering the moment it produced anything.
|
||||
build_status.text = "%s has nothing to extract" % planet.planet_name
|
||||
return
|
||||
if not GameState.spend_construction(definition.cost):
|
||||
build_status.text = "Not enough rocks (need %d, have %d)" % [definition.cost, GameState.construction_ore()]
|
||||
if not GameState.spend(definition.cost):
|
||||
build_status.text = "Not enough rocks (need %d, have %d)" % [definition.cost, GameState.available_ore()]
|
||||
return
|
||||
GameState.add_extractor(planet.planet_name, planet.position, planet.resource_type, planet.planet_id)
|
||||
build_menu.visible = false
|
||||
return
|
||||
|
||||
if definition.unique and GameState.has_building_of_type(type):
|
||||
if not GameState.can_afford_construction(definition.cost):
|
||||
if not GameState.can_afford(definition.cost):
|
||||
build_status.text = "Not enough rocks (need %d, have %d)" % [
|
||||
definition.cost, GameState.construction_ore()
|
||||
definition.cost, GameState.available_ore()
|
||||
]
|
||||
return
|
||||
# Only now is the old one destroyed - never before the new one is
|
||||
|
|
@ -775,8 +775,8 @@ func _confirm_build() -> void:
|
|||
|
||||
|
||||
func _try_place(type: String, cost: int) -> void:
|
||||
if not GameState.spend_construction(cost):
|
||||
build_status.text = "Not enough rocks (need %d, have %d)" % [cost, GameState.construction_ore()]
|
||||
if not GameState.spend(cost):
|
||||
build_status.text = "Not enough rocks (need %d, have %d)" % [cost, GameState.available_ore()]
|
||||
return
|
||||
building_field.place(type, fleet.get_centroid())
|
||||
build_menu.visible = false
|
||||
|
|
@ -817,7 +817,10 @@ func _refresh_skill_menu(id: String = "") -> void:
|
|||
skill_status.text = "Needs %s first" % GameState.skill_node(node.requires).name
|
||||
skill_unlock_button.visible = false
|
||||
elif not GameState.can_afford(int(node.cost)):
|
||||
skill_status.text = "Not enough rocks - you have %d" % GameState.rocks
|
||||
# available_ore(), not the bank alone: research is paid for the same
|
||||
# pooled way as everything else, so quoting the bank here would tell
|
||||
# the player they cannot afford something they can.
|
||||
skill_status.text = "Not enough rocks - you have %d" % GameState.available_ore()
|
||||
skill_unlock_button.visible = false
|
||||
elif GameState.research_points < points_needed:
|
||||
# #63: a distinct reason from the ore one above - conflating them
|
||||
|
|
@ -1110,8 +1113,10 @@ func _transfer_place_name() -> String:
|
|||
if b.is_empty():
|
||||
return "this building"
|
||||
if GameState.building_has_capability(b, "bank"):
|
||||
# Worth naming as the bank rather than as a structure: this is the
|
||||
# one building where unloading makes the ore spendable everywhere.
|
||||
# Worth naming as the bank rather than as a structure: it is the
|
||||
# shared pool every building's transporters draw from, not just
|
||||
# another store. (It is no longer where ore has to be to be SPENT -
|
||||
# purchases now draw on the fleet hold too.)
|
||||
return "the bank"
|
||||
return "this building"
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue