from .base import Base from time import time from nullptr.util import * from dataclasses import dataclass @dataclass class InventoryItem: symbol: str units: int def __str__(self): return self.symbol + ': ' + str(self.units) class Ship(Base): cargo:dict = {} mission_state:dict = {} status:str = '' cargo_capacity:int = 0 cargo_units:int = 0 location_str = '' cooldown:int = 0 arrival:int = 0 fuel_current:int = 0 fuel_capacity:int = 0 mission:str = None mission_status:str = 'init' @classmethod def ext(self): return 'shp' def location(self): return self.store.get('Waypoint', self.location_str) def path(self): agent = self.symbol.split('-')[0] return f'{agent}/{self.symbol}.{self.ext()}' def update(self, d): self.seta('status', d, 'nav.status') self.seta('location_str', d, 'nav.waypointSymbol') self.seta('cargo_capacity', d, 'cargo.capacity') self.seta('cargo_units', d, 'cargo.units') self.seta('fuel_capacity', d, 'fuel.capacity') self.seta('fuel_current', d,'fuel.current') cargo = sg(d, 'cargo.inventory') if cargo is not None: self.load_cargo(cargo) cooldown = sg(d, 'cooldown.expiration') if cooldown: self.cooldown = parse_timestamp(cooldown) arrival = sg(d, 'nav.route.arrival') if arrival: self.arrival = parse_timestamp(arrival) def tick(self): if self.status == 'IN_TRANSIT' and self.arrival < time(): self.status = 'IN_ORBIT' def is_cooldown(self): return self.cooldown > time() def is_travelling(self): return self.status == 'IN_TRANSIT' def get_cargo(self, typ): if typ not in self.cargo: return 0 return self.cargo[typ].units def load_cargo(self, cargo): result = {} for i in cargo: symbol = must_get(i, 'symbol') units = must_get(i, 'units') result[symbol] = InventoryItem(symbol, units) self.cargo = result def deliverable_cargo(self, contract): result = [] for d in contract.deliveries: if self.get_cargo(d.trade_symbol) > 0: result.append(d.trade_symbol) return result def nondeliverable_cargo(self, contract): cargo = [c.symbol for c in self.cargo.values()] deliveries = [d.trade_symbol for d in contract.deliveries] garbage = [c for c in cargo if c not in deliveries] return garbage def update_timers(self): if self.status == 'IN_TRANSIT' and self.arrival < time(): self.status = 'IN_ORBIT' def f(self, detail=1): self.update_timers() arrival = int(self.arrival - time()) cooldown = int(self.cooldown - time()) r = self.symbol if detail > 1: r += ' ' + self.status r += f' [{self.fuel_current}/{self.fuel_capacity}]' r += ' ' + str(self.location()) if self.is_travelling(): r += f' [A: {arrival}]' if self.is_cooldown(): r += f' [C: {cooldown}]' return r