diff --git a/src/citymania/cm_console_cmds.cpp b/src/citymania/cm_console_cmds.cpp index 772e3cb8da..c24882f01d 100644 --- a/src/citymania/cm_console_cmds.cpp +++ b/src/citymania/cm_console_cmds.cpp @@ -10,9 +10,14 @@ #include "../fileio_type.h" #include "../map_type.h" #include "../map_func.h" +#include "../strings_func.h" #include "../town.h" #include "../tree_map.h" +#include +#include +#include + #include "../safeguards.h" bool ReadHeightMap(DetailedFileType dft, const char *filename, uint *x, uint *y, byte **map); @@ -113,9 +118,8 @@ extern void (*UpdateTownGrowthRate)(Town *t); bool ConResetTownGrowth(byte argc, char *argv[]) { if (argc == 0) { - IConsoleHelp("Loads heighmap-like file and plants trees according to it, values 0-256 ore scaled to 0-4 trees."); - IConsoleHelp("Usage: 'cmtreemap '"); - IConsoleHelp("Default lookup path is in scenario/heightmap in your openttd directory"); + IConsoleHelp("Resets growth to normal for all towns."); + IConsoleHelp("Usage: 'cmresettowngrowth'"); return true; } @@ -128,4 +132,69 @@ bool ConResetTownGrowth(byte argc, char *argv[]) { return true; } +struct FakeCommand { + Date date; + DateFract date_fract; + uint company_id; + uint cmd; + TileIndex tile; + uint32 p1, p2; + std::string text; +}; + +static std::queue _fake_commands; + +void ExecuteFakeCommands(Date date, DateFract date_fract) { + auto backup_company = _current_company; + while (!_fake_commands.empty() && _fake_commands.front().date <= date && _fake_commands.front().date_fract <= date_fract) { + auto &x = _fake_commands.front(); + if (x.date < date || x.date_fract < date_fract) IConsolePrintF(CC_WARNING, + "Queued command is earlier than execution date: %d/%hu vs %d/%hu", + x.date, x.date_fract, date, date_fract); + fprintf(stderr, "Executing command: company=%u cmd=%u tile=%u p1=%u p2=%u text=%s ... ", x.company_id, x.cmd, x.tile, x.p1, x.p2, x.text.c_str()); + _current_company = (CompanyID)x.company_id; + auto res = DoCommandPInternal(x.tile, x.p1, x.p2, x.cmd | CMD_NETWORK_COMMAND, nullptr, x.text.c_str(), false, false); + if (res.Failed()) { + if (res.GetErrorMessage() != INVALID_STRING_ID) { + char buf[DRAW_STRING_BUFFER]; + GetString(buf, res.GetErrorMessage(), lastof(buf)); + fprintf(stderr, "%s\n", buf); + } else { + fprintf(stderr, "FAIL\n"); + } + } else { + fprintf(stderr, "OK\n"); + } + _fake_commands.pop(); + } + _current_company = backup_company; +} + +bool ConLoadCommands(byte argc, char *argv[]) { + if (argc == 0) { + IConsoleHelp("Loads a file with command queue to execute"); + IConsoleHelp("Usage: 'cmloadcommands '"); + return true; + } + + if (argc != 2) return false; + + std::queue().swap(_fake_commands); // clear queue + + std::ifstream file(argv[1], std::ios::in); + std::string str; + while(std::getline(file, str)) + { + std::istringstream ss(str); + FakeCommand cmd; + ss >> cmd.date >> cmd.date_fract >> cmd.company_id >> cmd.cmd >> cmd.p1 >> cmd.p2 >> cmd.tile; + std::string s; + ss.get(); + std::getline(ss, cmd.text); + // fprintf(stderr, "PARSED: company=%u cmd=%u tile=%u p1=%u p2=%u text=%s\n", cmd.company_id, cmd.cmd, cmd.tile, cmd.p1, cmd.p2, cmd.text.c_str()); + _fake_commands.push(cmd); + } + return true; +} + } // namespace citymania diff --git a/src/citymania/cm_console_cmds.hpp b/src/citymania/cm_console_cmds.hpp index 0609224f20..f14df23552 100644 --- a/src/citymania/cm_console_cmds.hpp +++ b/src/citymania/cm_console_cmds.hpp @@ -1,12 +1,16 @@ #ifndef CM_CONSOLE_CMDS_HPP #define CM_CONSOLE_CMDS_HPP +#include "../date_type.h" + namespace citymania { bool ConStep(byte argc, char *argv[]); bool ConExport(byte argc, char *argv[]); bool ConTreeMap(byte argc, char *argv[]); bool ConResetTownGrowth(byte argc, char *argv[]); +bool ConLoadCommands(byte argc, char *argv[]); +void ExecuteFakeCommands(Date date, DateFract date_fract); } // namespace citymania diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 2a3a4e691c..47b25e571f 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -2215,4 +2215,5 @@ void IConsoleStdLibRegister() IConsoleCmdRegister("cmexport", citymania::ConExport); IConsoleCmdRegister("cmtreemap", citymania::ConTreeMap, ConHookNoNetwork); IConsoleCmdRegister("cmresettowngrowth", citymania::ConResetTownGrowth, ConHookNoNetwork); + IConsoleCmdRegister("cmloadcommands", citymania::ConLoadCommands, ConHookNoNetwork); } diff --git a/src/openttd.cpp b/src/openttd.cpp index eb9600044e..d60e0d6b6e 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -70,6 +70,7 @@ #include "citymania/cm_highlight.hpp" #include "citymania/cm_main.hpp" +#include "citymania/cm_console_cmds.hpp" #include #include @@ -1526,6 +1527,7 @@ void GameLoop() * We do this here, because it means that the network is really closed */ NetworkClientConnectGame(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port), COMPANY_SPECTATOR); } + citymania::ExecuteFakeCommands(_date, _date_fract); /* Singleplayer */ StateGameLoop(); }