|
@@ -42,6 +42,47 @@ def main() -> None:
|
|
|
raw_materials: typing.Sequence[Material] = cache.get('https://rest.fnar.net/material/allmaterials')
|
|
raw_materials: typing.Sequence[Material] = cache.get('https://rest.fnar.net/material/allmaterials')
|
|
|
materials = {mat['Ticker']: mat for mat in raw_materials}
|
|
materials = {mat['Ticker']: mat for mat in raw_materials}
|
|
|
|
|
|
|
|
|
|
+ optimal, from_cx = calculate_optimal(planets, materials, args.weight, args.volume)
|
|
|
|
|
+ print(cyan('\nload at CX:\n') + json.dumps({
|
|
|
|
|
+ 'actions': [
|
|
|
|
|
+ {'name': 'BuyItems', 'type': 'CX Buy', 'group': 'A1', 'exchange': 'IC1',
|
|
|
|
|
+ 'priceLimits': {}, 'buyPartial': False, 'useCXInv': True},
|
|
|
|
|
+ {'type': 'MTRA', 'name': 'TransferAction', 'group': 'A1',
|
|
|
|
|
+ 'origin': 'Hortus Station Warehouse', 'dest': 'Configure on Execution'},
|
|
|
|
|
+ ],
|
|
|
|
|
+ 'global': {'name': 'supply ' + ' '.join(args.planets)},
|
|
|
|
|
+ 'groups': [{
|
|
|
|
|
+ 'type': 'Manual', 'name': 'A1', 'materials': {mat: amount for mat, amount in from_cx.items()}
|
|
|
|
|
+ }],
|
|
|
|
|
+ }))
|
|
|
|
|
+ for planet in planets:
|
|
|
|
|
+ buy = optimal[planet.name]
|
|
|
|
|
+ print(cyan(f'unload {planet.name}:\n') + json.dumps({
|
|
|
|
|
+ 'actions': [
|
|
|
|
|
+ {'type': 'MTRA', 'name': 'TransferAction', 'group': 'A1',
|
|
|
|
|
+ 'origin': 'Configure on Execution', 'dest': planet.name + ' Base'},
|
|
|
|
|
+ ],
|
|
|
|
|
+ 'global': {'name': 'unload ' + planet.name},
|
|
|
|
|
+ 'groups': [{
|
|
|
|
|
+ 'type': 'Manual', 'name': 'A1', 'materials': {mat: amount for mat, amount in buy.items()}
|
|
|
|
|
+ }],
|
|
|
|
|
+ }))
|
|
|
|
|
+
|
|
|
|
|
+def get_fio_burn(planet_names: typing.Sequence[str]) -> typing.Iterator[FIOBurn]:
|
|
|
|
|
+ planets: list[FIOBurn] = cache.get('https://rest.fnar.net/fioweb/burn/user/' + config.username,
|
|
|
|
|
+ headers={'Authorization': config.fio_api_key})
|
|
|
|
|
+ for name in planet_names:
|
|
|
|
|
+ name = name.casefold()
|
|
|
|
|
+ for planet_data in planets:
|
|
|
|
|
+ if name in (planet_data['PlanetName'].casefold(), planet_data['PlanetNaturalId'].casefold()):
|
|
|
|
|
+ assert planet_data['Error'] is None
|
|
|
|
|
+ yield planet_data
|
|
|
|
|
+ break
|
|
|
|
|
+ else:
|
|
|
|
|
+ raise ValueError(name + ' not found')
|
|
|
|
|
+
|
|
|
|
|
+def calculate_optimal(planets: typing.Sequence[Planet], materials: typing.Mapping[str, Material], max_weight: float,
|
|
|
|
|
+ max_volume: float) -> tuple[typing.Mapping[str, typing.Mapping[str, int]], typing.Mapping[str, int]]:
|
|
|
target_days = float('inf')
|
|
target_days = float('inf')
|
|
|
for planet in planets:
|
|
for planet in planets:
|
|
|
vol_per_day = weight_per_day = 0
|
|
vol_per_day = weight_per_day = 0
|
|
@@ -67,7 +108,7 @@ def main() -> None:
|
|
|
weight_used, volume_used = shipping_used(materials, config.supply_config(planet.name).ignore_materials, buy)
|
|
weight_used, volume_used = shipping_used(materials, config.supply_config(planet.name).ignore_materials, buy)
|
|
|
iteration_weight += weight_used
|
|
iteration_weight += weight_used
|
|
|
iteration_volume += volume_used
|
|
iteration_volume += volume_used
|
|
|
- if iteration_weight > args.weight or iteration_volume > args.volume:
|
|
|
|
|
|
|
+ if iteration_weight > max_weight or iteration_volume > max_volume:
|
|
|
load_more = False
|
|
load_more = False
|
|
|
break
|
|
break
|
|
|
buys[planet.name] = buy
|
|
buys[planet.name] = buy
|
|
@@ -116,45 +157,9 @@ def main() -> None:
|
|
|
else:
|
|
else:
|
|
|
print()
|
|
print()
|
|
|
print(f'\ntotal cost: {total_cost:,}')
|
|
print(f'\ntotal cost: {total_cost:,}')
|
|
|
- print(cyan('\nload at CX:\n') + json.dumps({
|
|
|
|
|
- 'actions': [
|
|
|
|
|
- {'name': 'BuyItems', 'type': 'CX Buy', 'group': 'A1', 'exchange': 'IC1',
|
|
|
|
|
- 'priceLimits': {}, 'buyPartial': False, 'useCXInv': True},
|
|
|
|
|
- {'type': 'MTRA', 'name': 'TransferAction', 'group': 'A1',
|
|
|
|
|
- 'origin': 'Hortus Station Warehouse', 'dest': 'Configure on Execution'},
|
|
|
|
|
- ],
|
|
|
|
|
- 'global': {'name': 'supply ' + ' '.join(args.planets)},
|
|
|
|
|
- 'groups': [{
|
|
|
|
|
- 'type': 'Manual', 'name': 'A1', 'materials': {mat: amount for mat, amount in from_cx.items()}
|
|
|
|
|
- }],
|
|
|
|
|
- }))
|
|
|
|
|
- for planet in planets:
|
|
|
|
|
- buy = optimal[planet.name]
|
|
|
|
|
- print(cyan(f'unload {planet.name}:\n') + json.dumps({
|
|
|
|
|
- 'actions': [
|
|
|
|
|
- {'type': 'MTRA', 'name': 'TransferAction', 'group': 'A1',
|
|
|
|
|
- 'origin': 'Configure on Execution', 'dest': planet.name + ' Base'},
|
|
|
|
|
- ],
|
|
|
|
|
- 'global': {'name': 'unload ' + planet.name},
|
|
|
|
|
- 'groups': [{
|
|
|
|
|
- 'type': 'Manual', 'name': 'A1', 'materials': {mat: amount for mat, amount in buy.items()}
|
|
|
|
|
- }],
|
|
|
|
|
- }))
|
|
|
|
|
-
|
|
|
|
|
-def get_fio_burn(planet_names: typing.Sequence[str]) -> typing.Iterator[FIOBurn]:
|
|
|
|
|
- planets: list[FIOBurn] = cache.get('https://rest.fnar.net/fioweb/burn/user/' + config.username,
|
|
|
|
|
- headers={'Authorization': config.fio_api_key})
|
|
|
|
|
- for name in planet_names:
|
|
|
|
|
- name = name.casefold()
|
|
|
|
|
- for planet_data in planets:
|
|
|
|
|
- if name in (planet_data['PlanetName'].casefold(), planet_data['PlanetNaturalId'].casefold()):
|
|
|
|
|
- assert planet_data['Error'] is None
|
|
|
|
|
- yield planet_data
|
|
|
|
|
- break
|
|
|
|
|
- else:
|
|
|
|
|
- raise ValueError(name + ' not found')
|
|
|
|
|
|
|
+ return optimal, from_cx
|
|
|
|
|
|
|
|
-def shipping_used(materials: dict[str, Material], ignore: typing.Collection[str], counts: dict[str, int]) -> tuple[float, float]:
|
|
|
|
|
|
|
+def shipping_used(materials: typing.Mapping[str, Material], ignore: typing.Collection[str], counts: dict[str, int]) -> tuple[float, float]:
|
|
|
weight = volume = 0
|
|
weight = volume = 0
|
|
|
for ticker, amount in counts.items():
|
|
for ticker, amount in counts.items():
|
|
|
if ticker in ignore:
|
|
if ticker in ignore:
|