extends SceneTree # Forgejo #217: transporters crawl by default, and a Burn Drive lets them # carry energy and spend it to go far faster. The energy is theirs to find - # they fetch it from the nearest store that has any - and it runs out, so the # speed is something the player's energy supply pays for continuously rather # than a one-off purchase. # # Covers: # A. unresearched, a transporter never detours for fuel however much energy # is lying about, and makes the base speed # B. researched and empty, an idle one goes for the NEAREST store with # energy in it, and takes what is there # C. a fuelled transporter is measurably faster than an unfuelled one # D. a leg burns a unit, and an empty tank drops it back to the crawl # E. the leg it flies to collect fuel is not itself charged const HUB_AT: Vector2 = Vector2(0.0, 0.0) const NEAR_ENERGY_AT: Vector2 = Vector2(400.0, 0.0) const FAR_ENERGY_AT: Vector2 = Vector2(-3000.0, 0.0) var state: Node var hub_id: int var near_id: int var far_id: int func _initialize() -> void: state = root.get_node("GameState") state.buildings.clear() state.extractors.clear() state.transporters.clear() state.stored_vessels.clear() state.vessel_deliveries.clear() state.reset_progression() state.rocks = 500 state.unlocked = ["shipyards", "logistics", "freight"] state.add_building(state.BUILDING_MOTHERSHIP, Vector2(0.0, 4000.0)) hub_id = state.add_building(state.BUILDING_TRANSPORT_HUB, HUB_AT) near_id = state.add_building(state.BUILDING_SHIP_CRAFTER, NEAR_ENERGY_AT) far_id = state.add_building(state.BUILDING_SHIP_LAB, FAR_ENERGY_AT) load("res://tests/_staff.gd").staff(state, hub_id, 1) func _initialize_done() -> void: pass func _process(_delta: float) -> bool: # The bank is deliberately empty of energy, so the only sources are the # two structures below and "nearest" is a real choice. state.bank_inventory.set_amount(GameState.RESOURCE_ENERGY, 0) state.deposit_resource_to_building(near_id, GameState.RESOURCE_ENERGY, 4) state.deposit_resource_to_building(far_id, GameState.RESOURCE_ENERGY, 50) var t: Dictionary = state.transporters[0] # --- A. unresearched: no tank, no detour, base speed ---------------- if state.transporter_burns_energy(): return _fail("an unresearched transporter already burns energy") var crawl: float = state.transporter_leg_speed(t) if not is_equal_approx(crawl, state.transporter_speed()): return _fail("an unfuelled transporter makes %.1f, expected the base %.1f" \ % [crawl, state.transporter_speed()]) state._refuel_idle_transporters() if String(t.state) != state.TRANSPORTER_IDLE: return _fail("an unresearched transporter went looking for fuel") print("unresearched: no detour, %.0f base speed" % crawl) # --- B. researched and empty: to the NEAREST store ------------------ state.vessel_levels["trn_burn"] = 1 if not state.transporter_burns_energy(): return _fail("a researched Burn Drive did not enable energy burning") state._refuel_idle_transporters() if String(t.state) != state.TRANSPORTER_TO_FUEL: return _fail("an empty transporter did not go for fuel (state %s)" % t.state) if not Vector2(t.to).is_equal_approx(NEAR_ENERGY_AT): return _fail("it flew to %s, not the nearer store at %s" % [t.to, NEAR_ENERGY_AT]) print("researched and empty: flies to the nearest store, not the fullest") # --- E. and the trip to collect is not itself charged --------------- var before_fuel: int = int(t.get("fuel", 0)) state._advance_transporters(600.0) if int(t.get("fuel", 0)) <= before_fuel: return _fail("the transporter came back from the fuel store with nothing") # The near store held 4, which is under the tank, so it took all of it. if int(t.fuel) != 4: return _fail("it drew %d energy, expected the 4 that were there" % int(t.fuel)) if state.building_resource(near_id, GameState.RESOURCE_ENERGY) != 0: return _fail("the store it drew from still holds energy") print("collected 4 - all the near store had - and was not charged for the trip") # --- C. fuelled is faster ------------------------------------------- var boosted: float = state.transporter_leg_speed(t) if boosted <= crawl: return _fail("a fuelled transporter makes %.1f, no better than the crawl %.1f" \ % [boosted, crawl]) if not is_equal_approx(boosted, crawl * state.transporter_fuel_boost()): return _fail("a fuelled transporter makes %.1f, expected %.1f" \ % [boosted, crawl * state.transporter_fuel_boost()]) print("fuelled: %.0f against %.0f, a %.1fx difference" \ % [boosted, crawl, state.transporter_fuel_boost()]) # --- D. and it burns down to the crawl ------------------------------ var tank: int = int(t.fuel) for leg in range(tank): t.state = state.TRANSPORTER_RETURNING t.progress = 0.0 t.from = HUB_AT t.to = NEAR_ENERGY_AT state._advance_transporters(600.0) if int(t.get("fuel", 0)) != 0: return _fail("%d legs left %d energy aboard, expected an empty tank" \ % [tank, int(t.fuel)]) if not is_equal_approx(state.transporter_leg_speed(t), crawl): return _fail("an emptied transporter did not drop back to the crawl") print("%d legs emptied the tank and it is back to %.0f" % [tank, crawl]) print("TEST_TRANSPORTER_BURN: PASS") quit(0) return true func _fail(message: String) -> bool: print("TEST_TRANSPORTER_BURN: FAIL (%s)" % message) quit(1) return true