#157 was already satisfied - second_hull is quest 7 and extractor is quest 11 - so this pins the property rather than adding a quest: nothing costing more than a single hold may be asked for before the chain has grown the fleet or taught banking. It fails if either is ever moved behind it. #158 - a building's local costs may now be paid out of the fleet's hold. #12 made production cost resources physically DELIVERED rather than money out of the bank, and that stands: the bank is still not raided here. The hold is simply the other place resources physically are, and making the player park, open the transfer menu and move cargo across by hand was ceremony rather than a decision. But only WHERE THE FLEET IS, and that qualifier is the whole design. The first draft had no range on it and test_manual_supply_route caught it immediately: a crafter three thousand units away reached into the hold and spent ore the player had just withdrawn to carry somewhere else - which is exactly the complaint that got automatic banking removed in #24, arriving from the other direction. The range is Building.interact_radius, the same distance that decides whether the transfer button appears, so the rule is not a hidden one: if you could hand the cargo over, the building can take it. #159 - the mothership floored at 1hp, so a battered one sat there reading as dead and never exploded. That exemption existed to prevent a soft-lock, and the soft-lock turns out not to exist: the bank is GameState.bank_inventory and the hangar is stored_vessels, both of which outlive any building; the mothership is the one structure research never gates; it costs exactly what a single interceptor's hold carries; and ore comes from asteroids, which do not run out. So the way back is always mine, fly, rebuild - and that is what test_building_health now asserts, in place of the exemption that used to stand in for it.
This commit is contained in:
parent
2e0c666c2b
commit
4c920f10b0
7 changed files with 397 additions and 39 deletions
|
|
@ -17,9 +17,12 @@ extends SceneTree
|
|||
# record outright
|
||||
# C. a record written before this existed reads as undamaged, not as
|
||||
# rubble - an existing save must not open on a field of wrecks
|
||||
# D. the mothership cannot be destroyed. The bank, the hangar and research
|
||||
# all live there and a wiped fleet rebuilds there, so losing it would
|
||||
# be a soft-lock; it bottoms out at 1hp instead
|
||||
# D. #159 - NOTHING is exempt from coming down, the mothership included.
|
||||
# It used to floor at 1hp to avoid a soft-lock, and a battered one sat
|
||||
# there reading as dead and never exploded. The soft-lock does not
|
||||
# exist: what is IN the mothership outlives it, and rebuilding it is
|
||||
# always reachable - so the way back is checked here rather than the
|
||||
# exemption that used to stand in for it
|
||||
# E. destroying a transport hub takes its transporters with it, and
|
||||
# nothing else keyed on the id is left pointing at a hole
|
||||
# F. the Building node follows its record out of existence, and shows
|
||||
|
|
@ -96,22 +99,50 @@ func _run_state_cases() -> bool:
|
|||
return _fail("one point of damage levelled a building carried over from an old save")
|
||||
print("a pre-#99 record reads as undamaged (%d hp), not as rubble" % lab_full)
|
||||
|
||||
# --- D. the mothership survives anything ----------------------------
|
||||
# --- D. #159: the mothership comes down like anything else ----------
|
||||
var mothership_id: int = game_state.add_building(GameState.BUILDING_MOTHERSHIP, Vector2.ZERO)
|
||||
if not game_state.building_is_indestructible(game_state.find_building(mothership_id)):
|
||||
return _fail("the mothership is not marked indestructible")
|
||||
if game_state.damage_building(mothership_id, 999999):
|
||||
return _fail("the mothership was destroyed - the bank, hangar and research went with it")
|
||||
if game_state.building_hp(mothership_id) != 1:
|
||||
return _fail("an overwhelmed mothership sits at %d hp, expected to floor at 1" \
|
||||
% game_state.building_hp(mothership_id))
|
||||
if game_state.destroy_building(mothership_id):
|
||||
return _fail("destroy_building demolished the mothership outright")
|
||||
if game_state.repair_building(mothership_id, 999999) <= 0:
|
||||
if game_state.building_is_indestructible(game_state.find_building(mothership_id)):
|
||||
return _fail("the mothership is still exempt - it would sit at 1hp reading as dead")
|
||||
# Stock the things that used to be the reason for the exemption, so
|
||||
# their survival is observed rather than assumed.
|
||||
game_state.bank_inventory.set_amount(GameState.RESOURCE_ORE, 400)
|
||||
game_state.stored_vessels.append(GameState.VESSEL_INTERCEPTOR)
|
||||
if not game_state.damage_building(mothership_id, 999999):
|
||||
return _fail("enough damage did not destroy the mothership")
|
||||
if not game_state.find_building(mothership_id).is_empty():
|
||||
return _fail("the mothership record outlived its own destruction")
|
||||
|
||||
# ...and the way back. This is what the exemption was protecting, so it
|
||||
# is what has to be true without it.
|
||||
if game_state.banked_resource(GameState.RESOURCE_ORE) != 400:
|
||||
return _fail("the bank died with the building - it holds %d" \
|
||||
% game_state.banked_resource(GameState.RESOURCE_ORE))
|
||||
if game_state.stored_vessels.is_empty():
|
||||
return _fail("the hangar died with the building")
|
||||
if game_state.research_for_building(GameState.BUILDING_MOTHERSHIP) != "":
|
||||
return _fail("rebuilding the mothership needs research, which needs a mothership")
|
||||
var rebuild: int = int(game_state.building_costs(GameState.BUILDING_MOTHERSHIP).get(
|
||||
GameState.RESOURCE_ORE, 0))
|
||||
var one_hold: int = game_state.fleet_cargo_capacity(
|
||||
PackedStringArray([GameState.VESSEL_INTERCEPTOR]))
|
||||
if rebuild > one_hold:
|
||||
return _fail("a rebuild costs %d ore and one surviving hull carries %d - unreachable with the bank gone" \
|
||||
% [rebuild, one_hold])
|
||||
print("the mothership comes down; bank, hangar and an ungated %d-ore rebuild all survive it" \
|
||||
% rebuild)
|
||||
# Repair, on a fresh one - the last was destroyed on purpose above.
|
||||
var rebuilt_id: int = game_state.add_building(GameState.BUILDING_MOTHERSHIP, Vector2.ZERO)
|
||||
var at_full: int = game_state.building_max_hp(GameState.BUILDING_MOTHERSHIP)
|
||||
if game_state.damage_building(rebuilt_id, at_full - 5):
|
||||
return _fail("damage short of the last few points still destroyed it")
|
||||
if game_state.building_hp(rebuilt_id) != 5:
|
||||
return _fail("a battered mothership sits at %d hp, expected 5" \
|
||||
% game_state.building_hp(rebuilt_id))
|
||||
if game_state.repair_building(rebuilt_id, 999999) <= 0:
|
||||
return _fail("a battered mothership could not be repaired")
|
||||
if game_state.building_hp(mothership_id) != game_state.building_max_hp(GameState.BUILDING_MOTHERSHIP):
|
||||
if game_state.building_hp(rebuilt_id) != at_full:
|
||||
return _fail("repair did not take the mothership back to full")
|
||||
print("the mothership floors at 1hp and repairs to full")
|
||||
print("a rebuilt one takes damage down to %d and repairs back to %d" % [5, at_full])
|
||||
|
||||
# --- E. a hub takes its transporters with it ------------------------
|
||||
var hub_id: int = game_state.add_building(GameState.BUILDING_TRANSPORT_HUB, Vector2(800.0, 0.0))
|
||||
|
|
|
|||
Loading…
Reference in a new issue