1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267 |
- #include "scripts.h"
- #include <boost/format.hpp>
- #include "logging.h"
- ScriptTerror::ScriptTerror(Director &d, const char *called)
- : Dispatch(d, called) {
- BUGZ_LOG(warning) << "ScriptTerror()";
- if (called == nullptr) name = "Terror";
- init();
- }
- ScriptTerror::~ScriptTerror() { BUGZ_LOG(warning) << "~ScriptTerror()"; }
- void ScriptTerror::init(void) {
- BUGZ_LOG(fatal) << "ScriptTerror::init()";
- move = std::make_shared<MoveDispatch>(director, "TerrorMove");
- md = static_cast<MoveDispatch *>(&(*move));
- // setup notify functions for results/completion.
- md->setNotify([this]() { this->move_notify(); });
- input = std::make_shared<InputDispatch>(director, "TerrorInput");
- 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, "TerrorTrader");
- 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, const char *called)
- : Dispatch(d, called) {
- BUGZ_LOG(warning) << "ScriptVoyager()";
- if (called == nullptr) name = "Voyager";
- init();
- }
- ScriptVoyager::~ScriptVoyager() { BUGZ_LOG(warning) << "~ScriptVoyager()"; }
- void ScriptVoyager::init(void) {
- move = std::make_shared<MoveDispatch>(director, "VoyagerMove");
- md = static_cast<MoveDispatch *>(&(*move));
- md->setNotify([this]() { this->move_notify(); });
- input = std::make_shared<InputDispatch>(director, "VoyagerInput");
- 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, const char *called)
- : Dispatch(d, called) {
- BUGZ_LOG(warning) << "ScriptExplore()";
- if (called == nullptr) name = "Explore";
- init();
- }
- ScriptExplore::~ScriptExplore() { BUGZ_LOG(warning) << "~ScriptExplore()"; }
- void ScriptExplore::init() {
- move = std::make_shared<MoveDispatch>(director, "ExploreMove");
- md = static_cast<MoveDispatch *>(&(*move));
- md->setNotify([this]() { this->move_notify(); });
- input = std::make_shared<InputDispatch>(director, "ExploreInput");
- 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 =
- startswith(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";
- }
- if (!director.galaxy.config.contains("use_nearest_unknown")) {
- director.galaxy.config["use_nearest_unknown"] = "Y";
- use_nearest_unknown = true;
- } else {
- use_nearest_unknown = startswith(
- json_str(director.galaxy.config["use_nearest_unknown"]), "Y");
- }
- if (!director.galaxy.meta["help"].contains("use_nearest_unknown")) {
- director.galaxy.meta["help"]["use_nearest_unknown"] =
- "Explorer will find nearest unknown when out of known sectors to "
- "explore";
- }
- BUGZ_LOG(warning) << "Prefer Ports: " << prefer_ports;
- }
- void ScriptExplore::activate() {
- us = director.chain;
- state = 1;
- to_server("I");
- }
- 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;
- target = unknown_warps.top();
- unknown_warps.pop();
- std::string message = "UNSAFE DESTINATION";
- ANSIColor alert(COLOR::WHITE, COLOR::RED, ATTR::BOLD);
- to_client(" " + alert() + message + reset() + "\n\r");
- BUGZ_LOG(warning) << "Target = " << target;
- next();
- } else {
- std::string message = "Move failed: " + md->why_failed + "\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;
- }
- bool has_port(const density d) {
- int den = d.density;
- if (d.navhaz <= 5) {
- den -= 21 * d.navhaz;
- }
- return den == 100 || den == 101;
- }
- bool sort_ports(const density a, const density b) {
- if (has_port(a) && has_port(b)) {
- return a.warps > b.warps;
- } else {
- if ((has_port(a) && !has_port(b)) || (!has_port(a) && has_port(b))) {
- return has_port(a);
- }
- return a.warps > b.warps;
- }
- }
- bool sort_warps(const density a, const density b) {
- if ((has_port(a) && !has_port(b)) || (!has_port(a) && has_port(b))) {
- return has_port(a) && a.warps > b.warps;
- }
- return a.warps > b.warps;
- }
- 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;
- std::array<density, 6> sectors = ds.d;
- for (int x = 0; x < 6; ++x) {
- if (sectors[x].known ||
- !density_clear(sectors[x].sector, sectors[x].density,
- sectors[x].navhaz)) {
- sectors[x].sector = 0;
- sectors[x].density = 0;
- sectors[x].warps = 0;
- sectors[x].navhaz = 0;
- sectors[x].known = false;
- sectors[x].anomaly = false;
- }
- }
- if (prefer_ports) {
- std::sort(sectors.begin(), sectors.end(), sort_ports);
- } else {
- std::sort(sectors.begin(), sectors.end(), sort_warps);
- }
- for (int x = 0; x < 6; ++x) {
- BUGZ_LOG(trace) << "[" << sectors[x].sector << ", " << sectors[x].density
- << ", " << sectors[x].warps << ", " << sectors[x].anomaly
- << ", " << sectors[x].known << "]";
- }
- BUGZ_LOG(warning) << "Best Sector: " << sectors[0].sector;
- best_sector = sectors[0];
- for (int x = 1; x < 6; ++x) {
- if (sectors[x].sector != 0 && sectors[x].sector != best_sector.sector) {
- unknown_warps.push(sectors[x].sector);
- BUGZ_LOG(info) << "Added " << sectors[x].sector << " to unknown_warps ("
- << unknown_warps.size() << ")";
- }
- }
- if (target != 0) {
- BUGZ_LOG(info) << "Using: " << target;
- best_sector.sector = target;
- target = 0;
- }
- BUGZ_LOG(warning) << "Unknown Warps: " << unknown_warps.size();
- if (best_sector.sector == 0) {
- if (unknown_warps.size() == 0) {
- if (!use_nearest_unknown) {
- to_client("No unknown warps.");
- deactivate();
- return;
- } else {
- BUGZ_LOG(warning) << "Seeking nearest unknown";
- std::string message = "Finding nearest unexplored";
- ANSIColor alert(COLOR::WHITE, COLOR::RED, ATTR::BOLD);
- to_client(" " + alert() + message + reset() + "\n\r");
- best_sector.sector =
- director.galaxy.find_nearest_unexplored(director.current_sector);
- if (best_sector.sector == 0) {
- to_client("No unknown warps in the galaxy!");
- deactivate();
- return;
- }
- }
- } else {
- BUGZ_LOG(warning) << "Seeking previous unexplored";
- best_sector.sector = unknown_warps.top();
- unknown_warps.pop();
- std::string message = "DEAD END";
- ANSIColor alert(COLOR::WHITE, COLOR::RED, ATTR::BOLD);
- to_client(" " + 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(trace) << "state = 1, prompting for user input";
- director.chain = input;
- input->activate();
- return;
- }
- }
- if (state == 3) {
- if (at_command_prompt(prompt)) {
- state = 4;
- BUGZ_LOG(trace) << "state = 3, calculating next sector";
- next();
- }
- }
- }
- ScriptPlanet::ScriptPlanet(Director &d, const char *called)
- : Dispatch(d, called) {
- BUGZ_LOG(warning) << "ScriptPlanet()";
- if (called == nullptr) name = "Planet";
- init();
- }
- ScriptPlanet::~ScriptPlanet() { BUGZ_LOG(warning) << "~ScriptPlanet()"; }
- void ScriptPlanet::init() {
- move = std::make_shared<MoveDispatch>(director, "PlanetMove");
- md = static_cast<MoveDispatch *>(&(*move));
- md->setNotify([this]() { this->move_notify(); });
- md->use_express = true;
- trader = std::make_shared<TraderDispatch>(director, "PlanetTrader");
- td = static_cast<TraderDispatch *>(&(*trader));
- td->setNotify([this]() { this->trade_notify(); });
- input = std::make_shared<InputDispatch>(director, "PlanetInput");
- 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;
- aborted = false;
- // FUTURE: handle special case here, where we activate at planet/citadel
- // prompt
- /*
- States:
- 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
- 13 = moving to buyer
- 14 = moving to planet
- 15 = product unloaded
- */
- 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::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;
- if (id->input.empty()) {
- deactivate();
- return;
- }
- int selected = sstoi(id->input);
- if (selected == 0) {
- deactivate();
- return;
- }
- // 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");
- 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
- clear_amounts();
- // Landing ...
- to_server("L");
- return;
- } else {
- // Let's get to the planet
- state = 4;
- md->move_to = sector;
- director.chain = move;
- move->activate();
- return;
- }
- }
- void ScriptPlanet::move_notify() {
- director.chain = us;
- if (md->success) {
- // Ok, we're here
- if (state == 4) {
- state = 5;
- // clear out numbers
- 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;
- } else if (state == 13) {
- // Ok, we're here!
- td->port[0] = current_buyfrom;
- td->port[1] = 0;
- for (int x = 0; x < 3; x++) {
- td->port_buysell[0].foe[x] = false;
- td->port_buysell[1].foe[x] = false;
- td->trades.foe[x] = false;
- }
- td->port_buysell[0].foe[current_product] = true;
- td->trades.foe[current_product] = true;
- director.chain = trader;
- td->activate();
- return;
- } else if (state == 14) {
- // We're at the planet! Time to 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() {
- director.chain = us;
- if (td->success) {
- if (state == 13) {
- // Ok, we have what we came from, return to the planet.
- state = 14;
- md->move_to = sector;
- director.chain = move;
- move->activate();
- return;
- }
- } else {
- to_client("Trade failed.\n\r");
- deactivate();
- return;
- }
- }
- void ScriptPlanet::server_prompt(const std::string &prompt) {
- if (state == 1) {
- if (at_command_prompt(prompt)) {
- state = 2;
- to_server("CYQ");
- return;
- }
- } 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;
- }
- } else if (state == 5) {
- // Are they prompting us for which planet to land on?
- // SP: [Land on which planet <Q to abort> ? ]
- if (prompt == "Land on which planet <Q to abort> ? ") {
- std::string text = std::to_string(planet) + "\r";
- to_server(text);
- return;
- }
- // SP: [Planet command (?=help) [D] ]
- 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: " << total_population;
- // FIXUP: Empty out the ship holds if they aren't empty.
- for (int x = 0; x < 3; ++x) {
- if (ship[x] != 0) {
- std::string message = str(
- boost::format("Transfer ship cargo %1% (%2%) to planet.\n\r") %
- foe[x] % ship[x]);
- to_client(message);
- std::string transfer = "TNL";
- transfer.append(std::to_string(x + 1));
- transfer.append("\r");
- to_server(transfer);
- ship[x] = 0;
- return;
- }
- }
- // citadel, upgrade
- // 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;
- std::string message =
- str(boost::format("Planet has %1% people, need %2%.\n\r") %
- total_population % support_construction);
- to_client(message);
- 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;
- }
- std::string message =
- str(boost::format("Has %1% of %2%, needs %3%\n\r") % amount[x] %
- foe[x] % needs[x]);
- to_client(message);
- 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
- current_product = -1;
- for (int x = 0; x < 3; ++x) {
- if (needs[x] > amount[x]) {
- current_product = x;
- break;
- }
- }
- if (current_product == -1) {
- // I think we have everything.
- BUGZ_LOG(fatal) << "I think we've got it...";
- to_server("CUY");
- deactivate();
- return;
- } else {
- // Ok, let's find where we need to go
- current_buyfrom = director.galaxy.find_nearest_selling(
- director.current_sector, current_product);
- if (current_buyfrom == 0) {
- to_client("We weren't able to locate a port selling.\n\r");
- deactivate();
- return;
- }
- state = 13;
- md->move_to = current_buyfrom;
- director.chain = move;
- md->activate();
- 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 - we're not in citadel.
- 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.
- // Need resources
- current_product = -1;
- for (int x = 0; x < 3; ++x) {
- if (needs[x] > amount[x]) {
- current_product = x;
- break;
- }
- }
- if (current_product == -1) {
- // I think we have everything.
- BUGZ_LOG(fatal) << "I think we've got it...";
- to_server("CUY");
- deactivate();
- return;
- } else {
- // Ok, let's find where we need to go
- current_buyfrom = director.galaxy.find_nearest_selling(
- director.current_sector, current_product);
- if (current_buyfrom == 0) {
- to_client("We weren't able to locate a port selling.\n\r");
- deactivate();
- return;
- }
- to_server("Q");
- state = 13;
- md->move_to = current_buyfrom;
- director.chain = move;
- md->activate();
- return;
- }
- // ending here for now. (not in citadel)
- // to_server("Q");
- // deactivate();
- // return;
- }
- } else if (state == 14) {
- 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] ") {
- state = 15;
- std::string command = "TNL";
- command.append(std::to_string(current_product + 1));
- command.append("\r");
- to_server(command);
- return;
- }
- } else if (state == 15) {
- if (prompt == "Planet command (?=help) [D] ") {
- // Ok, we're done unloading ... what do we need next?
- // Need resources
- current_product = -1;
- for (int x = 0; x < 3; ++x) {
- if (needs[x] > amount[x]) {
- current_product = x;
- break;
- }
- }
- if (current_product == -1) {
- // I think we have everything.
- BUGZ_LOG(fatal) << "I think we've got it...";
- to_server("CUY");
- deactivate();
- return;
- } else {
- // Ok, let's find where we need to go
- current_buyfrom = director.galaxy.find_nearest_selling(
- director.current_sector, current_product);
- if (current_buyfrom == 0) {
- to_client("We weren't able to locate a port selling.\n\r");
- deactivate();
- return;
- }
- to_server("Q");
- state = 13;
- md->move_to = current_buyfrom;
- director.chain = move;
- md->activate();
- return;
- }
- }
- }
- }
- void ScriptPlanet::server_line(const std::string &line,
- const std::string &raw_line) {
- // because I'm not sending this to the client, this is all hidden from them.
- 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]
- */
- std::string work = line;
- replace(work, "Fuel Ore", "Fuel");
- replace(work, ",", "");
- auto parts = split(work);
- if (parts.size() == 7) {
- int pos = -1;
- if (parts[0] == "Fuel") {
- pos = 0;
- } else if (parts[0] == "Organics") {
- pos = 1;
- } else if (parts[0] == "Equipment") {
- pos = 2;
- }
- // 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[4]);
- // What do we have on-board the ship?
- ship[pos] = sstoi(parts[5]);
- BUGZ_LOG(fatal) << pos << " : pop " << population[pos] << " 2M1 "
- << to_make_one[pos] << " amount " << amount[pos]
- << " ship: " << ship[pos];
- }
- }
- } else if (state == 6) {
- // [Be patient, your Citadel is not yet finished.]
- if ((line == "Be patient, your Citadel is not yet finished.") ||
- (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.]
- [Construction of a Combat Control Computer on this type of planet requires]
- */
- if ((line == "Citadel construction on this type of planet requires the "
- "following:") ||
- (endswith(line, " on this type of planet requires"))) {
- 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 == 9) {
- bool output = false;
- if (startswith(line, "How many groups of Colonist")) output = true;
- if (startswith(line, "The Colonists file aboard your ship")) output = true;
- if (output) {
- // output to client
- std::string work = raw_line;
- work += "\n\r";
- to_client(work);
- }
- } else if (state == 11) {
- // SL: [How many groups of Colonists do you want to leave ([125] on board)
- // ? ]
- bool output = false;
- 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;
- output = true;
- BUGZ_LOG(fatal) << "Population now: " << total_population;
- }
- if (startswith(line, "The Colonists disembark")) output = true;
- if (output) {
- // output to client
- std::string work = raw_line;
- work += "\n\r";
- to_client(work);
- }
- } else if (state == 15) {
- bool output = false;
- // SL: [How many holds of Organics do you want to leave ([250] on board) ? ]
- if (startswith(line, "How many holds of ") &&
- endswith(line, "] on board) ? ")) {
- std::string work = line.substr(line.find('[') + 1);
- int amount_moved = sstoi(work);
- amount[current_product] += amount_moved;
- output = true;
- BUGZ_LOG(fatal) << "Planet " << current_product << " +" << amount_moved
- << " = " << amount[current_product];
- }
- if (startswith(line, "You unload the ")) output = true;
- if (output) {
- // output to client
- std::string work = raw_line;
- work += "\n\r";
- to_client(work);
- }
- }
- }
- void ScriptPlanet::client_input(const std::string &input) { deactivate(); }
|