Changeset - r26103:316b73a1be08
[Not reviewed]
master
0 47 0
Michael Lutz - 3 years ago 2021-10-31 18:39:09
michi@icosahedron.de
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 with 375 insertions and 332 deletions:
0 comments (0 inline, 0 general)
src/ai/ai_gui.cpp
Show inline comments
 
@@ -25,12 +25,14 @@
 
#include "../textfile_gui.h"
 
#include "../widgets/dropdown_type.h"
 
#include "../widgets/dropdown_func.h"
 
#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"
 
#include "../script/api/script_log.hpp"
 
#include "ai_config.hpp"
 
#include "ai_info.hpp"
 
@@ -1287,14 +1289,14 @@ struct AIDebugWindow : public Window {
 
				ChangeToAI(OWNER_DEITY);
 
				break;
 

	
 
			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:
 
				ShowAISettingsWindow(ai_debug_company);
 
				break;
 

	
 
@@ -1327,13 +1329,13 @@ struct AIDebugWindow : public Window {
 
								all_unpaused = false;
 
								break;
 
							}
 
						}
 
						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, {});
 
						}
 
					}
 
				}
 

	
 
				this->highlight_row = -1;
 
				this->InvalidateData(-1);
 
@@ -1376,13 +1378,13 @@ struct AIDebugWindow : public Window {
 
							AI::Pause(ai_debug_company);
 
						}
 
					}
 

	
 
					/* 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 */
 
					this->highlight_row = log->pos;
 
				}
 
			}
src/airport_gui.cpp
Show inline comments
 
@@ -68,13 +68,13 @@ static void PlaceAirport(TileIndex tile)
 
		if (test) {
 
			return Command<CMD_BUILD_AIRPORT>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_AIRPORT>()), tile, p1, p2, {}).Succeeded();
 
		} else {
 
			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, {});
 
		}
 
	};
 

	
 
	ShowSelectStationIfNeeded(TileArea(tile, _thd.size.x / TILE_SIZE, _thd.size.y / TILE_SIZE), proc);
 
}
 

	
src/autoreplace_gui.cpp
Show inline comments
 
@@ -22,12 +22,15 @@
 
#include "engine_gui.h"
 
#include "settings_func.h"
 
#include "core/geometry_func.hpp"
 
#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"
 

	
 
#include "safeguards.h"
 

	
 
void DrawEngineList(VehicleType type, int x, int r, int y, const GUIEngineList *eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group);
 
@@ -214,13 +217,13 @@ class ReplaceVehicleWindow : public Wind
 
	 * @param replace_when_old Replace now or only when old?
 
	 */
 
	void ReplaceClick_StartReplace(bool replace_when_old)
 
	{
 
		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:
 
	ReplaceVehicleWindow(WindowDesc *desc, VehicleType vehicletype, GroupID id_g) : Window(desc)
 
	{
 
		this->sel_railtype = INVALID_RAILTYPE;
 
@@ -538,16 +541,16 @@ public:
 
				}
 
				break;
 

	
 
			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;
 
			}
 

	
 
			case WID_RV_START_REPLACE: { // Start replacing
 
				if (this->GetWidget<NWidgetLeaf>(widget)->ButtonHit(pt)) {
 
@@ -559,13 +562,13 @@ public:
 
				}
 
				break;
 
			}
 

	
 
			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;
 
			}
 

	
 
			case WID_RV_LEFT_MATRIX:
 
			case WID_RV_RIGHT_MATRIX: {
 
				byte click_side;
 
@@ -581,13 +584,13 @@ public:
 

	
 
				/* If Ctrl is pressed on the left side and we don't have any engines of the selected type, stop autoreplacing.
 
				 * This is most common when we have finished autoreplacing the engine and want to remove it from the list. */
 
				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;
 
				}
 

	
 
				if (e == this->sel_engine[click_side]) break; // we clicked the one we already selected
 
				this->sel_engine[click_side] = e;
 
				if (click_side == 0) {
src/bridge_gui.cpp
Show inline comments
 
@@ -116,14 +116,14 @@ private:
 
	{
 
		switch ((TransportType)(this->type >> 15)) {
 
			case TRANSPORT_RAIL: _last_railbridge_type = this->bridges->at(i).index; break;
 
			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 */
 
	void SortBridgeList()
 
	{
 
		this->bridges->Sort();
 
@@ -382,13 +382,13 @@ void ShowBuildBridgeWindow(TileIndex sta
 
	switch (transport_type) {
 
		case TRANSPORT_ROAD: last_bridge_type = _last_roadbridge_type; break;
 
		case TRANSPORT_RAIL: last_bridge_type = _last_railbridge_type; break;
 
		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;
 
	}
 

	
 
	/* only query bridge building possibility once, result is the same for all bridges!
 
	 * returns CMD_ERROR on failure, and price on success */
 
	StringID errmsg = INVALID_STRING_ID;
src/build_vehicle_gui.cpp
Show inline comments
 
@@ -27,12 +27,13 @@
 
#include "vehicle_func.h"
 
#include "widgets/dropdown_func.h"
 
#include "engine_gui.h"
 
#include "cargotype.h"
 
#include "core/geometry_func.hpp"
 
#include "autoreplace_func.h"
 
#include "engine_cmd.h"
 
#include "train_cmd.h"
 
#include "vehicle_cmd.h"
 

	
 
#include "widgets/build_vehicle_widget.h"
 

	
 
#include "table/strings.h"
 
@@ -1457,24 +1458,24 @@ struct BuildVehicleWindow : Window {
 
				ShowDropDownMenu(this, this->cargo_filter_texts, this->cargo_filter_criteria, WID_BV_CARGO_FILTER_DROPDOWN, 0, 0);
 
				break;
 

	
 
			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;
 
			}
 

	
 
			case WID_BV_BUILD: {
 
				EngineID sel_eng = this->sel_engine;
 
				if (sel_eng != INVALID_ENGINE) {
 
					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;
 
			}
 

	
 
			case WID_BV_RENAME: {
 
				EngineID sel_eng = this->sel_engine;
 
@@ -1633,13 +1634,13 @@ struct BuildVehicleWindow : Window {
 
	}
 

	
 
	void OnQueryTextFinished(char *str) override
 
	{
 
		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
 
	{
 
		switch (widget) {
 
			case WID_BV_SORT_DROPDOWN:
src/cheat_gui.cpp
Show inline comments
 
@@ -25,12 +25,13 @@
 
#include "company_gui.h"
 
#include "linkgraph/linkgraphschedule.h"
 
#include "map_func.h"
 
#include "tile_map.h"
 
#include "newgrf.h"
 
#include "error.h"
 
#include "misc_cmd.h"
 

	
 
#include "widgets/cheat_widget.h"
 

	
 
#include "table/sprites.h"
 

	
 
#include "safeguards.h"
 
@@ -51,13 +52,13 @@ static int32 _money_cheat_amount = 10000
 
 * @param p1 not used.
 
 * @param p2 is -1 or +1 (down/up)
 
 * @return Amount of money cheat.
 
 */
 
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;
 
}
 

	
 
/**
 
 * Handle changing of company.
 
 * @param p1 company to set to
src/command.cpp
Show inline comments
 
@@ -210,57 +210,56 @@ void CommandHelperBase::InternalDoAfter(
 
		if (res.Succeeded() && top_level && !(flags & DC_BANKRUPT)) {
 
			SubtractMoneyFromCompany(res);
 
		}
 
	}
 
}
 

	
 
/*!
 
 * 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? */
 
	if (_pause_mode != PM_UNPAUSED && !IsCommandAllowedWhilePaused(cmd) && !estimate_only) {
 
		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 };
 
	}
 
}
 

	
 
/**
 
 * 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;
 

	
 
	if (_pause_mode != PM_UNPAUSED && !IsCommandAllowedWhilePaused(cmd) && !estimate_only) {
 
		ShowErrorMessage(err_message, STR_ERROR_NOT_ALLOWED_WHILE_PAUSED, WL_INFO, x, y);
 
		return false;
 
	}
 

	
 
	/* 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;
 

	
 
	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)) {
 
			ShowErrorMessage(err_message, res.GetErrorMessage(), WL_INFO, x, y, res.GetTextRefStackGRF(), res.GetTextRefStackSize(), res.GetTextRefStack());
 
		}
 
	} else if (estimate_only) {
 
@@ -270,101 +269,12 @@ static bool DoCommandP(Commands cmd, Str
 
		 * execute the command, i.e. we're not sending it to
 
		 * the server, when it has cost the local company
 
		 * something. Furthermore in the editor there is no
 
		 * 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. */
 
static std::string CommandParametersToHexString(TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
 
{
 
	return FormatArrayAsHex(EndianBufferWriter<>::FromValue(std::make_tuple(tile, p1, p2, text)));
src/command_func.h
Show inline comments
 
@@ -34,20 +34,12 @@ static const CommandCost CMD_ERROR = Com
 
 */
 
#define return_cmd_error(errcode) return CommandCost(errcode);
 

	
 
/** 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);
 
void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, TileIndex location, const CommandDataBuffer &cmd_data);
 

	
 
extern Money _additional_cash_required;
 
@@ -93,12 +85,14 @@ private:
 
template<Commands TCmd, typename T> struct CommandHelper;
 

	
 
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);
 
};
 

	
 
/**
 
 * Templated wrapper that exposes the command parameter arguments
 
 * for the various Command::Do/Post calls.
 
 * @tparam Tcmd The command-id to execute.
 
@@ -144,12 +138,89 @@ public:
 
		InternalDoBefore(counter.IsTopLevel(), false);
 
		CommandCost res = CommandTraits<Tcmd>::proc(flags, args...);
 
		InternalDoAfter(res, flags, counter.IsTopLevel(), false);
 

	
 
		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>
 
using Command = CommandHelper<Tcmd, typename CommandTraits<Tcmd>::ProcType>;
 

	
 
#endif /* COMMAND_FUNC_H */
src/company_cmd.cpp
Show inline comments
 
@@ -601,13 +601,13 @@ static bool MaybeStartNewCompany()
 
		if (c->is_ai) n++;
 
	}
 

	
 
	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;
 
}
 

	
 
/** Initialize the pool of companies. */
src/company_gui.cpp
Show inline comments
 
@@ -34,12 +34,17 @@
 
#include "window_func.h"
 
#include "road_func.h"
 
#include "water.h"
 
#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"
 

	
 
#include "safeguards.h"
 

	
 

	
 
@@ -432,17 +437,17 @@ struct CompanyFinancesWindow : Window {
 
				} else {
 
					this->ReInit();
 
				}
 
				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
 
				ShowCompanyInfrastructure((CompanyID)this->window_number);
 
				break;
 
		}
 
@@ -992,18 +997,18 @@ public:
 

	
 
		if (this->livery_class < LC_GROUP_RAIL) {
 
			/* Set company colour livery */
 
			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), {});
 
		}
 
	}
 

	
 
	/**
 
	 * Some data on this window has become invalid.
 
	 * @param data Information about the changed data.
 
@@ -1578,13 +1583,13 @@ public:
 
				this->SelectDisplayPlanes(this->advanced);
 
				this->ReInit();
 
				break;
 

	
 
			/* 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 */
 
			case WID_SCMF_CANCEL:
 
				this->Close();
 
				break;
 
@@ -2573,17 +2578,17 @@ struct CompanyWindow : Window
 
			case WID_C_GIVE_MONEY:
 
				this->query_widget = WID_C_GIVE_MONEY;
 
				ShowQueryString(STR_EMPTY, STR_COMPANY_VIEW_GIVE_MONEY_QUERY_CAPTION, 30, this, CS_NUMERAL, QSF_NONE);
 
				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:
 
				if (this->window_number == _local_company) ShowNetworkCompanyPasswordWindow(this);
 
				break;
 

	
 
@@ -2610,13 +2615,13 @@ struct CompanyWindow : Window
 
		/* redraw the window every now and then */
 
		this->SetDirty();
 
	}
 

	
 
	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();
 
		}
 
	}
 

	
 
	void OnPlaceObjectAbort() override
 
@@ -2632,22 +2637,22 @@ struct CompanyWindow : Window
 
			default: NOT_REACHED();
 

	
 
			case WID_C_GIVE_MONEY: {
 
				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:
 
				NetworkClientRequestMove((CompanyID)this->window_number, str);
 
				break;
 
		}
 
@@ -2768,13 +2773,13 @@ struct BuyCompanyWindow : Window {
 
		switch (widget) {
 
			case WID_BC_NO:
 
				this->Close();
 
				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;
 
		}
 
	}
 
};
 

	
 
static const NWidgetPart _nested_buy_company_widgets[] = {
src/console_cmds.cpp
Show inline comments
 
@@ -39,12 +39,14 @@
 
#include "engine_base.h"
 
#include "road.h"
 
#include "rail.h"
 
#include "game/game.hpp"
 
#include "table/strings.h"
 
#include "walltime_func.h"
 
#include "company_cmd.h"
 
#include "misc_cmd.h"
 

	
 
#include "safeguards.h"
 

	
 
/* scriptfile handling */
 
static uint _script_current_depth; ///< Depth of scripts running (used to abort execution when #ConReturn is encountered).
 

	
 
@@ -627,13 +629,13 @@ DEF_CONSOLE_CMD(ConPauseGame)
 
	if (_game_mode == GM_MENU) {
 
		IConsolePrint(CC_ERROR, "This command is only available in-game and in the editor.");
 
		return true;
 
	}
 

	
 
	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.");
 
	}
 

	
 
	return true;
 
@@ -649,13 +651,13 @@ DEF_CONSOLE_CMD(ConUnpauseGame)
 
	if (_game_mode == GM_MENU) {
 
		IConsolePrint(CC_ERROR, "This command is only available in-game and in the editor.");
 
		return true;
 
	}
 

	
 
	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.");
 
	} else if (_pause_mode != PM_UNPAUSED) {
 
		IConsolePrint(CC_DEFAULT, "Game cannot be unpaused manually; disable pause_on_join/min_active_clients.");
 
	} else {
 
@@ -860,13 +862,13 @@ DEF_CONSOLE_CMD(ConResetCompany)
 
	if (ci->client_playas == index) {
 
		IConsolePrint(CC_ERROR, "Cannot remove company: the server is connected to that company.");
 
		return true;
 
	}
 

	
 
	/* 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;
 
}
 

	
 
DEF_CONSOLE_CMD(ConNetworkClients)
 
@@ -1217,13 +1219,13 @@ DEF_CONSOLE_CMD(ConStartAI)
 
		if (argc == 3) {
 
			config->StringToSettings(argv[2]);
 
		}
 
	}
 

	
 
	/* 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;
 
}
 

	
 
DEF_CONSOLE_CMD(ConReloadAI)
 
{
 
@@ -1253,14 +1255,14 @@ DEF_CONSOLE_CMD(ConReloadAI)
 
	if (Company::IsHumanID(company_id) || company_id == _local_company) {
 
		IConsolePrint(CC_ERROR, "Company is not controlled by an AI.");
 
		return true;
 
	}
 

	
 
	/* 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;
 
}
 

	
 
DEF_CONSOLE_CMD(ConStopAI)
 
@@ -1291,13 +1293,13 @@ DEF_CONSOLE_CMD(ConStopAI)
 
	if (Company::IsHumanID(company_id) || company_id == _local_company) {
 
		IConsolePrint(CC_ERROR, "Company is not controlled by an AI.");
 
		return true;
 
	}
 

	
 
	/* 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;
 
}
 

	
 
DEF_CONSOLE_CMD(ConRescanAI)
src/depot_gui.cpp
Show inline comments
 
@@ -23,12 +23,15 @@
 
#include "company_func.h"
 
#include "tilehighlight_func.h"
 
#include "window_gui.h"
 
#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"
 

	
 
#include "table/strings.h"
 

	
 
#include "safeguards.h"
 
@@ -139,13 +142,13 @@ static void TrainDepotMoveVehicle(const 
 
		wagon = wagon->Previous();
 
		if (wagon == nullptr) return;
 
	}
 

	
 
	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.
 
static VehicleCellSize _base_block_sizes_purchase[VEH_COMPANY_END]; ///< Cell size for vehicle images in the purchase list.
 
static uint _consistent_train_width;                                ///< Whether trains of all lengths are consistently scaled. Either TRAININFO_DEFAULT_VEHICLE_WIDTH, VEHICLEINFO_FULL_VEHICLE_WIDTH, or 0.
 

	
 
@@ -800,13 +803,13 @@ struct DepotWindow : Window {
 
				ShowQueryString(STR_DEPOT_NAME, STR_DEPOT_RENAME_DEPOT_CAPTION, MAX_LENGTH_DEPOT_NAME_CHARS, this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT | QSF_LEN_IN_CHARS);
 
				break;
 

	
 
			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;
 
			}
 

	
 
			case WID_D_SELL_ALL:
 
				/* Only open the confirmation window if there are anything to sell */
 
				if (this->vehicle_list.size() != 0 || this->wagon_list.size() != 0) {
 
@@ -823,24 +826,24 @@ struct DepotWindow : Window {
 

	
 
			case WID_D_VEHICLE_LIST:
 
				ShowVehicleListWindow(GetTileOwner(this->window_number), this->type, (TileIndex)this->window_number);
 
				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;
 

	
 
		}
 
	}
 

	
 
	void OnQueryTextFinished(char *str) override
 
	{
 
		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
 
	{
 
		if (widget != WID_D_MATRIX) return false;
 

	
 
@@ -902,16 +905,16 @@ struct DepotWindow : Window {
 
	 * @return Always true.
 
	 */
 
	bool OnVehicleSelect(const Vehicle *v) override
 
	{
 
		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();
 
			}
 
		}
 

	
 
		return true;
 
	}
 
@@ -999,13 +1002,13 @@ struct DepotWindow : Window {
 
				NWidgetBase *nwi = this->GetWidget<NWidgetBase>(WID_D_MATRIX);
 
				if (this->type == VEH_TRAIN) {
 
					GetDepotVehiclePtData gdvp = { nullptr, nullptr };
 

	
 
					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);
 
						} else if (gdvp.head != nullptr && gdvp.head->IsFrontEngine()) {
 
							ShowVehicleViewWindow(gdvp.head);
 
						}
 
@@ -1024,13 +1027,13 @@ struct DepotWindow : Window {
 

	
 
				const Vehicle *v = Vehicle::Get(this->sel);
 
				this->sel = INVALID_VEHICLE;
 
				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;
 
			}
 

	
 
			default:
 
				this->sel = INVALID_VEHICLE;
 
				this->SetDirty();
 
@@ -1088,13 +1091,13 @@ struct DepotWindow : Window {
 
static void DepotSellAllConfirmationCallback(Window *win, bool confirmed)
 
{
 
	if (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, {});
 
	}
 
}
 

	
 
/**
 
 * Opens a depot window
 
 * @param tile The tile where the depot/hangar is located
src/dock_gui.cpp
Show inline comments
 
@@ -25,12 +25,14 @@
 
#include "hotkeys.h"
 
#include "gui.h"
 
#include "zoom_func.h"
 
#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"
 

	
 
#include "table/sprites.h"
 
#include "table/strings.h"
 

	
 
@@ -191,21 +193,21 @@ struct BuildDocksToolbarWindow : Window 
 
		switch (this->last_clicked_widget) {
 
			case WID_DT_CANAL: // Build canal button
 
				VpStartPlaceSizing(tile, (_game_mode == GM_EDITOR) ? VPM_X_AND_Y : VPM_X_OR_Y, DDSP_CREATE_WATER);
 
				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
 
				PlaceProc_DemolishArea(tile);
 
				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
 
				/* Determine the watery part of the dock. */
 
				DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile));
 
				TileIndex tile_to = (dir != INVALID_DIAGDIR ? TileAddByDiagDir(tile, ReverseDiagDir(dir)) : tile);
 
@@ -217,30 +219,30 @@ struct BuildDocksToolbarWindow : Window 
 
					if (test) {
 
						return Command<CMD_BUILD_DOCK>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_DOCK>()), tile, p1, p2, {}).Succeeded();
 
					} else {
 
						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, {});
 
					}
 
				};
 

	
 
				ShowSelectStationIfNeeded(TileArea(tile, tile_to), proc);
 
				break;
 
			}
 

	
 
			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)
 
				VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CREATE_RIVER);
 
				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();
 
		}
 
	}
 

	
 
@@ -254,16 +256,16 @@ struct BuildDocksToolbarWindow : Window 
 
		if (pt.x != -1) {
 
			switch (select_proc) {
 
				case DDSP_DEMOLISH_AREA:
 
					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;
 
			}
 
		}
 
	}
src/economy.cpp
Show inline comments
 
@@ -45,12 +45,13 @@
 
#include "water.h"
 
#include "game/game.hpp"
 
#include "cargomonitor.h"
 
#include "goal_base.h"
 
#include "story_base.h"
 
#include "linkgraph/refresh.h"
 
#include "company_cmd.h"
 
#include "economy_cmd.h"
 
#include "vehicle_cmd.h"
 

	
 
#include "table/strings.h"
 
#include "table/pricebase.h"
 

	
 
@@ -626,13 +627,13 @@ static void CompanyCheckBankrupt(Company
 
			 * updating the local company triggers an assert later on. In the
 
			 * case of a network game the command will be processed at a time
 
			 * that changing the current company is okay. In case of single
 
			 * 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;
 
		}
 
	}
 

	
src/engine_gui.cpp
Show inline comments
 
@@ -20,12 +20,13 @@
 
#include "road.h"
 
#include "settings_type.h"
 
#include "train.h"
 
#include "roadveh.h"
 
#include "ship.h"
 
#include "aircraft.h"
 
#include "engine_cmd.h"
 

	
 
#include "widgets/engine_widget.h"
 

	
 
#include "table/strings.h"
 

	
 
#include "safeguards.h"
 
@@ -122,13 +123,13 @@ struct EnginePreviewWindow : Window {
 
	}
 

	
 
	void OnClick(Point pt, int widget, int click_count) override
 
	{
 
		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();
 
				break;
 
		}
 
	}
src/fios_gui.cpp
Show inline comments
 
@@ -24,12 +24,13 @@
 
#include "engine_func.h"
 
#include "landscape_type.h"
 
#include "date_func.h"
 
#include "core/geometry_func.hpp"
 
#include "gamelog.h"
 
#include "stringfilter_type.h"
 
#include "misc_cmd.h"
 

	
 
#include "widgets/fios_widget.h"
 

	
 
#include "table/sprites.h"
 
#include "table/strings.h"
 

	
 
@@ -355,13 +356,13 @@ public:
 
		this->querystrings[WID_SL_FILTER] = &this->filter_editbox;
 
		this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR;
 

	
 
		/* 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);
 

	
 
		this->OnInvalidateData(SLIWD_RESCAN_FILES);
 

	
 
		ResetObjectToPlace();
 
@@ -399,13 +400,13 @@ public:
 
	}
 

	
 
	void Close() override
 
	{
 
		/* 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();
 
	}
 

	
 
	void DrawWidget(const Rect &r, int widget) const override
 
	{
src/goal_gui.cpp
Show inline comments
 
@@ -20,12 +20,13 @@
 
#include "company_func.h"
 
#include "company_base.h"
 
#include "company_gui.h"
 
#include "story_base.h"
 
#include "command_func.h"
 
#include "string_func.h"
 
#include "goal_cmd.h"
 

	
 
#include "widgets/goal_widget.h"
 

	
 
#include "table/strings.h"
 

	
 
#include "safeguards.h"
 
@@ -379,23 +380,23 @@ struct GoalQuestionWindow : public Windo
 
	}
 

	
 
	void OnClick(Point pt, int widget, int click_count) override
 
	{
 
		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;
 
		}
 
	}
 

	
 
	void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
src/group_gui.cpp
Show inline comments
 
@@ -23,12 +23,13 @@
 
#include "vehicle_gui_base.h"
 
#include "core/geometry_func.hpp"
 
#include "company_base.h"
 
#include "company_gui.h"
 
#include "gui.h"
 
#include "group_cmd.h"
 
#include "vehicle_cmd.h"
 

	
 
#include "widgets/group_widget.h"
 

	
 
#include "table/sprites.h"
 

	
 
#include "safeguards.h"
 
@@ -638,13 +639,13 @@ public:
 

	
 
	static void DeleteGroupCallback(Window *win, bool confirmed)
 
	{
 
		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, {});
 
		}
 
	}
 

	
 
	void OnClick(Point pt, int widget, int click_count) override
 
	{
 
		switch (widget) {
 
@@ -769,13 +770,13 @@ public:
 
				}
 

	
 
				break;
 
			}
 

	
 
			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;
 
			}
 

	
 
			case WID_GL_DELETE_GROUP: { // Delete the selected group
 
				this->group_confirm = this->vli.index;
 
				ShowQuery(STR_QUERY_GROUP_DELETE_CAPTION, STR_GROUP_DELETE_QUERY_TEXT, this, DeleteGroupCallback);
 
@@ -798,20 +799,20 @@ public:
 
				ShowDropDownList(this, this->BuildActionDropdownList(true, Group::IsValidID(this->vli.index)), 0, WID_GL_MANAGE_VEHICLES_DROPDOWN);
 
				break;
 
			}
 

	
 
			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;
 
			}
 
		}
 
	}
 

	
 
@@ -820,26 +821,26 @@ public:
 
		const Group *g = Group::Get(this->group_sel);
 

	
 
		switch (widget) {
 
			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;
 
				this->group_over = INVALID_GROUP;
 
				this->SetDirty();
 
				break;
 

	
 
			case WID_GL_LIST_GROUP: { // Matrix group
 
				uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP);
 
				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;
 
				this->group_over = INVALID_GROUP;
 
				this->SetDirty();
 
				break;
 
@@ -848,13 +849,13 @@ public:
 
	}
 

	
 
	void OnDragDrop_Vehicle(Point pt, int widget)
 
	{
 
		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;
 

	
 
				this->SetDirty();
 
				break;
 
@@ -865,13 +866,13 @@ public:
 
				this->group_over = INVALID_GROUP;
 
				this->SetDirty();
 

	
 
				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;
 
			}
 

	
 
			case WID_GL_LIST_VEHICLE: { // Matrix vehicle
 
				const VehicleID vindex = this->vehicle_sel;
 
				this->vehicle_sel = INVALID_VEHICLE;
 
@@ -920,13 +921,13 @@ public:
 

	
 
		_cursor.vehchain = false;
 
	}
 

	
 
	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;
 
	}
 

	
 
	void OnResize() override
 
	{
 
		this->group_sb->SetCapacityFromWidget(this, WID_GL_LIST_GROUP);
 
@@ -950,25 +951,25 @@ public:
 
				switch (index) {
 
					case ADI_REPLACE: // Replace window
 
						ShowReplaceGroupVehicleWindow(this->vli.index, this->vli.vtype);
 
						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();
 
				}
 
				break;
 

	
 
			default: NOT_REACHED();
src/highscore_gui.cpp
Show inline comments
 
@@ -18,12 +18,13 @@
 
#include "command_func.h"
 
#include "company_func.h"
 
#include "company_base.h"
 
#include "strings_func.h"
 
#include "hotkeys.h"
 
#include "zoom_func.h"
 
#include "misc_cmd.h"
 

	
 
#include "widgets/highscore_widget.h"
 

	
 
#include "safeguards.h"
 

	
 
struct EndGameHighScoreBaseWindow : Window {
 
@@ -93,13 +94,13 @@ struct EndGameHighScoreBaseWindow : Wind
 

	
 
/** End game window shown at the end of the game */
 
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;
 

	
 
		if (_local_company != COMPANY_SPECTATOR) {
 
			const Company *c = Company::Get(_local_company);
 
			if (c->old_economy[0].performance_history == SCORE_MAX) {
 
@@ -121,13 +122,13 @@ struct EndGameWindow : EndGameHighScoreB
 

	
 
		MarkWholeScreenDirty();
 
	}
 

	
 
	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();
 
	}
 

	
 
	void OnPaint() override
 
	{
 
@@ -156,13 +157,13 @@ struct HighScoreWindow : EndGameHighScor
 
	bool game_paused_by_player; ///< True if the game was paused by the player when the highscore window was opened.
 

	
 
	HighScoreWindow(WindowDesc *desc, int difficulty, int8 ranking) : EndGameHighScoreBaseWindow(desc)
 
	{
 
		/* 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();
 

	
 
		MarkWholeScreenDirty();
 
		this->window_number = difficulty; // show highscore chart for difficulty...
 
@@ -171,13 +172,13 @@ struct HighScoreWindow : EndGameHighScor
 
	}
 

	
 
	void Close() override
 
	{
 
		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();
 
	}
 

	
 
	void OnPaint() override
 
	{
src/industry_gui.cpp
Show inline comments
 
@@ -36,12 +36,13 @@
 
#include "genworld.h"
 
#include "smallmap_gui.h"
 
#include "widgets/dropdown_type.h"
 
#include "widgets/industry_widget.h"
 
#include "clear_map.h"
 
#include "zoom_func.h"
 
#include "industry_cmd.h"
 

	
 
#include "table/strings.h"
 

	
 
#include <bitset>
 

	
 
#include "safeguards.h"
 
@@ -676,13 +677,13 @@ public:
 
				if (this->selected_type != INVALID_INDUSTRYTYPE) ShowIndustryCargoesWindow(this->selected_type);
 
				break;
 

	
 
			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);
 
					}
 
				}
 
				break;
 
@@ -713,19 +714,19 @@ public:
 
			}
 

	
 
			Backup<CompanyID> cur_company(_current_company, OWNER_NONE, FILE_LINE);
 
			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 */
 
		if (success && !_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
 
	}
 

	
src/linkgraph/linkgraphschedule.cpp
Show inline comments
 
@@ -13,12 +13,13 @@
 
#include "demands.h"
 
#include "mcf.h"
 
#include "flowmapper.h"
 
#include "../framerate_type.h"
 
#include "../command_func.h"
 
#include "../network/network.h"
 
#include "../misc_cmd.h"
 

	
 
#include "../safeguards.h"
 

	
 
/**
 
 * Static instance of LinkGraphSchedule.
 
 * Note: This instance is created on task start.
 
@@ -170,21 +171,21 @@ LinkGraphSchedule::~LinkGraphSchedule()
 
 */
 
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 &&
 
			_date % _settings_game.linkgraph.recalc_interval == _settings_game.linkgraph.recalc_interval / 2 &&
 
			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, {});
 
	}
 
}
 

	
 
/**
 
 * Pause the game on load if we would do a join with the next link graph job,
 
 * but it is still running, and it would not be caught by a call to
src/main_gui.cpp
Show inline comments
 
@@ -30,12 +30,13 @@
 
#include "linkgraph/linkgraph_gui.h"
 
#include "tilehighlight_func.h"
 
#include "hotkeys.h"
 
#include "guitimer_func.h"
 
#include "error.h"
 
#include "news_gui.h"
 
#include "misc_cmd.h"
 

	
 
#include "saveload/saveload.h"
 

	
 
#include "widgets/main_widget.h"
 

	
 
#include "network/network.h"
 
@@ -323,13 +324,13 @@ struct MainWindow : Window
 
			case GHK_CRASH: // Crash the game
 
				*(volatile byte *)nullptr = 0;
 
				break;
 

	
 
			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
 
				UpdateAllVirtCoords();
 
				break;
 

	
src/misc_cmd.cpp
Show inline comments
 
@@ -132,13 +132,13 @@ CommandCost CmdDecreaseLoan(DoCommandFla
 
 * @param w         unused
 
 * @param confirmed whether the user confirmed their action
 
 */
 
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, {});
 
	}
 
}
 

	
 
/**
 
 * Pause/Unpause the game (server-only).
 
 * Set or unset a bit in the pause mode. If pause mode is zero the game is
src/network/network.cpp
Show inline comments
 
@@ -392,13 +392,13 @@ void NetworkHandlePauseChange(PauseMode 
 
 * @param pm the mode which we would like to pause with
 
 */
 
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, {});
 
}
 

	
 
/**
 
 * Counts the number of active clients connected.
 
 * It has to be in STATUS_ACTIVE and not a spectator
 
 * @return number of active clients
src/network/network_command.cpp
Show inline comments
 
@@ -448,8 +448,8 @@ CommandDataBuffer SanitizeCmdStrings(con
 
}
 

	
 
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);
 
}
src/network/network_gui.cpp
Show inline comments
 
@@ -33,12 +33,13 @@
 
#include "../genworld.h"
 
#include "../map_type.h"
 
#include "../guitimer_func.h"
 
#include "../zoom_func.h"
 
#include "../sprite.h"
 
#include "../settings_internal.h"
 
#include "../company_cmd.h"
 

	
 
#include "../widgets/network_widget.h"
 

	
 
#include "table/strings.h"
 
#include "../table/sprites.h"
 

	
 
@@ -1392,13 +1393,13 @@ static void AdminClientBanCallback(Windo
 
 * @param confirmed Iff the user pressed Yes.
 
 */
 
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, {});
 
	}
 
}
 

	
 
/**
 
 * Callback function for admin command to unlock company.
 
 * @param w The window which initiated the confirmation dialog.
 
@@ -1532,13 +1533,13 @@ private:
 
	 * @param pt The point where this button was clicked.
 
	 * @param company_id The company this button was assigned to.
 
	 */
 
	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, {});
 
		}
 
	}
 

	
 
	/**
src/network/network_server.cpp
Show inline comments
 
@@ -26,12 +26,13 @@
 
#include "../company_gui.h"
 
#include "../company_cmd.h"
 
#include "../roadveh.h"
 
#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>
 

	
 
#include "../safeguards.h"
 

	
 
@@ -1552,13 +1553,13 @@ static void NetworkAutoCleanCompanies()
 
			/* The company is empty for one month more */
 
			_network_company_states[c->index].months_empty++;
 

	
 
			/* 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? */
 
			if (_settings_client.network.autoclean_protected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_protected && !_network_company_states[c->index].password.empty()) {
 
				/* Unprotect the company */
 
				_network_company_states[c->index].password.clear();
 
@@ -1566,13 +1567,13 @@ static void NetworkAutoCleanCompanies()
 
				_network_company_states[c->index].months_empty = 0;
 
				NetworkServerUpdateCompanyPassworded(c->index, false);
 
			}
 
			/* 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 {
 
			/* It is not empty, reset the date */
 
			_network_company_states[c->index].months_empty = 0;
 
		}
src/object_gui.cpp
Show inline comments
 
@@ -22,12 +22,13 @@
 
#include "viewport_func.h"
 
#include "tilehighlight_func.h"
 
#include "window_gui.h"
 
#include "window_func.h"
 
#include "zoom_func.h"
 
#include "terraform_cmd.h"
 
#include "object_cmd.h"
 

	
 
#include "widgets/object_widget.h"
 

	
 
#include "table/strings.h"
 

	
 
#include "safeguards.h"
 
@@ -539,14 +540,14 @@ 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
 
	{
 
		this->UpdateButtons(_selected_object_class, -1, _selected_object_view);
 
	}
src/openttd.cpp
Show inline comments
 
@@ -63,12 +63,13 @@
 
#include "gfx_layout.h"
 
#include "viewport_func.h"
 
#include "viewport_sprite_sorter.h"
 
#include "framerate_type.h"
 
#include "industry.h"
 
#include "network/network_gui.h"
 
#include "misc_cmd.h"
 

	
 
#include "linkgraph/linkgraphschedule.h"
 

	
 
#include <stdarg.h>
 
#include <system_error>
 

	
 
@@ -848,13 +849,13 @@ static void MakeNewGameDone()
 
{
 
	SettingsDisableElrail(_settings_game.vehicle.disable_elrails);
 

	
 
	/* 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;
 
	}
 

	
 
	/* Create a single company */
 
	DoStartupNewCompany(false);
 

	
 
@@ -877,13 +878,13 @@ static void MakeNewGameDone()
 
	/* We are the server, we start a new company (not dedicated),
 
	 * so set the default password *if* needed. */
 
	if (_network_server && !_settings_client.network.default_company_pass.empty()) {
 
		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();
 
	MarkWholeScreenDirty();
 

	
 
	if (_network_server && !_network_dedicated) ShowClientList();
 
@@ -1042,13 +1043,13 @@ void SwitchToMode(SwitchMode new_mode)
 
				if (_file_to_saveload.abstract_ftype == FT_SCENARIO) {
 
					/* Reset engine pool to simplify changing engine NewGRFs in scenario editor. */
 
					EngineOverrideManager::ResetToCurrentNewGRFConfig();
 
				}
 
				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;
 
		}
 

	
 
		case SM_RESTART_HEIGHTMAP: // Load a heightmap and start a new game from it with current settings
 
		case SM_START_HEIGHTMAP: // Load a heightmap and start a new game from it
 
@@ -1064,13 +1065,13 @@ void SwitchToMode(SwitchMode new_mode)
 

	
 
		case SM_LOAD_SCENARIO: { // Load scenario from scenario editor
 
			if (SafeLoad(_file_to_saveload.name, _file_to_saveload.file_op, _file_to_saveload.detail_ftype, GM_EDITOR, NO_DIRECTORY)) {
 
				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);
 
			}
 
			break;
 
		}
src/order_backup.cpp
Show inline comments
 
@@ -168,13 +168,13 @@ CommandCost CmdClearOrderBackup(DoComman
 
	assert(_network_server);
 

	
 
	for (OrderBackup *ob : OrderBackup::Iterate()) {
 
		/* 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;
 
	}
 
}
 

	
 
/**
 
 * Reset the OrderBackups from GUI/game logic.
src/order_gui.cpp
Show inline comments
 
@@ -26,12 +26,13 @@
 
#include "waypoint_base.h"
 
#include "core/geometry_func.hpp"
 
#include "hotkeys.h"
 
#include "aircraft.h"
 
#include "engine_func.h"
 
#include "vehicle_func.h"
 
#include "order_cmd.h"
 

	
 
#include "widgets/order_widget.h"
 

	
 
#include "safeguards.h"
 

	
 

	
 
@@ -588,13 +589,13 @@ private:
 

	
 
		if (toggle && order->GetLoadType() == load_type) {
 
			load_type = OLF_LOAD_IF_POSSIBLE; // reset to 'default'
 
		}
 
		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), {});
 
	}
 

	
 
	/**
 
	 * Handle the click on the service.
 
	 */
 
	void OrderClick_Service(int i)
 
@@ -603,13 +604,13 @@ private:
 

	
 
		if (i < 0) {
 
			const Order *order = this->vehicle->GetOrder(sel_ord);
 
			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), {});
 
	}
 

	
 
	/**
 
	 * Handle the click on the service in nearest depot button.
 
	 */
 
	void OrderClick_NearestDepot()
 
@@ -618,13 +619,13 @@ private:
 
		order.next = nullptr;
 
		order.index = 0;
 
		order.MakeGoToDepot(0, ODTFB_PART_OF_ORDERS,
 
				_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(), {});
 
	}
 

	
 
	/**
 
	 * Handle the click on the unload button.
 
	 * @param unload_type Unload flag to apply. If matches existing unload type, toggles to default of 'unload if possible'.
 
	 * @param toggle If we toggle or not (used for hotkey behavior)
 
@@ -638,17 +639,17 @@ private:
 

	
 
		if (toggle && order->GetUnloadType() == unload_type) {
 
			unload_type = OUF_UNLOAD_IF_POSSIBLE;
 
		}
 
		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);
 
		}
 
	}
 

	
 
	/**
 
	 * Handle the click on the nonstop button.
 
@@ -666,38 +667,38 @@ private:
 
		/* Keypress if negative, so 'toggle' to the next */
 
		if (non_stop < 0) {
 
			non_stop = order->GetNonStopType() ^ ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS;
 
		}
 

	
 
		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, {});
 
	}
 

	
 
	/**
 
	 * Handle the click on the skip button.
 
	 * If ctrl is pressed, skip to selected order, else skip to current order + 1
 
	 */
 
	void OrderClick_Skip()
 
	{
 
		/* Don't skip when there's nothing to skip */
 
		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()), {});
 
	}
 

	
 
	/**
 
	 * Handle the click on the delete button.
 
	 */
 
	void OrderClick_Delete()
 
	{
 
		/* 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();
 
		}
 
	}
 

	
 
	/**
 
@@ -716,13 +717,13 @@ private:
 
			return;
 
		}
 

	
 
		/* 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();
 
		}
 
	}
 

	
 
	/**
 
	 * Handle the click on the refit button.
 
@@ -731,16 +732,16 @@ private:
 
	 * @param auto_refit Select refit for auto-refitting.
 
	 */
 
	void OrderClick_Refit(int i, bool auto_refit)
 
	{
 
		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);
 
			}
 
		}
 
	}
 

	
 
@@ -1156,13 +1157,13 @@ public:
 
					if (order_id != INVALID_VEH_ORDER_ID) {
 
						Order order;
 
						order.next = nullptr;
 
						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;
 
				}
 

	
 
				VehicleOrderID sel = this->GetOrderFromPt(pt.y);
 
@@ -1179,15 +1180,15 @@ public:
 

	
 
				if (sel == INVALID_VEH_ORDER_ID || this->vehicle->owner != _local_company) {
 
					/* Deselect clicked order */
 
					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 */
 
					this->selected_order = sel;
 

	
 
					if (this->vehicle->owner == _local_company) {
 
@@ -1328,13 +1329,13 @@ public:
 
					value = Clamp(value, 0, 100);
 
					break;
 

	
 
				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, {});
 
		}
 
	}
 

	
 
	void OnDropdownSelect(int widget, int index) override
 
	{
 
		switch (widget) {
 
@@ -1366,30 +1367,30 @@ public:
 

	
 
			case WID_O_REFIT_DROPDOWN:
 
				this->OrderClick_Refit(index, true);
 
				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;
 
		}
 
	}
 

	
 
	void OnDragDrop(Point pt, int widget) override
 
	{
 
		switch (widget) {
 
			case WID_O_ORDER_LIST: {
 
				VehicleOrderID from_order = this->OrderGetSel();
 
				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();
 
				}
 
				break;
 
			}
 

	
 
@@ -1435,13 +1436,13 @@ public:
 
	void OnPlaceObject(Point pt, TileIndex tile) override
 
	{
 
		if (this->goto_type == OPOS_GOTO) {
 
			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();
 
			}
 
		}
 
	}
 

	
 
@@ -1452,14 +1453,14 @@ public:
 
		 * ourself as it easily copies orders of vehicles within a station when we mean the station.
 
		 * Obviously if you press CTRL on a non-empty orders vehicle you know what you are doing
 
		 * TODO: give a warning message */
 
		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();
 
		}
 
		return true;
 
	}
 

	
src/rail_gui.cpp
Show inline comments
 
@@ -36,12 +36,13 @@
 
#include "sortlist_type.h"
 
#include "stringfilter_type.h"
 
#include "string_func.h"
 
#include "station_cmd.h"
 
#include "tunnelbridge_cmd.h"
 
#include "waypoint_cmd.h"
 
#include "rail_cmd.h"
 

	
 
#include "station_map.h"
 
#include "tunnelbridge_map.h"
 

	
 
#include "widgets/rail_widget.h"
 

	
 
@@ -92,16 +93,19 @@ void CcPlaySound_CONSTRUCTION_RAIL(const
 
{
 
	if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_20_CONSTRUCTION_RAIL, 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), {});
 
	}
 
}
 

	
 
/**
 
 * Try to add an additional rail-track at the entrance of a depot
 
 * @param tile  Tile to use for adding the rail-track
 
 * @param dir   Direction to check for already present tracks
 
@@ -111,13 +115,13 @@ static void GenericPlaceRail(TileIndex t
 
static void PlaceExtraDepotRail(TileIndex tile, DiagDirection dir, Track track)
 
{
 
	if (GetRailTileType(tile) == RAIL_TILE_DEPOT) return;
 
	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. */
 
static const Track _place_depot_extra_track[12] = {
 
	TRACK_LEFT,  TRACK_UPPER, TRACK_UPPER, TRACK_RIGHT, // First additional track for directions 0..3
 
	TRACK_X,     TRACK_Y,     TRACK_X,     TRACK_Y,     // Second additional track
 
@@ -165,13 +169,13 @@ static void PlaceRail_Waypoint(TileIndex
 
		/* Valid tile for waypoints */
 
		VpStartPlaceSizing(tile, axis == AXIS_X ? VPM_X_LIMITED : VPM_Y_LIMITED, DDSP_BUILD_STATION);
 
		VpSetPlaceSizingLimit(_settings_game.station.station_spread);
 
	} 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, {});
 
	}
 
}
 

	
 
void CcStation(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
 
{
 
	if (result.Failed()) return;
 
@@ -205,13 +209,13 @@ static void PlaceRail_Station(TileIndex 
 
			if (test) {
 
				return Command<CMD_BUILD_RAIL_STATION>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_RAIL_STATION>()), tile, p1, p2, {}).Succeeded();
 
			} else {
 
				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, {});
 
			}
 
		};
 

	
 
		ShowSelectStationIfNeeded(TileArea(tile, w, h), proc);
 
	}
 
}
 
@@ -233,13 +237,13 @@ static void GenericPlaceSignals(TileInde
 
		trackbits = (_tile_fract_coords.x + _tile_fract_coords.y <= 15) ? TRACK_BIT_UPPER : TRACK_BIT_LOWER;
 
	}
 

	
 
	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);
 

	
 
		/* various bitstuffed elements for CmdBuildSingleSignal() */
 
		uint32 p1 = track;
 

	
 
@@ -264,14 +268,14 @@ static void GenericPlaceSignals(TileInde
 
			SB(p1, 4, 1, (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC));
 
			SB(p1, 5, 3, SIGTYPE_PBS_ONEWAY);
 
			SB(p1, 8, 1, 0);
 
			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, {});
 
	}
 
}
 

	
 
/**
 
 * Start placing a rail bridge.
 
 * @param tile Position of the first tile of the bridge.
 
@@ -367,16 +371,19 @@ static void BuildRailClick_Remove(Window
 
	}
 
}
 

	
 
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()
 
{
 
	int trackstat = _thd.drawstyle & HT_DIR_MASK; // 0..5
 

	
 
@@ -421,16 +428,19 @@ static void HandleAutoSignalPlacement()
 
		SB(p2, 24, 8, _settings_client.gui.drag_signals_density);
 
		SB(p2, 10, 1, !_settings_client.gui.drag_signals_fixed_distance);
 
	}
 

	
 
	/* _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, {});
 
	}
 
}
 

	
 

	
 
/** Rail toolbar management class. */
 
struct BuildRailToolbarWindow : Window {
 
	RailType railtype;    ///< Rail type to build.
 
@@ -650,14 +660,13 @@ struct BuildRailToolbarWindow : Window {
 

	
 
			case WID_RAT_DEMOLISH:
 
				PlaceProc_DemolishArea(tile);
 
				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:
 
				PlaceRail_Waypoint(tile);
 
				break;
 

	
 
@@ -671,13 +680,13 @@ struct BuildRailToolbarWindow : Window {
 

	
 
			case WID_RAT_BUILD_BRIDGE:
 
				PlaceRail_Bridge(tile, this);
 
				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:
 
				VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CONVERT_RAIL);
 
				break;
 

	
 
@@ -713,41 +722,41 @@ struct BuildRailToolbarWindow : Window {
 

	
 
				case DDSP_DEMOLISH_AREA:
 
					GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
 
					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:
 
				case DDSP_BUILD_STATION:
 
					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;
 
							uint32 p2 = STAT_CLASS_WAYP | _cur_waypoint_type << 8 | INVALID_STATION << 16;
 

	
 
							auto proc = [=](bool test, StationID to_join) -> bool {
 
								if (test) {
 
									return Command<CMD_BUILD_RAIL_WAYPOINT>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_RAIL_WAYPOINT>()), ta.tile, p1, p2, {}).Succeeded();
 
								} else {
 
									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, {});
 
								}
 
							};
 

	
 
							ShowSelectWaypointIfNeeded(ta, proc);
 
						}
 
					}
 
@@ -910,13 +919,13 @@ static void HandleStationPlacement(TileI
 
		if (test) {
 
			return Command<CMD_BUILD_RAIL_STATION>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_RAIL_STATION>()), ta.tile, p1, p2, {}).Succeeded();
 
		} else {
 
			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, {});
 
		}
 
	};
 

	
 
	ShowSelectStationIfNeeded(ta, proc);
 
}
 

	
src/road_gui.cpp
Show inline comments
 
@@ -29,12 +29,13 @@
 
#include "zoom_func.h"
 
#include "engine_base.h"
 
#include "strings_func.h"
 
#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"
 

	
 
#include "table/strings.h"
 

	
 
@@ -124,13 +125,13 @@ void CcBuildRoadTunnel(const CommandCost
 
void ConnectRoadToStructure(TileIndex tile, DiagDirection direction)
 
{
 
	tile += TileOffsByDiagDir(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, {});
 
		}
 
	}
 
}
 

	
 
void CcRoadDepot(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
 
{
 
@@ -202,13 +203,13 @@ static void PlaceRoadStop(TileIndex star
 
		if (test) {
 
			return Command<CMD_BUILD_ROAD_STOP>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_ROAD_STOP>()), ta.tile, p1, p2, {}).Succeeded();
 
		} else {
 
			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, {});
 
		}
 
	};
 

	
 
	ShowSelectStationIfNeeded(ta, proc);
 
}
 

	
 
@@ -563,14 +564,14 @@ struct BuildRoadToolbarWindow : Window {
 

	
 
			case WID_ROT_DEMOLISH:
 
				PlaceProc_DemolishArea(tile);
 
				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:
 
				PlaceRoad_BusStation(tile);
 
				break;
 

	
 
@@ -580,14 +581,14 @@ struct BuildRoadToolbarWindow : Window {
 

	
 
			case WID_ROT_BUILD_BRIDGE:
 
				PlaceRoad_Bridge(tile, this);
 
				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:
 
				VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CONVERT_ROAD);
 
				break;
 

	
 
@@ -682,43 +683,47 @@ struct BuildRoadToolbarWindow : Window {
 

	
 
					/* Even if _cur_roadtype_id is a uint8 we only use 5 bits so
 
					 * we could ignore the last 3 bits and reuse them for other
 
					 * 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:
 
				case DDSP_REMOVE_BUSSTOP:
 
					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]);
 
						}
 
					}
 
					break;
 

	
 
				case DDSP_BUILD_TRUCKSTOP:
 
				case DDSP_REMOVE_TRUCKSTOP:
 
					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]);
 
						}
 
					}
 
					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;
 
			}
 
		}
 
	}
 

	
 
	void OnPlacePresize(Point pt, TileIndex tile) override
src/settings.cpp
Show inline comments
 
@@ -1547,13 +1547,13 @@ CommandCost CmdChangeCompanySetting(DoCo
 
 */
 
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);
 
		return true;
 
	}
 

	
 
@@ -1573,13 +1573,13 @@ bool SetSettingValue(const IntSettingDes
 
		setting->ChangeValue(&_settings_newgame, value);
 
		return true;
 
	}
 

	
 
	/* 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;
 
}
 

	
 
/**
 
 * Set the company settings for a new company to their default values.
src/signs_cmd.cpp
Show inline comments
 
@@ -129,8 +129,8 @@ void CcPlaceSign(const CommandCost &resu
 
 * PlaceProc function, called when someone pressed the button if the
 
 *  sign-tool is selected
 
 * @param tile on which to place the sign
 
 */
 
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, {});
 
}
src/signs_gui.cpp
Show inline comments
 
@@ -23,12 +23,13 @@
 
#include "stringfilter_type.h"
 
#include "string_func.h"
 
#include "core/geometry_func.hpp"
 
#include "hotkeys.h"
 
#include "transparency.h"
 
#include "gui.h"
 
#include "signs_cmd.h"
 

	
 
#include "widgets/sign_widget.h"
 

	
 
#include "table/strings.h"
 
#include "table/sprites.h"
 

	
 
@@ -410,13 +411,13 @@ Window *ShowSignList()
 
 * @param text  the new name.
 
 * @return true if the window will already be removed after returning.
 
 */
 
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;
 
}
 

	
 
struct SignWindow : Window, SignList {
 
	QueryString name_editbox;
 
	SignID cur_sign;
src/station_gui.cpp
Show inline comments
 
@@ -28,12 +28,13 @@
 
#include "sortlist_type.h"
 
#include "core/geometry_func.hpp"
 
#include "vehiclelist.h"
 
#include "town.h"
 
#include "linkgraph/linkgraph.h"
 
#include "zoom_func.h"
 
#include "station_cmd.h"
 

	
 
#include "widgets/station_widget.h"
 

	
 
#include "table/strings.h"
 

	
 
#include <set>
 
@@ -1944,13 +1945,13 @@ struct StationViewWindow : public Window
 
				SetDParam(0, this->window_number);
 
				ShowQueryString(STR_STATION_NAME, STR_STATION_VIEW_RENAME_STATION_CAPTION, MAX_LENGTH_STATION_NAME_CHARS,
 
						this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT | QSF_LEN_IN_CHARS);
 
				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
 
			case WID_SV_ROADVEHS: // Show list of scheduled road-vehicles to this station
 
			case WID_SV_SHIPS:    // Show list of scheduled ships to this station
 
			case WID_SV_PLANES: { // Show list of scheduled aircraft to this station
 
@@ -2081,13 +2082,13 @@ struct StationViewWindow : public Window
 
	}
 

	
 
	void OnQueryTextFinished(char *str) override
 
	{
 
		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
 
	{
 
		this->vscroll->SetCapacityFromWidget(this, WID_SV_WAITING, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM);
 
	}
src/story_gui.cpp
Show inline comments
 
@@ -22,12 +22,13 @@
 
#include "goal_base.h"
 
#include "viewport_func.h"
 
#include "window_func.h"
 
#include "company_base.h"
 
#include "tilehighlight_func.h"
 
#include "vehicle_base.h"
 
#include "story_cmd.h"
 

	
 
#include "widgets/story_widget.h"
 

	
 
#include "table/strings.h"
 
#include "table/sprites.h"
 

	
 
@@ -563,13 +564,13 @@ protected:
 
			case SPET_BUTTON_PUSH:
 
				if (this->active_button_id != INVALID_STORY_PAGE_ELEMENT) ResetObjectToPlace();
 
				this->active_button_id = pe.index;
 
				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:
 
				if (this->active_button_id == pe.index) {
 
					ResetObjectToPlace();
 
					this->active_button_id = INVALID_STORY_PAGE_ELEMENT;
 
@@ -918,13 +919,13 @@ public:
 
			ResetObjectToPlace();
 
			this->active_button_id = INVALID_STORY_PAGE_ELEMENT;
 
			this->SetWidgetDirty(WID_SB_PAGE_PANEL);
 
			return;
 
		}
 

	
 
		DoCommandP(CMD_STORY_PAGE_BUTTON, tile, pe->index, 0);
 
		Command<CMD_STORY_PAGE_BUTTON>::Post(tile, pe->index, 0, {});
 
		ResetObjectToPlace();
 
	}
 

	
 
	bool OnVehicleSelect(const Vehicle *v) override
 
	{
 
		const StoryPageElement *const pe = StoryPageElement::GetIfValid(this->active_button_id);
 
@@ -937,13 +938,13 @@ public:
 

	
 
		/* Check that the vehicle matches the requested type */
 
		StoryPageButtonData data{ pe->referenced_id };
 
		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;
 
	}
 

	
 
	void OnPlaceObjectAbort() override
 
	{
src/terraform_gui.cpp
Show inline comments
 
@@ -32,12 +32,14 @@
 
#include "engine_base.h"
 
#include "terraform_gui.h"
 
#include "terraform_cmd.h"
 
#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"
 

	
 
#include "table/strings.h"
 

	
 
#include "safeguards.h"
 
@@ -60,13 +62,13 @@ static void GenerateDesertArea(TileIndex
 

	
 
	Backup<bool> old_generating_world(_generating_world, true, FILE_LINE);
 

	
 
	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();
 
	InvalidateWindowClassesData(WC_TOWN_VIEW, 0);
 
}
 

	
 
@@ -115,22 +117,22 @@ bool GUIPlaceProcDragXY(ViewportDragDrop
 
		if (TileX(end_tile) == MapMaxX()) end_tile += TileDiffXY(-1, 0);
 
		if (TileY(end_tile) == MapMaxY()) end_tile += TileDiffXY(0, -1);
 
	}
 

	
 
	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);
 
			break;
 
		case DDSP_CREATE_DESERT:
 
			GenerateDesertArea(end_tile, start_tile);
 
@@ -238,13 +240,13 @@ struct TerraformToolbarWindow : Window {
 

	
 
			case WID_TT_DEMOLISH: // Demolish aka dynamite button
 
				PlaceProc_DemolishArea(tile);
 
				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
 
				PlaceProc_Sign(tile);
 
				break;
 

	
 
@@ -395,13 +397,13 @@ static byte _terraform_size = 1;
 
static void CommonRaiseLowerBigLand(TileIndex tile, int mode)
 
{
 
	if (_terraform_size == 1) {
 
		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);
 
		ta.ClampToMap();
 

	
 
		if (ta.w == 0 || ta.h == 0) return;
 
@@ -422,13 +424,13 @@ static void CommonRaiseLowerBigLand(Tile
 
				h = std::max(h, TileHeight(tile2));
 
			}
 
		}
 

	
 
		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, {});
 
			}
 
		}
 
	}
 
}
 

	
 
static const int8 _multi_terraform_coords[][2] = {
src/timetable_gui.cpp
Show inline comments
 
@@ -19,12 +19,13 @@
 
#include "gfx_func.h"
 
#include "company_func.h"
 
#include "date_func.h"
 
#include "date_gui.h"
 
#include "vehicle_gui.h"
 
#include "settings_type.h"
 
#include "timetable_cmd.h"
 

	
 
#include "widgets/timetable_widget.h"
 

	
 
#include "table/sprites.h"
 
#include "table/strings.h"
 

	
 
@@ -139,13 +140,13 @@ static void FillTimetableArrivalDepartur
 
 * Callback for when a time has been chosen to start the time table
 
 * @param w the window related to the setting of the date
 
 * @param date the actually chosen date
 
 */
 
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, {});
 
}
 

	
 

	
 
struct TimetableWindow : Window {
 
	int sel_index;
 
	const Vehicle *vehicle; ///< Vehicle monitored by the window.
 
@@ -575,31 +576,31 @@ struct TimetableWindow : Window {
 
				ShowQueryString(current, STR_TIMETABLE_CHANGE_SPEED, 31, this, CS_NUMERAL, QSF_NONE);
 
				break;
 
			}
 

	
 
			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;
 
			}
 

	
 
			case WID_VT_EXPECTED:
 
				this->show_expected = !this->show_expected;
 
				break;
 
@@ -626,13 +627,13 @@ struct TimetableWindow : Window {
 
		} else {
 
			if (!_settings_client.gui.timetable_in_ticks) val *= DAY_TICKS;
 
		}
 

	
 
		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
 
	{
 
		/* Update the scroll bar */
 
		this->vscroll->SetCapacityFromWidget(this, WID_VT_TIMETABLE_PANEL, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM);
src/toolbar_gui.cpp
Show inline comments
 
@@ -46,12 +46,13 @@
 
#include "goal_base.h"
 
#include "story_base.h"
 
#include "toolbar_gui.h"
 
#include "framerate_type.h"
 
#include "guitimer_func.h"
 
#include "screenshot_gui.h"
 
#include "misc_cmd.h"
 

	
 
#include "widgets/toolbar_widget.h"
 

	
 
#include "network/network.h"
 
#include "network/network_gui.h"
 
#include "network/network_func.h"
 
@@ -262,13 +263,13 @@ static CallBackFunction SelectSignTool()
 
/* --- Pausing --- */
 

	
 
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;
 
}
 

	
 
/**
src/town_gui.cpp
Show inline comments
 
@@ -30,12 +30,13 @@
 
#include "core/backup_type.hpp"
 
#include "core/geometry_func.hpp"
 
#include "genworld.h"
 
#include "stringfilter_type.h"
 
#include "widgets/dropdown_func.h"
 
#include "town_kdtree.h"
 
#include "town_cmd.h"
 

	
 
#include "widgets/town_widget.h"
 

	
 
#include "table/strings.h"
 

	
 
#include "safeguards.h"
 
@@ -284,13 +285,13 @@ public:
 
				/* When double-clicking, continue */
 
				if (click_count == 1 || y < 0) break;
 
				FALLTHROUGH;
 
			}
 

	
 
			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;
 
		}
 
	}
 

	
 
	void OnHundredthTick() override
 
	{
 
@@ -471,18 +472,18 @@ public:
 

	
 
				if (!_settings_game.economy.allow_town_roads && !_warn_town_no_roads) {
 
					ShowErrorMessage(STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS, INVALID_STRING_ID, WL_WARNING);
 
					_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;
 
		}
 
	}
 

	
 
	void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
 
	{
 
@@ -558,13 +559,13 @@ public:
 
	}
 

	
 
	void OnQueryTextFinished(char *str) override
 
	{
 
		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);
 
	}
 
};
 

	
 
static const NWidgetPart _nested_town_game_view_widgets[] = {
 
	NWidget(NWID_HORIZONTAL),
 
		NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
 
@@ -1159,13 +1160,13 @@ public:
 
			/* If user changed the name, send it */
 
			char buf[MAX_LENGTH_TOWN_NAME_CHARS * MAX_CHAR_LENGTH];
 
			GetTownName(buf, &this->params, this->townnameparts, lastof(buf));
 
			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. */
 
		if (success && !_shift_pressed) this->RandomTownName();
 
	}
 

	
src/train_cmd.cpp
Show inline comments
 
@@ -32,12 +32,13 @@
 
#include "newgrf.h"
 
#include "order_backup.h"
 
#include "zoom_func.h"
 
#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"
 

	
 
#include "safeguards.h"
 

	
 
@@ -84,13 +85,13 @@ void CheckTrainsLengths()
 
						SetDParam(0, v->index);
 
						SetDParam(1, v->owner);
 
						ShowErrorMessage(STR_BROKEN_VEHICLE_LENGTH, INVALID_STRING_ID, WL_CRITICAL);
 

	
 
						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;
 
					}
 
				}
 
			}
src/train_gui.cpp
Show inline comments
 
@@ -11,12 +11,13 @@
 
#include "window_gui.h"
 
#include "command_func.h"
 
#include "train.h"
 
#include "strings_func.h"
 
#include "vehicle_func.h"
 
#include "zoom_func.h"
 
#include "train_cmd.h"
 

	
 
#include "table/strings.h"
 

	
 
#include "safeguards.h"
 

	
 
/**
 
@@ -42,13 +43,13 @@ void CcBuildWagon(const CommandCost &res
 
	}
 

	
 
	/* if we found a loco, */
 
	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);
 
	}
 
}
 

	
 
/**
 
 * Highlight the position where a rail vehicle is dragged over by drawing a light gray background.
src/tree_gui.cpp
Show inline comments
 
@@ -16,12 +16,13 @@
 
#include "command_func.h"
 
#include "core/random_func.hpp"
 
#include "sound_func.h"
 
#include "strings_func.h"
 
#include "zoom_func.h"
 
#include "tree_map.h"
 
#include "tree_cmd.h"
 

	
 
#include "widgets/tree_widget.h"
 

	
 
#include "table/sprites.h"
 
#include "table/strings.h"
 
#include "table/tree_land.h"
 
@@ -227,23 +228,23 @@ public:
 
		if (_game_mode != GM_EDITOR && this->mode == PM_NORMAL) {
 
			VpSelectTilesWithMethod(pt.x, pt.y, select_method);
 
		} else {
 
			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);
 
			}
 
		}
 
	}
 

	
 
	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, {});
 
		}
 
	}
 

	
 
	void OnPlaceObjectAbort() override
 
	{
 
		this->tree_to_plant = -1;
src/vehicle_gui.cpp
Show inline comments
 
@@ -35,12 +35,15 @@
 
#include "engine_func.h"
 
#include "station_base.h"
 
#include "tilehighlight_func.h"
 
#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"
 

	
 

	
 
BaseVehicleListWindow::GroupBy _grouping[VLT_END][VEH_COMPANY_END];
 
Sorting _sorting[BaseVehicleListWindow::GB_END];
 
@@ -1032,15 +1035,15 @@ struct RefitWindow : public Window {
 
			case WID_VR_REFIT: // refit button
 
				if (this->cargo != nullptr) {
 
					const Vehicle *v = Vehicle::Get(this->window_number);
 

	
 
					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;
 
		}
 
	}
 

	
 
@@ -1893,13 +1896,13 @@ public:
 
				ShowDropDownList(this, this->BuildActionDropdownList(VehicleListIdentifier::UnPack(this->window_number).type == VL_STANDARD, false), 0, WID_VL_MANAGE_VEHICLES_DROPDOWN);
 
				break;
 
			}
 

	
 
			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;
 
		}
 
	}
 

	
 
	void OnDropdownSelect(int widget, int index) override
 
	{
 
@@ -1918,13 +1921,13 @@ public:
 
				switch (index) {
 
					case ADI_REPLACE: // Replace window
 
						ShowReplaceGroupVehicleWindow(ALL_GROUP, this->vli.vtype);
 
						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();
 
				}
 
				break;
 

	
 
@@ -2421,13 +2424,13 @@ struct VehicleDetailsWindow : Window {
 
				const Vehicle *v = Vehicle::Get(this->window_number);
 

	
 
				mod = (widget == WID_VD_DECREASE_SERVICING_INTERVAL) ? -mod : mod;
 
				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;
 
			}
 

	
 
			case WID_VD_SERVICE_INTERVAL_DROPDOWN: {
 
				const Vehicle *v = Vehicle::Get(this->window_number);
 
				ShowDropDownMenu(this, _service_interval_dropdown, v->ServiceIntervalIsCustom() ? (v->ServiceIntervalIsPercent() ? 2 : 1) : 0, widget, 0, 0);
 
@@ -2457,13 +2460,13 @@ struct VehicleDetailsWindow : Window {
 
		switch (widget) {
 
			case WID_VD_SERVICE_INTERVAL_DROPDOWN: {
 
				const Vehicle *v = Vehicle::Get(this->window_number);
 
				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;
 
			}
 
		}
 
	}
 

	
 
	void OnResize() override
 
@@ -2640,13 +2643,13 @@ void CcStartStopVehicle(const CommandCos
 
 * @param v Vehicle to start/stop
 
 * @param texteffect Should a texteffect be shown?
 
 */
 
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.*/
 
static bool IsVehicleRefitable(const Vehicle *v)
 
{
 
	if (!v->IsStoppedInDepot()) return false;
 
@@ -2964,13 +2967,13 @@ public:
 
						ScrollMainWindowTo(v->x_pos, v->y_pos, v->z_pos);
 
					}
 
				}
 
				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);
 
				break;
 
			case WID_VV_SHOW_ORDERS: // show orders
 
				if (_ctrl_pressed) {
 
@@ -2988,36 +2991,36 @@ public:
 
				break;
 
			case WID_VV_CLONE: // clone vehicle
 
				/* Suppress the vehicle GUI when share-cloning.
 
				 * 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;
 
		}
 
	}
 

	
 
	void OnQueryTextFinished(char *str) override
 
	{
 
		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
 
	{
 
		bool start_stop = widget == WID_VV_START_STOP;
 
		if (start_stop != mouse_over_start_stop) {
src/waypoint_gui.cpp
Show inline comments
 
@@ -17,12 +17,13 @@
 
#include "strings_func.h"
 
#include "command_func.h"
 
#include "company_func.h"
 
#include "company_base.h"
 
#include "window_func.h"
 
#include "waypoint_base.h"
 
#include "waypoint_cmd.h"
 

	
 
#include "widgets/waypoint_widget.h"
 

	
 
#include "table/strings.h"
 

	
 
#include "safeguards.h"
 
@@ -135,13 +136,13 @@ public:
 
	}
 

	
 
	void OnQueryTextFinished(char *str) override
 
	{
 
		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);
 
	}
 

	
 
};
 

	
 
/** The widgets of the waypoint view. */
 
static const NWidgetPart _nested_waypoint_view_widgets[] = {
0 comments (0 inline, 0 general)