| 
					
				 | 
			
			
				@@ -9,6 +9,29 @@ from twisted.internet.defer import gatherResults 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from itertools import cycle 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import pendulum 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from pprint import pformat 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+from galaxy import GameData, PORT_CLASSES, CLASSES_PORT 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class SpinningCursor(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    """ Spinner class, that handles every so many clicks  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    s = SpinningCursor(5)  # every 5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for x in range(10): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if s.click(): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            print(s.cycle()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def __init__(self, every=10): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.itercycle = cycle(["/", "-", "\\", "|"]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.count = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.every = every 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def reset(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.itercycle = cycle(["/", "-", "\\", "|"]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.count = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def click(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.count += 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return self.count % self.every == 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def cycle(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return next(self.itercycle) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 def merge(color_string): 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -134,7 +157,7 @@ class PlayerInput(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def get_input(self, chunk): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """ Data from player (in bytes) """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        chunk = chunk.decode("utf-8", "ignore") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        chunk = chunk.decode("latin-1", "ignore") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         for ch in chunk: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if ch == "\b": 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -197,17 +220,6 @@ class PlayerInput(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return line 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-PORT_CLASSES = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    1: "BBS", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    2: "BSB", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    3: "SBB", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    4: "SSB", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    5: "SBS", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    6: "BSS", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    7: "SSS", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    8: "BBB", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-CLASSES_PORT = {v: k for k, v in PORT_CLASSES.items()} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import re 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # The CIMWarpReport -- is only needed if the json file gets damaged in some way. 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -239,13 +251,13 @@ class CIMWarpReport(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.queue_player.put("^")  # Activate CIM 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.state = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # self.warpdata = {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        self.warpcycle = cycle(["/", "-", "\\", "|"]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.warpcycle = SpinningCursor()  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def game_prompt(self, prompt): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if prompt == ": ": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if self.state == 1: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 # Ok, then we're ready to request the port report 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                self.warpcycle = cycle(["/", "-", "\\", "|"]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.warpcycle.reset() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 self.queue_player.put("I") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 self.state = 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             elif self.state == 2: 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -275,8 +287,8 @@ class CIMWarpReport(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # This should be the CIM Report Data -- parse it 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if self.warpcycle: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if len(self.game.gamedata.warps) % 10 == 0: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                self.queue_game.put("\b" + next(self.warpcycle)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if self.warpcycle.click(): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.queue_game.put("\b" + self.warpcycle.cycle()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         work = line.strip() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         parts = re.split(r"(?<=\d)\s", work) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -296,7 +308,7 @@ class CIMWarpReport(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def player(self, chunk): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """ Data from player (in bytes). """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        chunk = chunk.decode("utf-8", "ignore") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        chunk = chunk.decode("latin-1", "ignore") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         key = chunk.upper() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         log.msg("CIMWarpReport.player({0}) : I AM stopping...".format(key)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -367,13 +379,13 @@ class CIMPortReport(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.queue_player.put("^")  # Activate CIM 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.state = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # self.portdata = {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        self.portcycle = cycle(["/", "-", "\\", "|"]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.portcycle = SpinningCursor() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def game_prompt(self, prompt): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if prompt == ": ": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if self.state == 1: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 # Ok, then we're ready to request the port report 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                self.portcycle = cycle(["/", "-", "\\", "|"]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.portcycle.reset() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 self.queue_player.put("R") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 self.state = 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             elif self.state == 2: 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -393,7 +405,7 @@ class CIMPortReport(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     self.defer.callback(self.game.gamedata.ports) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     self.defer = None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    def game_line(self, line): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def game_line(self, line: str): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if line == "" or line == ": ": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if line == ": ENDINTERROG": 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -401,8 +413,8 @@ class CIMPortReport(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # This should be the CIM Report Data -- parse it 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if self.portcycle: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if len(self.game.gamedata.ports) % 10 == 0: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                self.queue_game.put("\b" + next(self.portcycle)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if self.portcycle.click(): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.queue_game.put("\b" + self.portcycle.cycle()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         work = line.replace("%", "") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -451,7 +463,7 @@ class CIMPortReport(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def player(self, chunk): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """ Data from player (in bytes). """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        chunk = chunk.decode("utf-8", "ignore") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        chunk = chunk.decode("latin-1", "ignore") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         key = chunk.upper() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         log.msg("CIMPortReport.player({0}) : I AM stopping...".format(key)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -474,55 +486,6 @@ class CIMPortReport(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             self.observer.load(self.save) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-def port_burnt(port): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    """ Is this port burned out? """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if all( x in port for x in ['fuel', 'org', 'equ']): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if all( 'pct' in port[x] for x in ['fuel', 'org', 'equ']): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if port['equ']['pct'] <= 20 or port['fuel']['pct'] <= 20 or port['org']['pct'] <= 20: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                return True 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return False 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    # Since we don't have any port information, hope for the best, assume it isn't burnt. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return False 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-def flip(port): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return port.replace('S', 'W').replace('B', 'S').replace('W', 'B') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-def port_trading(port1, port2): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    """ Are there possible trades at these ports? """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if port1 == port2: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return False 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    p1 = [ c for c in port1] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    p2 = [ c for c in port2] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    # Any that are the same?  Remove them. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    rem = False 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for i in range(3): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if p1[i] == p2[i]: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            p1[i] = 'X' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            p2[i] = 'X' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            rem = True 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if rem: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        j1 = "".join(p1).replace('X', '') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        j2 = "".join(p2).replace('X', '') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if j1 == 'BS' and j2 == 'SB': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return True 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if j1 == 'SB' and j2 == 'BS': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return True 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    # Matching 2 of them. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    rport1 = flip(port1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    c = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    match = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for i in range(3): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if rport1[i] == port2[i]: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            match.append(port2[i]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            c += 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if c > 1: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        f = flip(match.pop(0)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if f in match: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return True 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return False 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return False 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class ScriptPort(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     """ Performs the Port script.  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -607,10 +570,10 @@ class ScriptPort(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if self.sector2 is None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     # Ok, we need to prompt for this. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     self.queue_game.put(self.r + self.nl +  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        "Which sector to trade with? {0}".format(port_show_part(self.this_sector, self.game.gamedata.ports[self.this_sector])) + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        "Which sector to trade with? {0}".format(GameData.port_show_part(self.this_sector, self.game.gamedata.ports[self.this_sector])) + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         self.nl + Fore.CYAN) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     for i, p in enumerate(self.possible): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        self.queue_game.put(" " + str(i + 1) + " : " + port_show_part(p, self.game.gamedata.ports[p]) + self.nl) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        self.queue_game.put(" " + str(i + 1) + " : " + GameData.port_show_part(p, self.game.gamedata.ports[p]) + self.nl) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                      
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     pi = PlayerInput(self.game) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     def got_need1(*_): 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -645,10 +608,8 @@ class ScriptPort(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     self.queue_game.put(self.r + self.nl + "Trading {0}".format( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        port_show(self.this_sector,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            self.game.gamedata.ports[self.this_sector], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            self.sector2,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            self.game.gamedata.ports[self.sector2]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        self.game.gamedata.port_trade_show(self.this_sector, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        self.sector2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     )) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     # The code is smart enough now, that this can't happen.  :(   Drat! 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -859,7 +820,7 @@ class ScriptPort(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         # Ok, we are in the portdata 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         pd = self.game.gamedata.ports[self.this_sector] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if port_burnt(pd): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if GameData.port_burnt(pd): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             log.msg("Current sector {0} port is burnt (<= 20%).".format(self.this_sector)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             self.queue_game.put(self.r + self.nl + "Current sector port is burnt out. <= 20%." + self.nl) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             self.deactivate() 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -882,7 +843,7 @@ class ScriptPort(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         self.deactivate() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    possible = [ x for x in possible if not port_burnt(self.game.gamedata.ports[x]) ] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    possible = [ x for x in possible if not GameData.port_burnt(self.game.gamedata.ports[x]) ] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     log.msg("Possible:", possible) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     if len(possible) == 0: 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -891,7 +852,7 @@ class ScriptPort(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         self.deactivate() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    possible = [ x for x in possible if port_trading(self.game.gamedata.ports[self.this_sector]['port'], self.game.gamedata.ports[x]['port'])] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    possible = [ x for x in possible if GameData.port_trading(self.game.gamedata.ports[self.this_sector]['port'], self.game.gamedata.ports[x]['port'])] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     self.possible = possible 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     if len(possible) == 0: 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -975,8 +936,13 @@ class ScriptPort(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 self.state = 5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 self.trade()     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if "WHAT?!@!? you must be crazy!" in line: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                log.msg("fix offer") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 self.fix_offer = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if "So, you think I'm as stupid as you look?" in line: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                log.msg("fix offer")                 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.fix_offer = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if "Quit playing around, you're wasting my time!" in line: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                log.msg("fix offer")                 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 self.fix_offer = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         elif self.state == 8: 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1008,19 +974,6 @@ class ScriptPort(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         #     self.deactivate() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         #     return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-def port_pct(port): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    # Make sure these exist in the port data given. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if all( x in port for x in ['fuel', 'org', 'equ']): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return "{0:3},{1:3},{2:3}%".format( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            port['fuel']['pct'], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            port['org']['pct'], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            port['equ']['pct']) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return "---,---,---%" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class ScriptExplore(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     """ Script Explore v1.00 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         By: David Thielemann 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1202,16 +1155,265 @@ class ScriptExplore(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-def port_show_part(sector, sector_port): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return "{0:5} ({1}) {2}".format(sector, sector_port['port'], port_pct(sector_port)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class ScriptSpace(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    """ Space Exploration script.  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Send "SD", verify paths are clear. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Find nearest unknown.  Sector + CR. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Save "shortest path from to" information. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    At 'Engage the Autopilot', Send "S" (Single Step) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    At '[Stop in this sector', Send "SD", verify path is clear. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Send "SH" (glean sector/port information along the way.) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Send "N" (Next)! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Send "SD" / Verify clear. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Send "SH" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Repeat for Next closest. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def __init__(self, game): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.game = game 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.queue_game = game.queue_game 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.queue_player = game.queue_player 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.observer = game.observer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.r = Style.RESET_ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.nl = "\n\r" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.this_sector = None     # Starting sector 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.target_sector = None   # Sector going to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.path = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.times_left = 0     # How many times to look for target 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.density = dict()   # Results of density scan.  (Just the numbers) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        # Activate 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.prompt = game.buffer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.save = self.observer.save() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.observer.connect('player', self.player) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.observer.connect("prompt", self.game_prompt) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.observer.connect("game-line", self.game_line) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.defer = None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.queue_game.put( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.nl + "Bugz (like space), is big." + self.r + self.nl 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.state = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.queue_player.put("SD") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        # Get current density scan + also get the current sector. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        # [Command [TL=00:00:00]:[XXXX] (?=Help)? : D] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def whenDone(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.defer = defer.Deferred() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        # Call this to chain something after we exit. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return self.defer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def deactivate(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.state = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        log.msg("ScriptPort.deactivate ({0})".format(self.times_left)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert(not self.save is None) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.observer.load(self.save) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.save = None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if self.defer: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.defer.callback('done') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.defer = None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def player(self, chunk: bytes): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        # If we receive anything -- ABORT! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.deactivate() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def unknown_search(self, starting_sector): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        seen = set() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        possible = set() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        possible.add(int(starting_sector)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        done = False 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        while not done: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            next_possible = set() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for s in possible: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                p = self.game.gamedata.get_warps(s) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if p is not None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    for pos in p: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if pos not in seen: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            next_possible.add(pos) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    log.msg("unknown found:", s) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    self.unknown = s 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    done = True 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    break 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                seen.add(s) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if self.unknown is None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                log.msg("possible:", next_possible) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                possible = next_possible 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                yield 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def find_unknown(self, starting_sector): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        log.msg("find_unknown( {0})".format(starting_sector)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        d = defer.Deferred() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        # Process things 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.unknown = None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        c = coiterate(self.unknown_search(starting_sector)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        c.addCallback(lambda unknown: d.callback(self.unknown)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return d 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def show_unknown(self, sector): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if sector is None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.deactivate() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        log.msg("Travel to {0}...".format(sector)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.queue_player.put("{0}\r".format(sector)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def game_prompt(self, prompt: str): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        log.msg("{0} : {1}".format(self.state, prompt)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if self.state == 3: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if re.match(r"Command \[TL=.* \(\?=Help\)\? :", prompt): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                # this_sector code isn't working -- so!  Get sector from prompt 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.state = 4 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                _, _, sector = prompt.partition(']:[') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                sector, _, _ = sector.partition(']') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.this_sector = int(sector) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                # Ok, we're done with Density Scan, and we're back at the command prompt 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                log.msg("Go find the nearest unknown...") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                d = self.find_unknown(sector) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                d.addCallback(self.show_unknown) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif self.state == 6: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            # Engage the autopilot? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if prompt.startswith('Engage the Autopilot? (Y/N/Single step/Express) [Y]'): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.state = 7 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                sector = self.path.pop(0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if sector in self.density: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if self.density[sector] in (0, 100): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        # Ok, looks safe! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        self.queue_player.put("S") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        self.this_sector = sector 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        log.msg("FATAL: Density for {0} is {1}".format(sector, self.density[sector])) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        self.deactivate() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    log.msg("{0} not in density scan? (how's that possible?)".format(sector))                 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    self.deactivate() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif self.state == 7: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            # Ok, we're in a new sector (single stepping through space) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            # update density scan 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if prompt.startswith('Stop in this sector (Y,N,E,I,R,S,D,P,?) (?=Help) [N] ?'): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.queue_player.put("SD")                 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.state = 8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif self.state == 10: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            # Because we're here 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if prompt.startswith('Stop in this sector (Y,N,E,I,R,S,D,P,?) (?=Help) [N] ?'): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.queue_player.put("SH")                 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.state = 11 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif self.state == 11: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if prompt.startswith('Stop in this sector (Y,N,E,I,R,S,D,P,?) (?=Help) [N] ?'): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                # Ok, is the density scan clear? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                sector = self.path.pop(0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if sector in self.density: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if self.density[sector] in (0, 100): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        # Ok, looks safe 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        self.queue_player.put("N") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        self.state = 7 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        self.this_sector = sector 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        log.msg("FATAL: Density for {0} is {1}".format(sector, self.density[sector])) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        self.deactivate() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    log.msg("{0} not in density scane? (how's that possible...)".format(sector)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    self.deactivate() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def next_unknown(self, sector): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        log.msg("Unknown is :", sector) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.deactivate() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def game_line(self, line: str): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        log.msg("line {0} : {1}".format(self.state, line)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if line.startswith('Sector  : '): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            work = line.strip() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            parts = re.split(r"\s+", work) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.this_sector = int(parts[2]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            log.msg("game_line sector", self.this_sector) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif line.startswith("Command [TL=]"): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            # Ok, get the current sector from this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            _, _, sector = line.partition("]:[") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sector, _, _ = sector.partition("]") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.this_sector = int(sector) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            log.msg("current sector: {0}".format(self.this_sector)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif line.startswith('Warps to Sector(s) :'): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            # Warps to Sector(s) :  5468 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            _, _, work = line.partition(':') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            work = work.strip().replace('(', '').replace(')', '').replace(' - ', ' ') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            parts = [ int(x) for x in work.split(' ')] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.path = list(parts) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if self.state in (1, 8): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if 'Relative Density Scan' in line: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                # Start Density Scan 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.state += 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.density = {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif self.state in (2, 9): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if line == '': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                # End of Density Scan 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.state += 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                log.msg("Density: {0}".format(self.density)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                # self.deactivate()             
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            elif line.startswith('Sector'): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                # Parse Density Scan values 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                work = line.replace('(', '').replace(')', '').replace(':', '').replace('%', '').replace(',', '') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                parts = re.split(r'\s+', work) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                log.msg("Sector", parts) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                sector = int(parts[1]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.density[sector] = int(parts[3]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if parts[7] != '0': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    log.msg("NavHaz {0} : {1}".format(parts[7], work)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    self.density[sector] += 99 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if parts[9] != 'No': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    log.msg("Anom {0} : {1}".format(parts[9], work)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    self.density[sector] += 990 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif self.state == 4: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            # Looking for shortest path message / warp info 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            # Or possibly, "We're here!" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if line.startswith('Sector  :') and str(self.unknown) in line: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                # Ok, I'd guess that we're already there! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                # Try it again! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.queue_player.put("SD") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.state = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if line.startswith('The shortest path'): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.state = 5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif self.state == 5: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            # This is the warps line 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            # Can this be multiple lines? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if line == "": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.state = 6 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                work = line.replace("(", "").replace(")", "").replace(">", "").strip() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.path = [int(x) for x in work.split()] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                log.msg("Path:", self.path) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                # Verify 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                current = self.path.pop(0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if current != self.this_sector: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    log.msg("Failed: {0} != {1}".format(current, self.this_sector)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    self.deactivate() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif self.state == 7: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if self.unknown == self.this_sector: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                # We have arrived! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                log.msg("We're here!") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                self.deactivate() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-def port_show(sector, sector_port, warp, warp_port): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    sector_pct = port_pct(sector_port) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    warp_pct = port_pct(warp_port) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return "{0} -=- {1}".format( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        port_show_part(sector, sector_port), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        port_show_part(warp, warp_port) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class ProxyMenu(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     """ Display ProxyMenu  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1318,9 +1520,10 @@ class ProxyMenu(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ok_trades = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         best_trades = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for sector, pd in self.game.gamedata.ports.items(): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if not port_burnt(pd): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        # for sector, pd in self.game.gamedata.ports.items(): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for sector in sorted(self.game.gamedata.ports.keys()): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            pd = self.game.gamedata.ports[sector] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if not GameData.port_burnt(pd): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 pc = pd['class'] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 # Ok, let's look into it. 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1333,7 +1536,7 @@ class ProxyMenu(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     # (We can get back from it) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     if w in self.game.gamedata.warps and sector in self.game.gamedata.warps[w]: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         # Ok, we can get there -- and get back! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if w > sector and w in self.game.gamedata.ports and not port_burnt(self.game.gamedata.ports[w]): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if w > sector and w in self.game.gamedata.ports and not GameData.port_burnt(self.game.gamedata.ports[w]): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             # it is > and has a port. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             wd = self.game.gamedata.ports[w] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             wc = wd['class'] 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1348,14 +1551,14 @@ class ProxyMenu(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             # 8: "BBB", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             if pc in (1,5) and wc in (2,4): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                best_trades.append(port_show(sector, pd, w, wd)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                best_trades.append(self.game.gamedata.port_trade_show(sector, w)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                 # best_trades.append( "{0:5} -=- {1:5}".format(sector, w)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             elif pc in (2,4) and wc in (1,5): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                best_trades.append(port_show(sector, pd, w, wd)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                best_trades.append(self.game.gamedata.port_trade_show(sector, w)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                 # best_trades.append( "{0:5} -=- {1:5}".format(sector, w)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            elif port_trading(pd['port'], self.game.gamedata.ports[w]['port']): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            elif GameData.port_trading(pd['port'], self.game.gamedata.ports[w]['port']): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                 # ok_trades.append( "{0:5} -=- {1:5}".format(sector,w)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                ok_trades.append(port_show(sector, pd, w, wd)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                ok_trades.append(self.game.gamedata.port_trade_show(sector, w)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             yield 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.trade_report.append("Best Trades: (org/equ)") 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1373,7 +1576,7 @@ class ProxyMenu(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def player(self, chunk: bytes): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """ Data from player (in bytes). """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        chunk = chunk.decode("utf-8", "ignore") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        chunk = chunk.decode("latin-1", "ignore") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         key = chunk.upper() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         log.msg("ProxyMenu.player({0})".format(key)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1519,13 +1722,13 @@ class ProxyMenu(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         menu_item("1", "Ports (Trades between two sectors)") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         menu_item("2", "Explore (Strange new sectors)") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        menu_item("3", "TODO") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        menu_item("3", "Space... the final frontier...") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         menu_item("X", "eXit") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.queue_game.put("   " + c1 + "-=>" + self.r + " ") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def scripts_player(self, chunk: bytes): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """ Data from player (in bytes). """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        chunk = chunk.decode("utf-8", "ignore") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        chunk = chunk.decode("latin-1", "ignore") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         key = chunk.upper() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				          
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if key == '1': 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1538,13 +1741,18 @@ class ProxyMenu(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             d.addCallback(self.deactivate_scripts_menu) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             d.addErrback(self.deactivate_scripts_menu) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if key == '2': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif key == '2': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             self.queue_game.put(self.c + key + self.r + self.nl) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            # Activate this magical event here 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             explore = ScriptExplore(self.game) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             d = explore.whenDone() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            # d.addCallback(self.scripts_menu) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            # d.addErrback(self.scripts_menu) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            d.addCallback(self.deactivate_scripts_menu) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            d.addErrback(self.deactivate_scripts_menu) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif key == '3': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.queue_game.put(self.c + key + self.r + self.nl) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            space = ScriptSpace(self.game) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            d = space.whenDone() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             d.addCallback(self.deactivate_scripts_menu) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             d.addErrback(self.deactivate_scripts_menu) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return 
			 |