diff options
author | Michael Lutz <michi@icosahedron.de> | 2021-10-31 19:39:09 +0100 |
---|---|---|
committer | Michael Lutz <michi@icosahedron.de> | 2021-12-16 22:28:32 +0100 |
commit | 0f64ee5ce1548d9cda69917f27c5b1a3cb91823d (patch) | |
tree | 161f0e6ac300e604de61b8203b5a58279637f9eb | |
parent | e740c24eb7a90bc771f5976d64d80639ee7576e5 (diff) | |
download | openttd-0f64ee5ce1548d9cda69917f27c5b1a3cb91823d.tar.xz |
Codechange: Template DoCommandP to automagically reflect the parameters of the command proc.
When finished, this will allow each command handler to take individually
different parameters, obliviating the need for bit-packing.
47 files changed, 374 insertions, 331 deletions
diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp index 340b6db95..5996039c9 100644 --- a/src/ai/ai_gui.cpp +++ b/src/ai/ai_gui.cpp @@ -28,6 +28,8 @@ #include "../hotkeys.h" #include "../core/geometry_func.hpp" #include "../guitimer_func.h" +#include "../company_cmd.h" +#include "../misc_cmd.h" #include "ai.hpp" #include "ai_gui.hpp" @@ -1290,8 +1292,8 @@ struct AIDebugWindow : public Window { case WID_AID_RELOAD_TOGGLE: if (ai_debug_company == OWNER_DEITY) break; /* First kill the company of the AI, then start a new one. This should start the current AI again */ - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | ai_debug_company << 16 | CRR_MANUAL << 24, 0); - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_NEW_AI | ai_debug_company << 16, 0); + Command<CMD_COMPANY_CTRL>::Post(0, CCA_DELETE | ai_debug_company << 16 | CRR_MANUAL << 24, 0, {}); + Command<CMD_COMPANY_CTRL>::Post(0, CCA_NEW_AI | ai_debug_company << 16, 0, {}); break; case WID_AID_SETTINGS: @@ -1330,7 +1332,7 @@ struct AIDebugWindow : public Window { } if (all_unpaused) { /* All scripts have been unpaused => unpause the game. */ - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 0); + Command<CMD_PAUSE>::Post(0, PM_PAUSED_NORMAL, 0, {}); } } } @@ -1379,7 +1381,7 @@ struct AIDebugWindow : public Window { /* Pause the game. */ if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) { - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 1); + Command<CMD_PAUSE>::Post(0, PM_PAUSED_NORMAL, 1, {}); } /* Highlight row that matched */ diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index 98776e52f..af1fb1309 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -71,7 +71,7 @@ static void PlaceAirport(TileIndex tile) uint32 p2_final = p2; if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); - return DoCommandP(CMD_BUILD_AIRPORT, STR_ERROR_CAN_T_BUILD_AIRPORT_HERE, CcBuildAirport, tile, p1, p2_final); + return Command<CMD_BUILD_AIRPORT>::Post(STR_ERROR_CAN_T_BUILD_AIRPORT_HERE, CcBuildAirport, tile, p1, p2_final, {}); } }; diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index d4e392c97..c5cfd04cb 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -25,6 +25,9 @@ #include "rail_gui.h" #include "road_gui.h" #include "widgets/dropdown_func.h" +#include "autoreplace_cmd.h" +#include "group_cmd.h" +#include "settings_cmd.h" #include "widgets/autoreplace_widget.h" @@ -217,7 +220,7 @@ class ReplaceVehicleWindow : public Window { { EngineID veh_from = this->sel_engine[0]; EngineID veh_to = this->sel_engine[1]; - DoCommandP(CMD_SET_AUTOREPLACE, 0, (replace_when_old ? 1 : 0) | (this->sel_group << 16), veh_from + (veh_to << 16)); + Command<CMD_SET_AUTOREPLACE>::Post(0, (replace_when_old ? 1 : 0) | (this->sel_group << 16), veh_from + (veh_to << 16), {}); } public: @@ -541,10 +544,10 @@ public: case WID_RV_TRAIN_WAGONREMOVE_TOGGLE: { const Group *g = Group::GetIfValid(this->sel_group); if (g != nullptr) { - DoCommandP(CMD_SET_GROUP_FLAG, 0, this->sel_group | (GroupFlags::GF_REPLACE_WAGON_REMOVAL << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL) ? 0 : 1) | (_ctrl_pressed << 1)); + Command<CMD_SET_GROUP_FLAG>::Post(0, this->sel_group | (GroupFlags::GF_REPLACE_WAGON_REMOVAL << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL) ? 0 : 1) | (_ctrl_pressed << 1), {}); } else { // toggle renew_keep_length - DoCommandP(CMD_CHANGE_COMPANY_SETTING, 0, 0, Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, "company.renew_keep_length"); + Command<CMD_CHANGE_COMPANY_SETTING>::Post(0, 0, Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, "company.renew_keep_length"); } break; } @@ -562,7 +565,7 @@ public: case WID_RV_STOP_REPLACE: { // Stop replacing EngineID veh_from = this->sel_engine[0]; - DoCommandP(CMD_SET_AUTOREPLACE, 0, this->sel_group << 16, veh_from + (INVALID_ENGINE << 16)); + Command<CMD_SET_AUTOREPLACE>::Post(0, this->sel_group << 16, veh_from + (INVALID_ENGINE << 16), {}); break; } @@ -584,7 +587,7 @@ public: if (click_side == 0 && _ctrl_pressed && e != INVALID_ENGINE && (GetGroupNumEngines(_local_company, sel_group, e) == 0 || GetGroupNumEngines(_local_company, ALL_GROUP, e) == 0)) { EngineID veh_from = e; - DoCommandP(CMD_SET_AUTOREPLACE, 0, this->sel_group << 16, veh_from + (INVALID_ENGINE << 16)); + Command<CMD_SET_AUTOREPLACE>::Post(0, this->sel_group << 16, veh_from + (INVALID_ENGINE << 16), {}); break; } diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp index abd1f3da5..e9e1f48f5 100644 --- a/src/bridge_gui.cpp +++ b/src/bridge_gui.cpp @@ -119,8 +119,8 @@ private: case TRANSPORT_ROAD: _last_roadbridge_type = this->bridges->at(i).index; break; default: break; } - DoCommandP(CMD_BUILD_BRIDGE, STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, CcBuildBridge, - this->end_tile, this->start_tile, this->type | this->bridges->at(i).index); + Command<CMD_BUILD_BRIDGE>::Post(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, CcBuildBridge, + this->end_tile, this->start_tile, this->type | this->bridges->at(i).index, {}); } /** Sort the builable bridges */ @@ -385,7 +385,7 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo default: break; // water ways and air routes don't have bridge types } if (_ctrl_pressed && CheckBridgeAvailability(last_bridge_type, bridge_len).Succeeded()) { - DoCommandP(CMD_BUILD_BRIDGE, STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, CcBuildBridge, end, start, type | last_bridge_type); + Command<CMD_BUILD_BRIDGE>::Post(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, CcBuildBridge, end, start, type | last_bridge_type, {}); return; } diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 9082de5a9..639bab7a9 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -30,6 +30,7 @@ #include "cargotype.h" #include "core/geometry_func.hpp" #include "autoreplace_func.h" +#include "engine_cmd.h" #include "train_cmd.h" #include "vehicle_cmd.h" @@ -1460,7 +1461,7 @@ struct BuildVehicleWindow : Window { case WID_BV_SHOW_HIDE: { const Engine *e = (this->sel_engine == INVALID_ENGINE) ? nullptr : Engine::Get(this->sel_engine); if (e != nullptr) { - DoCommandP(CMD_SET_VEHICLE_VISIBILITY, 0, 0, this->sel_engine | (e->IsHidden(_current_company) ? 0 : (1u << 31))); + Command<CMD_SET_VEHICLE_VISIBILITY>::Post(0, 0, this->sel_engine | (e->IsHidden(_current_company) ? 0 : (1u << 31)), {}); } break; } @@ -1471,7 +1472,7 @@ struct BuildVehicleWindow : Window { CommandCallback *callback = (this->vehicle_type == VEH_TRAIN && RailVehInfo(sel_eng)->railveh_type == RAILVEH_WAGON) ? CcBuildWagon : CcBuildPrimaryVehicle; CargoID cargo = this->cargo_filter[this->cargo_filter_criteria]; if (cargo == CF_ANY || cargo == CF_ENGINES) cargo = CF_NONE; - DoCommandP(CMD_BUILD_VEHICLE, GetCmdBuildVehMsg(this->vehicle_type), callback, this->window_number, sel_eng | (cargo << 24), 0); + Command<CMD_BUILD_VEHICLE>::Post(GetCmdBuildVehMsg(this->vehicle_type), callback, this->window_number, sel_eng | (cargo << 24), 0, {}); } break; } @@ -1636,7 +1637,7 @@ struct BuildVehicleWindow : Window { { if (str == nullptr) return; - DoCommandP(CMD_RENAME_ENGINE, STR_ERROR_CAN_T_RENAME_TRAIN_TYPE + this->vehicle_type, 0, this->rename_engine, 0, str); + Command<CMD_RENAME_ENGINE>::Post(STR_ERROR_CAN_T_RENAME_TRAIN_TYPE + this->vehicle_type, 0, this->rename_engine, 0, str); } void OnDropdownSelect(int widget, int index) override diff --git a/src/cheat_gui.cpp b/src/cheat_gui.cpp index 84884b3de..fcc9a3ef0 100644 --- a/src/cheat_gui.cpp +++ b/src/cheat_gui.cpp @@ -28,6 +28,7 @@ #include "tile_map.h" #include "newgrf.h" #include "error.h" +#include "misc_cmd.h" #include "widgets/cheat_widget.h" @@ -54,7 +55,7 @@ static int32 _money_cheat_amount = 10000000; */ static int32 ClickMoneyCheat(int32 p1, int32 p2) { - DoCommandP(CMD_MONEY_CHEAT, 0, (uint32)(p2 * _money_cheat_amount), 0); + Command<CMD_MONEY_CHEAT>::Post(0, (uint32)(p2 * _money_cheat_amount), 0, {}); return _money_cheat_amount; } diff --git a/src/command.cpp b/src/command.cpp index 69cbaa6c9..dc536a843 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -213,51 +213,50 @@ void CommandHelperBase::InternalDoAfter(CommandCost &res, DoCommandFlag flags, b } } -/*! - * Toplevel network safe docommand function for the current company. Must not be called recursively. - * The callback is called when the command succeeded or failed. The parameters - * \a tile, \a p1, and \a p2 are from the #CommandProc function. The parameter \a cmd is the command to execute. - * The parameter \a my_cmd is used to indicate if the command is from a company or the server. - * - * @param cmd The command to execute (a CMD_* value) - * @param callback A callback function to call after the command is finished - * @param my_cmd indicator if the command is from a company or server (to display error messages for a user) - * @param network_command execute the command without sending it on the network - * @param tile The tile to perform a command on (see #CommandProc) - * @param p1 Additional data for the command (see #CommandProc) - * @param p2 Additional data for the command (see #CommandProc) - * @param text The text to pass - * @return \c true if the command succeeded, else \c false. +/** + * Decide what to do with the command depending on current game state. + * @param cmd Command to execute. + * @param flags Command flags. + * @param tile Tile of command execution. + * @param err_message Message prefix to show on error. + * @param network_command Does this command come from the network? + * @return error state + do only cost estimation? + send to network only? */ -static bool DoCommandP(Commands cmd, StringID err_message, CommandCallback *callback, bool my_cmd, bool network_command, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +std::tuple<bool, bool, bool> CommandHelperBase::InternalPostBefore(Commands cmd, CommandFlags flags, TileIndex tile, StringID err_message, bool network_command) { /* Cost estimation is generally only done when the * local user presses shift while doing something. * However, in case of incoming network commands, * map generation or the pause button we do want * to execute. */ - bool estimate_only = _shift_pressed && IsLocalCompany() && - !_generating_world && - !network_command && - !(GetCommandFlags(cmd) & CMD_NO_EST); + bool estimate_only = _shift_pressed && IsLocalCompany() && !_generating_world && !network_command && !(flags & CMD_NO_EST); /* We're only sending the command, so don't do * fancy things for 'success'. */ bool only_sending = _networking && !network_command; - /* Where to show the message? */ - int x = TileX(tile) * TILE_SIZE; - int y = TileY(tile) * TILE_SIZE; - if (_pause_mode != PM_UNPAUSED && !IsCommandAllowedWhilePaused(cmd) && !estimate_only) { - ShowErrorMessage(err_message, STR_ERROR_NOT_ALLOWED_WHILE_PAUSED, WL_INFO, x, y); - return false; + ShowErrorMessage(err_message, STR_ERROR_NOT_ALLOWED_WHILE_PAUSED, WL_INFO, TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE); + return { true, estimate_only, only_sending }; + } else { + return { false, estimate_only, only_sending }; } +} - /* Only set p2 when the command does not come from the network. */ - if (!network_command && GetCommandFlags(cmd) & CMD_CLIENT_ID && p2 == 0) p2 = CLIENT_ID_SERVER; +/** + * Process result of executing a command, possibly displaying any error to the player. + * @param res Command result. + * @param tile Tile of command execution. + * @param estimate_only Is this just cost estimation? + * @param only_sending Was the command only sent to network? + * @param err_message Message prefix to show on error. + * @param my_cmd Is the command from this client? + */ +void CommandHelperBase::InternalPostResult(const CommandCost &res, TileIndex tile, bool estimate_only, bool only_sending, StringID err_message, bool my_cmd) +{ + int x = TileX(tile) * TILE_SIZE; + int y = TileY(tile) * TILE_SIZE; - CommandCost res = DoCommandPInternal(cmd, err_message, callback, my_cmd, estimate_only, network_command, tile, p1, p2, text); if (res.Failed()) { /* Only show the error when it's for us. */ if (estimate_only || (IsLocalCompany() && err_message != 0 && my_cmd)) { @@ -273,95 +272,6 @@ static bool DoCommandP(Commands cmd, StringID err_message, CommandCallback *call * concept of cost, so don't show it there either. */ ShowCostOrIncomeAnimation(x, y, GetSlopePixelZ(x, y), res.GetCost()); } - - if (!estimate_only && !only_sending && callback != nullptr) { - callback(res, cmd, tile, p1, p2, text); - } - - return res.Succeeded(); -} - -/** - * Shortcut for the long DoCommandP when not using a callback or error message. - * @param cmd The command to execute (a CMD_* value) - * @param tile The tile to perform a command on (see #CommandProc) - * @param p1 Additional data for the command (see #CommandProc) - * @param p2 Additional data for the command (see #CommandProc) - * @param text The text to pass - * @return \c true if the command succeeded, else \c false. - */ -bool DoCommandP(Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) -{ - return DoCommandP(cmd, STR_NULL, nullptr, true, false, tile, p1, p2, text); -} - -/** - * Shortcut for the long DoCommandP when not using an error message. - * @param cmd The command to execute (a CMD_* value) - * @param callback A callback function to call after the command is finished - * @param tile The tile to perform a command on (see #CommandProc) - * @param p1 Additional data for the command (see #CommandProc) - * @param p2 Additional data for the command (see #CommandProc) - * @param text The text to pass - * @return \c true if the command succeeded, else \c false. - */ -bool DoCommandP(Commands cmd, CommandCallback *callback, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) -{ - return DoCommandP(cmd, STR_NULL, callback, true, false, tile, p1, p2, text); -} - -/** - * Shortcut for the long DoCommandP when not using a callback. - * @param cmd The command to execute (a CMD_* value) - * @param err_message Message prefix to show on error - * @param tile The tile to perform a command on (see #CommandProc) - * @param p1 Additional data for the command (see #CommandProc) - * @param p2 Additional data for the command (see #CommandProc) - * @param text The text to pass - * @return \c true if the command succeeded, else \c false. - */ -bool DoCommandP(Commands cmd, StringID err_message, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) -{ - return DoCommandP(cmd, err_message, nullptr, true, false, tile, p1, p2, text); -} - -/*! - * Toplevel network safe docommand function for the current company. Must not be called recursively. - * The callback is called when the command succeeded or failed. The parameters - * \a tile, \a p1, and \a p2 are from the #CommandProc function. The parameter \a cmd is the command to execute. - * - * @param cmd The command to execute (a CMD_* value) - * @param err_message Message prefix to show on error - * @param callback A callback function to call after the command is finished - * @param tile The tile to perform a command on (see #CommandProc) - * @param p1 Additional data for the command (see #CommandProc) - * @param p2 Additional data for the command (see #CommandProc) - * @param text The text to pass - * @return \c true if the command succeeded, else \c false. - */ -bool DoCommandP(Commands cmd, StringID err_message, CommandCallback *callback, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) -{ - return DoCommandP(cmd, err_message, callback, true, false, tile, p1, p2, text); -} - -/** - * Toplevel network safe docommand function for the current company. Must not be called recursively. - * The callback is called when the command succeeded or failed. The parameters - * \a tile, \a p1, and \a p2 are from the #CommandProc function. The parameter \a cmd is the command to execute. - * - * @param cmd The command to execute (a CMD_* value) - * @param err_message Message prefix to show on error - * @param callback A callback function to call after the command is finished - * @param my_cmd indicator if the command is from a company or server (to display error messages for a user) - * @param tile The tile to perform a command on (see #CommandProc) - * @param p1 Additional data for the command (see #CommandProc) - * @param p2 Additional data for the command (see #CommandProc) - * @param text The text to pass - * @return \c true if the command succeeded, else \c false. - */ -bool InjectNetworkCommand(Commands cmd, StringID err_message, CommandCallback *callback, bool my_cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) -{ - return DoCommandP(cmd, err_message, callback, my_cmd, true, tile, p1, p2, text); } /** Helper to format command parameters into a hex string. */ diff --git a/src/command_func.h b/src/command_func.h index 1c24221cd..6a9b93ff5 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -37,14 +37,6 @@ static const CommandCost CMD_ERROR = CommandCost(INVALID_STRING_ID); /** Storage buffer for serialized command data. */ typedef std::vector<byte> CommandDataBuffer; - -bool DoCommandP(Commands cmd, StringID err_message, CommandCallback *callback, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); -bool DoCommandP(Commands cmd, StringID err_message, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); -bool DoCommandP(Commands cmd, CommandCallback *callback, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); -bool DoCommandP(Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); - -bool InjectNetworkCommand(Commands cmd, StringID err_message, CommandCallback *callback, bool my_cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); - CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallback *callback, bool my_cmd, bool estimate_only, bool network_command, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); @@ -96,6 +88,8 @@ class CommandHelperBase { protected: static void InternalDoBefore(bool top_level, bool test); static void InternalDoAfter(CommandCost &res, DoCommandFlag flags, bool top_level, bool test); + static std::tuple<bool, bool, bool> InternalPostBefore(Commands cmd, CommandFlags flags, TileIndex tile, StringID err_message, bool network_command); + static void InternalPostResult(const CommandCost &res, TileIndex tile, bool estimate_only, bool only_sending, StringID err_message, bool my_cmd); }; /** @@ -147,6 +141,83 @@ public: return res; } + + /** + * Shortcut for the long Post when not using a callback. + * @param err_message Message prefix to show on error + * @param args Parameters for the command + */ + static inline bool Post(StringID err_message, Targs... args) { return Post(err_message, nullptr, std::forward<Targs>(args)...); } + /** + * Shortcut for the long Post when not using an error message. + * @param callback A callback function to call after the command is finished + * @param args Parameters for the command + */ + static inline bool Post(CommandCallback *callback, Targs... args) { return Post((StringID)0, callback, std::forward<Targs>(args)...); } + /** + * Shortcut for the long Post when not using a callback or an error message. + * @param args Parameters for the command + */ + static inline bool Post(Targs... args) { return Post((StringID)0, nullptr, std::forward<Targs>(args)...); } + + /** + * Top-level network safe command execution for the current company. + * Must not be called recursively. The callback is called when the + * command succeeded or failed. + * + * @param err_message Message prefix to show on error + * @param callback A callback function to call after the command is finished + * @param args Parameters for the command + * @return \c true if the command succeeded, else \c false. + */ + static bool Post(StringID err_message, CommandCallback *callback, Targs... args) + { + return InternalPost(err_message, callback, true, false, std::forward_as_tuple(args...)); + } + + /** + * Execute a command coming from the network. + * @param err_message Message prefix to show on error + * @param callback A callback function to call after the command is finished + * @param my_cmd indicator if the command is from a company or server (to display error messages for a user) + * @param location Tile location for user feedback. + * @param args Parameters for the command + * @return \c true if the command succeeded, else \c false. + */ + static bool PostFromNet(StringID err_message, CommandCallback *callback, bool my_cmd, TileIndex location, std::tuple<Targs...> args) + { + return InternalPost(err_message, callback, my_cmd, true, location, std::move(args)); + } + +protected: + static bool InternalPost(StringID err_message, CommandCallback *callback, bool my_cmd, bool network_command, std::tuple<Targs...> args) + { + /* Where to show the message? */ + TileIndex tile{}; + if constexpr (std::is_same_v<TileIndex, std::tuple_element_t<0, decltype(args)>>) { + tile = std::get<0>(args); + } + + return InternalPost(err_message, callback, my_cmd, network_command, tile, std::move(args)); + } + + static bool InternalPost(StringID err_message, CommandCallback *callback, bool my_cmd, bool network_command, TileIndex tile, std::tuple<Targs...> args) + { + auto [err, estimate_only, only_sending] = InternalPostBefore(Tcmd, GetCommandFlags<Tcmd>(), tile, err_message, network_command); + if (err) return false; + + /* Only set p2 when the command does not come from the network. */ + if (!network_command && GetCommandFlags<Tcmd>() & CMD_CLIENT_ID && std::get<2>(args) == 0) std::get<2>(args) = CLIENT_ID_SERVER; + + CommandCost res = std::apply(DoCommandPInternal, std::tuple_cat(std::make_tuple(Tcmd, err_message, callback, my_cmd, estimate_only, network_command), args)); + InternalPostResult(res, tile, estimate_only, only_sending, err_message, my_cmd); + + if (!estimate_only && !only_sending && callback != nullptr) { + std::apply(callback, std::tuple_cat(std::tuple<const CommandCost &, Commands>{ res, Tcmd }, args)); + } + + return res.Succeeded(); + } }; template <Commands Tcmd> diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 6bd60659b..cf44af25c 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -604,7 +604,7 @@ static bool MaybeStartNewCompany() if (n < (uint)_settings_game.difficulty.max_no_competitors) { /* Send a command to all clients to start up a new AI. * Works fine for Multiplayer and Singleplayer */ - return DoCommandP(CMD_COMPANY_CTRL, 0, CCA_NEW_AI | INVALID_COMPANY << 16, 0); + return Command<CMD_COMPANY_CTRL>::Post(0, CCA_NEW_AI | INVALID_COMPANY << 16, 0, {}); } return false; diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 7a6e68dea..c2695b910 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -37,6 +37,11 @@ #include "station_func.h" #include "zoom_func.h" #include "sortlist_type.h" +#include "company_cmd.h" +#include "economy_cmd.h" +#include "group_cmd.h" +#include "misc_cmd.h" +#include "object_cmd.h" #include "widgets/company_widget.h" @@ -435,11 +440,11 @@ struct CompanyFinancesWindow : Window { break; case WID_CF_INCREASE_LOAN: // increase loan - DoCommandP(CMD_INCREASE_LOAN, STR_ERROR_CAN_T_BORROW_ANY_MORE_MONEY, 0, 0, _ctrl_pressed); + Command<CMD_INCREASE_LOAN>::Post(STR_ERROR_CAN_T_BORROW_ANY_MORE_MONEY, 0, 0, _ctrl_pressed, {}); break; case WID_CF_REPAY_LOAN: // repay loan - DoCommandP(CMD_DECREASE_LOAN, STR_ERROR_CAN_T_REPAY_LOAN, 0, 0, _ctrl_pressed); + Command<CMD_DECREASE_LOAN>::Post(STR_ERROR_CAN_T_REPAY_LOAN, 0, 0, _ctrl_pressed, {}); break; case WID_CF_INFRASTRUCTURE: // show infrastructure details @@ -995,12 +1000,12 @@ public: for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) { /* Changed colour for the selected scheme, or all visible schemes if CTRL is pressed. */ if (HasBit(this->sel, scheme) || (_ctrl_pressed && _livery_class[scheme] == this->livery_class && HasBit(_loaded_newgrf_features.used_liveries, scheme))) { - DoCommandP(CMD_SET_COMPANY_COLOUR, 0, scheme | (widget == WID_SCL_PRI_COL_DROPDOWN ? 0 : 256), index); + Command<CMD_SET_COMPANY_COLOUR>::Post(0, scheme | (widget == WID_SCL_PRI_COL_DROPDOWN ? 0 : 256), index, {}); } } } else { /* Setting group livery */ - DoCommandP(CMD_SET_GROUP_LIVERY, 0, this->sel, (widget == WID_SCL_PRI_COL_DROPDOWN ? 0 : 256) | (index << 16)); + Command<CMD_SET_GROUP_LIVERY>::Post(0, this->sel, (widget == WID_SCL_PRI_COL_DROPDOWN ? 0 : 256) | (index << 16), {}); } } @@ -1581,7 +1586,7 @@ public: /* OK button */ case WID_SCMF_ACCEPT: - DoCommandP(CMD_SET_COMPANY_MANAGER_FACE, 0, 0, this->face); + Command<CMD_SET_COMPANY_MANAGER_FACE>::Post(0, 0, this->face, {}); FALLTHROUGH; /* Cancel button */ @@ -2576,11 +2581,11 @@ struct CompanyWindow : Window break; case WID_C_BUY_SHARE: - DoCommandP(CMD_BUY_SHARE_IN_COMPANY, STR_ERROR_CAN_T_BUY_25_SHARE_IN_THIS, (TileIndex)0, this->window_number, 0); + Command<CMD_BUY_SHARE_IN_COMPANY>::Post(STR_ERROR_CAN_T_BUY_25_SHARE_IN_THIS, 0, this->window_number, 0, {}); break; case WID_C_SELL_SHARE: - DoCommandP(CMD_SELL_SHARE_IN_COMPANY, STR_ERROR_CAN_T_SELL_25_SHARE_IN, (TileIndex)0, this->window_number, 0); + Command<CMD_SELL_SHARE_IN_COMPANY>::Post(STR_ERROR_CAN_T_SELL_25_SHARE_IN, 0, this->window_number, 0, {}); break; case WID_C_COMPANY_PASSWORD: @@ -2613,7 +2618,7 @@ struct CompanyWindow : Window void OnPlaceObject(Point pt, TileIndex tile) override { - if (DoCommandP(CMD_BUILD_OBJECT, STR_ERROR_CAN_T_BUILD_COMPANY_HEADQUARTERS, tile, OBJECT_HQ, 0) && !_shift_pressed) { + if (Command<CMD_BUILD_OBJECT>::Post(STR_ERROR_CAN_T_BUILD_COMPANY_HEADQUARTERS, tile, OBJECT_HQ, 0, {}) && !_shift_pressed) { ResetObjectToPlace(); this->RaiseButtons(); } @@ -2635,16 +2640,16 @@ struct CompanyWindow : Window Money money = (Money)(strtoull(str, nullptr, 10) / _currency->rate); uint32 money_c = Clamp(ClampToI32(money), 0, 20000000); // Clamp between 20 million and 0 - DoCommandP(CMD_GIVE_MONEY, STR_ERROR_CAN_T_GIVE_MONEY, 0, money_c, this->window_number); + Command<CMD_GIVE_MONEY>::Post(STR_ERROR_CAN_T_GIVE_MONEY, 0, money_c, this->window_number, {}); break; } case WID_C_PRESIDENT_NAME: - DoCommandP(CMD_RENAME_PRESIDENT, STR_ERROR_CAN_T_CHANGE_PRESIDENT, 0, 0, 0, str); + Command<CMD_RENAME_PRESIDENT>::Post(STR_ERROR_CAN_T_CHANGE_PRESIDENT, 0, 0, 0, str); break; case WID_C_COMPANY_NAME: - DoCommandP(CMD_RENAME_COMPANY, STR_ERROR_CAN_T_CHANGE_COMPANY_NAME, 0, 0, 0, str); + Command<CMD_RENAME_COMPANY>::Post(STR_ERROR_CAN_T_CHANGE_COMPANY_NAME, 0, 0, 0, str); break; case WID_C_COMPANY_JOIN: @@ -2771,7 +2776,7 @@ struct BuyCompanyWindow : Window { break; case WID_BC_YES: - DoCommandP(CMD_BUY_COMPANY, STR_ERROR_CAN_T_BUY_COMPANY, (TileIndex)0, this->window_number, 0); + Command<CMD_BUY_COMPANY>::Post(STR_ERROR_CAN_T_BUY_COMPANY, 0, this->window_number, 0, {}); break; } } diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 040b938fe..42a94aa89 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -42,6 +42,8 @@ #include "game/game.hpp" #include "table/strings.h" #include "walltime_func.h" +#include "company_cmd.h" +#include "misc_cmd.h" #include "safeguards.h" @@ -630,7 +632,7 @@ DEF_CONSOLE_CMD(ConPauseGame) } if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) { - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 1); + Command<CMD_PAUSE>::Post(0, PM_PAUSED_NORMAL, 1, {}); if (!_networking) IConsolePrint(CC_DEFAULT, "Game paused."); } else { IConsolePrint(CC_DEFAULT, "Game is already paused."); @@ -652,7 +654,7 @@ DEF_CONSOLE_CMD(ConUnpauseGame) } if ((_pause_mode & PM_PAUSED_NORMAL) != PM_UNPAUSED) { - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 0); + Command<CMD_PAUSE>::Post(0, PM_PAUSED_NORMAL, 0, {}); if (!_networking) IConsolePrint(CC_DEFAULT, "Game unpaused."); } else if ((_pause_mode & PM_PAUSED_ERROR) != PM_UNPAUSED) { IConsolePrint(CC_DEFAULT, "Game is in error state and cannot be unpaused via console."); @@ -863,7 +865,7 @@ DEF_CONSOLE_CMD(ConResetCompany) } /* It is safe to remove this company */ - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | index << 16 | CRR_MANUAL << 24, 0); + Command<CMD_COMPANY_CTRL>::Post(0, CCA_DELETE | index << 16 | CRR_MANUAL << 24, 0, {}); IConsolePrint(CC_DEFAULT, "Company deleted."); return true; @@ -1220,7 +1222,7 @@ DEF_CONSOLE_CMD(ConStartAI) } /* Start a new AI company */ - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_NEW_AI | INVALID_COMPANY << 16, 0); + Command<CMD_COMPANY_CTRL>::Post(0, CCA_NEW_AI | INVALID_COMPANY << 16, 0, {}); return true; } @@ -1256,8 +1258,8 @@ DEF_CONSOLE_CMD(ConReloadAI) } /* First kill the company of the AI, then start a new one. This should start the current AI again */ - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | company_id << 16 | CRR_MANUAL << 24, 0); - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_NEW_AI | company_id << 16, 0); + Command<CMD_COMPANY_CTRL>::Post(0, CCA_DELETE | company_id << 16 | CRR_MANUAL << 24, 0, {}); + Command<CMD_COMPANY_CTRL>::Post(0, CCA_NEW_AI | company_id << 16, 0, {}); IConsolePrint(CC_DEFAULT, "AI reloaded."); return true; @@ -1294,7 +1296,7 @@ DEF_CONSOLE_CMD(ConStopAI) } /* Now kill the company of the AI. */ - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | company_id << 16 | CRR_MANUAL << 24, 0); + Command<CMD_COMPANY_CTRL>::Post(0, CCA_DELETE | company_id << 16 | CRR_MANUAL << 24, 0, {}); IConsolePrint(CC_DEFAULT, "AI stopped, company deleted."); return true; diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 0aba48e40..76e03ef39 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -26,6 +26,9 @@ #include "vehiclelist.h" #include "order_backup.h" #include "zoom_func.h" +#include "depot_cmd.h" +#include "train_cmd.h" +#include "vehicle_cmd.h" #include "widgets/depot_widget.h" @@ -142,7 +145,7 @@ static void TrainDepotMoveVehicle(const Vehicle *wagon, VehicleID sel, const Veh if (wagon == v) return; - DoCommandP(CMD_MOVE_RAIL_VEHICLE, STR_ERROR_CAN_T_MOVE_VEHICLE, v->tile, v->index | (_ctrl_pressed ? 1 : 0) << 20, wagon == nullptr ? INVALID_VEHICLE : wagon->index); + Command<CMD_MOVE_RAIL_VEHICLE>::Post(STR_ERROR_CAN_T_MOVE_VEHICLE, v->tile, v->index | (_ctrl_pressed ? 1 : 0) << 20, wagon == nullptr ? INVALID_VEHICLE : wagon->index, {}); } static VehicleCellSize _base_block_sizes_depot[VEH_COMPANY_END]; ///< Cell size for vehicle images in the depot view. @@ -803,7 +806,7 @@ struct DepotWindow : Window { case WID_D_STOP_ALL: case WID_D_START_ALL: { VehicleListIdentifier vli(VL_DEPOT_LIST, this->type, this->owner); - DoCommandP(CMD_MASS_START_STOP, this->window_number, (widget == WID_D_START_ALL ? (1 << 0) : 0), vli.Pack()); + Command<CMD_MASS_START_STOP>::Post(this->window_number, (widget == WID_D_START_ALL ? (1 << 0) : 0), vli.Pack(), {}); break; } @@ -826,7 +829,7 @@ struct DepotWindow : Window { break; case WID_D_AUTOREPLACE: - DoCommandP(CMD_DEPOT_MASS_AUTOREPLACE, this->window_number, this->type, 0); + Command<CMD_DEPOT_MASS_AUTOREPLACE>::Post(this->window_number, this->type, 0, {}); break; } @@ -837,7 +840,7 @@ struct DepotWindow : Window { if (str == nullptr) return; /* Do depot renaming */ - DoCommandP(CMD_RENAME_DEPOT, STR_ERROR_CAN_T_RENAME_DEPOT, 0, this->GetDepotIndex(), 0, str); + Command<CMD_RENAME_DEPOT>::Post(STR_ERROR_CAN_T_RENAME_DEPOT, 0, this->GetDepotIndex(), 0, str); } bool OnRightClick(Point pt, int widget) override @@ -905,10 +908,10 @@ struct DepotWindow : Window { { if (_ctrl_pressed) { /* Share-clone, do not open new viewport, and keep tool active */ - DoCommandP(CMD_CLONE_VEHICLE, STR_ERROR_CAN_T_BUY_TRAIN + v->type, this->window_number, v->index, 1); + Command<CMD_CLONE_VEHICLE>::Post(STR_ERROR_CAN_T_BUY_TRAIN + v->type, this->window_number, v->index, 1, {}); } else { - /* Copy-clone, open viewport for new vehicle, and deselect the tool (assume player wants to changs things on new vehicle) */ - if (DoCommandP(CMD_CLONE_VEHICLE, STR_ERROR_CAN_T_BUY_TRAIN + v->type, CcCloneVehicle, this->window_number, v->index, 0)) { + /* Copy-clone, open viewport for new vehicle, and deselect the tool (assume player wants to change things on new vehicle) */ + if (Command<CMD_CLONE_VEHICLE>::Post(STR_ERROR_CAN_T_BUY_TRAIN + v->type, CcCloneVehicle, this->window_number, v->index, 0, {})) { ResetObjectToPlace(); } } @@ -1002,7 +1005,7 @@ struct DepotWindow : Window { if (this->GetVehicleFromDepotWndPt(pt.x - nwi->pos_x, pt.y - nwi->pos_y, &v, &gdvp) == MODE_DRAG_VEHICLE && sel != INVALID_VEHICLE) { if (gdvp.wagon != nullptr && gdvp.wagon->index == sel && _ctrl_pressed) { - DoCommandP(CMD_REVERSE_TRAIN_DIRECTION, STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE, Vehicle::Get(sel)->tile, Vehicle::Get(sel)->index, true); + Command<CMD_REVERSE_TRAIN_DIRECTION>::Post(STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE, Vehicle::Get(sel)->tile, Vehicle::Get(sel)->index, true, {}); } else if (gdvp.wagon == nullptr || gdvp.wagon->index != sel) { this->vehicle_over = INVALID_VEHICLE; TrainDepotMoveVehicle(gdvp.wagon, sel, gdvp.head); @@ -1027,7 +1030,7 @@ struct DepotWindow : Window { this->SetDirty(); int sell_cmd = (v->type == VEH_TRAIN && (widget == WID_D_SELL_CHAIN || _ctrl_pressed)) ? 1 : 0; - DoCommandP(CMD_SELL_VEHICLE, GetCmdSellVehMsg(v->type), v->tile, v->index | sell_cmd << 20 | MAKE_ORDER_BACKUP_FLAG, 0); + Command<CMD_SELL_VEHICLE>::Post(GetCmdSellVehMsg(v->type), v->tile, v->index | sell_cmd << 20 | MAKE_ORDER_BACKUP_FLAG, 0, {}); break; } @@ -1091,7 +1094,7 @@ static void DepotSellAllConfirmationCallback(Window *win, bool confirmed) DepotWindow *w = (DepotWindow*)win; TileIndex tile = w->window_number; byte vehtype = w->type; - DoCommandP(CMD_DEPOT_SELL_ALL_VEHICLES, tile, vehtype, 0); + Command<CMD_DEPOT_SELL_ALL_VEHICLES>::Post(tile, vehtype, 0, {}); } } diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index 571bfdcec..3cb101f7a 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -28,6 +28,8 @@ #include "tunnelbridge_cmd.h" #include "dock_cmd.h" #include "station_cmd.h" +#include "water_cmd.h" +#include "waypoint_cmd.h" #include "widgets/dock_widget.h" @@ -194,7 +196,7 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_LOCK: // Build lock button - DoCommandP(CMD_BUILD_LOCK, STR_ERROR_CAN_T_BUILD_LOCKS, CcBuildDocks, tile, 0, 0); + Command<CMD_BUILD_LOCK>::Post(STR_ERROR_CAN_T_BUILD_LOCKS, CcBuildDocks, tile, 0, 0, {}); break; case WID_DT_DEMOLISH: // Demolish aka dynamite button @@ -202,7 +204,7 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_DEPOT: // Build depot button - DoCommandP(CMD_BUILD_SHIP_DEPOT, STR_ERROR_CAN_T_BUILD_SHIP_DEPOT, CcBuildDocks, tile, _ship_depot_direction, 0); + Command<CMD_BUILD_SHIP_DEPOT>::Post(STR_ERROR_CAN_T_BUILD_SHIP_DEPOT, CcBuildDocks, tile, _ship_depot_direction, 0, {}); break; case WID_DT_STATION: { // Build station button @@ -220,7 +222,7 @@ struct BuildDocksToolbarWindow : Window { uint32 p2_final = p2; if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); - return DoCommandP(CMD_BUILD_DOCK, STR_ERROR_CAN_T_BUILD_DOCK_HERE, CcBuildDocks, tile, p1, p2_final); + return Command<CMD_BUILD_DOCK>::Post(STR_ERROR_CAN_T_BUILD_DOCK_HERE, CcBuildDocks, tile, p1, p2_final, {}); } }; @@ -229,7 +231,7 @@ struct BuildDocksToolbarWindow : Window { } case WID_DT_BUOY: // Build buoy button - DoCommandP(CMD_BUILD_BUOY, STR_ERROR_CAN_T_POSITION_BUOY_HERE, CcBuildDocks, tile, 0, 0); + Command<CMD_BUILD_BUOY>::Post(STR_ERROR_CAN_T_POSITION_BUOY_HERE, CcBuildDocks, tile, 0, 0, {}); break; case WID_DT_RIVER: // Build river button (in scenario editor) @@ -237,7 +239,7 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_BUILD_AQUEDUCT: // Build aqueduct button - DoCommandP(CMD_BUILD_BRIDGE, STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE, CcBuildBridge, tile, GetOtherAqueductEnd(tile), TRANSPORT_WATER << 15); + Command<CMD_BUILD_BRIDGE>::Post(STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE, CcBuildBridge, tile, GetOtherAqueductEnd(tile), TRANSPORT_WATER << 15, {}); break; default: NOT_REACHED(); @@ -257,10 +259,10 @@ struct BuildDocksToolbarWindow : Window { GUIPlaceProcDragXY(select_proc, start_tile, end_tile); break; case DDSP_CREATE_WATER: - DoCommandP(CMD_BUILD_CANAL, STR_ERROR_CAN_T_BUILD_CANALS, CcPlaySound_CONSTRUCTION_WATER, end_tile, start_tile, (_game_mode == GM_EDITOR && _ctrl_pressed) ? WATER_CLASS_SEA : WATER_CLASS_CANAL); + Command<CMD_BUILD_CANAL>::Post(STR_ERROR_CAN_T_BUILD_CANALS, CcPlaySound_CONSTRUCTION_WATER, end_tile, start_tile, (_game_mode == GM_EDITOR && _ctrl_pressed) ? WATER_CLASS_SEA : WATER_CLASS_CANAL, {}); break; case DDSP_CREATE_RIVER: - DoCommandP(CMD_BUILD_CANAL, STR_ERROR_CAN_T_PLACE_RIVERS, CcPlaySound_CONSTRUCTION_WATER, end_tile, start_tile, WATER_CLASS_RIVER | (_ctrl_pressed ? 1 << 2 : 0)); + Command<CMD_BUILD_CANAL>::Post(STR_ERROR_CAN_T_PLACE_RIVERS, CcPlaySound_CONSTRUCTION_WATER, end_tile, start_tile, WATER_CLASS_RIVER | (_ctrl_pressed ? 1 << 2 : 0), {}); break; default: break; diff --git a/src/economy.cpp b/src/economy.cpp index e7daf8e3d..c65d997b8 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -48,6 +48,7 @@ #include "goal_base.h" #include "story_base.h" #include "linkgraph/refresh.h" +#include "company_cmd.h" #include "economy_cmd.h" #include "vehicle_cmd.h" @@ -629,7 +630,7 @@ static void CompanyCheckBankrupt(Company *c) * player we are sure (the above check) that we are not the local * company and thus we won't be moved. */ if (!_networking || _network_server) { - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | (c->index << 16) | (CRR_BANKRUPT << 24), 0); + Command<CMD_COMPANY_CTRL>::Post(0, CCA_DELETE | (c->index << 16) | (CRR_BANKRUPT << 24), 0, {}); return; } break; diff --git a/src/engine_gui.cpp b/src/engine_gui.cpp index 6710967f4..c3b9553a7 100644 --- a/src/engine_gui.cpp +++ b/src/engine_gui.cpp @@ -23,6 +23,7 @@ #include "roadveh.h" #include "ship.h" #include "aircraft.h" +#include "engine_cmd.h" #include "widgets/engine_widget.h" @@ -125,7 +126,7 @@ struct EnginePreviewWindow : Window { { switch (widget) { case WID_EP_YES: - DoCommandP(CMD_WANT_ENGINE_PREVIEW, 0, this->window_number, 0); + Command<CMD_WANT_ENGINE_PREVIEW>::Post(0, this->window_number, 0, {}); FALLTHROUGH; case WID_EP_NO: if (!_shift_pressed) this->Close(); diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp index 9d7ab70d8..73315edf0 100644 --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -27,6 +27,7 @@ #include "core/geometry_func.hpp" #include "gamelog.h" #include "stringfilter_type.h" +#include "misc_cmd.h" #include "widgets/fios_widget.h" @@ -358,7 +359,7 @@ public: /* pause is only used in single-player, non-editor mode, non-menu mode. It * will be unpaused in the WE_DESTROY event handler. */ if (_game_mode != GM_MENU && !_networking && _game_mode != GM_EDITOR) { - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_SAVELOAD, 1); + Command<CMD_PAUSE>::Post(0, PM_PAUSED_SAVELOAD, 1, {}); } SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0); @@ -402,7 +403,7 @@ public: { /* pause is only used in single-player, non-editor mode, non menu mode */ if (!_networking && _game_mode != GM_EDITOR && _game_mode != GM_MENU) { - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_SAVELOAD, 0); + Command<CMD_PAUSE>::Post(0, PM_PAUSED_SAVELOAD, 0, {}); } this->Window::Close(); } diff --git a/src/goal_gui.cpp b/src/goal_gui.cpp index d6180b0df..ef63197d5 100644 --- a/src/goal_gui.cpp +++ b/src/goal_gui.cpp @@ -23,6 +23,7 @@ #include "story_base.h" #include "command_func.h" #include "string_func.h" +#include "goal_cmd.h" #include "widgets/goal_widget.h" @@ -382,17 +383,17 @@ struct GoalQuestionWindow : public Window { { switch (widget) { case WID_GQ_BUTTON_1: - DoCommandP(CMD_GOAL_QUESTION_ANSWER, 0, this->window_number, this->button[0]); + Command<CMD_GOAL_QUESTION_ANSWER>::Post(0, this->window_number, this->button[0], {}); this->Close(); break; case WID_GQ_BUTTON_2: - DoCommandP(CMD_GOAL_QUESTION_ANSWER, 0, this->window_number, this->button[1]); + Command<CMD_GOAL_QUESTION_ANSWER>::Post(0, this->window_number, this->button[1], {}); this->Close(); break; case WID_GQ_BUTTON_3: - DoCommandP(CMD_GOAL_QUESTION_ANSWER, 0, this->window_number, this->button[2]); + Command<CMD_GOAL_QUESTION_ANSWER>::Post(0, this->window_number, this->button[2], {}); this->Close(); break; } diff --git a/src/group_gui.cpp b/src/group_gui.cpp index 8beab1884..b2deba309 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -26,6 +26,7 @@ #include "company_gui.h" #include "gui.h" #include "group_cmd.h" +#include "vehicle_cmd.h" #include "widgets/group_widget.h" @@ -641,7 +642,7 @@ public: if (confirmed) { VehicleGroupWindow *w = (VehicleGroupWindow*)win; w->vli.index = ALL_GROUP; - DoCommandP(CMD_DELETE_GROUP, STR_ERROR_GROUP_CAN_T_DELETE, (TileIndex)0, w->group_confirm, 0); + Command<CMD_DELETE_GROUP>::Post(STR_ERROR_GROUP_CAN_T_DELETE, 0, w->group_confirm, 0, {}); } } @@ -772,7 +773,7 @@ public: } case WID_GL_CREATE_GROUP: { // Create a new group - DoCommandP(CMD_CREATE_GROUP, STR_ERROR_GROUP_CAN_T_CREATE, CcCreateGroup, 0, this->vli.vtype, this->vli.index); + Command<CMD_CREATE_GROUP>::Post(STR_ERROR_GROUP_CAN_T_CREATE, CcCreateGroup, 0, this->vli.vtype, this->vli.index, {}); break; } @@ -801,14 +802,14 @@ public: case WID_GL_START_ALL: case WID_GL_STOP_ALL: { // Start/stop all vehicles of the list - DoCommandP(CMD_MASS_START_STOP, 0, (1 << 1) | (widget == WID_GL_START_ALL ? (1 << 0) : 0), this->vli.Pack()); + Command<CMD_MASS_START_STOP>::Post(0, (1 << 1) | (widget == WID_GL_START_ALL ? (1 << 0) : 0), this->vli.Pack(), {}); break; } case WID_GL_REPLACE_PROTECTION: { const Group *g = Group::GetIfValid(this->vli.index); if (g != nullptr) { - DoCommandP(CMD_SET_GROUP_FLAG, 0, this->vli.index | (GroupFlags::GF_REPLACE_PROTECTION << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_PROTECTION) ? 0 : 1) | (_ctrl_pressed << 1)); + Command<CMD_SET_GROUP_FLAG>::Post(0, this->vli.index | (GroupFlags::GF_REPLACE_PROTECTION << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_PROTECTION) ? 0 : 1) | (_ctrl_pressed << 1), {}); } break; } @@ -823,7 +824,7 @@ public: case WID_GL_ALL_VEHICLES: // All vehicles case WID_GL_DEFAULT_VEHICLES: // Ungrouped vehicles if (g->parent != INVALID_GROUP) { - DoCommandP(CMD_ALTER_GROUP, STR_ERROR_GROUP_CAN_T_SET_PARENT, 0, this->group_sel | (1 << 16), INVALID_GROUP); + Command<CMD_ALTER_GROUP>::Post(STR_ERROR_GROUP_CAN_T_SET_PARENT, 0, this->group_sel | (1 << 16), INVALID_GROUP, {}); } this->group_sel = INVALID_GROUP; @@ -836,7 +837,7 @@ public: GroupID new_g = id_g >= this->groups.size() ? INVALID_GROUP : this->groups[id_g]->index; if (this->group_sel != new_g && g->parent != new_g) { - DoCommandP(CMD_ALTER_GROUP, STR_ERROR_GROUP_CAN_T_SET_PARENT, 0, this->group_sel | (1 << 16), new_g); + Command<CMD_ALTER_GROUP>::Post(STR_ERROR_GROUP_CAN_T_SET_PARENT, 0, this->group_sel | (1 << 16), new_g, {}); } this->group_sel = INVALID_GROUP; @@ -851,7 +852,7 @@ public: { switch (widget) { case WID_GL_DEFAULT_VEHICLES: // Ungrouped vehicles - DoCommandP(CMD_ADD_VEHICLE_GROUP, STR_ERROR_GROUP_CAN_T_ADD_VEHICLE, 0, DEFAULT_GROUP, this->vehicle_sel | (_ctrl_pressed || this->grouping == GB_SHARED_ORDERS ? 1 << 31 : 0)); + Command<CMD_ADD_VEHICLE_GROUP>::Post(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE, 0, DEFAULT_GROUP, this->vehicle_sel | (_ctrl_pressed || this->grouping == GB_SHARED_ORDERS ? 1 << 31 : 0), {}); this->vehicle_sel = INVALID_VEHICLE; this->group_over = INVALID_GROUP; @@ -868,7 +869,7 @@ public: uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP); GroupID new_g = id_g >= this->groups.size() ? NEW_GROUP : this->groups[id_g]->index; - DoCommandP(CMD_ADD_VEHICLE_GROUP, STR_ERROR_GROUP_CAN_T_ADD_VEHICLE, new_g == NEW_GROUP ? CcAddVehicleNewGroup : nullptr, 0, new_g, vindex | (_ctrl_pressed || this->grouping == GB_SHARED_ORDERS ? 1 << 31 : 0)); + Command<CMD_ADD_VEHICLE_GROUP>::Post(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE, new_g == NEW_GROUP ? CcAddVehicleNewGroup : nullptr, 0, new_g, vindex | (_ctrl_pressed || this->grouping == GB_SHARED_ORDERS ? 1 << 31 : 0), {}); break; } @@ -923,7 +924,7 @@ public: void OnQueryTextFinished(char *str) override { - if (str != nullptr) DoCommandP(CMD_ALTER_GROUP, STR_ERROR_GROUP_CAN_T_RENAME, 0, this->group_rename, 0, str); + if (str != nullptr) Command<CMD_ALTER_GROUP>::Post(STR_ERROR_GROUP_CAN_T_RENAME, 0, this->group_rename, 0, str); this->group_rename = INVALID_GROUP; } @@ -953,19 +954,19 @@ public: break; case ADI_SERVICE: // Send for servicing case ADI_DEPOT: { // Send to Depots - DoCommandP(CMD_SEND_VEHICLE_TO_DEPOT, GetCmdSendToDepotMsg(this->vli.vtype), 0, DEPOT_MASS_SEND | (index == ADI_SERVICE ? DEPOT_SERVICE : 0U), this->vli.Pack()); + Command<CMD_SEND_VEHICLE_TO_DEPOT>::Post(GetCmdSendToDepotMsg(this->vli.vtype), 0, DEPOT_MASS_SEND | (index == ADI_SERVICE ? DEPOT_SERVICE : 0U), this->vli.Pack(), {}); break; } case ADI_ADD_SHARED: // Add shared Vehicles assert(Group::IsValidID(this->vli.index)); - DoCommandP(CMD_ADD_SHARED_VEHICLE_GROUP, STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE, 0, this->vli.index, this->vli.vtype); + Command<CMD_ADD_SHARED_VEHICLE_GROUP>::Post(STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE, 0, this->vli.index, this->vli.vtype, {}); break; case ADI_REMOVE_ALL: // Remove all Vehicles from the selected group assert(Group::IsValidID(this->vli.index)); - DoCommandP(CMD_REMOVE_ALL_VEHICLES_GROUP, STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES, (TileIndex)0, this->vli.index, 0); + Command<CMD_REMOVE_ALL_VEHICLES_GROUP>::Post(STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES, 0, this->vli.index, 0, {}); break; default: NOT_REACHED(); } diff --git a/src/highscore_gui.cpp b/src/highscore_gui.cpp index 0dfaebc3b..bf09b1b94 100644 --- a/src/highscore_gui.cpp +++ b/src/highscore_gui.cpp @@ -21,6 +21,7 @@ #include "strings_func.h" #include "hotkeys.h" #include "zoom_func.h" +#include "misc_cmd.h" #include "widgets/highscore_widget.h" @@ -96,7 +97,7 @@ struct EndGameWindow : EndGameHighScoreBaseWindow { EndGameWindow(WindowDesc *desc) : EndGameHighScoreBaseWindow(desc) { /* Pause in single-player to have a look at the highscore at your own leisure */ - if (!_networking) DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 1); + if (!_networking) Command<CMD_PAUSE>::Post(0, PM_PAUSED_NORMAL, 1, {}); this->background_img = SPR_TYCOON_IMG1_BEGIN; @@ -124,7 +125,7 @@ struct EndGameWindow : EndGameHighScoreBaseWindow { void Close() override { - if (!_networking) DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 0); // unpause + if (!_networking) Command<CMD_PAUSE>::Post(0, PM_PAUSED_NORMAL, 0, {}); // unpause ShowHighscoreTable(this->window_number, this->rank); this->EndGameHighScoreBaseWindow::Close(); } @@ -159,7 +160,7 @@ struct HighScoreWindow : EndGameHighScoreBaseWindow { { /* pause game to show the chart */ this->game_paused_by_player = _pause_mode == PM_PAUSED_NORMAL; - if (!_networking && !this->game_paused_by_player) DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 1); + if (!_networking && !this->game_paused_by_player) Command<CMD_PAUSE>::Post(0, PM_PAUSED_NORMAL, 1, {}); /* Close all always on-top windows to get a clean screen */ if (_game_mode != GM_MENU) HideVitalWindows(); @@ -174,7 +175,7 @@ struct HighScoreWindow : EndGameHighScoreBaseWindow { { if (_game_mode != GM_MENU) ShowVitalWindows(); - if (!_networking && !this->game_paused_by_player) DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 0); // unpause + if (!_networking && !this->game_paused_by_player) Command<CMD_PAUSE>::Post(0, PM_PAUSED_NORMAL, 0, {}); // unpause this->EndGameHighScoreBaseWindow::Close(); } diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 5aea6f59a..29da3c76e 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -39,6 +39,7 @@ #include "widgets/industry_widget.h" #include "clear_map.h" #include "zoom_func.h" +#include "industry_cmd.h" #include "table/strings.h" @@ -679,7 +680,7 @@ public: case WID_DPI_FUND_WIDGET: { if (this->selected_type != INVALID_INDUSTRYTYPE) { if (_game_mode != GM_EDITOR && _settings_game.construction.raw_industry_construction == 2 && GetIndustrySpec(this->selected_type)->IsRawIndustry()) { - DoCommandP(CMD_BUILD_INDUSTRY, STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, 0, this->selected_type, InteractiveRandom()); + Command<CMD_BUILD_INDUSTRY>::Post(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, 0, this->selected_type, InteractiveRandom(), {}); this->HandleButtonClick(WID_DPI_FUND_WIDGET); } else { HandlePlacePushButton(this, WID_DPI_FUND_WIDGET, SPR_CURSOR_INDUSTRY, HT_RECT); @@ -716,13 +717,13 @@ public: Backup<bool> old_generating_world(_generating_world, true, FILE_LINE); _ignore_restrictions = true; - DoCommandP(CMD_BUILD_INDUSTRY, STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, &CcBuildIndustry, tile, (layout_index << 8) | this->selected_type, seed); + Command<CMD_BUILD_INDUSTRY>::Post(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, &CcBuildIndustry, tile, (layout_index << 8) | this->selected_type, seed, {}); cur_company.Restore(); old_generating_world.Restore(); _ignore_restrictions = false; } else { - success = DoCommandP(CMD_BUILD_INDUSTRY, STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, tile, (layout_index << 8) | this->selected_type, seed); + success = Command<CMD_BUILD_INDUSTRY>::Post(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, tile, (layout_index << 8) | this->selected_type, seed, {}); } /* If an industry has been built, just reset the cursor and the system */ diff --git a/src/linkgraph/linkgraphschedule.cpp b/src/linkgraph/linkgraphschedule.cpp index c4fc2d5f9..0a6b89150 100644 --- a/src/linkgraph/linkgraphschedule.cpp +++ b/src/linkgraph/linkgraphschedule.cpp @@ -16,6 +16,7 @@ #include "../framerate_type.h" #include "../command_func.h" #include "../network/network.h" +#include "../misc_cmd.h" #include "../safeguards.h" @@ -173,7 +174,7 @@ void StateGameLoop_LinkGraphPauseControl() if (_pause_mode & PM_PAUSED_LINK_GRAPH) { /* We are paused waiting on a job, check the job every tick. */ if (!LinkGraphSchedule::instance.IsJoinWithUnfinishedJobDue()) { - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_LINK_GRAPH, 0); + Command<CMD_PAUSE>::Post(0, PM_PAUSED_LINK_GRAPH, 0, {}); } } else if (_pause_mode == PM_UNPAUSED && _date_fract == LinkGraphSchedule::SPAWN_JOIN_TICK - 2 && @@ -181,7 +182,7 @@ void StateGameLoop_LinkGraphPauseControl() LinkGraphSchedule::instance.IsJoinWithUnfinishedJobDue()) { /* Perform check two _date_fract ticks before we would join, to make * sure it also works in multiplayer. */ - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_LINK_GRAPH, 1); + Command<CMD_PAUSE>::Post(0, PM_PAUSED_LINK_GRAPH, 1, {}); } } diff --git a/src/main_gui.cpp b/src/main_gui.cpp index a4bec45d5..847d32845 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -33,6 +33,7 @@ #include "guitimer_func.h" #include "error.h" #include "news_gui.h" +#include "misc_cmd.h" #include "saveload/saveload.h" @@ -326,7 +327,7 @@ struct MainWindow : Window case GHK_MONEY: // Gimme money /* You can only cheat for money in singleplayer mode. */ - if (!_networking) DoCommandP(CMD_MONEY_CHEAT, 0, 10000000, 0); + if (!_networking) Command<CMD_MONEY_CHEAT>::Post(0, 10000000, 0, {}); break; case GHK_UPDATE_COORDS: // Update the coordinates of all station signs diff --git a/src/misc_cmd.cpp b/src/misc_cmd.cpp index 243c5347a..84c61e3f1 100644 --- a/src/misc_cmd.cpp +++ b/src/misc_cmd.cpp @@ -135,7 +135,7 @@ CommandCost CmdDecreaseLoan(DoCommandFlag flags, TileIndex tile, uint32 p1, uint static void AskUnsafeUnpauseCallback(Window *w, bool confirmed) { if (confirmed) { - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_ERROR, 0); + Command<CMD_PAUSE>::Post(0, PM_PAUSED_ERROR, 0, {}); } } diff --git a/src/network/network.cpp b/src/network/network.cpp index 8194f34d0..3bd287f85 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -395,7 +395,7 @@ static void CheckPauseHelper(bool pause, PauseMode pm) { if (pause == ((_pause_mode & pm) != PM_UNPAUSED)) return; - DoCommandP(CMD_PAUSE, 0, pm, pause ? 1 : 0); + Command<CMD_PAUSE>::Post(0, pm, pause ? 1 : 0, {}); } /** diff --git a/src/network/network_command.cpp b/src/network/network_command.cpp index 472d5e60e..983f4b565 100644 --- a/src/network/network_command.cpp +++ b/src/network/network_command.cpp @@ -451,5 +451,5 @@ template <Commands Tcmd> void UnpackNetworkCommand(const CommandPacket *cp) { auto args = EndianBufferReader::ToValue<typename CommandTraits<Tcmd>::Args>(cp->data); - std::apply(&InjectNetworkCommand, std::tuple_cat(std::make_tuple(Tcmd, cp->err_msg, cp->callback, cp->my_cmd), args)); + Command<Tcmd>::PostFromNet(cp->err_msg, cp->callback, cp->my_cmd, cp->tile, args); } diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 82e01e81e..a2b34593e 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -36,6 +36,7 @@ #include "../zoom_func.h" #include "../sprite.h" #include "../settings_internal.h" +#include "../company_cmd.h" #include "../widgets/network_widget.h" @@ -1395,7 +1396,7 @@ static void AdminCompanyResetCallback(Window *w, bool confirmed) { if (confirmed) { if (NetworkCompanyHasClients(_admin_company_id)) return; - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | _admin_company_id << 16 | CRR_MANUAL << 24, 0); + Command<CMD_COMPANY_CTRL>::Post(0, CCA_DELETE | _admin_company_id << 16 | CRR_MANUAL << 24, 0, {}); } } @@ -1535,7 +1536,7 @@ private: static void OnClickCompanyNew(NetworkClientListWindow *w, Point pt, CompanyID company_id) { if (_network_server) { - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_NEW, _network_own_client_id); + Command<CMD_COMPANY_CTRL>::Post(0, CCA_NEW, _network_own_client_id, {}); } else { NetworkSendCommand(CMD_COMPANY_CTRL, STR_NULL, nullptr, _local_company, 0, CCA_NEW, 0, {}); } diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 967ad40a8..65f3188de 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -29,6 +29,7 @@ #include "../order_backup.h" #include "../core/pool_func.hpp" #include "../core/random_func.hpp" +#include "../company_cmd.h" #include "../rev.h" #include <mutex> #include <condition_variable> @@ -1555,7 +1556,7 @@ static void NetworkAutoCleanCompanies() /* Is the company empty for autoclean_unprotected-months, and is there no protection? */ if (_settings_client.network.autoclean_unprotected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_unprotected && _network_company_states[c->index].password.empty()) { /* Shut the company down */ - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | c->index << 16 | CRR_AUTOCLEAN << 24, 0); + Command<CMD_COMPANY_CTRL>::Post(0, CCA_DELETE | c->index << 16 | CRR_AUTOCLEAN << 24, 0, {}); IConsolePrint(CC_INFO, "Auto-cleaned company #{} with no password.", c->index + 1); } /* Is the company empty for autoclean_protected-months, and there is a protection? */ @@ -1569,7 +1570,7 @@ static void NetworkAutoCleanCompanies() /* Is the company empty for autoclean_novehicles-months, and has no vehicles? */ if (_settings_client.network.autoclean_novehicles != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_novehicles && vehicles_in_company[c->index] == 0) { /* Shut the company down */ - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | c->index << 16 | CRR_AUTOCLEAN << 24, 0); + Command<CMD_COMPANY_CTRL>::Post(0, CCA_DELETE | c->index << 16 | CRR_AUTOCLEAN << 24, 0, {}); IConsolePrint(CC_INFO, "Auto-cleaned company #{} with no vehicles.", c->index + 1); } } else { diff --git a/src/object_gui.cpp b/src/object_gui.cpp index a3ea3f8b1..562af15ae 100644 --- a/src/object_gui.cpp +++ b/src/object_gui.cpp @@ -25,6 +25,7 @@ #include "window_func.h" #include "zoom_func.h" #include "terraform_cmd.h" +#include "object_cmd.h" #include "widgets/object_widget.h" @@ -542,8 +543,8 @@ public: void OnPlaceObject(Point pt, TileIndex tile) override { ObjectClass *objclass = ObjectClass::Get(_selected_object_class); - DoCommandP(CMD_BUILD_OBJECT, STR_ERROR_CAN_T_BUILD_OBJECT, CcTerraform, - tile, objclass->GetSpec(_selected_object_index)->Index(), _selected_object_view); + Command<CMD_BUILD_OBJECT>::Post(STR_ERROR_CAN_T_BUILD_OBJECT, CcTerraform, + tile, objclass->GetSpec(_selected_object_index)->Index(), _selected_object_view, {}); } void OnPlaceObjectAbort() override diff --git a/src/openttd.cpp b/src/openttd.cpp index abd5d99df..c5c849e71 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -66,6 +66,7 @@ #include "framerate_type.h" #include "industry.h" #include "network/network_gui.h" +#include "misc_cmd.h" #include "linkgraph/linkgraphschedule.h" @@ -851,7 +852,7 @@ static void MakeNewGameDone() /* In a dedicated server, the server does not play */ if (!VideoDriver::GetInstance()->HasGUI()) { OnStartGame(true); - if (_settings_client.gui.pause_on_newgame) DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 1); + if (_settings_client.gui.pause_on_newgame) Command<CMD_PAUSE>::Post(0, PM_PAUSED_NORMAL, 1, {}); return; } @@ -880,7 +881,7 @@ static void MakeNewGameDone() NetworkChangeCompanyPassword(_local_company, _settings_client.network.default_company_pass); } - if (_settings_client.gui.pause_on_newgame) DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 1); + if (_settings_client.gui.pause_on_newgame) Command<CMD_PAUSE>::Post(0, PM_PAUSED_NORMAL, 1, {}); CheckEngines(); CheckIndustries(); @@ -1045,7 +1046,7 @@ void SwitchToMode(SwitchMode new_mode) } OnStartGame(_network_dedicated); /* Decrease pause counter (was increased from opening load dialog) */ - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_SAVELOAD, 0); + Command<CMD_PAUSE>::Post(0, PM_PAUSED_SAVELOAD, 0, {}); } break; } @@ -1067,7 +1068,7 @@ void SwitchToMode(SwitchMode new_mode) SetLocalCompany(OWNER_NONE); _settings_newgame.game_creation.starting_year = _cur_year; /* Cancel the saveload pausing */ - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_SAVELOAD, 0); + Command<CMD_PAUSE>::Post(0, PM_PAUSED_SAVELOAD, 0, {}); } else { SetDParamStr(0, GetSaveLoadErrorString()); ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR); diff --git a/src/order_backup.cpp b/src/order_backup.cpp index 80fc9fa6d..987b3154f 100644 --- a/src/order_backup.cpp +++ b/src/order_backup.cpp @@ -171,7 +171,7 @@ CommandCost CmdClearOrderBackup(DoCommandFlag flags, TileIndex tile, uint32 p1, /* If it's not a backup of us, ignore it. */ if (ob->user != user) continue; - DoCommandP(CMD_CLEAR_ORDER_BACKUP, 0, 0, user); + Command<CMD_CLEAR_ORDER_BACKUP>::Post(0, 0, user, {}); return; } } diff --git a/src/order_gui.cpp b/src/order_gui.cpp index b934b9d16..50413c735 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -29,6 +29,7 @@ #include "aircraft.h" #include "engine_func.h" #include "vehicle_func.h" +#include "order_cmd.h" #include "widgets/order_widget.h" @@ -591,7 +592,7 @@ private: } if (order->GetLoadType() == load_type) return; // If we still match, do nothing - DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_LOAD | (load_type << 4)); + Command<CMD_MODIFY_ORDER>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_LOAD | (load_type << 4), {}); } /** @@ -606,7 +607,7 @@ private: if (order == nullptr) return; i = (order->GetDepotOrderType() & ODTFB_SERVICE) ? DA_ALWAYS_GO : DA_SERVICE; } - DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_DEPOT_ACTION | (i << 4)); + Command<CMD_MODIFY_ORDER>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_DEPOT_ACTION | (i << 4), {}); } /** @@ -621,7 +622,7 @@ private: _settings_client.gui.new_nonstop && this->vehicle->IsGroundVehicle() ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE); order.SetDepotActionType(ODATFB_NEAREST_DEPOT); - DoCommandP(CMD_INSERT_ORDER, STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), order.Pack()); + Command<CMD_INSERT_ORDER>::Post(STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), order.Pack(), {}); } /** @@ -641,11 +642,11 @@ private: } if (order->GetUnloadType() == unload_type) return; // If we still match, do nothing - DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_UNLOAD | (unload_type << 4)); + Command<CMD_MODIFY_ORDER>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_UNLOAD | (unload_type << 4), {}); /* Transfer and unload orders with leave empty as default */ if (unload_type == OUFB_TRANSFER || unload_type == OUFB_UNLOAD) { - DoCommandP(CMD_MODIFY_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_LOAD | (OLFB_NO_LOAD << 4)); + Command<CMD_MODIFY_ORDER>::Post(this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_LOAD | (OLFB_NO_LOAD << 4), {}); this->SetWidgetDirty(WID_O_FULL_LOAD); } } @@ -669,7 +670,7 @@ private: } this->SetWidgetDirty(WID_O_NON_STOP); - DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_NON_STOP | non_stop << 4); + Command<CMD_MODIFY_ORDER>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_NON_STOP | non_stop << 4, {}); } /** @@ -682,8 +683,8 @@ private: if (_ctrl_pressed && this->vehicle->cur_implicit_order_index == this->OrderGetSel()) return; if (this->vehicle->GetNumOrders() <= 1) return; - DoCommandP(CMD_SKIP_TO_ORDER, _ctrl_pressed ? STR_ERROR_CAN_T_SKIP_TO_ORDER : STR_ERROR_CAN_T_SKIP_ORDER, - this->vehicle->tile, this->vehicle->index, _ctrl_pressed ? this->OrderGetSel() : ((this->vehicle->cur_implicit_order_index + 1) % this->vehicle->GetNumOrders())); + Command<CMD_SKIP_TO_ORDER>::Post(_ctrl_pressed ? STR_ERROR_CAN_T_SKIP_TO_ORDER : STR_ERROR_CAN_T_SKIP_ORDER, + this->vehicle->tile, this->vehicle->index, _ctrl_pressed ? this->OrderGetSel() : ((this->vehicle->cur_implicit_order_index + 1) % this->vehicle->GetNumOrders()), {}); } /** @@ -694,7 +695,7 @@ private: /* When networking, move one order lower */ int selected = this->selected_order + (int)_networking; - if (DoCommandP(CMD_DELETE_ORDER, STR_ERROR_CAN_T_DELETE_THIS_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel())) { + if (Command<CMD_DELETE_ORDER>::Post(STR_ERROR_CAN_T_DELETE_THIS_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), {})) { this->selected_order = selected >= this->vehicle->GetNumOrders() ? -1 : selected; this->UpdateButtonState(); } @@ -719,7 +720,7 @@ private: /* Get another vehicle that share orders with this vehicle. */ Vehicle *other_shared = (this->vehicle->FirstShared() == this->vehicle) ? this->vehicle->NextShared() : this->vehicle->PreviousShared(); /* Copy the order list of the other vehicle. */ - if (DoCommandP(CMD_CLONE_ORDER, STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST, this->vehicle->tile, this->vehicle->index | CO_COPY << 30, other_shared->index)) { + if (Command<CMD_CLONE_ORDER>::Post(STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST, this->vehicle->tile, this->vehicle->index | CO_COPY << 30, other_shared->index, {})) { this->UpdateButtonState(); } } @@ -734,10 +735,10 @@ private: { if (_ctrl_pressed) { /* Cancel refitting */ - DoCommandP(CMD_ORDER_REFIT, this->vehicle->tile, this->vehicle->index, (this->OrderGetSel() << 16) | (CT_NO_REFIT << 8) | CT_NO_REFIT); + Command<CMD_ORDER_REFIT>::Post(this->vehicle->tile, this->vehicle->index, (this->OrderGetSel() << 16) | (CT_NO_REFIT << 8) | CT_NO_REFIT, {}); } else { if (i == 1) { // Auto-refit to available cargo type. - DoCommandP(CMD_ORDER_REFIT, this->vehicle->tile, this->vehicle->index, (this->OrderGetSel() << 16) | CT_AUTO_REFIT); + Command<CMD_ORDER_REFIT>::Post(this->vehicle->tile, this->vehicle->index, (this->OrderGetSel() << 16) | CT_AUTO_REFIT, {}); } else { ShowVehicleRefitWindow(this->vehicle, this->OrderGetSel(), this, auto_refit); } @@ -1159,7 +1160,7 @@ public: order.index = 0; order.MakeConditional(order_id); - DoCommandP(CMD_INSERT_ORDER, STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), order.Pack()); + Command<CMD_INSERT_ORDER>::Post(STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), order.Pack(), {}); } ResetObjectToPlace(); break; @@ -1182,9 +1183,9 @@ public: this->selected_order = -1; } else if (sel == this->selected_order) { if (this->vehicle->type == VEH_TRAIN && sel < this->vehicle->GetNumOrders()) { - DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, + Command<CMD_MODIFY_ORDER>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel << 20), - MOF_STOP_LOCATION | ((this->vehicle->GetOrder(sel)->GetStopLocation() + 1) % OSL_END) << 4); + MOF_STOP_LOCATION | ((this->vehicle->GetOrder(sel)->GetStopLocation() + 1) % OSL_END) << 4, {}); } } else { /* Select clicked order */ @@ -1331,7 +1332,7 @@ public: default: break; } - DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel << 20), MOF_COND_VALUE | Clamp(value, 0, 2047) << 4); + Command<CMD_MODIFY_ORDER>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel << 20), MOF_COND_VALUE | Clamp(value, 0, 2047) << 4, {}); } } @@ -1369,11 +1370,11 @@ public: break; case WID_O_COND_VARIABLE: - DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), MOF_COND_VARIABLE | index << 4); + Command<CMD_MODIFY_ORDER>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), MOF_COND_VARIABLE | index << 4, {}); break; case WID_O_COND_COMPARATOR: - DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), MOF_COND_COMPARATOR | index << 4); + Command<CMD_MODIFY_ORDER>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), MOF_COND_COMPARATOR | index << 4, {}); break; } } @@ -1386,7 +1387,7 @@ public: VehicleOrderID to_order = this->GetOrderFromPt(pt.y); if (!(from_order == to_order || from_order == INVALID_VEH_ORDER_ID || from_order > this->vehicle->GetNumOrders() || to_order == INVALID_VEH_ORDER_ID || to_order > this->vehicle->GetNumOrders()) && - DoCommandP(CMD_MOVE_ORDER, STR_ERROR_CAN_T_MOVE_THIS_ORDER, this->vehicle->tile, this->vehicle->index, from_order | (to_order << 16))) { + Command<CMD_MOVE_ORDER>::Post(STR_ERROR_CAN_T_MOVE_THIS_ORDER, this->vehicle->tile, this->vehicle->index, from_order | (to_order << 16), {})) { this->selected_order = -1; this->UpdateButtonState(); } @@ -1438,7 +1439,7 @@ public: const Order cmd = GetOrderCmdFromTile(this->vehicle, tile); if (cmd.IsType(OT_NOTHING)) return; - if (DoCommandP(CMD_INSERT_ORDER, STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), cmd.Pack())) { + if (Command<CMD_INSERT_ORDER>::Post(STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), cmd.Pack(), {})) { /* With quick goto the Go To button stays active */ if (!_settings_client.gui.quick_goto) ResetObjectToPlace(); } @@ -1455,8 +1456,8 @@ public: bool share_order = _ctrl_pressed || this->goto_type == OPOS_SHARE; if (this->vehicle->GetNumOrders() != 0 && !share_order) return false; - if (DoCommandP(CMD_CLONE_ORDER, share_order ? STR_ERROR_CAN_T_SHARE_ORDER_LIST : STR_ERROR_CAN_T_COPY_ORDER_LIST, - this->vehicle->tile, this->vehicle->index | (share_order ? CO_SHARE : CO_COPY) << 30, v->index)) { + if (Command<CMD_CLONE_ORDER>::Post(share_order ? STR_ERROR_CAN_T_SHARE_ORDER_LIST : STR_ERROR_CAN_T_COPY_ORDER_LIST, + this->vehicle->tile, this->vehicle->index | (share_order ? CO_SHARE : CO_COPY) << 30, v->index, {})) { this->selected_order = -1; ResetObjectToPlace(); } diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index f88352f9e..a57e2f8e5 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -39,6 +39,7 @@ #include "station_cmd.h" #include "tunnelbridge_cmd.h" #include "waypoint_cmd.h" +#include "rail_cmd.h" #include "station_map.h" #include "tunnelbridge_map.h" @@ -95,10 +96,13 @@ void CcPlaySound_CONSTRUCTION_RAIL(const CommandCost &result, Commands cmd, Tile static void GenericPlaceRail(TileIndex tile, int cmd) { - DoCommandP(_remove_button_clicked ? CMD_REMOVE_SINGLE_RAIL : CMD_BUILD_SINGLE_RAIL, - _remove_button_clicked ? STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK : STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK, - CcPlaySound_CONSTRUCTION_RAIL, - tile, _cur_railtype, cmd | (_settings_client.gui.auto_remove_signals << 3)); + if (_remove_button_clicked) { + Command<CMD_REMOVE_SINGLE_RAIL>::Post(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL, + tile, _cur_railtype, cmd | (_settings_client.gui.auto_remove_signals << 3), {}); + } else { + Command<CMD_BUILD_SINGLE_RAIL>::Post(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL, + tile, _cur_railtype, cmd | (_settings_client.gui.auto_remove_signals << 3), {}); + } } /** @@ -114,7 +118,7 @@ static void PlaceExtraDepotRail(TileIndex tile, DiagDirection dir, Track track) if (GetRailTileType(tile) == RAIL_TILE_SIGNALS && !_settings_client.gui.auto_remove_signals) return; if ((GetTrackBits(tile) & DiagdirReachesTracks(dir)) == 0) return; - DoCommandP(CMD_BUILD_SINGLE_RAIL, tile, _cur_railtype, track | (_settings_client.gui.auto_remove_signals << 3)); + Command<CMD_BUILD_SINGLE_RAIL>::Post(tile, _cur_railtype, track | (_settings_client.gui.auto_remove_signals << 3), {}); } /** Additional pieces of track to add at the entrance of a depot. */ @@ -168,7 +172,7 @@ static void PlaceRail_Waypoint(TileIndex tile) } else { /* Tile where we can't build rail waypoints. This is always going to fail, * but provides the user with a proper error message. */ - DoCommandP(CMD_BUILD_RAIL_WAYPOINT, STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT, tile, 1 << 8 | 1 << 16, STAT_CLASS_WAYP | INVALID_STATION << 16); + Command<CMD_BUILD_RAIL_WAYPOINT>::Post(STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT, tile, 1 << 8 | 1 << 16, STAT_CLASS_WAYP | INVALID_STATION << 16, {}); } } @@ -208,7 +212,7 @@ static void PlaceRail_Station(TileIndex tile) uint32 p2_final = p2; if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); - return DoCommandP(CMD_BUILD_RAIL_STATION, STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, tile, p1, p2_final); + return Command<CMD_BUILD_RAIL_STATION>::Post(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, tile, p1, p2_final, {}); } }; @@ -236,7 +240,7 @@ static void GenericPlaceSignals(TileIndex tile) Track track = FindFirstTrack(trackbits); if (_remove_button_clicked) { - DoCommandP(CMD_REMOVE_SIGNALS, STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM, CcPlaySound_CONSTRUCTION_RAIL, tile, track, 0); + Command<CMD_REMOVE_SIGNALS>::Post(STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM, CcPlaySound_CONSTRUCTION_RAIL, tile, track, 0, {}); } else { const Window *w = FindWindowById(WC_BUILD_SIGNAL, 0); @@ -267,8 +271,8 @@ static void GenericPlaceSignals(TileIndex tile) SB(p1, 9, 6, cycle_types); } - DoCommandP(CMD_BUILD_SIGNALS, (w != nullptr && _convert_signal_button) ? STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE : STR_ERROR_CAN_T_BUILD_SIGNALS_HERE, - CcPlaySound_CONSTRUCTION_RAIL, tile, p1, 0); + Command<CMD_BUILD_SIGNALS>::Post((w != nullptr && _convert_signal_button) ? STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE : STR_ERROR_CAN_T_BUILD_SIGNALS_HERE, + CcPlaySound_CONSTRUCTION_RAIL, tile, p1, 0, {}); } } @@ -370,10 +374,13 @@ static void BuildRailClick_Remove(Window *w) static void DoRailroadTrack(int mode) { uint32 p2 = _cur_railtype | (mode << 6) | (_settings_client.gui.auto_remove_signals << 11); - DoCommandP(_remove_button_clicked ? CMD_REMOVE_RAILROAD_TRACK : CMD_BUILD_RAILROAD_TRACK, - _remove_button_clicked ? STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK : STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK, - CcPlaySound_CONSTRUCTION_RAIL, - TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2); + if (_remove_button_clicked) { + Command<CMD_REMOVE_RAILROAD_TRACK>::Post(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL, + TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2, {}); + } else { + Command<CMD_BUILD_RAILROAD_TRACK>::Post(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL, + TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2, {}); + } } static void HandleAutodirPlacement() @@ -424,10 +431,13 @@ static void HandleAutoSignalPlacement() /* _settings_client.gui.drag_signals_density is given as a parameter such that each user * in a network game can specify their own signal density */ - DoCommandP(_remove_button_clicked ? CMD_REMOVE_SIGNAL_TRACK : CMD_BUILD_SIGNAL_TRACK, - _remove_button_clicked ? STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM : STR_ERROR_CAN_T_BUILD_SIGNALS_HERE, - CcPlaySound_CONSTRUCTION_RAIL, - TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2); + if (_remove_button_clicked) { + Command<CMD_REMOVE_SIGNAL_TRACK>::Post(STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM, CcPlaySound_CONSTRUCTION_RAIL, + TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2, {}); + } else { + Command<CMD_BUILD_SIGNAL_TRACK>::Post(STR_ERROR_CAN_T_BUILD_SIGNALS_HERE, CcPlaySound_CONSTRUCTION_RAIL, + TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2, {}); + } } @@ -653,8 +663,7 @@ struct BuildRailToolbarWindow : Window { break; case WID_RAT_BUILD_DEPOT: - DoCommandP(CMD_BUILD_TRAIN_DEPOT, STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT, - CcRailDepot, tile, _cur_railtype, _build_depot_direction); + Command<CMD_BUILD_TRAIN_DEPOT>::Post(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT, CcRailDepot, tile, _cur_railtype, _build_depot_direction, {}); break; case WID_RAT_BUILD_WAYPOINT: @@ -674,7 +683,7 @@ struct BuildRailToolbarWindow : Window { break; case WID_RAT_BUILD_TUNNEL: - DoCommandP(CMD_BUILD_TUNNEL, STR_ERROR_CAN_T_BUILD_TUNNEL_HERE, CcBuildRailTunnel, tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0); + Command<CMD_BUILD_TUNNEL>::Post(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE, CcBuildRailTunnel, tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, {}); break; case WID_RAT_CONVERT_RAIL: @@ -716,7 +725,7 @@ struct BuildRailToolbarWindow : Window { break; case DDSP_CONVERT_RAIL: - DoCommandP(CMD_CONVERT_RAIL, STR_ERROR_CAN_T_CONVERT_RAIL, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _cur_railtype | (_ctrl_pressed ? 1 << 6 : 0)); + Command<CMD_CONVERT_RAIL>::Post(STR_ERROR_CAN_T_CONVERT_RAIL, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _cur_railtype | (_ctrl_pressed ? 1 << 6 : 0), {}); break; case DDSP_REMOVE_STATION: @@ -724,14 +733,14 @@ struct BuildRailToolbarWindow : Window { if (this->IsWidgetLowered(WID_RAT_BUILD_STATION)) { /* Station */ if (_remove_button_clicked) { - DoCommandP(CMD_REMOVE_FROM_RAIL_STATION, STR_ERROR_CAN_T_REMOVE_PART_OF_STATION, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _ctrl_pressed ? 0 : 1); + Command<CMD_REMOVE_FROM_RAIL_STATION>::Post(STR_ERROR_CAN_T_REMOVE_PART_OF_STATION, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _ctrl_pressed ? 0 : 1, {}); } else { HandleStationPlacement(start_tile, end_tile); } } else { /* Waypoint */ if (_remove_button_clicked) { - DoCommandP(CMD_REMOVE_FROM_RAIL_WAYPOINT, STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _ctrl_pressed ? 0 : 1); + Command<CMD_REMOVE_FROM_RAIL_WAYPOINT>::Post(STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _ctrl_pressed ? 0 : 1, {}); } else { TileArea ta(start_tile, end_tile); uint32 p1 = _cur_railtype | (select_method == VPM_X_LIMITED ? AXIS_X : AXIS_Y) << 6 | ta.w << 8 | ta.h << 16 | _ctrl_pressed << 24; @@ -744,7 +753,7 @@ struct BuildRailToolbarWindow : Window { uint32 p2_final = p2; if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); - return DoCommandP(CMD_BUILD_RAIL_WAYPOINT, STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT, CcPlaySound_CONSTRUCTION_RAIL, ta.tile, p1, p2_final); + return Command<CMD_BUILD_RAIL_WAYPOINT>::Post(STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT, CcPlaySound_CONSTRUCTION_RAIL, ta.tile, p1, p2_final, {}); } }; @@ -913,7 +922,7 @@ static void HandleStationPlacement(TileIndex start, TileIndex end) uint32 p2_final = p2; if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); - return DoCommandP(CMD_BUILD_RAIL_STATION, STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, ta.tile, p1, p2_final); + return Command<CMD_BUILD_RAIL_STATION>::Post(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, ta.tile, p1, p2_final, {}); } }; diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 145934ffc..948095f77 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -32,6 +32,7 @@ #include "core/geometry_func.hpp" #include "date_func.h" #include "station_cmd.h" +#include "road_cmd.h" #include "tunnelbridge_cmd.h" #include "widgets/road_widget.h" @@ -127,7 +128,7 @@ void ConnectRoadToStructure(TileIndex tile, DiagDirection direction) /* if there is a roadpiece just outside of the station entrance, build a connecting route */ if (IsNormalRoadTile(tile)) { if (GetRoadBits(tile, GetRoadTramType(_cur_roadtype)) != ROAD_NONE) { - DoCommandP(CMD_BUILD_ROAD, tile, _cur_roadtype << 4 | DiagDirToRoadBits(ReverseDiagDir(direction)), 0); + Command<CMD_BUILD_ROAD>::Post(tile, _cur_roadtype << 4 | DiagDirToRoadBits(ReverseDiagDir(direction)), 0, {}); } } } @@ -205,7 +206,7 @@ static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, S uint32 p2_final = p2; if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); - return DoCommandP(CMD_BUILD_ROAD_STOP, err_msg, CcRoadStop, ta.tile, p1, p2_final); + return Command<CMD_BUILD_ROAD_STOP>::Post(err_msg, CcRoadStop, ta.tile, p1, p2_final, {}); } }; @@ -566,8 +567,8 @@ struct BuildRoadToolbarWindow : Window { break; case WID_ROT_DEPOT: - DoCommandP(CMD_BUILD_ROAD_DEPOT, this->rti->strings.err_depot, CcRoadDepot, - tile, _cur_roadtype << 2 | _road_depot_orientation, 0); + Command<CMD_BUILD_ROAD_DEPOT>::Post(this->rti->strings.err_depot, CcRoadDepot, + tile, _cur_roadtype << 2 | _road_depot_orientation, 0, {}); break; case WID_ROT_BUS_STATION: @@ -583,8 +584,8 @@ struct BuildRoadToolbarWindow : Window { break; case WID_ROT_BUILD_TUNNEL: - DoCommandP(CMD_BUILD_TUNNEL, STR_ERROR_CAN_T_BUILD_TUNNEL_HERE, CcBuildRoadTunnel, - tile, _cur_roadtype | (TRANSPORT_ROAD << 8), 0); + Command<CMD_BUILD_TUNNEL>::Post(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE, CcBuildRoadTunnel, + tile, _cur_roadtype | (TRANSPORT_ROAD << 8), 0, {}); break; case WID_ROT_CONVERT_ROAD: @@ -685,9 +686,13 @@ struct BuildRoadToolbarWindow : Window { * flags */ _place_road_flag = (RoadFlags)((_place_road_flag & RF_DIR_Y) ? (_place_road_flag & 0x07) : (_place_road_flag >> 3)); - DoCommandP(_remove_button_clicked ? CMD_REMOVE_LONG_ROAD : CMD_BUILD_LONG_ROAD, - _remove_button_clicked ? this->rti->strings.err_remove_road : this->rti->strings.err_build_road, CcPlaySound_CONSTRUCTION_OTHER, - start_tile, end_tile, _place_road_flag | (_cur_roadtype << 3) | (_one_way_button_clicked << 10)); + if (_remove_button_clicked) { + Command<CMD_REMOVE_LONG_ROAD>::Post(this->rti->strings.err_remove_road, CcPlaySound_CONSTRUCTION_OTHER, + start_tile, end_tile, _place_road_flag | (_cur_roadtype << 3) | (_one_way_button_clicked << 10), {}); + } else { + Command<CMD_BUILD_LONG_ROAD>::Post(this->rti->strings.err_build_road, CcPlaySound_CONSTRUCTION_OTHER, + start_tile, end_tile, _place_road_flag | (_cur_roadtype << 3) | (_one_way_button_clicked << 10), {}); + } break; case DDSP_BUILD_BUSSTOP: @@ -695,7 +700,7 @@ struct BuildRoadToolbarWindow : Window { if (this->IsWidgetLowered(WID_ROT_BUS_STATION)) { if (_remove_button_clicked) { TileArea ta(start_tile, end_tile); - DoCommandP(CMD_REMOVE_ROAD_STOP, this->rti->strings.err_remove_station[ROADSTOP_BUS], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_BUS); + Command<CMD_REMOVE_ROAD_STOP>::Post(this->rti->strings.err_remove_station[ROADSTOP_BUS], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_BUS, {}); } else { PlaceRoadStop(start_tile, end_tile, _cur_roadtype << 5 | (_ctrl_pressed << 2) | ROADSTOP_BUS, this->rti->strings.err_build_station[ROADSTOP_BUS]); } @@ -707,7 +712,7 @@ struct BuildRoadToolbarWindow : Window { if (this->IsWidgetLowered(WID_ROT_TRUCK_STATION)) { if (_remove_button_clicked) { TileArea ta(start_tile, end_tile); - DoCommandP(CMD_REMOVE_ROAD_STOP, this->rti->strings.err_remove_station[ROADSTOP_TRUCK], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_TRUCK); + Command<CMD_REMOVE_ROAD_STOP>::Post(this->rti->strings.err_remove_station[ROADSTOP_TRUCK], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_TRUCK, {}); } else { PlaceRoadStop(start_tile, end_tile, _cur_roadtype << 5 | (_ctrl_pressed << 2) | ROADSTOP_TRUCK, this->rti->strings.err_build_station[ROADSTOP_TRUCK]); } @@ -715,7 +720,7 @@ struct BuildRoadToolbarWindow : Window { break; case DDSP_CONVERT_ROAD: - DoCommandP(CMD_CONVERT_ROAD, rti->strings.err_convert_road, CcPlaySound_CONSTRUCTION_OTHER, end_tile, start_tile, _cur_roadtype); + Command<CMD_CONVERT_ROAD>::Post(rti->strings.err_convert_road, CcPlaySound_CONSTRUCTION_OTHER, end_tile, start_tile, _cur_roadtype, {}); break; } } diff --git a/src/settings.cpp b/src/settings.cpp index 1bf651304..63c7478a0 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1550,7 +1550,7 @@ bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame) const IntSettingDesc *setting = sd->AsIntSetting(); if ((setting->flags & SF_PER_COMPANY) != 0) { if (Company::IsValidID(_local_company) && _game_mode != GM_MENU) { - return DoCommandP(CMD_CHANGE_COMPANY_SETTING, 0, 0, value, setting->GetName()); + return Command<CMD_CHANGE_COMPANY_SETTING>::Post(0, 0, value, setting->GetName()); } setting->ChangeValue(&_settings_client.company, value); @@ -1576,7 +1576,7 @@ bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame) /* send non-company-based settings over the network */ if (!_networking || (_networking && _network_server)) { - return DoCommandP(CMD_CHANGE_SETTING, 0, 0, value, setting->GetName()); + return Command<CMD_CHANGE_SETTING>::Post(0, 0, value, setting->GetName()); } return false; } diff --git a/src/signs_cmd.cpp b/src/signs_cmd.cpp index cf742df83..4fdfc0ab5 100644 --- a/src/signs_cmd.cpp +++ b/src/signs_cmd.cpp @@ -132,5 +132,5 @@ void CcPlaceSign(const CommandCost &result, Commands cmd, TileIndex tile, uint32 */ void PlaceProc_Sign(TileIndex tile) { - DoCommandP(CMD_PLACE_SIGN, STR_ERROR_CAN_T_PLACE_SIGN_HERE, CcPlaceSign, tile, 0, 0); + Command<CMD_PLACE_SIGN>::Post(STR_ERROR_CAN_T_PLACE_SIGN_HERE, CcPlaceSign, tile, 0, 0, {}); } diff --git a/src/signs_gui.cpp b/src/signs_gui.cpp index 0bb9fa2da..b10e6d38c 100644 --- a/src/signs_gui.cpp +++ b/src/signs_gui.cpp @@ -26,6 +26,7 @@ #include "hotkeys.h" #include "transparency.h" #include "gui.h" +#include "signs_cmd.h" #include "widgets/sign_widget.h" @@ -413,7 +414,7 @@ Window *ShowSignList() static bool RenameSign(SignID index, const char *text) { bool remove = StrEmpty(text); - DoCommandP(CMD_RENAME_SIGN, StrEmpty(text) ? STR_ERROR_CAN_T_DELETE_SIGN : STR_ERROR_CAN_T_CHANGE_SIGN_NAME, 0, index, 0, text); + Command<CMD_RENAME_SIGN>::Post(StrEmpty(text) ? STR_ERROR_CAN_T_DELETE_SIGN : STR_ERROR_CAN_T_CHANGE_SIGN_NAME, 0, index, 0, text); return remove; } diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 2e04e7ac4..1177e558c 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -31,6 +31,7 @@ #include "town.h" #include "linkgraph/linkgraph.h" #include "zoom_func.h" +#include "station_cmd.h" #include "widgets/station_widget.h" @@ -1947,7 +1948,7 @@ struct StationViewWindow : public Window { break; case WID_SV_CLOSE_AIRPORT: - DoCommandP(CMD_OPEN_CLOSE_AIRPORT, 0, this->window_number, 0); + Command<CMD_OPEN_CLOSE_AIRPORT>::Post(0, this->window_number, 0, {}); break; case WID_SV_TRAINS: // Show list of scheduled trains to this station @@ -2084,7 +2085,7 @@ struct StationViewWindow : public Window { { if (str == nullptr) return; - DoCommandP(CMD_RENAME_STATION, STR_ERROR_CAN_T_RENAME_STATION, 0, this->window_number, 0, str); + Command<CMD_RENAME_STATION>::Post(STR_ERROR_CAN_T_RENAME_STATION, 0, this->window_number, 0, str); } void OnResize() override diff --git a/src/story_gui.cpp b/src/story_gui.cpp index 5330b8a30..21dba8fd1 100644 --- a/src/story_gui.cpp +++ b/src/story_gui.cpp @@ -25,6 +25,7 @@ #include "company_base.h" #include "tilehighlight_func.h" #include "vehicle_base.h" +#include "story_cmd.h" #include "widgets/story_widget.h" @@ -566,7 +567,7 @@ protected: this->SetTimeout(); this->SetWidgetDirty(WID_SB_PAGE_PANEL); - DoCommandP(CMD_STORY_PAGE_BUTTON, 0, pe.index, 0); + Command<CMD_STORY_PAGE_BUTTON>::Post(0, pe.index, 0, {}); break; case SPET_BUTTON_TILE: @@ -921,7 +922,7 @@ public: return; } - DoCommandP(CMD_STORY_PAGE_BUTTON, tile, pe->index, 0); + Command<CMD_STORY_PAGE_BUTTON>::Post(tile, pe->index, 0, {}); ResetObjectToPlace(); } @@ -940,7 +941,7 @@ public: VehicleType wanted_vehtype = data.GetVehicleType(); if (wanted_vehtype != VEH_INVALID && wanted_vehtype != v->type) return false; - DoCommandP(CMD_STORY_PAGE_BUTTON, 0, pe->index, v->index); + Command<CMD_STORY_PAGE_BUTTON>::Post(0, pe->index, v->index, {}); ResetObjectToPlace(); return true; } diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index 71d897c3d..c65adad7d 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -35,6 +35,8 @@ #include "zoom_func.h" #include "rail_cmd.h" #include "landscape_cmd.h" +#include "terraform_cmd.h" +#include "object_cmd.h" #include "widgets/terraform_widget.h" @@ -63,7 +65,7 @@ static void GenerateDesertArea(TileIndex end, TileIndex start) TileArea ta(start, end); for (TileIndex tile : ta) { SetTropicZone(tile, (_ctrl_pressed) ? TROPICZONE_NORMAL : TROPICZONE_DESERT); - DoCommandP(CMD_LANDSCAPE_CLEAR, tile, 0, 0); + Command<CMD_LANDSCAPE_CLEAR>::Post(tile, 0, 0, {}); MarkTileDirtyByTile(tile); } old_generating_world.Restore(); @@ -118,16 +120,16 @@ bool GUIPlaceProcDragXY(ViewportDragDropSelectionProcess proc, TileIndex start_t switch (proc) { case DDSP_DEMOLISH_AREA: - DoCommandP(CMD_CLEAR_AREA, STR_ERROR_CAN_T_CLEAR_THIS_AREA, CcPlaySound_EXPLOSION, end_tile, start_tile, _ctrl_pressed ? 1 : 0); + Command<CMD_CLEAR_AREA>::Post(STR_ERROR_CAN_T_CLEAR_THIS_AREA, CcPlaySound_EXPLOSION, end_tile, start_tile, _ctrl_pressed ? 1 : 0, {}); break; case DDSP_RAISE_AND_LEVEL_AREA: - DoCommandP(CMD_LEVEL_LAND, STR_ERROR_CAN_T_RAISE_LAND_HERE, CcTerraform, end_tile, start_tile, LM_RAISE << 1 | (_ctrl_pressed ? 1 : 0)); + Command<CMD_LEVEL_LAND>::Post(STR_ERROR_CAN_T_RAISE_LAND_HERE, CcTerraform, end_tile, start_tile, LM_RAISE << 1 | (_ctrl_pressed ? 1 : 0), {}); break; case DDSP_LOWER_AND_LEVEL_AREA: - DoCommandP(CMD_LEVEL_LAND, STR_ERROR_CAN_T_LOWER_LAND_HERE, CcTerraform, end_tile, start_tile, LM_LOWER << 1 | (_ctrl_pressed ? 1 : 0)); + Command<CMD_LEVEL_LAND>::Post(STR_ERROR_CAN_T_LOWER_LAND_HERE, CcTerraform, end_tile, start_tile, LM_LOWER << 1 | (_ctrl_pressed ? 1 : 0), {}); break; case DDSP_LEVEL_AREA: - DoCommandP(CMD_LEVEL_LAND, STR_ERROR_CAN_T_LEVEL_LAND_HERE, CcTerraform, end_tile, start_tile, LM_LEVEL << 1 | (_ctrl_pressed ? 1 : 0)); + Command<CMD_LEVEL_LAND>::Post(STR_ERROR_CAN_T_LEVEL_LAND_HERE, CcTerraform, end_tile, start_tile, LM_LEVEL << 1 | (_ctrl_pressed ? 1 : 0), {}); break; case DDSP_CREATE_ROCKS: GenerateRockyArea(end_tile, start_tile); @@ -241,7 +243,7 @@ struct TerraformToolbarWindow : Window { break; case WID_TT_BUY_LAND: // Buy land button - DoCommandP(CMD_BUILD_OBJECT, STR_ERROR_CAN_T_PURCHASE_THIS_LAND, CcPlaySound_CONSTRUCTION_RAIL, tile, OBJECT_OWNED_LAND, 0); + Command<CMD_BUILD_OBJECT>::Post(STR_ERROR_CAN_T_PURCHASE_THIS_LAND, CcPlaySound_CONSTRUCTION_RAIL, tile, OBJECT_OWNED_LAND, 0, {}); break; case WID_TT_PLACE_SIGN: // Place sign button @@ -398,7 +400,7 @@ static void CommonRaiseLowerBigLand(TileIndex tile, int mode) StringID msg = mode ? STR_ERROR_CAN_T_RAISE_LAND_HERE : STR_ERROR_CAN_T_LOWER_LAND_HERE; - DoCommandP(CMD_TERRAFORM_LAND, msg, CcTerraform, tile, SLOPE_N, (uint32)mode); + Command<CMD_TERRAFORM_LAND>::Post(msg, CcTerraform, tile, SLOPE_N, (uint32)mode, {}); } else { assert(_terraform_size != 0); TileArea ta(tile, _terraform_size, _terraform_size); @@ -425,7 +427,7 @@ static void CommonRaiseLowerBigLand(TileIndex tile, int mode) for (TileIndex tile2 : ta) { if (TileHeight(tile2) == h) { - DoCommandP(CMD_TERRAFORM_LAND, tile2, SLOPE_N, (uint32)mode); + Command<CMD_TERRAFORM_LAND>::Post(tile2, SLOPE_N, (uint32)mode, {}); } } } diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index a205a505e..12c391487 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -22,6 +22,7 @@ #include "date_gui.h" #include "vehicle_gui.h" #include "settings_type.h" +#include "timetable_cmd.h" #include "widgets/timetable_widget.h" @@ -142,7 +143,7 @@ static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID */ static void ChangeTimetableStartCallback(const Window *w, Date date) { - DoCommandP(CMD_SET_TIMETABLE_START, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, w->window_number, date); + Command<CMD_SET_TIMETABLE_START>::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, w->window_number, date, {}); } @@ -578,25 +579,25 @@ struct TimetableWindow : Window { case WID_VT_CLEAR_TIME: { // Clear waiting time. uint32 p1 = PackTimetableArgs(v, this->sel_index, false); - DoCommandP(CMD_CHANGE_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, (TileIndex)0, p1, 0); + Command<CMD_CHANGE_TIMETABLE>::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, p1, 0, {}); break; } case WID_VT_CLEAR_SPEED: { // Clear max speed button. uint32 p1 = PackTimetableArgs(v, this->sel_index, true); - DoCommandP(CMD_CHANGE_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, (TileIndex)0, p1, UINT16_MAX); + Command<CMD_CHANGE_TIMETABLE>::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, p1, UINT16_MAX, {}); break; } case WID_VT_RESET_LATENESS: // Reset the vehicle's late counter. - DoCommandP(CMD_SET_VEHICLE_ON_TIME, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, (TileIndex)0, v->index, 0); + Command<CMD_SET_VEHICLE_ON_TIME>::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, v->index, 0, {}); break; case WID_VT_AUTOFILL: { // Autofill the timetable. uint32 p2 = 0; if (!HasBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE)) SetBit(p2, 0); if (_ctrl_pressed) SetBit(p2, 1); - DoCommandP(CMD_AUTOFILL_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, (TileIndex)0, v->index, p2); + Command<CMD_AUTOFILL_TIMETABLE>::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, v->index, p2, {}); break; } @@ -629,7 +630,7 @@ struct TimetableWindow : Window { uint32 p2 = std::min<uint32>(val, UINT16_MAX); - DoCommandP(CMD_CHANGE_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, p1, p2); + Command<CMD_CHANGE_TIMETABLE>::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, p1, p2, {}); } void OnResize() override diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index 665556e8a..b2b25afa6 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -49,6 +49,7 @@ #include "framerate_type.h" #include "guitimer_func.h" #include "screenshot_gui.h" +#include "misc_cmd.h" #include "widgets/toolbar_widget.h" @@ -265,7 +266,7 @@ static CallBackFunction ToolbarPauseClick(Window *w) { if (_networking && !_network_server) return CBF_NONE; // only server can pause the game - if (DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, _pause_mode == PM_UNPAUSED)) { + if (Command<CMD_PAUSE>::Post(0, PM_PAUSED_NORMAL, _pause_mode == PM_UNPAUSED, {})) { if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP); } return CBF_NONE; diff --git a/src/town_gui.cpp b/src/town_gui.cpp index cb88c5c00..8f315a055 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -33,6 +33,7 @@ #include "stringfilter_type.h" #include "widgets/dropdown_func.h" #include "town_kdtree.h" +#include "town_cmd.h" #include "widgets/town_widget.h" @@ -287,7 +288,7 @@ public: } case WID_TA_EXECUTE: - DoCommandP(CMD_DO_TOWN_ACTION, STR_ERROR_CAN_T_DO_THIS, this->town->xy, this->window_number, this->sel_index); + Command<CMD_DO_TOWN_ACTION>::Post(STR_ERROR_CAN_T_DO_THIS, this->town->xy, this->window_number, this->sel_index, {}); break; } } @@ -474,12 +475,12 @@ public: _warn_town_no_roads = true; } - DoCommandP(CMD_EXPAND_TOWN, STR_ERROR_CAN_T_EXPAND_TOWN, (TileIndex)0, this->window_number, 0); + Command<CMD_EXPAND_TOWN>::Post(STR_ERROR_CAN_T_EXPAND_TOWN, 0, this->window_number, 0, {}); break; } case WID_TV_DELETE: // delete town - only available on Scenario editor - DoCommandP(CMD_DELETE_TOWN, STR_ERROR_TOWN_CAN_T_DELETE, (TileIndex)0, this->window_number, 0); + Command<CMD_DELETE_TOWN>::Post(STR_ERROR_TOWN_CAN_T_DELETE, 0, this->window_number, 0, {}); break; } } @@ -561,7 +562,7 @@ public: { if (str == nullptr) return; - DoCommandP(CMD_RENAME_TOWN, STR_ERROR_CAN_T_RENAME_TOWN, 0, this->window_number, 0, str); + Command<CMD_RENAME_TOWN>::Post(STR_ERROR_CAN_T_RENAME_TOWN, 0, this->window_number, 0, str); } }; @@ -1162,7 +1163,7 @@ public: if (strcmp(buf, this->townname_editbox.text.buf) != 0) name = this->townname_editbox.text.buf; } - bool success = DoCommandP(CMD_FOUND_TOWN, errstr, cc, + bool success = Command<CMD_FOUND_TOWN>::Post(errstr, cc, tile, this->town_size | this->city << 2 | this->town_layout << 3 | random << 6, townnameparts, name); /* Rerandomise name, if success and no cost-estimation. */ diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index b060ecdba..a86e835bd 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -35,6 +35,7 @@ #include "newgrf_debug.h" #include "framerate_type.h" #include "train_cmd.h" +#include "misc_cmd.h" #include "table/strings.h" #include "table/train_sprites.h" @@ -87,7 +88,7 @@ void CheckTrainsLengths() if (!_networking && first) { first = false; - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_ERROR, 1); + Command<CMD_PAUSE>::Post(0, PM_PAUSED_ERROR, 1, {}); } /* Break so we warn only once for each train. */ break; diff --git a/src/train_gui.cpp b/src/train_gui.cpp index 7031a8968..8fc97d857 100644 --- a/src/train_gui.cpp +++ b/src/train_gui.cpp @@ -14,6 +14,7 @@ #include "strings_func.h" #include "vehicle_func.h" #include "zoom_func.h" +#include "train_cmd.h" #include "table/strings.h" @@ -45,7 +46,7 @@ void CcBuildWagon(const CommandCost &result, Commands cmd, TileIndex tile, uint3 if (found != nullptr) { found = found->Last(); /* put the new wagon at the end of the loco. */ - DoCommandP(CMD_MOVE_RAIL_VEHICLE, 0, _new_vehicle_id, found->index); + Command<CMD_MOVE_RAIL_VEHICLE>::Post(0, _new_vehicle_id, found->index, {}); InvalidateWindowClassesData(WC_TRAINS_LIST, 0); } } diff --git a/src/tree_gui.cpp b/src/tree_gui.cpp index f176668b1..794135716 100644 --- a/src/tree_gui.cpp +++ b/src/tree_gui.cpp @@ -19,6 +19,7 @@ #include "strings_func.h" #include "zoom_func.h" #include "tree_map.h" +#include "tree_cmd.h" #include "widgets/tree_widget.h" @@ -230,7 +231,7 @@ public: TileIndex tile = TileVirtXY(pt.x, pt.y); if (this->mode == PM_NORMAL) { - DoCommandP(CMD_PLANT_TREE, tile, this->tree_to_plant, tile); + Command<CMD_PLANT_TREE>::Post(tile, this->tree_to_plant, tile, {}); } else { this->DoPlantForest(tile); } @@ -240,7 +241,7 @@ public: void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) override { if (_game_mode != GM_EDITOR && this->mode == PM_NORMAL && pt.x != -1 && select_proc == DDSP_PLANT_TREES) { - DoCommandP(CMD_PLANT_TREE, STR_ERROR_CAN_T_PLANT_TREE_HERE, end_tile, this->tree_to_plant, start_tile); + Command<CMD_PLANT_TREE>::Post(STR_ERROR_CAN_T_PLANT_TREE_HERE, end_tile, this->tree_to_plant, start_tile, {}); } } diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index d5d6978cc..c54910150 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -38,6 +38,9 @@ #include "zoom_func.h" #include "depot_cmd.h" #include "vehicle_cmd.h" +#include "order_cmd.h" +#include "roadveh_cmd.h" +#include "train_cmd.h" #include "safeguards.h" @@ -1035,9 +1038,9 @@ struct RefitWindow : public Window { if (this->order == INVALID_VEH_ORDER_ID) { bool delete_window = this->selected_vehicle == v->index && this->num_vehicles == UINT8_MAX; - if (DoCommandP(CMD_REFIT_VEHICLE, GetCmdRefitVehMsg(v), v->tile, this->selected_vehicle, this->cargo->cargo | this->cargo->subtype << 8 | this->num_vehicles << 16) && delete_window) this->Close(); + if (Command<CMD_REFIT_VEHICLE>::Post(GetCmdRefitVehMsg(v), v->tile, this->selected_vehicle, this->cargo->cargo | this->cargo->subtype << 8 | this->num_vehicles << 16, {}) && delete_window) this->Close(); } else { - if (DoCommandP(CMD_ORDER_REFIT, v->tile, v->index, this->cargo->cargo | this->order << 16)) this->Close(); + if (Command<CMD_ORDER_REFIT>::Post(v->tile, v->index, this->cargo->cargo | this->order << 16, {})) this->Close(); } } break; @@ -1896,7 +1899,7 @@ public: case WID_VL_STOP_ALL: case WID_VL_START_ALL: - DoCommandP(CMD_MASS_START_STOP, 0, (1 << 1) | (widget == WID_VL_START_ALL ? (1 << 0) : 0), this->window_number); + Command<CMD_MASS_START_STOP>::Post(0, (1 << 1) | (widget == WID_VL_START_ALL ? (1 << 0) : 0), this->window_number, {}); break; } } @@ -1921,7 +1924,7 @@ public: break; case ADI_SERVICE: // Send for servicing case ADI_DEPOT: // Send to Depots - DoCommandP(CMD_SEND_VEHICLE_TO_DEPOT, GetCmdSendToDepotMsg(this->vli.vtype), 0, DEPOT_MASS_SEND | (index == ADI_SERVICE ? DEPOT_SERVICE : (DepotCommand)0), this->window_number); + Command<CMD_SEND_VEHICLE_TO_DEPOT>::Post(GetCmdSendToDepotMsg(this->vli.vtype), 0, DEPOT_MASS_SEND | (index == ADI_SERVICE ? DEPOT_SERVICE : (DepotCommand)0), this->window_number, {}); break; default: NOT_REACHED(); @@ -2424,7 +2427,7 @@ struct VehicleDetailsWindow : Window { mod = GetServiceIntervalClamped(mod + v->GetServiceInterval(), v->ServiceIntervalIsPercent()); if (mod == v->GetServiceInterval()) return; - DoCommandP(CMD_CHANGE_SERVICE_INT, STR_ERROR_CAN_T_CHANGE_SERVICING, v->tile, v->index, mod | (1 << 16) | (v->ServiceIntervalIsPercent() << 17)); + Command<CMD_CHANGE_SERVICE_INT>::Post(STR_ERROR_CAN_T_CHANGE_SERVICING, v->tile, v->index, mod | (1 << 16) | (v->ServiceIntervalIsPercent() << 17), {}); break; } @@ -2460,7 +2463,7 @@ struct VehicleDetailsWindow : Window { bool iscustom = index != 0; bool ispercent = iscustom ? (index == 2) : Company::Get(v->owner)->settings.vehicle.servint_ispercent; uint16 interval = GetServiceIntervalClamped(v->GetServiceInterval(), ispercent); - DoCommandP(CMD_CHANGE_SERVICE_INT, STR_ERROR_CAN_T_CHANGE_SERVICING, v->tile, v->index, interval | (iscustom << 16) | (ispercent << 17)); + Command<CMD_CHANGE_SERVICE_INT>::Post(STR_ERROR_CAN_T_CHANGE_SERVICING, v->tile, v->index, interval | (iscustom << 16) | (ispercent << 17), {}); break; } } @@ -2643,7 +2646,7 @@ void CcStartStopVehicle(const CommandCost &result, Commands cmd, TileIndex tile, void StartStopVehicle(const Vehicle *v, bool texteffect) { assert(v->IsPrimaryVehicle()); - DoCommandP(CMD_START_STOP_VEHICLE, _vehicle_msg_translation_table[VCT_CMD_START_STOP][v->type], texteffect ? CcStartStopVehicle : nullptr, v->tile, v->index, 0); + Command<CMD_START_STOP_VEHICLE>::Post(_vehicle_msg_translation_table[VCT_CMD_START_STOP][v->type], texteffect ? CcStartStopVehicle : nullptr, v->tile, v->index, 0, {}); } /** Checks whether the vehicle may be refitted at the moment.*/ @@ -2967,7 +2970,7 @@ public: break; case WID_VV_GOTO_DEPOT: // goto hangar - DoCommandP(CMD_SEND_VEHICLE_TO_DEPOT, GetCmdSendToDepotMsg(v), v->tile, v->index | (_ctrl_pressed ? DEPOT_SERVICE : 0U), 0); + Command<CMD_SEND_VEHICLE_TO_DEPOT>::Post(GetCmdSendToDepotMsg(v), v->tile, v->index | (_ctrl_pressed ? DEPOT_SERVICE : 0U), 0, {}); break; case WID_VV_REFIT: // refit ShowVehicleRefitWindow(v, INVALID_VEH_ORDER_ID, this); @@ -2991,21 +2994,21 @@ public: * There is no point to it except for starting the vehicle. * For starting the vehicle the player has to open the depot GUI, which is * most likely already open, but is also visible in the vehicle viewport. */ - DoCommandP(CMD_CLONE_VEHICLE, _vehicle_msg_translation_table[VCT_CMD_CLONE_VEH][v->type], + Command<CMD_CLONE_VEHICLE>::Post(_vehicle_msg_translation_table[VCT_CMD_CLONE_VEH][v->type], _ctrl_pressed ? nullptr : CcCloneVehicle, - v->tile, v->index, _ctrl_pressed ? 1 : 0); + v->tile, v->index, _ctrl_pressed ? 1 : 0, {}); break; case WID_VV_TURN_AROUND: // turn around assert(v->IsGroundVehicle()); if (v->type == VEH_ROAD) { - DoCommandP(CMD_TURN_ROADVEH, _vehicle_msg_translation_table[VCT_CMD_TURN_AROUND][v->type], v->tile, v->index, 0); + Command<CMD_TURN_ROADVEH>::Post(_vehicle_msg_translation_table[VCT_CMD_TURN_AROUND][v->type], v->tile, v->index, 0, {}); } else { - DoCommandP(CMD_REVERSE_TRAIN_DIRECTION, _vehicle_msg_translation_table[VCT_CMD_TURN_AROUND][v->type], v->tile, v->index, 0); + Command<CMD_REVERSE_TRAIN_DIRECTION>::Post(_vehicle_msg_translation_table[VCT_CMD_TURN_AROUND][v->type], v->tile, v->index, 0, {}); } break; case WID_VV_FORCE_PROCEED: // force proceed assert(v->type == VEH_TRAIN); - DoCommandP(CMD_FORCE_TRAIN_PROCEED, STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL, v->tile, v->index, 0); + Command<CMD_FORCE_TRAIN_PROCEED>::Post(STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL, v->tile, v->index, 0, {}); break; } } @@ -3014,7 +3017,7 @@ public: { if (str == nullptr) return; - DoCommandP(CMD_RENAME_VEHICLE, STR_ERROR_CAN_T_RENAME_TRAIN + Vehicle::Get(this->window_number)->type, 0, this->window_number, 0, str); + Command<CMD_RENAME_VEHICLE>::Post(STR_ERROR_CAN_T_RENAME_TRAIN + Vehicle::Get(this->window_number)->type, 0, this->window_number, 0, str); } void OnMouseOver(Point pt, int widget) override diff --git a/src/waypoint_gui.cpp b/src/waypoint_gui.cpp index 44e2718b6..673601f89 100644 --- a/src/waypoint_gui.cpp +++ b/src/waypoint_gui.cpp @@ -20,6 +20,7 @@ #include "company_base.h" #include "window_func.h" #include "waypoint_base.h" +#include "waypoint_cmd.h" #include "widgets/waypoint_widget.h" @@ -138,7 +139,7 @@ public: { if (str == nullptr) return; - DoCommandP(CMD_RENAME_WAYPOINT, STR_ERROR_CAN_T_CHANGE_WAYPOINT_NAME, 0, this->window_number, 0, str); + Command<CMD_RENAME_WAYPOINT>::Post(STR_ERROR_CAN_T_CHANGE_WAYPOINT_NAME, 0, this->window_number, 0, str); } }; |