implementing api changes since 5 months ago
This commit is contained in:
		
							parent
							
								
									1ba10260c0
								
							
						
					
					
						commit
						a287897da9
					
				@ -52,6 +52,7 @@ class Analyzer:
 | 
			
		||||
    possibles = sorted(candidates, key=lambda m: m[2])
 | 
			
		||||
    possibles = possibles[:10]
 | 
			
		||||
    results = []
 | 
			
		||||
    print(len(possibles))
 | 
			
		||||
    for typ,m,d in possibles:
 | 
			
		||||
      system = m.waypoint.system
 | 
			
		||||
      p = self.find_path(origin, system)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										128
									
								
								nullptr/api.py
									
									
									
									
									
								
							
							
						
						
									
										128
									
								
								nullptr/api.py
									
									
									
									
									
								
							@ -61,6 +61,7 @@ class Api:
 | 
			
		||||
      self.last_error = 0
 | 
			
		||||
      return result['data']
 | 
			
		||||
  
 | 
			
		||||
  ######## Account #########
 | 
			
		||||
  def register(self, faction):
 | 
			
		||||
    callsign = self.agent.symbol
 | 
			
		||||
    data = {
 | 
			
		||||
@ -77,6 +78,7 @@ class Api:
 | 
			
		||||
    self.agent.update(data)
 | 
			
		||||
    return self.agent
 | 
			
		||||
  
 | 
			
		||||
  ######## Atlas #########
 | 
			
		||||
  def list_systems(self, page=1):
 | 
			
		||||
    data = self.request('get', 'systems', params={'page': page})
 | 
			
		||||
    #pprint(self.last_meta)
 | 
			
		||||
@ -87,6 +89,9 @@ class Api:
 | 
			
		||||
  
 | 
			
		||||
  def list_waypoints(self, system):
 | 
			
		||||
    data = self.request('get', f'systems/{system}/waypoints/')
 | 
			
		||||
    tp = total_pages(self.last_meta)
 | 
			
		||||
    for p in range(1, tp):
 | 
			
		||||
      data += self.request('get', f'systems/{system}/waypoints/', params={'page': p})
 | 
			
		||||
    # pprint(data)
 | 
			
		||||
    return self.store.update_list(Waypoint, data)
 | 
			
		||||
  
 | 
			
		||||
@ -100,10 +105,32 @@ class Api:
 | 
			
		||||
    symbol = str(waypoint)
 | 
			
		||||
    return self.store.update(Jumpgate, data, symbol)
 | 
			
		||||
  
 | 
			
		||||
  def shipyard(self, wp):
 | 
			
		||||
    return self.request('get', f'systems/{wp.system}/waypoints/{wp}/shipyard')
 | 
			
		||||
 | 
			
		||||
  ######## Fleet #########
 | 
			
		||||
  def list_ships(self):
 | 
			
		||||
    data = self.request('get', 'my/ships')
 | 
			
		||||
    return self.store.update_list(Ship, data)
 | 
			
		||||
  
 | 
			
		||||
  def refuel(self, ship, from_cargo=False):
 | 
			
		||||
    fuel_need = ship.fuel_capacity - ship.fuel_current
 | 
			
		||||
    fuel_avail = ship.get_cargo('FUEL') * 100
 | 
			
		||||
    units = fuel_need
 | 
			
		||||
    if from_cargo:
 | 
			
		||||
      units = min(units, fuel_avail)
 | 
			
		||||
    data = {'fromCargo': from_cargo, 'units': units }
 | 
			
		||||
    data =  self.request('post', f'my/ships/{ship}/refuel', data)
 | 
			
		||||
    if from_cargo:
 | 
			
		||||
      boxes = ceil(float(units) / 100)
 | 
			
		||||
      ship.take_cargo('FUEL', boxes)
 | 
			
		||||
    if 'fuel' in data:
 | 
			
		||||
      ship.update(data)
 | 
			
		||||
    if 'agent' in data:
 | 
			
		||||
      self.agent.update(data['agent'])
 | 
			
		||||
    return data
 | 
			
		||||
    
 | 
			
		||||
  ######## Contract #########
 | 
			
		||||
  def list_contracts(self):
 | 
			
		||||
    data = self.request('get', 'my/contracts')
 | 
			
		||||
    return self.store.update_list('Contract', data)
 | 
			
		||||
@ -114,6 +141,14 @@ class Api:
 | 
			
		||||
      contract = self.store.update('Contract', data['contract'])
 | 
			
		||||
      return contract
 | 
			
		||||
      
 | 
			
		||||
  def accept_contract(self, contract):
 | 
			
		||||
    data = self.request('post', f'my/contracts/{contract.symbol.lower()}/accept')
 | 
			
		||||
    if 'contract' in data:
 | 
			
		||||
      contract.update(data['contract'])
 | 
			
		||||
    if 'agent' in data:
 | 
			
		||||
      self.agent.update(data['agent'])
 | 
			
		||||
    return contract
 | 
			
		||||
    
 | 
			
		||||
  def deliver(self, ship, typ, contract):
 | 
			
		||||
    units = ship.get_cargo(typ)
 | 
			
		||||
    if units == 0:
 | 
			
		||||
@ -139,6 +174,7 @@ class Api:
 | 
			
		||||
      self.agent.update(data['agent'])
 | 
			
		||||
    return contract
 | 
			
		||||
  
 | 
			
		||||
  ######## Nav #########
 | 
			
		||||
  def navigate(self, ship, wp):
 | 
			
		||||
    data = {'waypointSymbol': str(wp)}
 | 
			
		||||
    response = self.request('post', f'my/ships/{ship}/navigate', data)
 | 
			
		||||
@ -154,22 +190,51 @@ class Api:
 | 
			
		||||
    ship.update(data)
 | 
			
		||||
    return data
 | 
			
		||||
  
 | 
			
		||||
  def refuel(self, ship):
 | 
			
		||||
    data =  self.request('post', f'my/ships/{ship}/refuel')
 | 
			
		||||
    if 'fuel' in data:
 | 
			
		||||
      ship.update(data)
 | 
			
		||||
    if 'agent' in data:
 | 
			
		||||
      self.agent.update(data['agent'])
 | 
			
		||||
  def flight_mode(self, ship, mode):
 | 
			
		||||
    data = {'flightMode': mode}
 | 
			
		||||
    data = self.request('patch', f'my/ships/{ship}/nav', data)
 | 
			
		||||
    return data
 | 
			
		||||
    
 | 
			
		||||
  def accept_contract(self, contract):
 | 
			
		||||
    data = self.request('post', f'my/contracts/{contract.symbol.lower()}/accept')
 | 
			
		||||
    if 'contract' in data:
 | 
			
		||||
      contract.update(data['contract'])
 | 
			
		||||
    if 'agent' in data:
 | 
			
		||||
      self.agent.update(data['agent'])
 | 
			
		||||
    return contract
 | 
			
		||||
  def jump(self, ship, waypoint):
 | 
			
		||||
    if type(waypoint) == Waypoint:
 | 
			
		||||
      waypoint = waypoint.symbol
 | 
			
		||||
    data = {
 | 
			
		||||
      "waypointSymbol": waypoint
 | 
			
		||||
    }
 | 
			
		||||
    data = self.request('post', f'my/ships/{ship}/jump', data)
 | 
			
		||||
    if 'nav' in data:
 | 
			
		||||
      ship.update(data)
 | 
			
		||||
    return ship
 | 
			
		||||
    
 | 
			
		||||
  ######## Extraction #########
 | 
			
		||||
  def siphon(self, ship):
 | 
			
		||||
    data = self.request('post', f'my/ships/{ship}/siphon')
 | 
			
		||||
    ship.update(data)
 | 
			
		||||
    return data['siphon']
 | 
			
		||||
  
 | 
			
		||||
  def extract(self, ship, survey=None):
 | 
			
		||||
    data = {}
 | 
			
		||||
    url = f'my/ships/{ship}/extract'
 | 
			
		||||
    if survey is not None:
 | 
			
		||||
      data['survey'] = survey.api_dict()
 | 
			
		||||
      url += '/survey'
 | 
			
		||||
    try:
 | 
			
		||||
      data =  self.request('post', url, data=data)
 | 
			
		||||
    except ApiError as e:
 | 
			
		||||
      if e.code in [ 4221, 4224]:
 | 
			
		||||
        survey.exhausted = True
 | 
			
		||||
      else:
 | 
			
		||||
        raise e
 | 
			
		||||
    ship.update(data)
 | 
			
		||||
    return data
 | 
			
		||||
  
 | 
			
		||||
  def survey(self, ship):
 | 
			
		||||
    data =  self.request('post', f'my/ships/{ship}/survey')
 | 
			
		||||
    ship.update(data)
 | 
			
		||||
    result = self.store.update_list('Survey', mg(data, 'surveys'))
 | 
			
		||||
    return result
 | 
			
		||||
  
 | 
			
		||||
  ######## Commerce #########
 | 
			
		||||
  def sell(self, ship, typ):
 | 
			
		||||
    units = ship.get_cargo(typ)
 | 
			
		||||
    data = {
 | 
			
		||||
@ -222,40 +287,3 @@ class Api:
 | 
			
		||||
    if 'ship' in data:
 | 
			
		||||
      ship = self.store.update('Ship', data['ship'])  
 | 
			
		||||
      return ship
 | 
			
		||||
    
 | 
			
		||||
  def jump(self, ship, system):
 | 
			
		||||
    if type(system) == System:
 | 
			
		||||
      system = system.symbol
 | 
			
		||||
    data = {
 | 
			
		||||
      "systemSymbol": system
 | 
			
		||||
    }
 | 
			
		||||
    data = self.request('post', f'my/ships/{ship}/jump', data)
 | 
			
		||||
    if 'nav' in data:
 | 
			
		||||
      ship.update(data)
 | 
			
		||||
    return ship
 | 
			
		||||
    
 | 
			
		||||
  def shipyard(self, wp):
 | 
			
		||||
    return self.request('get', f'systems/{wp.system}/waypoints/{wp}/shipyard')
 | 
			
		||||
 | 
			
		||||
  def extract(self, ship, survey=None):
 | 
			
		||||
    data = {}
 | 
			
		||||
    url = f'my/ships/{ship}/extract'
 | 
			
		||||
    if survey is not None:
 | 
			
		||||
      data['survey'] = survey.api_dict()
 | 
			
		||||
      url += '/survey'
 | 
			
		||||
    try:
 | 
			
		||||
      data =  self.request('post', url, data=data)
 | 
			
		||||
    except ApiError as e:
 | 
			
		||||
      if e.code in [ 4221, 4224]:
 | 
			
		||||
        survey.exhausted = True
 | 
			
		||||
      else:
 | 
			
		||||
        raise e
 | 
			
		||||
    ship.update(data)
 | 
			
		||||
    return data
 | 
			
		||||
  
 | 
			
		||||
  def survey(self, ship):
 | 
			
		||||
    data =  self.request('post', f'my/ships/{ship}/survey')
 | 
			
		||||
    ship.update(data)
 | 
			
		||||
    result = self.store.update_list('Survey', mg(data, 'surveys'))
 | 
			
		||||
    return result
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
@ -63,10 +63,10 @@ class AtlasBuilder:
 | 
			
		||||
      if 'UNCHARTED' in w.traits:
 | 
			
		||||
        continue
 | 
			
		||||
      if 'MARKETPLACE' in w.traits:
 | 
			
		||||
        #  print(f'marketplace at {w}')
 | 
			
		||||
        print(f'marketplace at {w}')
 | 
			
		||||
        self.sched(self.api.marketplace, w)
 | 
			
		||||
      if w.type == 'JUMP_GATE':
 | 
			
		||||
        # print(f'jumpgate at {w}')
 | 
			
		||||
        print(f'jumpgate at {w}')
 | 
			
		||||
        self.sched(self.api.jumps, w)
 | 
			
		||||
      if 'SHIPYARD' in w.traits:
 | 
			
		||||
        # todo
 | 
			
		||||
 | 
			
		||||
@ -68,8 +68,11 @@ class Commander(CommandLine):
 | 
			
		||||
    self.agent = agent
 | 
			
		||||
    api = Api(self.store, agent)
 | 
			
		||||
    self.api = api
 | 
			
		||||
    faction = input('faction: ')
 | 
			
		||||
    api.register(faction.upper().strip())
 | 
			
		||||
    faction = input('faction or token: ')
 | 
			
		||||
    if len(faction) > 50:
 | 
			
		||||
      self.agent.token = faction
 | 
			
		||||
    else:
 | 
			
		||||
      api.register(faction.upper().strip())
 | 
			
		||||
    print('=== agent:')
 | 
			
		||||
    print(agent)
 | 
			
		||||
    print('=== ships')
 | 
			
		||||
@ -226,15 +229,32 @@ class Commander(CommandLine):
 | 
			
		||||
    r = self.store.all_members(system, 'Waypoint')
 | 
			
		||||
    for w in r:
 | 
			
		||||
      traits = []
 | 
			
		||||
      if 'MARKETPLACE' in w.traits:
 | 
			
		||||
        traits.append('MARKET')
 | 
			
		||||
      if 'SHIPYARD' in w.traits:
 | 
			
		||||
        traits.append('SHIPYARD')
 | 
			
		||||
      if w.type == 'JUMP_GATE':
 | 
			
		||||
        traits.append('JUMP')
 | 
			
		||||
      if w.type == 'ASTEROID_FIELD':
 | 
			
		||||
        traits.append('ASTROIDS')
 | 
			
		||||
      print(w.symbol.split('-')[2], ', '.join(traits))
 | 
			
		||||
      if 'SHIPYARD' in w.traits:
 | 
			
		||||
        traits.append('SHIPYARD')
 | 
			
		||||
      if 'MARKETPLACE' in w.traits:
 | 
			
		||||
        traits.append('MARKET')
 | 
			
		||||
      
 | 
			
		||||
      
 | 
			
		||||
      if w.type == 'ASTEROID':
 | 
			
		||||
        if 'COMMON_METAL_DEPOSITS' in w.traits:
 | 
			
		||||
          traits.append('METAL')
 | 
			
		||||
        if 'PRECIOUS_METAL_DEPOSITS' in w.traits:
 | 
			
		||||
          traits.append('GOLD')
 | 
			
		||||
        if 'EXPLOSIVE_GASSES' in w.traits:
 | 
			
		||||
          traits.append('GAS')
 | 
			
		||||
        if 'MINERAL_DEPOSITS' in w.traits:
 | 
			
		||||
          traits.append('MINS')
 | 
			
		||||
        if 'STRIPPED' in w.traits:
 | 
			
		||||
          traits.append('STRIPPED')
 | 
			
		||||
      
 | 
			
		||||
      wname = w.symbol.split('-')[2]
 | 
			
		||||
      traits = ', '.join(traits)
 | 
			
		||||
      typ = w.type[0]
 | 
			
		||||
      if typ not in ['F','J'] and len(traits) == 0:
 | 
			
		||||
        continue
 | 
			
		||||
      print(f'{wname:4} {typ} {traits}')
 | 
			
		||||
  
 | 
			
		||||
  def do_wp(self, s=''):
 | 
			
		||||
    self.do_waypoints(s)
 | 
			
		||||
@ -243,6 +263,10 @@ class Commander(CommandLine):
 | 
			
		||||
    waypoint = self.store.get(Waypoint, waypoint_str.upper())
 | 
			
		||||
    r = self.api.marketplace(waypoint)
 | 
			
		||||
    
 | 
			
		||||
  def do_atlas(self):
 | 
			
		||||
    atlas = self.store.get(Atlas, 'ATLAS')
 | 
			
		||||
    pprint(atlas, 5)
 | 
			
		||||
    
 | 
			
		||||
  def do_jumps(self, waypoint_str=None):
 | 
			
		||||
    if waypoint_str is None:
 | 
			
		||||
      if not self.has_ship(): return
 | 
			
		||||
@ -332,15 +356,32 @@ class Commander(CommandLine):
 | 
			
		||||
    self.api.orbit(self.ship)
 | 
			
		||||
    pprint(self.ship)
 | 
			
		||||
  
 | 
			
		||||
  def do_siphon(self):
 | 
			
		||||
    if not self.has_ship(): return
 | 
			
		||||
    data = self.api.siphon(self.ship)
 | 
			
		||||
    pprint(data)
 | 
			
		||||
    
 | 
			
		||||
  def do_negotiate(self):
 | 
			
		||||
    if not self.has_ship(): return
 | 
			
		||||
    r =  self.api.negotiate(self.ship)
 | 
			
		||||
    pprint(r)
 | 
			
		||||
  
 | 
			
		||||
  def do_refuel(self):
 | 
			
		||||
  def do_token(self):
 | 
			
		||||
    print(self.agent.token)
 | 
			
		||||
  
 | 
			
		||||
  def do_speed(self, speed):
 | 
			
		||||
    if not self.has_ship(): return 
 | 
			
		||||
    r =  self.api.refuel(self.ship)
 | 
			
		||||
    pprint(self.ship)
 | 
			
		||||
    speed = speed.upper()
 | 
			
		||||
    speeds = ['DRIFT', 'STEALTH','CRUISE','BURN']
 | 
			
		||||
    if speed not in speeds:
 | 
			
		||||
      print('please choose from:', speeds)
 | 
			
		||||
    self.api.flight_mode(self.ship, speed)
 | 
			
		||||
    
 | 
			
		||||
  def do_refuel(self, source='market'):
 | 
			
		||||
    if not self.has_ship(): return
 | 
			
		||||
    from_cargo = source != 'market'
 | 
			
		||||
    r =  self.api.refuel(self.ship, from_cargo=from_cargo)
 | 
			
		||||
    pprint(r)
 | 
			
		||||
    
 | 
			
		||||
  def do_accept(self, c):
 | 
			
		||||
    contract = self.resolve('Contract', c)
 | 
			
		||||
@ -358,6 +399,7 @@ class Commander(CommandLine):
 | 
			
		||||
  
 | 
			
		||||
  def do_cargo(self):
 | 
			
		||||
    if not self.has_ship(): return
 | 
			
		||||
    print(f'== Cargo {self.ship.cargo_units}/{self.ship.cargo_capacity} ==')
 | 
			
		||||
    for c, units in self.ship.cargo.items():
 | 
			
		||||
      print(f'{units:4d} {c}')
 | 
			
		||||
      
 | 
			
		||||
@ -385,13 +427,11 @@ class Commander(CommandLine):
 | 
			
		||||
    for s in must_get(data, 'ships'):
 | 
			
		||||
      print(s['type'], s['purchasePrice'])
 | 
			
		||||
  
 | 
			
		||||
  def do_jump(self, system_str):
 | 
			
		||||
  def do_jump(self, waypoint_str):
 | 
			
		||||
    if not self.has_ship(): return
 | 
			
		||||
    if '-' not in system_str:
 | 
			
		||||
      sector = self.ship.location.system.sector.symbol
 | 
			
		||||
      system_str = f'{sector}-{system_str}'
 | 
			
		||||
    system = self.resolve('System', system_str)
 | 
			
		||||
    self.api.jump(self.ship, system)
 | 
			
		||||
    
 | 
			
		||||
    w = self.resolve('Waypoint', waypoint_str)
 | 
			
		||||
    self.api.jump(self.ship, w)
 | 
			
		||||
    pprint(self.ship)
 | 
			
		||||
    
 | 
			
		||||
  def do_purchase(self, ship_type):
 | 
			
		||||
 | 
			
		||||
@ -9,3 +9,8 @@ class Atlas(Base):
 | 
			
		||||
    self.total_pages = 0
 | 
			
		||||
    self.seen_pages = 0
 | 
			
		||||
    
 | 
			
		||||
  def f(self, detail=1):
 | 
			
		||||
    r = super().f(detail)
 | 
			
		||||
    if detail >2:
 | 
			
		||||
      r += f' {self.seen_pages}/{self.total_pages}'
 | 
			
		||||
    return r
 | 
			
		||||
 | 
			
		||||
@ -57,15 +57,16 @@ class Base:
 | 
			
		||||
        val = interp(val)
 | 
			
		||||
      setattr(self, attr, val)
 | 
			
		||||
  
 | 
			
		||||
  def setlst(self, attr, d, name, member, interp=None):
 | 
			
		||||
  def setlst(self, attr, d, name, member=None, interp=None):
 | 
			
		||||
    val = sg(d, name)
 | 
			
		||||
    if val is not None:
 | 
			
		||||
      lst = []
 | 
			
		||||
      for x in val:
 | 
			
		||||
        val = sg(x, member)
 | 
			
		||||
        if member is not None:
 | 
			
		||||
          x = sg(x, member)
 | 
			
		||||
        if interp is not None:
 | 
			
		||||
          val = interp(val)
 | 
			
		||||
        lst.append(val)
 | 
			
		||||
          x = interp(x)
 | 
			
		||||
        lst.append(x)
 | 
			
		||||
      setattr(self, attr, lst)
 | 
			
		||||
    
 | 
			
		||||
  def __setattr__(self, name, value):
 | 
			
		||||
 | 
			
		||||
@ -1,19 +1,15 @@
 | 
			
		||||
from .base import Base
 | 
			
		||||
from .system import System
 | 
			
		||||
from .waypoint import Waypoint
 | 
			
		||||
from dataclasses import field
 | 
			
		||||
 | 
			
		||||
class Jumpgate(Base):
 | 
			
		||||
  def define(self):
 | 
			
		||||
    self.range: int = 0
 | 
			
		||||
    self.faction: str = ''
 | 
			
		||||
    self.systems: list = []
 | 
			
		||||
    self.connections: list = []
 | 
			
		||||
    self.system = self.get_system()
 | 
			
		||||
  
 | 
			
		||||
  def update(self, d):
 | 
			
		||||
    getter = self.store.getter(System, create=True)
 | 
			
		||||
    self.setlst('systems', d, 'connectedSystems', 'symbol', interp=getter)
 | 
			
		||||
    self.seta('faction', d, 'factionSymbol')
 | 
			
		||||
    self.seta('range', d, 'jumpRange')
 | 
			
		||||
    getter = self.store.getter(Waypoint, create=True)
 | 
			
		||||
    self.setlst('connections', d, 'connections', interp=getter)
 | 
			
		||||
    
 | 
			
		||||
  @classmethod
 | 
			
		||||
  def ext(self):
 | 
			
		||||
@ -23,5 +19,5 @@ class Jumpgate(Base):
 | 
			
		||||
    r = self.symbol
 | 
			
		||||
    if detail > 1:
 | 
			
		||||
      r += '\n'
 | 
			
		||||
      r += '\n'.join([s.symbol for s in self.systems])
 | 
			
		||||
      r += '\n'.join([s.symbol for s in self.connections])
 | 
			
		||||
    return r
 | 
			
		||||
 | 
			
		||||
@ -55,12 +55,25 @@ class Ship(Base):
 | 
			
		||||
      return 0
 | 
			
		||||
    return self.cargo[typ]
 | 
			
		||||
  
 | 
			
		||||
  def take_cargo(self, typ, amt):
 | 
			
		||||
    if typ not in self.cargo:
 | 
			
		||||
      return
 | 
			
		||||
    if self.cargo[typ] <= amt:
 | 
			
		||||
      del self.cargo[typ]
 | 
			
		||||
    else:
 | 
			
		||||
      self.cargo[typ] -= amt
 | 
			
		||||
    
 | 
			
		||||
    self.cargo_units = sum(self.cargo.values())
 | 
			
		||||
    
 | 
			
		||||
  def load_cargo(self, cargo):
 | 
			
		||||
    result = {}
 | 
			
		||||
    total = 0
 | 
			
		||||
    for i in cargo:
 | 
			
		||||
      symbol = must_get(i, 'symbol')
 | 
			
		||||
      units = must_get(i, 'units')
 | 
			
		||||
      result[symbol] = units
 | 
			
		||||
      total += units
 | 
			
		||||
    self.cargo_units = total
 | 
			
		||||
    self.cargo = result
 | 
			
		||||
    
 | 
			
		||||
  def deliverable_cargo(self, contract):
 | 
			
		||||
 | 
			
		||||
@ -10,14 +10,17 @@ class Waypoint(Base):
 | 
			
		||||
    self.type:str = 'unknown'
 | 
			
		||||
    self.traits:list = []
 | 
			
		||||
    self.faction:str = ''
 | 
			
		||||
    self.is_under_construction:bool = False
 | 
			
		||||
    self.system = self.get_system()
 | 
			
		||||
    self.uncharted = True
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
  def update(self, d):
 | 
			
		||||
    self.seta('x', d)
 | 
			
		||||
    self.seta('y', d)
 | 
			
		||||
    self.seta('type', d)
 | 
			
		||||
    self.seta('faction', d, 'faction.symbol')
 | 
			
		||||
    self.seta('is_under_construction', d, 'isUnderConstruction')
 | 
			
		||||
    self.setlst('traits', d, 'traits', 'symbol')
 | 
			
		||||
    self.uncharted = 'UNCHARTED' in self.traits
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user