mining working again

This commit is contained in:
Richard 2024-01-25 19:57:49 +01:00
parent d8eb1c4954
commit f913d23c06
6 changed files with 82 additions and 57 deletions

View File

@ -5,7 +5,7 @@ from nullptr.models.marketplace import Marketplace
from nullptr.models.jumpgate import Jumpgate from nullptr.models.jumpgate import Jumpgate
from nullptr.models.ship import Ship from nullptr.models.ship import Ship
from .util import * from .util import *
from time import sleep from time import sleep, time
class ApiError(Exception): class ApiError(Exception):
def __init__(self, msg, code): def __init__(self, msg, code):
super().__init__(msg) super().__init__(msg)
@ -30,7 +30,11 @@ class Api:
def request(self, method, path, data=None, need_token=True, params={}): def request(self, method, path, data=None, need_token=True, params={}):
try: try:
return self.request_once(method, path, data, need_token, params) start = time()
result = self.request_once(method, path, data, need_token, params)
dur = time() - start
# print(f'api {dur:.03}')
return result
except (ApiLimitError, requests.exceptions.Timeout): except (ApiLimitError, requests.exceptions.Timeout):
# print('oops, hit the limit. take a break') # print('oops, hit the limit. take a break')
sleep(10) sleep(10)
@ -230,7 +234,7 @@ class Api:
data = {} data = {}
url = f'my/ships/{ship}/extract' url = f'my/ships/{ship}/extract'
if survey is not None: if survey is not None:
data['survey'] = survey.api_dict() data= survey.api_dict()
url += '/survey' url += '/survey'
try: try:
data = self.request('post', url, data=data) data = self.request('post', url, data=data)

View File

@ -3,7 +3,7 @@ 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 nullptr.models.waypoint import Waypoint
from random import choice, randrange from random import choice, randrange
from time import sleep from time import sleep, time
from threading import Thread from threading import Thread
from nullptr.atlas_builder import AtlasBuilder from nullptr.atlas_builder import AtlasBuilder
from nullptr.analyzer import Analyzer, Point from nullptr.analyzer import Analyzer, Point
@ -64,6 +64,7 @@ class CentralCommand:
while not self.stopping: while not self.stopping:
did_step = True did_step = True
request_counter = self.api.requests_sent request_counter = self.api.requests_sent
start = time()
while request_counter == self.api.requests_sent and did_step: while request_counter == self.api.requests_sent and did_step:
did_step = self.tick() did_step = self.tick()
if request_counter == self.api.requests_sent: if request_counter == self.api.requests_sent:
@ -72,7 +73,11 @@ class CentralCommand:
pass # print('nowork') pass # print('nowork')
self.store.flush() self.store.flush()
sleep(0.5) dur = time() - start
# print(f'step {dur:.03}')
zs = 0.5 - dur
if zs > 0:
sleep(zs)
self.stopping = False self.stopping = False
def stop(self): def stop(self):
@ -137,6 +142,17 @@ class CentralCommand:
self.assign_hauler(s) self.assign_hauler(s)
elif s.role == 'surveyor': elif s.role == 'surveyor':
self.assign_survey(s) self.assign_survey(s)
elif s.role == 'miner':
self.assign_mine(s)
def assign_mine(self, s):
if s.crew is None:
raise CentralCommandError('ship has no crew')
w = s.crew.site
resources = s.crew.resources
self.init_mission(s, 'mine')
self.smipa(s, 'site', w)
self.smipa(s, 'resources', resources)
def assign_survey(self, s): def assign_survey(self, s):
if s.crew is None: if s.crew is None:
@ -226,7 +242,7 @@ class CentralCommand:
metal_w = self.find_metal(system) metal_w = self.find_metal(system)
metal = self.store.get('Crew', 'METAL', create=True) metal = self.store.get('Crew', 'METAL', create=True)
metal.site = metal_w metal.site = metal_w
metal.resources = ['COPPER_ORE','IRON_ORE'] metal.resources = ['COPPER_ORE','IRON_ORE','ALUMINUM_ORE']
gas = self.store.get('Crew', 'GAS', create=True) gas = self.store.get('Crew', 'GAS', create=True)
gas.site = gas_w gas.site = gas_w
gas.resources = ['HYDROCARBON','LIQUID_HYDROGEN','LIQUID_NITROGEN'] gas.resources = ['HYDROCARBON','LIQUID_HYDROGEN','LIQUID_NITROGEN']

View File

@ -0,0 +1,28 @@
from nullptr.missions.base import BaseMission
class ExtractionMission(BaseMission):
def find_hauler(self, r):
for s in self.store.all('Ship'):
if s.mission != 'haul': continue
if s.location != self.ship.location:
continue
if s.mission_status != 'load':
continue
if r not in s.mission_state['resources']: continue
return s
return None
def step_unload(self):
if len(self.ship.cargo) == 0:
return 'done'
r = list(self.ship.cargo.keys())[0]
amt = self.ship.cargo[r]
h = self.find_hauler(r)
if h is None:
self.api.jettison(self.ship, r)
else:
space = h.cargo_space()
amt = min(space, amt)
if amt > 0:
self.api.transfer(self.ship, h, r, amt)
return 'more'

View File

@ -3,15 +3,16 @@ from nullptr.models.waypoint import Waypoint
from nullptr.models.survey import Survey from nullptr.models.survey import Survey
from nullptr.models.contract import Contract from nullptr.models.contract import Contract
from nullptr.util import * from nullptr.util import *
from nullptr.missions.extraction import ExtractionMission
class MiningMission(BaseMission): class MiningMission(ExtractionMission):
@classmethod @classmethod
def params(cls): def params(cls):
return { return {
'site': MissionParam(Waypoint, True), 'site': MissionParam(Waypoint, True),
'resources': MissionParam(list, True) 'resources': MissionParam(list, True)
} }
p
def start_state(self): def start_state(self):
return 'travel-to' return 'travel-to'
@ -20,7 +21,7 @@ class MiningMission(BaseMission):
**self.travel_steps('to', 'site', 'extract'), **self.travel_steps('to', 'site', 'extract'),
'extract': (self.step_extract, { 'extract': (self.step_extract, {
'more': 'extract', 'more': 'extract',
'full': 'unload' 'done': 'unload'
}), }),
'unload': (self.step_unload, { 'unload': (self.step_unload, {
'more': 'unload', 'more': 'unload',
@ -29,36 +30,31 @@ class MiningMission(BaseMission):
} }
def get_survey(self): def get_survey(self):
resource = self.st('resource') resources = self.st('resources')
site = self.rst(Waypoint,'site') site = self.rst(Waypoint,'site')
best_score = 0
best_survey = None
# todo optimize # todo optimize
for s in self.store.all(Survey): for s in self.store.all(Survey):
if resource in s.deposits and site.symbol == s.waypoint: if site != s.waypoint:
return s continue
return None good = len([1 for r in s.deposits if r in resources])
total = len(s.deposits)
score = good / total
if score > best_score:
best_score = score
best_survey = s
return best_survey
def step_extract(self): def step_extract(self):
survey = self.get_survey() survey = self.get_survey()
print('using survey:', str(survey))
result = self.api.extract(self.ship, survey) result = self.api.extract(self.ship, survey)
symbol = sg(result,'extraction.yield.symbol') symbol = sg(result,'extraction.yield.symbol')
units = sg(result,'extraction.yield.units') units = sg(result,'extraction.yield.units')
print('extracted:', units, symbol)
self.next_step = self.ship.cooldown self.next_step = self.ship.cooldown
if self.ship.cargo_units < self.ship.cargo_capacity: if self.ship.cargo_space() > 5:
return 'more' return 'more'
else: else:
return 'done' return 'done'
def step_dispose(self):
contract = self.rst(Contract, 'contract')
typs = self.ship.nondeliverable_cargo(contract)
if len(typs) > 0:
self.api.jettison(self.ship, typs[0])
if len(typs) > 1:
return 'more'
elif self.ship.cargo_units > self.ship.cargo_capacity - 3:
return 'full'
else:
return 'done'

View File

@ -1,7 +1,8 @@
from nullptr.missions.base import BaseMission, MissionParam from nullptr.missions.base import MissionParam
from nullptr.missions.extraction import ExtractionMission
from nullptr.models.waypoint import Waypoint from nullptr.models.waypoint import Waypoint
class SiphonMission(BaseMission): class SiphonMission(ExtractionMission):
def start_state(self): def start_state(self):
return 'travel-to' return 'travel-to'
@ -18,32 +19,7 @@ class SiphonMission(BaseMission):
return 'more' return 'more'
else: else:
return 'full' return 'full'
def find_hauler(self, r):
for s in self.store.all('Ship'):
if s.mission != 'haul': continue
if s.location != self.ship.location:
continue
if s.mission_status != 'load':
continue
if r not in s.mission_state['resources']: continue
return s
return None
def step_unload(self):
if len(self.ship.cargo) == 0:
return 'done'
r = list(self.ship.cargo.keys())[0]
amt = self.ship.cargo[r]
h = self.find_hauler(r)
if h is None:
self.api.jettison(self.ship, r)
else:
space = h.cargo_space()
amt = min(space, amt)
if amt > 0:
self.api.transfer(self.ship, h, r, amt)
return 'more'
def steps(self): def steps(self):
return { return {

View File

@ -18,6 +18,11 @@ class Survey(Base):
def ext(cls): def ext(cls):
return 'svy' return 'svy'
def get_waypoint(self):
sym = '-'.join(self.symbol.split('-')[:3])
return self.store.get('Waypoint', sym, create=True)
def is_expired(self): def is_expired(self):
return time() > self.expires or self.exhausted return time() > self.expires or self.exhausted
@ -28,7 +33,7 @@ class Survey(Base):
def api_dict(self): def api_dict(self):
return { return {
'signature': self.symbol, 'signature': self.symbol,
'symbol': self.waypoint, 'symbol': self.waypoint.symbol,
'deposits': [{'symbol': d} for d in self.deposits], 'deposits': [{'symbol': d} for d in self.deposits],
'expiration': self.expires_str, 'expiration': self.expires_str,
'size': size_names[self.size] 'size': size_names[self.size]