diff --git a/nullptr/central_command.py b/nullptr/central_command.py index 013906c..29c92ba 100644 --- a/nullptr/central_command.py +++ b/nullptr/central_command.py @@ -1,6 +1,6 @@ from nullptr.store import Store from nullptr.models.ship import Ship -from nullptr.mission import * +from nullptr.missions import create_mission from random import choice from time import sleep from threading import Thread diff --git a/nullptr/command_line.py b/nullptr/command_line.py index cc85563..923fa5d 100644 --- a/nullptr/command_line.py +++ b/nullptr/command_line.py @@ -90,5 +90,8 @@ class CommandLine: except EOFError: self.handle_eof() break - self.handle_cmd(c) + try: + self.handle_cmd(c) + except Exception as e: + logging.error(e, exc_info=True) diff --git a/nullptr/missions/__init__.py b/nullptr/missions/__init__.py new file mode 100644 index 0000000..c095596 --- /dev/null +++ b/nullptr/missions/__init__.py @@ -0,0 +1,18 @@ +from nullptr.missions.survey import SurveyMission +from nullptr.missions.mine import MiningMission +from nullptr.missions.haul import HaulMission +from nullptr.missions.travel import TravelMission + + +def create_mission(mtype, ship, store, api): + types = { + 'survey': SurveyMission, + 'mine': MiningMission, + 'haul': HaulMission, + 'travel': TravelMission + } + if mtype not in types: + logging.warning(f'invalid mission type {mtype}') + return + m = types[mtype](ship, store, api) + return m diff --git a/nullptr/mission.py b/nullptr/missions/base.py similarity index 65% rename from nullptr/mission.py rename to nullptr/missions/base.py index 5e0732a..6515f54 100644 --- a/nullptr/mission.py +++ b/nullptr/missions/base.py @@ -239,138 +239,3 @@ class BaseMission(Mission): f'dock-{nm}': (self.step_dock, f'refuel-{nm}'), f'refuel-{nm}': (self.step_refuel, next_step) } - -class MiningMission(BaseMission): - @classmethod - def params(cls): - return { - 'site': MissionParam(Waypoint, True), - 'resource': MissionParam(str, True), - 'dest': MissionParam(Waypoint, True), - 'delivery': MissionParam(str, True, 'deliver'), - 'contract': MissionParam(Contract, False) - } - - def start_state(self): - return 'travel-to' - - def steps(self): - return { - **self.travel_steps('to', 'site', 'extract'), - 'extract': (self.step_extract, { - 'done': 'dock', - 'more': 'extract' - }), - 'dock': (self.step_dock, 'sell'), - 'sell': (self.step_sell, { - 'more': 'sell', - 'done': 'orbit', - }), - 'orbit': (self.step_orbit, 'jettison'), - 'jettison': (self.step_dispose, { - 'more': 'jettison', - 'done': 'extract', - 'full': 'travel-back' - }), - **self.travel_steps('back', 'dest', 'unload'), - 'unload': (self.step_unload, { - 'done': 'travel-to', - 'more': 'unload' - }), - } - - def get_survey(self): - resource = self.st('resource') - site = self.rst(Waypoint,'site') - # todo optimize - for s in self.store.all(Survey): - if resource in s.deposits and site.symbol == s.waypoint(): - return s - return None - - def step_extract(self): - survey = self.get_survey() - print('using survey:', str(survey)) - result = self.api.extract(self.ship, survey) - symbol = sg(result,'extraction.yield.symbol') - units = sg(result,'extraction.yield.units') - print('extracted:', units, symbol) - self.next_step = self.ship.cooldown - if self.ship.cargo_units < self.ship.cargo_capacity: - return 'more' - else: - 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' - -class SurveyMission(BaseMission): - def start_state(self): - return 'survey' - - def steps(self): - return { - 'survey': (self.step_survey, 'survey') - } - - def step_survey(self): - result = self.api.survey(self.ship) - #pprint(result, 2) - self.next_step = self.ship.cooldown - -class HaulMission(BaseMission): - def start_state(self): - return 'travel-to' - - @classmethod - def params(cls): - return { - 'site': MissionParam(Waypoint, True), - 'resource': MissionParam(str, True), - 'dest': MissionParam(Waypoint, True), - 'delivery': MissionParam(str, True, 'deliver'), - 'contract': MissionParam(Contract, False) - } - - def steps(self): - return { - **self.travel_steps('to', 'site', 'load'), - 'load': (self.step_load, 'travel-back'), - **self.travel_steps('back', 'dest', 'load'), - 'unload': (self.step_unload, 'travel-to'), - } - -class TravelMission(BaseMission): - def start_state(self): - return 'travel-to' - - @classmethod - def params(cls): - return { - 'dest': MissionParam(Waypoint, True) - } - - def steps(self): - return self.travel_steps('to', 'dest', 'done') - -def create_mission(mtype, ship, store, api): - types = { - 'survey': SurveyMission, - 'mine': MiningMission, - 'haul': HaulMission, - 'travel': TravelMission - } - if mtype not in types: - logging.warning(f'invalid mission type {mtype}') - return - m = types[mtype](ship, store, api) - return m diff --git a/nullptr/missions/haul.py b/nullptr/missions/haul.py new file mode 100644 index 0000000..8072247 --- /dev/null +++ b/nullptr/missions/haul.py @@ -0,0 +1,25 @@ +from nullptr.missions.base import BaseMission, MissionParam +from nullptr.models.waypoint import Waypoint +from nullptr.models.survey import Survey +from nullptr.models.contract import Contract +class HaulMission(BaseMission): + def start_state(self): + return 'travel-to' + + @classmethod + def params(cls): + return { + 'site': MissionParam(Waypoint, True), + 'resource': MissionParam(str, True), + 'dest': MissionParam(Waypoint, True), + 'delivery': MissionParam(str, True, 'deliver'), + 'contract': MissionParam(Contract, False) + } + + def steps(self): + return { + **self.travel_steps('to', 'site', 'load'), + 'load': (self.step_load, 'travel-back'), + **self.travel_steps('back', 'dest', 'load'), + 'unload': (self.step_unload, 'travel-to'), + } diff --git a/nullptr/missions/mine.py b/nullptr/missions/mine.py new file mode 100644 index 0000000..3c8b53e --- /dev/null +++ b/nullptr/missions/mine.py @@ -0,0 +1,78 @@ +from nullptr.missions.base import BaseMission, MissionParam +from nullptr.models.waypoint import Waypoint +from nullptr.models.survey import Survey +from nullptr.models.contract import Contract + +class MiningMission(BaseMission): + @classmethod + def params(cls): + return { + 'site': MissionParam(Waypoint, True), + 'resource': MissionParam(str, True), + 'dest': MissionParam(Waypoint, True), + 'delivery': MissionParam(str, True, 'deliver'), + 'contract': MissionParam(Contract, False) + } + + def start_state(self): + return 'travel-to' + + def steps(self): + return { + **self.travel_steps('to', 'site', 'extract'), + 'extract': (self.step_extract, { + 'done': 'dock', + 'more': 'extract' + }), + 'dock': (self.step_dock, 'sell'), + 'sell': (self.step_sell, { + 'more': 'sell', + 'done': 'orbit', + }), + 'orbit': (self.step_orbit, 'jettison'), + 'jettison': (self.step_dispose, { + 'more': 'jettison', + 'done': 'extract', + 'full': 'travel-back' + }), + **self.travel_steps('back', 'dest', 'unload'), + 'unload': (self.step_unload, { + 'done': 'travel-to', + 'more': 'unload' + }), + } + + def get_survey(self): + resource = self.st('resource') + site = self.rst(Waypoint,'site') + # todo optimize + for s in self.store.all(Survey): + if resource in s.deposits and site.symbol == s.waypoint(): + return s + return None + + def step_extract(self): + survey = self.get_survey() + print('using survey:', str(survey)) + result = self.api.extract(self.ship, survey) + symbol = sg(result,'extraction.yield.symbol') + units = sg(result,'extraction.yield.units') + print('extracted:', units, symbol) + self.next_step = self.ship.cooldown + if self.ship.cargo_units < self.ship.cargo_capacity: + return 'more' + else: + 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' + diff --git a/nullptr/missions/survey.py b/nullptr/missions/survey.py new file mode 100644 index 0000000..2a41458 --- /dev/null +++ b/nullptr/missions/survey.py @@ -0,0 +1,15 @@ +from nullptr.missions.base import BaseMission, MissionParam + +class SurveyMission(BaseMission): + def start_state(self): + return 'survey' + + def steps(self): + return { + 'survey': (self.step_survey, 'survey') + } + + def step_survey(self): + result = self.api.survey(self.ship) + #pprint(result, 2) + self.next_step = self.ship.cooldown diff --git a/nullptr/missions/travel.py b/nullptr/missions/travel.py new file mode 100644 index 0000000..93f74ba --- /dev/null +++ b/nullptr/missions/travel.py @@ -0,0 +1,16 @@ +from nullptr.missions.base import BaseMission, MissionParam +from nullptr.models.waypoint import Waypoint + +class TravelMission(BaseMission): + def start_state(self): + return 'travel-to' + + @classmethod + def params(cls): + return { + 'dest': MissionParam(Waypoint, True) + } + + def steps(self): + return self.travel_steps('to', 'dest', 'done') +