siphoning and hauling
This commit is contained in:
parent
592c628a46
commit
3f7a416fdc
@ -161,7 +161,8 @@ class Analyzer:
|
|||||||
'wp': m.waypoint,
|
'wp': m.waypoint,
|
||||||
'buy': p.buy,
|
'buy': p.buy,
|
||||||
'sell': p.sell,
|
'sell': p.sell,
|
||||||
'volume': p.volume
|
'volume': p.volume,
|
||||||
|
'category': m.rtype(r)
|
||||||
})
|
})
|
||||||
return prices
|
return prices
|
||||||
|
|
||||||
@ -203,3 +204,14 @@ class Analyzer:
|
|||||||
best_margin = margin
|
best_margin = margin
|
||||||
best_resource = r
|
best_resource = r
|
||||||
return best_resource
|
return best_resource
|
||||||
|
|
||||||
|
def best_sell_market(self, system, r):
|
||||||
|
best_price = 0
|
||||||
|
best_market = None
|
||||||
|
for m in self.store.all_members(system, Marketplace):
|
||||||
|
if r not in m.prices: continue
|
||||||
|
price = m.prices[r].sell
|
||||||
|
if price > best_price:
|
||||||
|
best_price = price
|
||||||
|
best_market = m
|
||||||
|
return best_market
|
||||||
|
@ -213,6 +213,10 @@ class Api:
|
|||||||
def siphon(self, ship):
|
def siphon(self, ship):
|
||||||
data = self.request('post', f'my/ships/{ship}/siphon')
|
data = self.request('post', f'my/ships/{ship}/siphon')
|
||||||
ship.update(data)
|
ship.update(data)
|
||||||
|
amt = mg(data, 'siphon.yield.units')
|
||||||
|
rec = mg(data, 'siphon.yield.symbol')
|
||||||
|
ship.log(f"siphoned {amt} {rec}")
|
||||||
|
ship.location.extracted += amt
|
||||||
return data['siphon']
|
return data['siphon']
|
||||||
|
|
||||||
def extract(self, ship, survey=None):
|
def extract(self, ship, survey=None):
|
||||||
@ -229,6 +233,10 @@ class Api:
|
|||||||
else:
|
else:
|
||||||
raise e
|
raise e
|
||||||
ship.update(data)
|
ship.update(data)
|
||||||
|
amt = mg(data, 'extraction.yield.units')
|
||||||
|
rec = mg(data, 'extraction.yield.symbol')
|
||||||
|
ship.log(f"extracted {amt} {rec}")
|
||||||
|
ship.location.extracted += amt
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def survey(self, ship):
|
def survey(self, ship):
|
||||||
@ -239,6 +247,14 @@ class Api:
|
|||||||
|
|
||||||
|
|
||||||
######## Commerce #########
|
######## Commerce #########
|
||||||
|
def transaction_cost(self, data):
|
||||||
|
if not 'transaction' in data: return 0
|
||||||
|
act = mg(data,'transaction.type')
|
||||||
|
minus = -1 if act == 'PURCHASE' else 1
|
||||||
|
units = mg(data, 'transaction.units')
|
||||||
|
ppu = mg(data, 'transaction.pricePerUnit')
|
||||||
|
return ppu * units * minus
|
||||||
|
|
||||||
def log_transaction(self, data):
|
def log_transaction(self, data):
|
||||||
if not 'transaction' in data: return
|
if not 'transaction' in data: return
|
||||||
typ = mg(data, 'transaction.tradeSymbol')
|
typ = mg(data, 'transaction.tradeSymbol')
|
||||||
@ -294,6 +310,19 @@ class Api:
|
|||||||
self.agent.update(data['agent'])
|
self.agent.update(data['agent'])
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def transfer(self, sship, dship, typ, amt):
|
||||||
|
data = {
|
||||||
|
'tradeSymbol': typ,
|
||||||
|
'units': amt,
|
||||||
|
'shipSymbol': dship.symbol
|
||||||
|
}
|
||||||
|
data = self.request('post', f'my/ships/{sship.symbol}/transfer', data)
|
||||||
|
sship.log(f'transferred {amt} {typ} to {dship}')
|
||||||
|
dship.log(f'received {amt} {typ} from {sship}')
|
||||||
|
if 'cargo' in data:
|
||||||
|
sship.update(data)
|
||||||
|
dship.put_cargo(typ, amt)
|
||||||
|
|
||||||
def purchase(self, typ, wp):
|
def purchase(self, typ, wp):
|
||||||
data = {
|
data = {
|
||||||
'shipType': typ,
|
'shipType': typ,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
from nullptr.store import Store
|
from nullptr.store import Store
|
||||||
from nullptr.models.ship import Ship
|
from nullptr.models.ship import Ship
|
||||||
from nullptr.missions import create_mission, get_mission_class
|
from nullptr.missions import create_mission, get_mission_class
|
||||||
|
from nullptr.models.waypoint import Waypoint
|
||||||
from random import choice, randrange
|
from random import choice, randrange
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
@ -111,12 +112,34 @@ class CentralCommand:
|
|||||||
if s in self.missions:
|
if s in self.missions:
|
||||||
m = self.missions[s]
|
m = self.missions[s]
|
||||||
|
|
||||||
|
def find_gas(self, s):
|
||||||
|
system = s.location.system
|
||||||
|
m = [w for w in self.store.all_members(system, 'Waypoint') if w.type == 'GAS_GIANT']
|
||||||
|
if len(m)==0:
|
||||||
|
raise CentralCommandError('no gas giant found')
|
||||||
|
return m[0]
|
||||||
|
|
||||||
def assign_mission(self, s):
|
def assign_mission(self, s):
|
||||||
if s.role == 'trader':
|
if s.role == 'trader':
|
||||||
self.assign_trade(s)
|
self.assign_trade(s)
|
||||||
elif s.role == 'probe':
|
elif s.role == 'probe':
|
||||||
self.assign_probe(s)
|
self.assign_probe(s)
|
||||||
|
elif s.role == 'siphon':
|
||||||
|
self.assign_siphon(s)
|
||||||
|
elif s.role == 'hauler':
|
||||||
|
self.assign_hauler(s)
|
||||||
|
|
||||||
|
def assign_hauler(self, s):
|
||||||
|
w = self.find_gas(s)
|
||||||
|
m = self.analyzer.best_sell_market(s.location.system, 'HYDROCARBON')
|
||||||
|
self.init_mission(s, 'haul')
|
||||||
|
self.smipa(s, 'site', w)
|
||||||
|
self.smipa(s, 'dest', m)
|
||||||
|
|
||||||
|
def assign_siphon(self, s):
|
||||||
|
w = self.find_gas(s)
|
||||||
|
self.init_mission(s, 'siphon')
|
||||||
|
self.smipa(s, 'site', w)
|
||||||
|
|
||||||
def assign_probe(self, s):
|
def assign_probe(self, s):
|
||||||
system = s.location.system
|
system = s.location.system
|
||||||
@ -165,6 +188,7 @@ class CentralCommand:
|
|||||||
mtype = s.mission
|
mtype = s.mission
|
||||||
m = create_mission(mtype, s, self.store, self.api)
|
m = create_mission(mtype, s, self.store, self.api)
|
||||||
self.missions[s] = m
|
self.missions[s] = m
|
||||||
|
m.status(s.mission_status)
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def stop_mission(self, s):
|
def stop_mission(self, s):
|
||||||
|
@ -118,6 +118,12 @@ class Commander(CommandLine):
|
|||||||
raise CommandError(f'{w} not found')
|
raise CommandError(f'{w} not found')
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
def resolve_ship(self, arg):
|
||||||
|
symbol = f'{self.agent.symbol}-{arg}'
|
||||||
|
ship = self.store.get('Ship', symbol)
|
||||||
|
if ship is None:
|
||||||
|
raise CommandError(f'ship {arg} not found')
|
||||||
|
return ship
|
||||||
|
|
||||||
######## First run #########
|
######## First run #########
|
||||||
def agent_setup(self):
|
def agent_setup(self):
|
||||||
@ -170,13 +176,9 @@ class Commander(CommandLine):
|
|||||||
|
|
||||||
def do_ship(self, arg=''):
|
def do_ship(self, arg=''):
|
||||||
if arg != '':
|
if arg != '':
|
||||||
symbol = f'{self.agent.symbol}-{arg}'
|
ship = self.resolve_ship(arg)
|
||||||
ship = self.store.get('Ship', symbol)
|
|
||||||
if ship is None:
|
self.ship = ship
|
||||||
print('not found')
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
self.ship = ship
|
|
||||||
pprint(self.ship, 5)
|
pprint(self.ship, 5)
|
||||||
|
|
||||||
######## Atlas #########
|
######## Atlas #########
|
||||||
@ -292,6 +294,17 @@ class Commander(CommandLine):
|
|||||||
self.api.jettison(self.ship, resource.upper())
|
self.api.jettison(self.ship, resource.upper())
|
||||||
self.do_cargo()
|
self.do_cargo()
|
||||||
|
|
||||||
|
def do_transfer(self, resource, dship, amount=None):
|
||||||
|
if not self.has_ship(): return
|
||||||
|
resource = resource.upper()
|
||||||
|
avail = self.ship.get_cargo(resource)
|
||||||
|
if amount is None: amount = avail
|
||||||
|
amount = int(amount)
|
||||||
|
if avail < amount:
|
||||||
|
raise CommandError('resource not in cargo')
|
||||||
|
dship = self.resolve_ship(dship)
|
||||||
|
self.api.transfer(self.ship, dship, resource, amount)
|
||||||
|
|
||||||
|
|
||||||
def do_purchase(self, ship_type):
|
def do_purchase(self, ship_type):
|
||||||
if not self.has_ship(): return
|
if not self.has_ship(): return
|
||||||
@ -306,7 +319,6 @@ class Commander(CommandLine):
|
|||||||
def do_siphon(self):
|
def do_siphon(self):
|
||||||
if not self.has_ship(): return
|
if not self.has_ship(): return
|
||||||
data = self.api.siphon(self.ship)
|
data = self.api.siphon(self.ship)
|
||||||
pprint(data)
|
|
||||||
|
|
||||||
def do_survey(self):
|
def do_survey(self):
|
||||||
if not self.has_ship(): return
|
if not self.has_ship(): return
|
||||||
@ -334,7 +346,7 @@ class Commander(CommandLine):
|
|||||||
pprint(self.ship.mission_state)
|
pprint(self.ship.mission_state)
|
||||||
|
|
||||||
def do_role(self, role):
|
def do_role(self, role):
|
||||||
roles = [None, 'trader', 'probe']
|
roles = [None, 'trader', 'probe', 'siphon', 'hauler']
|
||||||
if not self.has_ship(): return
|
if not self.has_ship(): return
|
||||||
if role == 'none':
|
if role == 'none':
|
||||||
role = None
|
role = None
|
||||||
@ -565,7 +577,7 @@ class Commander(CommandLine):
|
|||||||
for res, p in prices.items():
|
for res, p in prices.items():
|
||||||
print('==' + res)
|
print('==' + res)
|
||||||
for m in p:
|
for m in p:
|
||||||
print(f"{m['wp'].symbol:12s} {m['volume']:5d} {m['buy']:5d} {m['sell']:5d}")
|
print(f"{m['wp'].symbol:12s} {m['category']} {m['volume']:5d} {m['buy']:5d} {m['sell']:5d}")
|
||||||
|
|
||||||
def do_path(self, waypoint_str):
|
def do_path(self, waypoint_str):
|
||||||
if not self.has_ship(): return
|
if not self.has_ship(): return
|
||||||
|
@ -4,7 +4,8 @@ from nullptr.missions.trade import TradeMission
|
|||||||
from nullptr.missions.travel import TravelMission
|
from nullptr.missions.travel import TravelMission
|
||||||
from nullptr.missions.probe import ProbeMission
|
from nullptr.missions.probe import ProbeMission
|
||||||
from nullptr.missions.idle import IdleMission
|
from nullptr.missions.idle import IdleMission
|
||||||
|
from nullptr.missions.siphon import SiphonMission
|
||||||
|
from nullptr.missions.haul import HaulMission
|
||||||
|
|
||||||
def get_mission_class( mtype):
|
def get_mission_class( mtype):
|
||||||
types = {
|
types = {
|
||||||
@ -13,7 +14,10 @@ def get_mission_class( mtype):
|
|||||||
'trade': TradeMission,
|
'trade': TradeMission,
|
||||||
'travel': TravelMission,
|
'travel': TravelMission,
|
||||||
'probe': ProbeMission,
|
'probe': ProbeMission,
|
||||||
'idle': IdleMission
|
'idle': IdleMission,
|
||||||
|
'siphon': SiphonMission,
|
||||||
|
'haul': HaulMission,
|
||||||
|
|
||||||
}
|
}
|
||||||
if mtype not in types:
|
if mtype not in types:
|
||||||
raise ValueError(f'invalid mission type {mtype}')
|
raise ValueError(f'invalid mission type {mtype}')
|
||||||
|
@ -51,8 +51,13 @@ class Mission:
|
|||||||
self.ship = ship
|
self.ship = ship
|
||||||
self.store = store
|
self.store = store
|
||||||
self.api = api
|
self.api = api
|
||||||
|
self.wait_for = None
|
||||||
self.next_step = 0
|
self.next_step = 0
|
||||||
self.analyzer = Analyzer(self.store)
|
self.analyzer = Analyzer(self.store)
|
||||||
|
self.setup()
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
pass
|
||||||
|
|
||||||
def sts(self, nm, v):
|
def sts(self, nm, v):
|
||||||
if issubclass(type(v), Base):
|
if issubclass(type(v), Base):
|
||||||
@ -74,6 +79,16 @@ class Mission:
|
|||||||
if nw is None:
|
if nw is None:
|
||||||
return self.ship.mission_status
|
return self.ship.mission_status
|
||||||
else:
|
else:
|
||||||
|
steps = self.steps()
|
||||||
|
if nw in ['init','done', 'error']:
|
||||||
|
self.ship.mission_status = nw
|
||||||
|
return
|
||||||
|
elif nw not in steps:
|
||||||
|
self.ship.log(f"Invalid mission status {nw}", 1)
|
||||||
|
self.ship.mission_status = 'error'
|
||||||
|
return
|
||||||
|
wait_for = steps[nw][2] if len(steps[nw]) > 2 else None
|
||||||
|
self.wait_for = wait_for
|
||||||
self.ship.mission_status = nw
|
self.ship.mission_status = nw
|
||||||
|
|
||||||
def start_state(self):
|
def start_state(self):
|
||||||
@ -96,10 +111,19 @@ class Mission:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def step_done(self):
|
def step_done(self):
|
||||||
self.ship.log(f'mission finished', 3)
|
self.ship.log(f'mission finished with balance {self.balance()}', 3)
|
||||||
|
|
||||||
def is_waiting(self):
|
def is_waiting(self):
|
||||||
return self.next_step > time() or self.ship.cooldown > time() or self.ship.arrival > time()
|
if self.next_step > time() or self.ship.cooldown > time() or self.ship.arrival > time():
|
||||||
|
return True
|
||||||
|
if self.wait_for is not None:
|
||||||
|
if self.wait_for():
|
||||||
|
self.wait_for = None
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def is_finished(self):
|
def is_finished(self):
|
||||||
return self.status() in ['done','error']
|
return self.status() in ['done','error']
|
||||||
@ -116,7 +140,10 @@ class Mission:
|
|||||||
self.ship.log(f"Invalid mission status {status}", 1)
|
self.ship.log(f"Invalid mission status {status}", 1)
|
||||||
self.status('error')
|
self.status('error')
|
||||||
return
|
return
|
||||||
handler, next_step = steps[status]
|
|
||||||
|
handler = steps[status][0]
|
||||||
|
next_step = steps[status][1]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = handler()
|
result = handler()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -136,6 +163,15 @@ class Mission:
|
|||||||
self.ship.log(f'{status} {result} -> {self.status()}', 8)
|
self.ship.log(f'{status} {result} -> {self.status()}', 8)
|
||||||
|
|
||||||
class BaseMission(Mission):
|
class BaseMission(Mission):
|
||||||
|
def balance(self, amt=0):
|
||||||
|
if type(amt) == dict:
|
||||||
|
amt = self.api.transaction_cost(amt)
|
||||||
|
balance = self.st('balance')
|
||||||
|
if balance is None: balance = 0
|
||||||
|
balance += amt
|
||||||
|
self.sts('balance', balance)
|
||||||
|
return balance
|
||||||
|
|
||||||
def step_go_dest(self):
|
def step_go_dest(self):
|
||||||
destination = self.rst(Waypoint, 'destination')
|
destination = self.rst(Waypoint, 'destination')
|
||||||
if self.ship.location() == destination:
|
if self.ship.location() == destination:
|
||||||
@ -179,8 +215,8 @@ class BaseMission(Mission):
|
|||||||
amt_cargo = self.ship.get_cargo(resource)
|
amt_cargo = self.ship.get_cargo(resource)
|
||||||
|
|
||||||
amount = min(amt_cargo, volume)
|
amount = min(amt_cargo, volume)
|
||||||
self.api.sell(self.ship, resource, amount)
|
res = self.api.sell(self.ship, resource, amount)
|
||||||
|
self.balance(res)
|
||||||
if len(sellables) == 1 and amt_cargo == amount:
|
if len(sellables) == 1 and amt_cargo == amount:
|
||||||
return 'done'
|
return 'done'
|
||||||
else:
|
else:
|
||||||
@ -228,7 +264,7 @@ class BaseMission(Mission):
|
|||||||
if dest_sys == loc_sys:
|
if dest_sys == loc_sys:
|
||||||
result = self.analyzer.find_nav_path(loc, dest, self.ship.range())
|
result = self.analyzer.find_nav_path(loc, dest, self.ship.range())
|
||||||
self.sts('traject', result)
|
self.sts('traject', result)
|
||||||
return
|
return 'done' if len(result) == 0 else 'more'
|
||||||
path = self.analyzer.find_path(loc_sys, dest_sys)
|
path = self.analyzer.find_path(loc_sys, dest_sys)
|
||||||
result = []
|
result = []
|
||||||
if loc.symbol != loc_jg.symbol:
|
if loc.symbol != loc_jg.symbol:
|
||||||
@ -238,7 +274,7 @@ class BaseMission(Mission):
|
|||||||
result.append(dest)
|
result.append(dest)
|
||||||
self.sts('traject', result)
|
self.sts('traject', result)
|
||||||
print(result)
|
print(result)
|
||||||
return result
|
return 'more'
|
||||||
|
|
||||||
def step_dock(self):
|
def step_dock(self):
|
||||||
if self.ship.status == 'DOCKED':
|
if self.ship.status == 'DOCKED':
|
||||||
@ -264,7 +300,10 @@ class BaseMission(Mission):
|
|||||||
calc = partial(self.step_calculate_traject, destination)
|
calc = partial(self.step_calculate_traject, destination)
|
||||||
steps = {
|
steps = {
|
||||||
|
|
||||||
f'travel-{nm}': (calc, f'dock-{nm}'),
|
f'travel-{nm}': (calc, {
|
||||||
|
'more': f'dock-{nm}',
|
||||||
|
'done': next_step
|
||||||
|
}),
|
||||||
f'dock-{nm}': (self.step_dock, f'refuel-{nm}'),
|
f'dock-{nm}': (self.step_dock, f'refuel-{nm}'),
|
||||||
f'refuel-{nm}': (self.step_refuel, f'orbit-{nm}'),
|
f'refuel-{nm}': (self.step_refuel, f'orbit-{nm}'),
|
||||||
f'orbit-{nm}': (self.step_orbit, f'go-{nm}'),
|
f'orbit-{nm}': (self.step_orbit, f'go-{nm}'),
|
||||||
|
73
nullptr/missions/haul.py
Normal file
73
nullptr/missions/haul.py
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
from nullptr.missions.base import BaseMission, MissionParam
|
||||||
|
from nullptr.models.waypoint import Waypoint
|
||||||
|
|
||||||
|
class HaulMission(BaseMission):
|
||||||
|
def start_state(self):
|
||||||
|
return 'travel-to'
|
||||||
|
|
||||||
|
def step_turn(self):
|
||||||
|
self.ship.log('starting haul load')
|
||||||
|
|
||||||
|
def wait_turn(self):
|
||||||
|
for s in self.store.all('Ship'):
|
||||||
|
if s.mission != 'haul': continue
|
||||||
|
if s.location != self.ship.location:
|
||||||
|
continue
|
||||||
|
if s.mission_state['dest'] != self.st('dest'):
|
||||||
|
continue
|
||||||
|
if s.mission_status != 'load':
|
||||||
|
continue
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def wait_cargo(self):
|
||||||
|
dmkt = self.store.get('Marketplace', self.st('dest'))
|
||||||
|
sellables = dmkt.prices.keys()
|
||||||
|
for s in self.store.all("Ship"):
|
||||||
|
if s.location != self.ship.location: continue
|
||||||
|
if s.mission not in ['mine','siphon']: continue
|
||||||
|
for r, a in s.cargo.items():
|
||||||
|
if r not in sellables: continue
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def step_load(self):
|
||||||
|
cargo_space = self.ship.cargo_capacity - self.ship.cargo_units
|
||||||
|
dmkt = self.store.get('Marketplace', self.st('dest'))
|
||||||
|
sellables = dmkt.prices.keys()
|
||||||
|
for s in self.store.all("Ship"):
|
||||||
|
if s.location != self.ship.location: continue
|
||||||
|
if s.mission not in ['mine','siphon']: continue
|
||||||
|
for r, a in s.cargo.items():
|
||||||
|
if r not in sellables: continue
|
||||||
|
amount = min(cargo_space, a)
|
||||||
|
|
||||||
|
res = self.api.transfer(s, self.ship, r, amount)
|
||||||
|
|
||||||
|
return 'done' if amount == cargo_space else 'more'
|
||||||
|
return 'more'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def params(cls):
|
||||||
|
return {
|
||||||
|
'site': MissionParam(Waypoint, True),
|
||||||
|
'dest': MissionParam(Waypoint, True),
|
||||||
|
}
|
||||||
|
|
||||||
|
def steps(self):
|
||||||
|
return {
|
||||||
|
**self.travel_steps('to', 'site', 'wait-turn'),
|
||||||
|
'wait-turn': (self.step_turn, 'load', self.wait_turn),
|
||||||
|
'load': (self.step_load, {
|
||||||
|
'more': 'load',
|
||||||
|
'done': 'travel-back'
|
||||||
|
}, self.wait_cargo),
|
||||||
|
**self.travel_steps('back', 'dest', 'dock-dest'),
|
||||||
|
'dock-dest': (self.step_dock, 'unload'),
|
||||||
|
'unload': (self.step_sell, {
|
||||||
|
'more': 'unload',
|
||||||
|
'done': 'market-dest'
|
||||||
|
}),
|
||||||
|
'market-dest': (self.step_market, 'report'),
|
||||||
|
'report': (self.step_done, 'done')
|
||||||
|
}
|
25
nullptr/missions/siphon.py
Normal file
25
nullptr/missions/siphon.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
from nullptr.missions.base import BaseMission, MissionParam
|
||||||
|
from nullptr.models.waypoint import Waypoint
|
||||||
|
|
||||||
|
class SiphonMission(BaseMission):
|
||||||
|
def start_state(self):
|
||||||
|
return 'travel-to'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def params(cls):
|
||||||
|
return {
|
||||||
|
'site': MissionParam(Waypoint, True),
|
||||||
|
}
|
||||||
|
|
||||||
|
def steps(self):
|
||||||
|
return {
|
||||||
|
**self.travel_steps('to', 'site', 'siphon'),
|
||||||
|
'siphon': (self.step_siphon, 'done', self.cargo_full)
|
||||||
|
}
|
||||||
|
|
||||||
|
def cargo_full(self):
|
||||||
|
return self.ship.cargo_capacity - self.ship.cargo_units > 5
|
||||||
|
|
||||||
|
def step_siphon(self):
|
||||||
|
result = self.api.siphon(self.ship)
|
||||||
|
self.next_step = self.ship.cooldown
|
@ -20,7 +20,8 @@ class TradeMission(BaseMission):
|
|||||||
amount = min(cargo_space, affordable, volume)
|
amount = min(cargo_space, affordable, volume)
|
||||||
if amount == 0:
|
if amount == 0:
|
||||||
return 'done'
|
return 'done'
|
||||||
self.api.buy(self.ship, resource, amount)
|
res = self.api.buy(self.ship, resource, amount)
|
||||||
|
self.balance(res)
|
||||||
return 'done' if amount == cargo_space else 'more'
|
return 'done' if amount == cargo_space else 'more'
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -46,5 +47,6 @@ class TradeMission(BaseMission):
|
|||||||
'more': 'unload',
|
'more': 'unload',
|
||||||
'done': 'market-dest'
|
'done': 'market-dest'
|
||||||
}),
|
}),
|
||||||
'market-dest': (self.step_market, 'done'),
|
'market-dest': (self.step_market, 'report'),
|
||||||
|
'report': (self.step_done, 'done')
|
||||||
}
|
}
|
||||||
|
@ -102,5 +102,5 @@ class Marketplace(Base):
|
|||||||
r += '\n'
|
r += '\n'
|
||||||
for res, p in self.prices.items():
|
for res, p in self.prices.items():
|
||||||
t = self.rtype(res)
|
t = self.rtype(res)
|
||||||
r += f'{t} {res:25s} {p.sell:5d} {p.buy:5d}\n'
|
r += f'{t} {res:25s} {p.buy:5d} {p.sell:5d}\n'
|
||||||
return r
|
return r
|
||||||
|
@ -89,6 +89,14 @@ class Ship(Base):
|
|||||||
|
|
||||||
self.cargo_units = sum(self.cargo.values())
|
self.cargo_units = sum(self.cargo.values())
|
||||||
|
|
||||||
|
def put_cargo(self, typ, amt):
|
||||||
|
if typ not in self.cargo:
|
||||||
|
self.cargo[typ] = amt
|
||||||
|
else:
|
||||||
|
self.cargo[typ] += amt
|
||||||
|
|
||||||
|
self.cargo_units = sum(self.cargo.values())
|
||||||
|
|
||||||
def load_cargo(self, cargo):
|
def load_cargo(self, cargo):
|
||||||
result = {}
|
result = {}
|
||||||
total = 0
|
total = 0
|
||||||
|
@ -13,6 +13,7 @@ class Waypoint(Base):
|
|||||||
self.faction:str = ''
|
self.faction:str = ''
|
||||||
self.is_under_construction:bool = False
|
self.is_under_construction:bool = False
|
||||||
self.uncharted = True
|
self.uncharted = True
|
||||||
|
self.extracted:int = 0
|
||||||
|
|
||||||
|
|
||||||
def update(self, d):
|
def update(self, d):
|
||||||
|
@ -9,6 +9,7 @@ import pickle
|
|||||||
from struct import unpack, pack
|
from struct import unpack, pack
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
from copy import copy
|
||||||
|
|
||||||
class StorePickler(pickle.Pickler):
|
class StorePickler(pickle.Pickler):
|
||||||
def persistent_id(self, obj):
|
def persistent_id(self, obj):
|
||||||
@ -315,7 +316,7 @@ class Store:
|
|||||||
self.cleanup()
|
self.cleanup()
|
||||||
it = 0
|
it = 0
|
||||||
start_time = time()
|
start_time = time()
|
||||||
for obj in self.dirty_objects:
|
for obj in copy(self.dirty_objects):
|
||||||
it += 1
|
it += 1
|
||||||
if obj.is_expired():
|
if obj.is_expired():
|
||||||
self.purge(obj)
|
self.purge(obj)
|
||||||
|
Loading…
Reference in New Issue
Block a user