Steve Thielemann 5 lat temu
rodzic
commit
7b9a57d0ca
2 zmienionych plików z 245 dodań i 10 usunięć
  1. 244 9
      flexible.py
  2. 1 1
      tcp-proxy.py

+ 244 - 9
flexible.py

@@ -96,6 +96,7 @@ class PlayerInput(object):
         keywords:
         abort_blank : Abort if they give us blank text.
         name : Stores the input in self.keep dict.
+        digits : Only allow 0-9 to be entered.
 
         """
         log.msg("PlayerInput({0}, {1}, {2}".format(user_prompt, limit, kw))
@@ -369,6 +370,12 @@ class ScriptPort(object):
         self.r = Style.RESET_ALL
         self.nl = "\n\r"
 
+        self.this_sector = None     # Starting sector
+        self.sector1 = None         # Current Sector
+        self.sector2 = None         # Next Sector Stop
+        self.percent = 5            # Stick with the good default.
+        self.credits = 0
+
         # Activate
         self.prompt = game.buffer
         self.save = self.observer.save()
@@ -381,7 +388,6 @@ class ScriptPort(object):
             self.nl + "Script based on: Port Pair Trading v2.00" + self.r + self.nl
         )
 
-        self.sector_number = None
         self.possible_sectors = None
 
         self.state = 1
@@ -404,6 +410,7 @@ class ScriptPort(object):
         return self.defer
 
     def deactivate(self):
+        self.state = 0
         log.msg("ScriptPort.deactivate")
         assert(not self.save is None)
         self.observer.load(self.save)
@@ -422,8 +429,151 @@ class ScriptPort(object):
             if re.match(r"Command \[TL=.* \(\?=Help\)\? :", prompt):
                 self.state = 4
                 log.msg("Ok, state 4")
-                self.deactivate()
+                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?" + self.nl + Fore.CYAN)
+                    for i, p in enumerate(self.possible):
+                        self.queue_game.put(" " + str(i + 1) + " : " + str(p) + self.nl)
+                    
+                    pi = PlayerInput(self.game)
+                    def got_need1(*_):
+                        log.msg("Ok, I have:", pi.keep)
+                        if pi.keep['count'].strip() == '':
+                            self.deactivate()
+                            return
+                        self.times_left = int(pi.keep['count'])
+                        if pi.keep['choice'].strip() == '':
+                            self.deactivate()
+                            return
+                        c = int(pi.keep['choice']) -1
+                        if c < 0 or c >= len(self.possible):
+                            self.deactivate()
+                            return
+
+                        self.sector2 = self.possible[int(pi.keep['choice']) -1]
+                        # self.queue_game.put(pformat(pi.keep).replace("\n", "\n\r"))                        
+                        self.state = 5
+                        self.trade()
+
+                    d = pi.prompt("Choose -=>", 5, name='choice', digits=True)
+                    d.addCallback(lambda ignore: pi.prompt("Times to execute script:", 5, name='count', digits=True))
+                    d.addCallback(got_need1)
+                else:
+                    # We already have our target port, so...
+                    pi = PlayerInput(self.game)
+                    def got_need2(*_):
+                        if pi.keep['count'].strip() == '':
+                            self.deactivate()
+                            return
+                        self.times_left = int(pi.keep['count'])
+                        log.msg("Ok, I have:", pi.keep)
+                        self.queue_game.put(pformat(pi.keep).replace("\n", "\n\r"))
+                        self.state = 5
+                        self.trade()
+
+                    self.queue_game.put(self.r + self.nl)
+                    d = pi.prompt("Times to execute script", 5, name='count')    
+                    d.addCallback(got_need2)
         
+        elif self.state == 7:
+            if re.match(r"Command \[TL=.* \(\?=Help\)\? :", prompt):
+                # Done
+                if self.this_sector == self.sector1:
+                    self.this_sector = self.sector2
+                    self.queue_player.put("{0}\r".format(self.sector2))
+                    self.state = 10
+                else:
+                    self.times_left -= 1
+                    if self.times_left <= 0:
+                        # Ok, exit out
+                        self.deactivate()
+                        return
+                    self.this_sector = self.sector1
+                    self.queue_player.put("{0}\r".format(self.sector1))
+                    self.state = 10
+
+        elif self.state == 8:
+            # What are we trading
+            if "How many holds of" in prompt:
+                parts = prompt.split()
+                trade_type = parts[4]
+
+                if trade_type == 'Fuel':
+                    if (self.tpc in (5,7)) and (self.opc in (2,3,4,8)):
+                        # Can buy equipment - fuel ore is worthless.
+                        self.queue_player.put("0\r")
+                        return
+                    if (self.tpc in(4,7)) and (self.opc in (1,3,5,8)):
+                        # Can buy organics - fuel ore is worthless.
+                        self.queue_player.put("0\r")
+                        return
+                    if (self.tpc in (4,7,3,5)) and (self.opc in (3,4,5,7)):
+                        # No point in buying fuel ore if it can't be sold.
+                        self.queue_player.put("0\r")
+                        return
+                elif trade_type == 'Organics':
+                    if (self.tpc in (6,7)) and (self.opc in (2,3,4,8)):
+                        # Can buy equipment - organics is worthless.
+                        self.queue_player.put("0\r")
+                        return
+                    if (self.tpc in (2,4,6,7)) and (self.opc in (2,4,6,7)):
+                        # No point in buying organics if it can't be sold.
+                        self.queue_player.put("0\r")
+                        return
+                elif trade_type == 'Equipment':
+                    if (self.opc in (1,5,6,7)):
+                        # No point in buying equipment if it can't be sold.
+                        self.queue_player.put("0\r")
+                        return
+
+                self.queue_player.put("\r")
+            elif re.match(r"Command \[TL=.* \(\?=Help\)\? :", prompt):
+                # Done
+                if self.this_sector == self.sector1:
+                    self.this_sector = self.sector2
+                    self.queue_player.put("{0}\r".format(self.sector2))
+                    self.state = 10
+                else:
+                    self.times_left -= 1
+                    if self.times_left <= 0:
+                        # Ok, exit out
+                        self.deactivate()
+                        return
+                    self.this_sector = self.sector1
+                    self.queue_player.put("{0}\r".format(self.sector1))
+                    self.state = 10
+
+
+
+        
+    def trade(self, *_):
+        # state 5
+        log.msg("trade!")
+        self.queue_player.put("pt")   # Port Trade
+
+        self.this_port = self.game.portdata[self.this_sector]
+        if self.this_sector == self.sector1:
+            self.other_port = self.game.portdata[self.sector2]
+        else:
+            self.other_port = self.game.portdata[self.sector1]
+
+        # Ok, perform some calculations
+        self.tpc = self.this_port['class']
+        self.opc = self.other_port['class']
+
+
+        # [ Items     Status  Trading % of max OnBoard]
+        # [ -----     ------  ------- -------- -------]
+        # [Fuel Ore   Selling   2573     93%       0]
+        # [Organics   Buying    2960    100%       0]
+        # [Equipment  Buying    1958     86%       0]
+        # []
+        # []
+        # [You have 1,000 credits and 20 empty cargo holds.]
+        # []
+        # [We are selling up to 2573.  You have 0 in your holds.]
+        # [How many holds of Fuel Ore do you want to buy [20]? 0]        
+        pass
 
     def game_line(self, line: str):
         if self.state == 1:
@@ -431,9 +581,9 @@ class ScriptPort(object):
             if line.startswith("Sector  :"):
                 # We have starting sector information
                 parts = re.split("\s+", line)
-                self.sector_number = int(parts[2])
+                self.this_sector = int(parts[2])
                 # These will be the ones swapped around as we trade back and forth.
-                self.sector1 = self.sector_number
+                self.sector1 = self.this_sector
             elif line.startswith("Warps to Sector(s) : "):
                 # Warps to Sector(s) :  397 - (562) - (639)
                 _, _, warps = line.partition(':')
@@ -448,21 +598,38 @@ class ScriptPort(object):
                 self.state = 3
                 # Check to see if we have information on any possible ports
                 if hasattr(self.game, 'portdata'):
-                    if not self.sector_number in self.game.portdata:
-                        log.msg("Current sector {0} not in portdata.".format(self.sector_number))
+                    if not self.this_sector in self.game.portdata:
+                        self.state = 0
+                        log.msg("Current sector {0} not in portdata.".format(self.this_sector))
                         self.queue_game.put(self.r + self.nl + "I can't find the current sector in the portdata." + self.nl)
                         self.deactivate()
                         return
-                    possible = [ x for x in self.warps if x in self.game.portdata]
+                    else:
+                        # Ok, we are in the portdata
+                        def port_burnt(port):
+                            if port['equ']['pct'] <= 20 or port['fuel']['pct'] <= 20 or port['org']['pct'] <= 20:
+                                return True
+                            return False
+
+                        pd = self.game.portdata[self.this_sector]
+                        if 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()
+                            return
+
+                    # possible = [ x for x in self.warps if x in self.game.portdata ]
+                    possible = [ x for x in self.warps if x in self.game.portdata and not port_burnt(self.game.portdata[x]) ]
                     log.msg("Possible:", possible)
                     self.possible = possible
                     if len(possible) == 0:
-                        self.queue_game.put(self.r + self.nl + "I don't see any ports in [{0}].".format(self.warps) + self.nl)
+                        self.state = 0
+                        self.queue_game.put(self.r + self.nl + "I don't see any (not burnt) ports in [{0}].".format(self.warps) + self.nl)
                         self.deactivate()
                         return
                     elif len(possible) == 1:
                         # Ok! there's only one!
-                        self.sector1 = possible[0]
+                        self.sector2 = possible[0]
                     
                     # Display possible ports:
                     # spos = [ str(x) for x in possible]    
@@ -470,10 +637,78 @@ class ScriptPort(object):
                     # At state 3, we only get a prompt.
                     return
                 else:
+                    self.state = 0
                     log.msg("We don't have any portdata!")
                     self.queue_game.put(self.r + self.nl + "I have no portdata.  Please run CIM Port Report." + self.nl)
                     self.deactivate()
                     return
+        elif self.state == 5:
+            if "-----" in line:
+                self.state = 6
+        elif self.state == 6:
+            if "We are buying up to" in line:
+                # Sell
+                self.state = 7
+                self.queue_player.put("\r")
+                self.sell_perc = 100 + self.percent                
+            if "We are selling up to" in line:
+                # Buy
+                self.state = 8
+                self.sell_perc = 100 - self.percent     
+            if "You don't have anything they want" in line:
+                # Neither!  DRAT!
+                self.deactivate()
+                return
+            if "We're not interested." in line:
+                log.msg("Try, try again.  :(")
+                self.state = 5
+                self.trade()
+
+        elif self.state == 7:
+            # Haggle Sell
+            if "We'll buy them for" in line or "Our final offer" in line:
+                if "Our final offer" in line:
+                    self.sell_perc -= 1
+                parts = line.replace(',', '').split()
+                start_price = int(parts[4])
+                price = start_price * self.sell_perc // 100
+                log.msg("start: {0} % {1} price {2}".format(start_price, self.sell_perc, price))
+                self.sell_perc -= 1
+                self.queue_player.put("{0}\r".format(price))
+            if "We are selling up to" in line:
+                # Buy
+                self.state = 8
+                self.sell_perc = 100 - self.percent      
+            if line.startswith("You have ") and 'credits and' in line:
+                parts = line.replace(',', '').split()
+                credits = int(parts[2])
+                if self.credits == 0:
+                    self.credits = credits
+                else:
+                    if credits <= self.credits:
+                        log.msg("We don't appear to be making any money here {0}.".format(credits))
+                        self.deactivate()
+                        return
+
+        elif self.state == 8:
+            # Haggle Buy
+            if "We'll sell them for" in line or "Our final offer" in line:
+                if "Our final offer" in line:
+                    self.sell_perc += 1
+                parts = line.replace(',', '').split()
+                start_price = int(parts[4])
+                price = start_price * self.sell_perc // 100
+                log.msg("start: {0} % {1} price {2}".format(start_price, self.sell_perc, price))                
+                self.sell_perc += 1
+                self.queue_player.put("{0}\r".format(price))
+
+        elif self.state == 10:
+            if "Sector  : " in line:
+                # Trade
+                self.state = 5
+                reactor.callLater(0, self.trade, 0)
+                # self.trade()
+
         # elif self.state == 3:
         #     log.msg("At state 3 [{0}]".format(line))
         #     self.queue_game.put("At state 3.")

+ 1 - 1
tcp-proxy.py

@@ -307,7 +307,7 @@ class Player(protocol.Protocol):
             elif type(chunk) == str:
                 self.transport.write(chunk.encode())
             else:
-                log.err("gameDataReceived: type (%s) given!", type(chunk))
+                log.err("gameDataReceived: type (%s) given!".format(type(chunk)))
                 self.transport.write(chunk)
             self.setGameReceived()