Browse Source

ScriptPlant handles moving colonists.

Steve Thielemann 3 years ago
parent
commit
e9a95e3638
3 changed files with 294 additions and 21 deletions
  1. 276 20
      scripts.cpp
  2. 13 1
      scripts.h
  3. 5 0
      utils.cpp

+ 276 - 20
scripts.cpp

@@ -605,6 +605,7 @@ void ScriptPlanet::init() {
 
 void ScriptPlanet::activate() {
   us = director.chain;
+  aborted = false;
 
   // FUTURE:  handle special case here, where we activate at planet/citadel
   // prompt
@@ -614,6 +615,15 @@ void ScriptPlanet::activate() {
     1 = Team List Planets
     2 = List Planets
     3 = Input Which planet to upgrade?
+    4 = Move to Planet
+    5 = Land, get planet information
+    6 = CU Citadel build/upgrade
+    7 = Parse Citadel needs
+    8 = Construct/upgrade ?
+    9 = to terra!
+    10 = back to the planet!
+    11 = unloading...
+    12 = resources ... TODO
   */
 
   state = 1;
@@ -630,6 +640,44 @@ void ScriptPlanet::deactivate() {
   notify();
 }
 
+void ScriptPlanet::clear_amounts(void) {
+  // clear amounts
+  for (int x = 0; x < 3; x++) {
+    population[x] = 0;
+    amount[x] = 0;
+    needs[x] = 0;
+    ship[x] = 0;
+    to_make_one[x] = 0;
+  }
+  total_population = 0;
+  support_construction = 0;
+  days = 0;
+}
+
+/**
+ * @brief Best place to put colonists
+ *
+ * Where is the best place to put colonists?
+ *
+ * That would be in production where they produce the most product.
+ * Where the number to make one is the least.
+ *
+ * @return int
+ */
+int ScriptPlanet::place_colonists(void) {
+  int best = 1000;
+  int pos = 0;
+  for (int x = 0; x < 3; x++) {
+    if (to_make_one[x] != 0) {
+      if (to_make_one[x] < best) {
+        best = to_make_one[x];
+        pos = x;
+      }
+    }
+  }
+  return pos;
+}
+
 void ScriptPlanet::input_notify() {
   // deactivate();
   director.chain = us;
@@ -647,24 +695,25 @@ void ScriptPlanet::input_notify() {
   // find the planet in our list
   auto pos = director.galaxy.planets.find(selected);
   if (pos == director.galaxy.planets.end()) {
-    to_client("Sorry, I can't find that planet.\n\r");
+    to_client("Sorry, I can't find that planet #.\n\r");
     deactivate();
     return;
   }
 
+  // Check planet level, if already max, don't bother!
+
   // Ok, we're off to planet # selected!
   planet = selected;
   sector = pos->second.sector;
+  current_level = pos->second.level;
 
   if (director.current_sector == sector) {
     // We're already there!
     state = 5;
     // clear out numbers
-    for (int x = 0; x < 3; x++) {
-      population[x] = 0;
-      amount[x] = 0;
-    }
+    clear_amounts();
 
+    // Landing ...
     to_server("L");
     return;
   } else {
@@ -684,14 +733,27 @@ void ScriptPlanet::move_notify() {
     if (state == 4) {
       state = 5;
       // clear out numbers
-      for (int x = 0; x < 3; x++) {
-        population[x] = 0;
-        amount[x] = 0;
-      }
+      clear_amounts();
+
+      to_server("L");
+      return;
+    } else if (state == 9) {
+      // Ok, we're at terra
+      to_server("LT\r");
+      return;
+    } else if (state == 10) {
+      // Back at the planet - Land and unload
       to_server("L");
       return;
     }
     return;
+  } else {
+    std::string message = "MOVE FAILED: ";
+    message.append(md->why_failed);
+    message.append("\n\r");
+    to_client(message);
+    deactivate();
+    return;
   }
 }
 void ScriptPlanet::trade_notify() {}
@@ -701,6 +763,7 @@ void ScriptPlanet::server_prompt(const std::string &prompt) {
     if (at_command_prompt(prompt)) {
       state = 2;
       to_server("CYQ");
+      return;
     }
   } else if (state == 2) {
     if (at_command_prompt(prompt)) {
@@ -734,12 +797,122 @@ void ScriptPlanet::server_prompt(const std::string &prompt) {
     if (prompt == "Planet command (?=help) [D] ") {
       // Ok, we're here on the planet.  (Did we capture the planet info on
       // landing?)
-      BUGZ_LOG(fatal) << "Total population: "
-                      << population[0] + population[1] + population[2];
+
+      BUGZ_LOG(fatal) << "Total population: " << total_population;
+
       // citadel, upgrade
-      // what is the message when you don't have a citadel yet? 
-      state = 6;                     
-      to_server("CU");                      
+      // what is the message when you don't have a citadel yet?
+      state = 6;
+      to_server("CU");
+      return;
+    }
+  } else if (state == 8) {
+    // SP: [Do you wish to construct one? ]
+    if (startswith(prompt, "Do you wish to construct ") &&
+        endswith(prompt, "? ")) {
+      // Do we have what we need?
+      bool ready = true;
+      if (total_population < support_construction) {
+        ready = false;
+        state = 9;
+        BUGZ_LOG(fatal) << "Need people ["
+                        << support_construction - total_population << "]";
+      }
+
+      for (int x = 0; x < 3; ++x) {
+        if (needs[x] > amount[x]) {
+          if (ready) {
+            ready = false;
+            state = 12;
+          }
+          BUGZ_LOG(fatal) << "Need " << x << " :" << needs[x] - amount[x];
+        }
+      }
+
+      if (ready) {
+        to_server("Y");
+        deactivate();
+        return;
+      }
+
+      // NNY!
+      if (current_level > 0) {
+        to_server("NQQ");
+      } else
+        to_server("NQ");
+
+      // Ok, time to start moving!
+      if (state == 9) {
+        md->move_to = 1;
+        director.chain = move;
+        md->activate();
+        return;
+      }
+
+      if (state == 12) {
+        // Need resources
+        deactivate();
+        return;
+      }
+
+      /*
+      if (current_level > 0)
+        to_server("NQQ");
+      else
+        to_server("NQ");
+
+      deactivate();
+      return;
+      */
+    }
+  } else if (state == 9) {
+    if (at_command_prompt(prompt)) {
+      // Ok! We have colonists ... back to the planet!
+      state = 10;
+      md->move_to = sector;
+      director.chain = move;
+      md->activate();
+      return;
+    }
+  } else if (state == 10) {
+    if (prompt == "Land on which planet <Q to abort> ? ") {
+      std::string text = std::to_string(planet) + "\r";
+      to_server(text);
+      return;
+    }
+    if (prompt == "Planet command (?=help) [D] ") {
+      // Ok, on the planet.
+      state = 11;
+      int place = place_colonists();
+      std::string unload = "SNL";
+      unload.append(std::to_string(place + 1));
+      unload.append("\r");
+      to_server(unload);
+      return;
+    }
+  } else if (state == 11) {
+    if (prompt == "Planet command (?=help) [D] ") {
+      if (total_population < support_construction) {
+        // Need More
+        if (current_level > 0) {
+          to_server("QQ");
+        } else
+          to_server("Q");
+        state = 9;
+        md->move_to = 1;
+        director.chain = move;
+        md->activate();
+        return;
+      }
+      // Ok, we're ready for the next step:
+      // checking the resources.
+
+      // ending here for now.
+      if (current_level > 0) {
+        to_server("QQ");
+      } else
+        to_server("Q");
+      deactivate();
       return;
     }
   }
@@ -752,11 +925,12 @@ void ScriptPlanet::server_line(const std::string &line,
   if (state == 5) {
     // Save the planet information
     /*
-SL: [ -------  ---------  ---------  ---------  ---------  ---------  ---------]
-SL: [Fuel Ore      4,950          2      2,475     28,135          0    200,000]
-SL: [Organics          0          5          0        100          0    200,000]
-SL: [Equipment       128         20          6        120          0    100,000]
-SL: [Fighters        N/A         24        206      2,395        200  1,000,000]
+SL: [ -------  ---------  ---------  ---------  ---------  ---------
+---------] SL: [Fuel Ore      4,950          2      2,475     28,135 0
+200,000] SL: [Organics          0          5          0        100          0
+200,000] SL: [Equipment       128         20          6        120          0
+100,000] SL: [Fighters        N/A         24        206      2,395        200
+1,000,000]
     */
     std::string work = line;
     replace(work, "Fuel Ore", "Fuel");
@@ -775,10 +949,92 @@ SL: [Fighters        N/A         24        206      2,395        200  1,000,000]
       // To save:
       if (pos >= 0) {
         population[pos] = sstoi(parts[1]);
+        to_make_one[pos] = sstoi(parts[2]);
+        total_population += population[pos];
         amount[pos] = sstoi(parts[3]);
+        // What do we have on-board the ship?
+        ship[pos] = sstoi(parts[5]);
       }
     }
   } else if (state == 6) {
+    if (startswith(line, "You may not upgrade while")) {
+      // We're already upgrading!
+      std::string work = raw_line;
+      work += "\n\r";
+      to_client(work);
+
+      if (current_level > 0) {
+        to_server("QQ");  // exit citadel, exit planet
+      } else {
+        to_server("Q");  // exit planet
+      };
+
+      deactivate();
+      return;
+    }
+
     // Citadel upgrade information (possibly)
+    /*
+    SL: [Citadel construction on this type of planet requires the following:]
+    SL: [               400,000 Colonists to support the construction,]
+    SL: [                   150 units of Fuel Ore,]
+    SL: [                   100 units of Organics,]
+    SL: [                   150 units of Equipment and]
+    SL: [                     2 days to construct.]
+    */
+    if (line ==
+        "Citadel construction on this type of planet requires the "
+        "following:") {
+      state = 7;
+    }
+  } else if (state == 7) {
+    if (line.empty()) {
+      state = 8;
+    } else {
+      // Display the upgrade information to the client
+      std::string work = raw_line;
+      work += "\n\r";
+      to_client(work);
+
+      work = line;
+      replace(work, ",", "");
+      trim(work);
+      auto pos = work.find(" Colonists to support");
+      if (pos != std::string::npos) {
+        support_construction = sstoi(work) / 1000;
+        return;
+      }
+      pos = work.find(" units of Fuel");
+      if (pos != std::string::npos) {
+        needs[0] = sstoi(work);
+        return;
+      }
+      pos = work.find(" units of Organics");
+      if (pos != std::string::npos) {
+        needs[1] = sstoi(work);
+        return;
+      }
+      pos = work.find(" units of Equipment");
+      if (pos != std::string::npos) {
+        needs[2] = sstoi(work);
+        return;
+      }
+      pos = work.find(" days to construct");
+      if (pos != std::string::npos) {
+        days = sstoi(work);
+        return;
+      }
+    }
+  } else if (state == 11) {
+    // SL: [How many groups of Colonists do you want to leave ([125] on board)
+    // ? ]
+    if (startswith(line, "How many groups of Colonists do you want to leave")) {
+      std::string work = line.substr(line.find('[') + 1);
+      int amount = sstoi(work);
+      total_population += amount;
+      BUGZ_LOG(fatal) << "Population now: " << total_population;
+    }
   }
-}
+}
+
+void ScriptPlanet::client_input(const std::string &input) { deactivate(); }

+ 13 - 1
scripts.h

@@ -107,10 +107,18 @@ class ScriptPlanet : public Dispatch {
     int planet;
     int sector;
     int state;
+    int current_level;
 
     int population[3];
+    int total_population;
     int amount[3];
-    
+    int ship[3];
+    int to_make_one[3];
+
+    int support_construction;
+    int needs[3];
+    int days;
+
     void init(void);
 
     void activate(void) override;
@@ -122,6 +130,10 @@ class ScriptPlanet : public Dispatch {
 
     void server_prompt(const std::string &prompt) override;
     void server_line(const std::string &line, const std::string &raw_line) override;
+    void client_input(const std::string &input) override;
+  private:
+    void clear_amounts(void); 
+    int place_colonists(void);   
 };
 
 #endif

+ 5 - 0
utils.cpp

@@ -136,6 +136,11 @@ bool endswith(const std::string &line, const std::string &has) {
   return (line.substr(line.length() - has.length()) == has);
 }
 
+/**
+ * Trim leading and trailing spaces from str.
+ * 
+ * @param str 
+ */
 void trim(std::string &str) {
   while (str.substr(0, 1) == " ") str.erase(0, 1);
   while (str.substr(str.length() - 1) == " ") str.erase(str.length() - 1);