123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547 |
- #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["trade_end_empty"]) {
- old_trade_end_empty =
- director.galaxy.config["trade_end_empty"].as<std::string>();
- } 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["stop_percent"]) {
- stop_percent = director.galaxy.config["stop_percent"].as<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 {
- to_client("Move FAILED.\n\r");
- 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["stop_percent"]) {
- stop_percent = director.galaxy.config["stop_percent"].as<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;
- }
- 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 {
- to_client("No safe moves.\n\r");
- 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;
- }
- 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 {
- to_client("No safe moves.\n\r");
- 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;
- for (int x = 0; x < ds.pos; ++x) {
- BUGZ_LOG(warning) << "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(warning) << "Subject: " << ds.d[x].sector;
- // Compare, Warp counts
- if (best_sector.sector != 0) {
- if((ds.d[x].warps >= best_sector.warps) || ((ds.d[x].density == 100 || ds.d[x].density == 101) && (best_sector.density != 100 || best_sector.density != 101))) {
- if(safe_sector(ds.d[x])) {
- if(best_sector.sector != 0) {
- BUGZ_LOG(warning) << "Storing previous best " << best_sector.sector;
- unknown_warps.push(best_sector.sector);
- }
- best_sector = ds.d[x];
- }
- } else {
- if(safe_sector(ds.d[x])) {
- BUGZ_LOG(warning) << "Added " << ds.d[x].sector << " to unknown_warps (" << unknown_warps.size() << ")";
- unknown_warps.push(ds.d[x].sector);
- }
- }
- } else {
- best_sector = ds.d[x];
- }
- // 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();
- }
- }
- BUGZ_LOG(warning) << "Targeting sector: " << best_sector.sector;
- md->move_to = best_sector.sector;
- director.chain = move;
- director.chain->activate();
- }
- bool ScriptExplore::safe_sector(density d) { // int sector, int density) {
- if (d.sector == 0) return false;
- if (d.anomaly) return false;
- int dense = d.density;
- /*
- http://wiki.classictw.com/index.php?title=Gypsy%27s_Big_Dummy%27s_Guide_to_TradeWars_Text#Trader_Information
- Density Readings:
- 0 = Empty Sector or Ferrengi Dreadanought
- 1 = Marker Beacon
- 2 = Limpet Type 2 Tracking Mine
- 5 = Fighter (per Fighter)
- 10 = Armid Type 1 Mine
- 21 = Navigation Hazard (Per 1 Percent)
- 21 = Destroyed Ship (Due to 1 Percent Nav-Haz)
- 38 = Unmanned Ship
- 40 = Manned Ship, Alien or Ferrengi Assault Trader
- 50 = Destroyed Starport (After 25 Percent Nav-Haz Clears)
- 100 = Starport or Ferrengi Battle Cruiser
- 210 = Destroyed Planet (Due to 10 Percent Nav-Haz)
- 462 = Federation Starship under Admiral Nelson
- 489 = Federation Starship under Captain Zyrain
- 500 = Planet
- 512 = Federation Starship under Admiral Clausewitz
- 575 = Destroyed Port (Before 25% Nav-Haz Clears)
- */
- // Adjust density by upto 5% navhaz (Only if navhaz less than 6%)
- if(d.navhaz != 0 && d.navhaz <= 5) {
- dense -= d.navhaz * 21;
- }
- // If navhaz above 5% report it unsafe
- if (d.navhaz > 5) return false;
- switch (dense) {
- case 0:
- case 1:
- case 100:
- case 101:
- return true;
- }
- // special case for sector 1:
- if ((d.sector == 1) && (dense == 601)) return true;
- return false;
- }
- void ScriptExplore::server_prompt(const std::string &prompt) {
- BUGZ_LOG(warning) << "Explorer State: SP " << state;
- //next();
- if(state == 1) {
- if(at_command_prompt(prompt)) {
- 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();
- return;
- }
- }
- state = 2;
- BUGZ_LOG(fatal) << "state = 1, prompting for user input";
- director.chain = input;
- input->activate();
- return;
- }
- }
- if (state == 3) {
- if(at_command_prompt(prompt)) {
- state = 4;
- next();
- }
- }
- }
|