| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650 | #include "scripts.h"#include <boost/format.hpp>#include "logging.h"ScriptTerror::ScriptTerror(Director &d) : Dispatch(d) {  BUGZ_LOG(warning) << "ScriptTerror()";  init();}ScriptTerror::~ScriptTerror() { BUGZ_LOG(warning) << "~ScriptTerror()"; }void ScriptTerror::init(void) {  BUGZ_LOG(fatal) << "ScriptTerror::init()";  move = std::make_shared<MoveDispatch>(director);  md = static_cast<MoveDispatch *>(&(*move));  // setup notify functions for results/completion.  md->setNotify([this]() { this->move_notify(); });  input = std::make_shared<InputDispatch>(director);  id = static_cast<InputDispatch *>(&(*input));  id->prompt = "Number of loops: ";  id->max_length = 4;  id->numeric = true;  id->setNotify([this]() { this->input_notify(); });  trader = std::make_shared<TraderDispatch>(director);  td = static_cast<TraderDispatch *>(&(*trader));  td->setNotify([this]() { this->trade_notify(); });  BUGZ_LOG(fatal) << "ScriptTerror::init() completed.";}void ScriptTerror::activate(void) {  BUGZ_LOG(warning) << "ScriptTerror::activate()";  // Need: InputDispatch, MoveDispatch, ScriptTrader  // Save the trade_end_empty setting, and set to Y  if (director.galaxy.config.contains("trade_end_empty")) {    old_trade_end_empty = director.galaxy.config["trade_end_empty"];  } else {    old_trade_end_empty = "Y";  }  director.galaxy.config["trade_end_empty"] = "Y";    // Step 0:  Get ship information / # of holds  max_loops = loops = -1;  to_server("I");  // Step 1:  Get number of loops of terror  // director.chain = input;  // input->activate();  // Step 2:  Look for closest trades, try ScriptTrade until none < some  // level. Step 3:  Move on, unless out of loops (or low on turns)  // deactivate();}void ScriptTerror::deactivate(void) {  BUGZ_LOG(warning) << "ScriptTerror::deactivate()";  // restore the original value.  director.galaxy.config["trade_end_empty"] = old_trade_end_empty;  notify();}void ScriptTerror::input_notify(void) {  if (id->input.empty()) {    deactivate();    return;  }  if (id->aborted) {    deactivate();    return;  }  max_loops = sstoi(id->input, -1);  if (max_loops == -1) {    deactivate();    return;  }  id->input.clear();  BUGZ_LOG(warning) << "Loops of terror: " << max_loops;  loops = max_loops;  // find nearest  int stop_percent;  if (director.galaxy.config.contains("stop_percent")) {    stop_percent = director.galaxy.config["stop_percent"].get<int>();  } else {    stop_percent = 25;    director.galaxy.config["stop_percent"] = stop_percent;  }  ppt = director.galaxy.find_closest_trade(director.current_sector, 3,                                           stop_percent);  if (ppt.type == 0) {    to_client("No trades found!  You've burnt the galaxy!\n\r");    deactivate();    return;  }  // ok, step 2:  move!  // md->setNotify([this]() { this->proxy_deactivate(); });  if (director.current_sector != ppt.s1) {    BUGZ_LOG(fatal) << "Moving to: " << ppt.s1;    md->move_to = ppt.s1;    director.chain = move;    director.chain->activate();    return;  } else {    // We're already there!    to_client("Ok!  Get trading!\n\r");    td->port[0] = ppt.s1;    td->port[1] = ppt.s2;    td->trades = ppt.trades;    td->type = ppt.type;    director.chain = trader;    director.chain->activate();    return;  }}void ScriptTerror::move_notify(void) {  BUGZ_LOG(fatal) << "move_notify()";  if (md->aborted) {    to_client("Move cancel.\n\r");    deactivate();    return;  }  // Check for success, and start trading!  if (md->success) {    to_client("We're here, get trading!\n\r");    td->port[0] = ppt.s1;    td->port[1] = ppt.s2;    td->trades = ppt.trades;    td->type = ppt.type;    director.chain = trader;    director.chain->activate();    return;  } else {    std::string message = "Move FAILED. " + md->why_failed + "\n\r";    // to_client("Move FAILED.\n\r");    to_client(message);    deactivate();  }}void ScriptTerror::server_prompt(const std::string &prompt) {  if ((loops == -1) && (max_loops == -1)) {    if (at_command_prompt(prompt)) {      // Step 1:  Get number of loops of terror      director.chain = input;      input->activate();      return;    }  }}void ScriptTerror::trade_notify(void) {  // Done trading -- maybe! :P  if (td->aborted) {    to_client("Trade cancel.\n\r");    deactivate();    return;  }  if (td->success) {    // success!    // find nearest    int stop_percent;    if (director.galaxy.config.contains("stop_percent")) {      stop_percent = director.galaxy.config["stop_percent"].get<int>();    } else {      stop_percent = 25;      director.galaxy.config["stop_percent"] = stop_percent;    }    ppt = director.galaxy.find_closest_trade(director.current_sector, 3,                                             stop_percent);    if (ppt.type == 0) {      to_client("No trades found!  You've burnt the galaxy!\n\r");      deactivate();      return;    }    if ((director.current_sector == ppt.s1) ||        (director.current_sector == ppt.s2)) {      // We're still here...      BUGZ_LOG(fatal) << "Trade it again, Sam.";      to_client("Keep trading.\n\r");      td->port[0] = ppt.s1;      td->port[1] = ppt.s2;      td->trades = ppt.trades;      td->type = ppt.type;      director.chain = trader;      director.chain->activate();      return;    }    // Ok, this isn't a local trade.    if (loops == 0) {      to_client("We're done terrorizing, for now...\n\r");      deactivate();      return;    }    --loops;    // Move to our next target    BUGZ_LOG(fatal) << "Moving to: " << ppt.s1;    md->move_to = ppt.s1;    director.chain = move;    director.chain->activate();    return;  } else {    std::string message = "Trade done: " + td->why_failed + "\n\r";    to_client(message);  }  // to_client("Ok, trade is done.\n\r");  deactivate();}ScriptVoyager::ScriptVoyager(Director &d) : Dispatch(d) {  BUGZ_LOG(warning) << "ScriptVoyager()";  init();}ScriptVoyager::~ScriptVoyager() { BUGZ_LOG(warning) << "~ScriptVoyager()"; }void ScriptVoyager::init(void) {  move = std::make_shared<MoveDispatch>(director);  md = static_cast<MoveDispatch *>(&(*move));  md->setNotify([this]() { this->move_notify(); });  input = std::make_shared<InputDispatch>(director);  id = static_cast<InputDispatch *>(&(*input));  id->prompt = "Number of loops/tries: ";  id->max_length = 5;  id->numeric = true;  id->setNotify([this]() { this->input_notify(); });}void ScriptVoyager::activate(void) {  director.chain = input;  input->activate();  return;}void ScriptVoyager::deactivate(void) {  BUGZ_LOG(warning) << "ScriptVoyager::deactivate()";  notify();}void ScriptVoyager::move_notify(void) {  if (md->aborted) {    deactivate();    return;  }  if (md->success) {    // Great!    next();    return;  } else {    std::string message = "No safe moves. " + md->why_failed + "\n\r";    to_client(message);    deactivate();  }}void ScriptVoyager::input_notify(void) {  if (id->input.empty() || id->aborted) {    to_client("Ok, maybe later then.\n\r");    deactivate();    return;  }  loops = sstoi(id->input, -1);  if (loops == -1) {    to_client("I'm sorry, WHAT?\n\r");    deactivate();  }  id->input.clear();  BUGZ_LOG(warning) << "Voyager loops: " << loops;  next();}void ScriptVoyager::next(void) {  if (loops == 0) {    // ok, stop here.    to_client("The voyage ends here, for now.\n\r");    deactivate();    return;  }  --loops;  sector_type s = director.galaxy.find_nearest_unexplored(director.current_sector);  if (s == 0) {    to_client("I don't see anything else to explorer.\n\r");    BUGZ_LOG(warning) << "find_nearest_unexplored returned 0";    deactivate();  }  BUGZ_LOG(warning) << "Next stop: " << s;  md->move_to = s;  director.chain = move;  director.chain->activate();}// SL: [###### DANGER! You have marked sector 740 to be avoided!]// SP: [Do you really want to warp there? (Y/N) ]void ScriptVoyager::server_prompt(const std::string &prompt) {}ScriptExplore::ScriptExplore(Director &d) : Dispatch(d) {  BUGZ_LOG(warning) << "ScriptExplore()";  init();}ScriptExplore::~ScriptExplore() {  BUGZ_LOG(warning) << "~ScriptExplore()";}void ScriptExplore::init() {  move = std::make_shared<MoveDispatch>(director);  md = static_cast<MoveDispatch *>(&(*move));  md->setNotify([this]() {this->move_notify();});  input = std::make_shared<InputDispatch>(director);  id = static_cast<InputDispatch *>(&(*input));  id->prompt = "Number of sectors to explore: ";  id->max_length = 5;  id->numeric = true;  id->setNotify([this](){this->input_notify();});  state = 0;  target = 0;  if(!director.galaxy.config.contains("prefer_ports")) {    director.galaxy.config["prefer_ports"] = "Y";    prefer_ports = true;  } else {    prefer_ports = json_str(director.galaxy.config["prefer_ports"]) == "Y";  }  if(!director.galaxy.meta["help"].contains("prefer_ports")) {    director.galaxy.meta["help"]["prefer_ports"] = "Explorer prefers to find ports.";  }  BUGZ_LOG(warning) << "Prefer Ports: " + prefer_ports;}void ScriptExplore::activate() {  us = director.chain;  state = 1;  to_server("I");  /*   director.chain = input;  input->activate();  if(director.galaxy.meta["ship"]) {    if(!director.galaxy.meta["ship"]["scanner"]) {      to_client("\n\rIt appears your ship doesn't have a long range scanner.\n\r");      deactivate();    }  }  state = 1;  return;  */}void ScriptExplore::deactivate() {  BUGZ_LOG(warning) << "ScriptExplore::deactivate()";  us.reset();  notify();}void ScriptExplore::move_notify() {  director.chain = us;  if (md->aborted) {    deactivate();    return;  }  if (md->success) {    to_server("SD");    state = 3;    return;  } else {    if (unknown_warps.size() != 0) {      BUGZ_LOG(warning) << "Seeking previous unexplored (Unsafe Dest.)";      state = 4;      next();      target = unknown_warps.top();      unknown_warps.pop();      std::string message = "UNSAFE DESTINATION";      std::string indenter = "    ";      ANSIColor alert(COLOR::WHITE, COLOR::RED, ATTR::BOLD);      to_client(indenter + alert() + message + reset() + "\n\r");    } else {      std::string message = "Move failed: " + md->why_failed + "\n\r";      //to_client("No safe moves.\n\r");      BUGZ_LOG(warning) << message;      to_client(message);      deactivate();    }  }}void ScriptExplore::input_notify() {  director.chain = us;  if (id->input.empty() || id->aborted) {    to_client("Maybe next time.\n\r");    deactivate();    return;  }  loops = sstoi(id->input, -1);  if (loops == -1) {    to_client("I'm sorry, WHAT?\n\r");    deactivate();    return;  }  if (loops == 0) {    infinite = true;  } else {    infinite = false;  }  id->input.clear();  if (!infinite) {    BUGZ_LOG(warning) << "Explore loops: " << loops;  } else {    to_client("Infinite Mode!\n\r");    to_client("[ PRESS A KEY TO STOP ]\n\r");    BUGZ_LOG(warning) << "Explore loops: INFINITE";  }  to_server("SD");  state = 3;}void ScriptExplore::next() {  if (loops <= 0 && !infinite) {    to_client("The exploration ends, for now.\n\r");    deactivate();    return;  }  if(!infinite)    --loops;  // Calculate next best sector to goto  density_scan & ds = director.galaxy.dscan;  density best_sector;  best_sector.sector = 0;  if (target != 0) {    BUGZ_LOG(info) << "Using: " << target;    best_sector.sector = target;    target = 0;  } else {    for (int x = 0; x < ds.pos; ++x) {      if(best_sector.sector != 0)        BUGZ_LOG(info) << "Comparing: " << ds.d[x].sector << " (" << ds.d[x].density << ", " << ds.d[x].known <<") to " << best_sector.sector << " (" << best_sector.density << ", " << best_sector.known << ")";      /* Is this sector prefered over others?        * Warp Counts (Number of warps)        * Density Check (Is this sector clear, does it contain a port)        * NavHaz Check (Avoid sectors with navhaz above X%)      */      if(!ds.d[x].known) {        BUGZ_LOG(info) << "Subject: " << ds.d[x].sector;        // Compare, Warp counts        if (best_sector.sector != 0) {          if(prefer_ports) {            if((ds.d[x].density == 100 || ds.d[x].density == 101) || (ds.d[x].warps >= best_sector.warps)) {              if(density_clear(ds.d[x].sector, ds.d[x].density, ds.d[x].navhaz)) {                if(best_sector.sector != 0) {                  BUGZ_LOG(info) << "Storing previous best " << best_sector.sector;                  unknown_warps.push(best_sector.sector);                }                best_sector = ds.d[x];              }            } else {              if(density_clear(ds.d[x].sector, ds.d[x].density, ds.d[x].navhaz)) {                BUGZ_LOG(info) << "Added " << ds.d[x].sector << " to unknown_warps (" << unknown_warps.size() << ")";                unknown_warps.push(ds.d[x].sector);              }            }          } else {            if((ds.d[x].warps >= best_sector.warps)) {              if(density_clear(ds.d[x].sector, ds.d[x].density, ds.d[x].navhaz)) {                if(best_sector.sector != 0) {                  BUGZ_LOG(info) << "Storing previous best " << best_sector.sector;                  unknown_warps.push(best_sector.sector);                }                best_sector = ds.d[x];              }            } else {              if(density_clear(ds.d[x].sector, ds.d[x].density, ds.d[x].navhaz)) {                BUGZ_LOG(info) << "Added " << ds.d[x].sector << " to unknown_warps (" << unknown_warps.size() << ")";                unknown_warps.push(ds.d[x].sector);              }            }          }        } else {          BUGZ_LOG(info) << "No-Op " << ds.d[x].sector << " is best.";          best_sector = ds.d[x];        }        // Check density for possible port      }      // Check density for possible port    }  }  BUGZ_LOG(warning) << "Unknown Warps: " << unknown_warps.size();  if (best_sector.sector == 0) {    if (unknown_warps.size() == 0) {      to_client("No unknown warps.");      deactivate();      return;    } else {      BUGZ_LOG(warning) << "Seeking previous unexplored";      best_sector.sector = unknown_warps.top();      unknown_warps.pop();      std::string message = "DEAD END";      std::string indenter = "    ";      ANSIColor alert(COLOR::WHITE, COLOR::RED, ATTR::BOLD);      to_client(indenter + alert() + message + reset() + "\n\r");    }  }  BUGZ_LOG(warning) << "Targeting sector: " << best_sector.sector;  if (director.current_sector != best_sector.sector) {    md->move_to = best_sector.sector;    director.chain = move;    director.chain->activate();  } else {    BUGZ_LOG(warning) << "Targeting current sector!";    state = 3;    to_server("SD");  }}void ScriptExplore::server_prompt(const std::string &prompt) {  BUGZ_LOG(info) << "Explorer State: SP " << state;  //next();  if(state == 1) {    if(at_command_prompt(prompt)) {      if(director.galaxy.meta.contains("ship")) {        if(!director.galaxy.meta["ship"].contains("scanner")) {          to_client("\n\rIt appears your ship doesn't have a long range scanner.\n\r");          deactivate();          return;        }      }      state = 2;      BUGZ_LOG(info) << "state = 1, prompting for user input";      director.chain = input;      input->activate();      return;    }  }  if (state == 3) {    if(at_command_prompt(prompt)) {      state = 4;      BUGZ_LOG(info) << "state = 3, calculating next sector";      next();    }  }}ScriptPlanet::ScriptPlanet(Director &d) : Dispatch(d) {  BUGZ_LOG(warning) << "ScriptPlanet()";  init();}ScriptPlanet::~ScriptPlanet() { BUGZ_LOG(warning) << "~ScriptPlanet()"; }void ScriptPlanet::init() {  move = std::make_shared<MoveDispatch>(director);  md = static_cast<MoveDispatch *>(&(*move));  md->setNotify([this]() { this->move_notify(); });  trader = std::make_shared<TraderDispatch>(director);  td = static_cast<TraderDispatch *>(&(*trader));  td->setNotify([this]() { this->trade_notify(); });  input = std::make_shared<InputDispatch>(director);  id = static_cast<InputDispatch *>(&(*input));  id->prompt = "Which planet would you like to upgrade => ";  id->max_length = 3;  id->numeric = true;  id->setNotify([this]() { this->input_notify(); });  state = 0;}void ScriptPlanet::activate() {  us = director.chain;  // FUTURE:  handle special case here, where we activate at planet/citadel  // prompt  state = 1;  // clear out the planets list -- we're refreshing.  director.galaxy.planets.clear();  // get planet lists  to_server("TLQ");}void ScriptPlanet::deactivate() {  BUGZ_LOG(warning) << "ScriptPlanet::deactivate()";  us.reset();  notify();}void ScriptPlanet::input_notify() {  deactivate();}void ScriptPlanet::move_notify() {}void ScriptPlanet::trade_notify() {}void ScriptPlanet::server_prompt(const std::string &prompt) {  if (state == 1) {    if (at_command_prompt(prompt)) {      state = 2;      to_server("CYQ");    }  } else if (state == 2) {    if (at_command_prompt(prompt)) {      state = 3;      if (director.galaxy.planets.empty()) {        to_client("Sorry, I don't see that you have any planets!\n\r");        deactivate();        return;      }      for (auto const &planet : director.galaxy.planets) {        std::string text =            str(boost::format("%1$3d <%2$5d> Class %3% Level %4% Name %5%\n\r") %                planet.first % planet.second.sector % planet.second.c %                planet.second.level % planet.second.name);        to_client(text);      }      director.chain = input;      director.chain->activate();      return;    }  }}void ScriptPlanet::server_line(const std::string &line,                               const std::string &raw_line) {}
 |