Просмотр исходного кода

TradeScript detects burnt ports.

We seem to be trading at a pretty good rate.  We tend to
get 2 experience for every trade once we get going.

Fixed issue where when trading (O&E) it could also trade fuel.
We remove fuel from the trades so we get the best.
Steve Thielemann 3 лет назад
Родитель
Сommit
dae1e5efc2
4 измененных файлов с 183 добавлено и 39 удалено
  1. 40 2
      director.cpp
  2. 1 1
      galaxy.cpp
  3. 132 29
      scripts.cpp
  4. 10 7
      scripts.h

+ 40 - 2
director.cpp

@@ -7,6 +7,7 @@
 #include "logging.h"
 #include "scripts.h"
 #include "utils.h"
+#include <cctype>
 
 Director::Director() {
   BUGZ_LOG(warning) << "Director::Director()";
@@ -147,11 +148,11 @@ void Director::server_line(const std::string &line,
       if (!galaxy.config["display_lines"]) {
         galaxy.config["display_lines"] = 20;
       }
-      galaxy.meta["help"]["display_lines"] = "Number of lines to display";
+      galaxy.meta["help"]["display_lines"] = "Number of report lines to display";
       if (!galaxy.config["burnt_percent"]) {
         galaxy.config["burnt_percent"] = 40;
       }
-      galaxy.meta["help"]["burnt_percent"] = "Ignore ports below this %";
+      galaxy.meta["help"]["burnt_percent"] = "Ignore ports below this percent";
     }
     // not needed (handled by above Game Server check).
     if (ch == 'Q') {
@@ -202,8 +203,13 @@ void Director::server_line(const std::string &line,
     SL: []
     */
 
+    if (line == "<Port>") {
+      SL_parser = SF_portline;
+    }
+    /*
     if (startswith(line, " Items     Status  Trading % of max OnBoard"))
       SL_parser = SF_portline;
+    */
     if (startswith(line, "Sector  : ")) SL_parser = SF_sectorline;
     if (line == ": ") SL_parser = SF_cimline;
     if (line == "<Info>") SL_parser = SF_infoline;
@@ -791,10 +797,15 @@ void Director::SL_sectorline(const std::string &line) {
 }
 
 void Director::SL_portline(const std::string &line) {
+  /*
+  We take blank lines because we start at <Port>.
+  Otherwise, we trigger on computer port requests.
+
   if (line.empty()) {
     SL_parser = nullptr;
     return;
   }
+  */
   /*
   SL: [ Items     Status  Trading % of max OnBoard]
   SL: [ -----     ------  ------- -------- -------]
@@ -816,12 +827,39 @@ void Director::SL_portline(const std::string &line) {
     std::string work = line;
     replace(work, "Fuel Ore", "Fuel");
     auto parts = split(work);
+    
+    if (parts[0] == "Items")
+      return;
+    
+    char c = tolower(parts[0][0]);
+    int pos;
+    char foe[4] = "foe";
+
+    for( pos = 0; pos < 3; ++pos) {
+      if (c == foe[pos])
+        break;
+    }
+    int amount = stoi(parts[2]);
+    int percent = stoi(parts[3]);
+
+    // update port
+    auto port = galaxy.ports.find(current_sector);
+    if (port != galaxy.ports.end()) {
+      port->second.amount[pos] = amount;
+      port->second.percent[pos] = percent;
+    }
+
     /*
     BUGZ_LOG(fatal) << "portline split:";
     for (auto const p : parts) {
       BUGZ_LOG(fatal) << p;
     }
     */
+
+    // Here's the end:  
+    if (parts[0] == "Equipment") 
+      SL_parser = nullptr;
+    
     // BUGZ_LOG(fatal) << "portline split : [" << parts << "]";
   }
 }

+ 1 - 1
galaxy.cpp

@@ -475,7 +475,7 @@ std::vector<port_pair_type> Galaxy::find_trades(sector_type sector,
     
     // calculate trade type
     // int t = trade_type(port->second.type, possible_port->second.type);
-    BUGZ_LOG(trace) << "find_trades: Port " << sector << "," << port->second.type << " " << s << possible_port->second.type;
+    BUGZ_LOG(trace) << "find_trades: Port " << sector << "," << (int)port->second.type << " " << s << (int)possible_port->second.type;
     trade_type_result ttr =
         trade_type_info(port->second.type, possible_port->second.type);
     if ((ttr.type == 0) || (ttr.type == 4)) continue;

+ 132 - 29
scripts.cpp

@@ -4,6 +4,7 @@
 
 ScriptTrader::ScriptTrader(Director &d) : Dispatch(d) {
   BUGZ_LOG(fatal) << "ScriptTrader()";
+  state = 0;
 };
 
 ScriptTrader::~ScriptTrader() { BUGZ_LOG(fatal) << "~ScriptTrader()"; }
@@ -20,11 +21,27 @@ void ScriptTrader::activate(void) {
   BUGZ_LOG(fatal) << port0_type << " and " << port1_type;
   auto ttr = trade_type_info(port0_type, port1_type);
   trades = ttr.trades;
+
+  if (trades.foe[0] && trades.foe[1] && trades.foe[2]) {
+    // it has all three -- use the last 2.
+    trades.foe[0] = false;
+  }
+
   // Ok, what do we do first here?
   // I - Info
   state = 1;
-  percent = 5.0;  // check meta for past trades information
+  percent = 5.0;
   to_server("I");
+  if (director.galaxy.config["stop_percent"]) {
+    stop_percent = director.galaxy.config["stop_percent"].as<int>();
+    director.galaxy.meta["help"]["stop_percent"] =
+        "ScriptTrader stop trading if below this percent.";
+  } else {
+    stop_percent = 20;
+    director.galaxy.config["stop_percent"] = stop_percent;
+    director.galaxy.meta["help"]["stop_percent"] =
+        "ScriptTrader stop trading if below this percent.";
+  }
 }
 
 void ScriptTrader::deactivate(void) { notify(); }
@@ -32,21 +49,74 @@ void ScriptTrader::deactivate(void) { notify(); }
 void ScriptTrader::server_line(const std::string &line,
                                const std::string &raw_line) {
   // FUTURE:  powering up weapons check
+
+  // Show what's going on...
+  if (state > 1) {
+    std::string temp = raw_line;
+    temp.append("\n\r");
+    to_client(temp);
+  }
+
   if (line == "Docking...") {
     last_offer = 0;
     final_offer = 0;
     initial_offer = 0;
   }
 
+  static std::set<std::string> success_lines = {
+      "If only more honest traders would port here, we'll take them though.",
+      "You will put me out of business, I'll take your offer.",
+      "FINE, we'll take them, just leave!",
+      "Agreed, and a pleasure doing business with you!",
+      "You are a rogue! We'll take them anyway.",
+      "You insult my intelligence, but we'll buy them anyway.",
+      "Very well, we'll take that offer.",
+      "You drive a hard bargain, but we'll take them.",
+      "Done, we'll take the lot.",
+      "I hate haggling, they're all yours.",
+      "You are robbing me, but we'll buy them anyway.",
+      "SOLD!  Come back anytime!",
+      "Cheapskate.  Here, take them and leave me alone.",
+      "Very well, we'll buy them.",
+      "You are a shrewd trader, they're all yours.",
+      "I could have twice that much in the Androcan Empire, but they're yours.",
+      "Oh well, maybe I can sell these to some other fool, we'll take them.",
+      "I PAID more than that!  But we'll sell them to you anyway.",
+      "(Sigh) Very well, pay up and take them away.",
+      "Agreed! We'll purchase them!"};
+
+  if (success_lines.find(line) != success_lines.end()) {
+    BUGZ_LOG(fatal) << "Success " << buying << " " << initial_offer << " : "
+                    << last_offer;
+    // calculate % ?
+    BUGZ_LOG(fatal) << "% " << (float)initial_offer / (float)last_offer * 100.0;
+    BUGZ_LOG(fatal) << "meta trade setting: " << percent << " for "
+                    << active_port << " " << product;
+    director.galaxy.meta["trade"][active_port][product] = percent;
+  }
+
+  // <P-Probe estimates your offer was
+
+  if (startswith(line, "Agreed, ")) {
+    last_offer = 0;
+    final_offer = 0;
+    if (director.galaxy.meta["trade"][active_port][product]) {
+      percent = director.galaxy.meta["trade"][active_port][product].as<float>();
+      percent += 1.0;
+      BUGZ_LOG(fatal) << "Percent for " << active_port << " now " << percent;
+    } else {
+      BUGZ_LOG(fatal) << "using default for " << active_port;
+      percent = 5.0;  // check meta for past trades information
+    }
+  }
+
   if (startswith(line, "We'll buy them for ")) {
     // I need the initial offer!
     std::string offer = line.substr(19);
     replace(offer, ",", "");
     initial_offer = stoi(offer);
     BUGZ_LOG(fatal) << "Buying, initial: " << initial_offer;
-    buying = true;
-    last_offer = 0;
-    final_offer = 0;
+    buying = true;  // Port is buying, we are selling.
   }
 
   if (startswith(line, "We'll sell them for ")) {
@@ -55,14 +125,13 @@ void ScriptTrader::server_line(const std::string &line,
     replace(offer, ",", "");
     initial_offer = stoi(offer);
     BUGZ_LOG(fatal) << "Selling, initial: " << initial_offer;
-    buying = false;
-    last_offer = 0;
-    final_offer = 0;
+    buying = false;  // Port is selling, we are buying.
   }
+
   // SL: [Our final offer is 1,263 credits.]
   if (startswith(line, "Our final offer is ")) {
     // Well snap!
-    std::string offer = line.substr(20);
+    std::string offer = line.substr(19);
     replace(offer, ",", "");
     final_offer = stoi(offer);
     BUGZ_LOG(fatal) << "Final offer: " << final_offer;
@@ -158,7 +227,7 @@ void ScriptTrader::server_prompt(const std::string &prompt) {
       if (director.current_sector == active_port) {
         // begin state 3
         state = 3;
-        to_client("Trade...\n\r");
+        to_client("Trading...\n\r");
         to_server("PT");
         return;
       } else {
@@ -178,6 +247,7 @@ void ScriptTrader::server_prompt(const std::string &prompt) {
       if (director.current_sector == active_port) {
         // We're here
         state = 3;
+        to_client("Trading...\n\r");
         to_server("PT");
         return;
       } else {
@@ -191,24 +261,33 @@ void ScriptTrader::server_prompt(const std::string &prompt) {
   }
 
   if (state == 3) {
-    if (in(prompt, " to sell ")) {
-      // always sell everything
-      to_server("\r");
-      return;
-    }
-    if (in(prompt, " to buy ") && startswith(prompt, "How many holds of ")) {
-      // Ok, what are they selling?
+    if (startswith(prompt, "How many holds of ")) {
       char selling = tolower(prompt[18]);
-      BUGZ_LOG(fatal) << "Selling: " << selling;
       for (int x = 0; x < 3; ++x) {
-        if (foe[x] == selling) {
-          // We found the item ... is it something that we're trading?
-          if (trades.foe[x]) {
-            // Yes!
-            to_server("\r");
-          } else {
-            // No!
-            to_server("0\r");
+        if (foe[x] == selling) product = x;
+      }
+
+      if (in(prompt, " to sell ")) {
+        // always sell everything
+        to_server("\r");
+        return;
+      }
+
+      if (in(prompt, " to buy ")) {
+        // Ok, what are they selling?
+        // char selling = tolower(prompt[18]);
+        BUGZ_LOG(fatal) << "Selling: " << selling;
+        for (int x = 0; x < 3; ++x) {
+          if (foe[x] == selling) {
+            // We found the item ... is it something that we're trading?
+            if (trades.foe[x]) {
+              // Yes!
+              to_server("\r");
+              product = x;
+            } else {
+              // No!
+              to_server("0\r");
+            }
           }
         }
       }
@@ -219,10 +298,12 @@ void ScriptTrader::server_prompt(const std::string &prompt) {
       if (last_offer != 0) percent -= 1.0;
 
       if (buying)
-        last_offer = (int)(initial_offer * (100 - percent) / 100.0);
-      else
         last_offer = (int)(initial_offer * (100 + percent) / 100.0);
-      BUGZ_LOG(fatal) << "Offer: " << last_offer << " % " << percent;
+      else
+        last_offer = (int)(initial_offer * (100 - percent) / 100.0);
+
+      BUGZ_LOG(fatal) << "Offer: " << buying << " offer " << last_offer << " % "
+                      << percent;
       std::string text = std::to_string(last_offer);
       text.append("\r");
       to_server(text);
@@ -233,12 +314,34 @@ void ScriptTrader::server_prompt(const std::string &prompt) {
       // do we carry on, or stop?
       // 1.) CHECK TURNS // need turn tracking
       // 2.) PORTS BURNT?
-      
+
       if (active_port == port[0])
         active_port = port[1];
       else
         active_port = port[0];
 
+      // Is target port burnt?
+      auto pos = director.galaxy.ports.find(active_port);
+      bool burnt = false;
+
+      if (pos != director.galaxy.ports.end()) {
+        // We'll find the port.  Really.
+
+        for (int x = 0; x < 3; ++x) {
+          if (trades.foe[x]) {
+            BUGZ_LOG(fatal) << x << " % " << (int)pos->second.percent[x] << " "
+                            << stop_percent;
+            if (pos->second.percent[x] < stop_percent) burnt = true;
+          }
+        }
+      }
+
+      if (burnt) {
+        to_client("Ports burnt.\n\r");
+        deactivate();
+        return;
+      }
+
       std::string move = std::to_string(active_port);
       to_client("Moving...\n\r");
       move.append("\r");

+ 10 - 7
scripts.h

@@ -6,22 +6,22 @@
 #include "galaxy.h"
 
 class ScriptTrader : public Dispatch {
-private:
-public:
+ private:
+ public:
   ScriptTrader(Director &);
-  ~ScriptTrader();  
+  ~ScriptTrader();
 
   char foe[4] = "foe";
 
   /**
    * internal state
-   * 
+   *
    * 1 = <Info> query.
    * 2 = move to active port
    * 3 = trade
    * 4 = if (burnt), stop, otherwise toggle active_port and state = 2
-   * 
-   * 
+   *
+   *
    */
   int state;
   float percent;
@@ -29,8 +29,11 @@ public:
   int initial_offer;
   int last_offer;
   int final_offer;
+  int product; // product we are buying/selling 0,1,2 foe.
+  int stop_percent;
 
-  int active_port; // port trading with
+  // should this be 0/1 ?  right now it is the port's sector number.
+  int active_port;  // port trading with
   // information from the find_best_trades function + others.
   int port[2];
   int active;