Codechange: Pass rail and roadtypes separately for tunnel and bridge commands. (#15438)

Avoids passing and casting each via an unrelated type, at the expense of an extra command parameter.
This commit is contained in:
Peter Nelson
2026-04-06 14:45:22 +01:00
committed by GitHub
parent 9acfa96cb3
commit a9d7397a77
10 changed files with 58 additions and 48 deletions
+27 -14
View File
@@ -54,7 +54,7 @@ typedef GUIList<BuildBridgeData> GUIBridgeList; ///< List of bridges, used in #B
* @param tile_start start tile
* @param transport_type transport type.
*/
void CcBuildBridge(Commands, const CommandCost &result, TileIndex end_tile, TileIndex tile_start, TransportType transport_type, BridgeType, uint8_t)
void CcBuildBridge(Commands, const CommandCost &result, TileIndex end_tile, TileIndex tile_start, TransportType transport_type, BridgeType, RailType, RoadType)
{
if (result.Failed()) return;
if (_settings_client.sound.confirm) SndPlayTileFx(SND_27_CONSTRUCTION_BRIDGE, end_tile);
@@ -85,7 +85,8 @@ private:
TileIndex start_tile = INVALID_TILE;
TileIndex end_tile = INVALID_TILE;
TransportType transport_type = INVALID_TRANSPORT;
uint8_t road_rail_type = 0;
RailType railtype = INVALID_RAILTYPE; ///< Rail type to build if building a rail bridge.
RoadType roadtype = INVALID_ROADTYPE; ///< Road type to build if building a road bridge.
GUIBridgeList bridges{};
int icon_width = 0; ///< Scaled width of the the bridge icon sprite.
Scrollbar *vscroll = nullptr;
@@ -116,7 +117,7 @@ private:
default: break;
}
Command<Commands::BuildBridge>::Post(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, CcBuildBridge,
this->end_tile, this->start_tile, this->transport_type, type, this->road_rail_type);
this->end_tile, this->start_tile, this->transport_type, type, this->railtype, this->roadtype);
}
/** Sort the builable bridges */
@@ -153,11 +154,22 @@ private:
}
public:
BuildBridgeWindow(WindowDesc &desc, TileIndex start, TileIndex end, TransportType transport_type, uint8_t road_rail_type, GUIBridgeList &&bl) : Window(desc),
/**
* Create this BuildBridgeWindoow.
* @param desc Window description.
* @param start Start tile of bridge.
* @param end End tile of bridge.
* @param transport_type Transport type of bridge (i.e. rail, road, or water).
* @param railtype Rail type for a rail bridge.
* @param roadtype Road type for a road bridge.
* @param bl List of bridges that can be built.
*/
BuildBridgeWindow(WindowDesc &desc, TileIndex start, TileIndex end, TransportType transport_type, RailType railtype, RoadType roadtype, GUIBridgeList &&bl) : Window(desc),
start_tile(start),
end_tile(end),
transport_type(transport_type),
road_rail_type(road_rail_type),
railtype(railtype),
roadtype(roadtype),
bridges(std::move(bl))
{
this->CreateNestedTree();
@@ -352,9 +364,10 @@ static WindowDesc _build_bridge_desc(
* @param start The start tile of the bridge
* @param end The end tile of the bridge
* @param transport_type The transport type
* @param road_rail_type The road/rail type
* @param railtype The rail type for a rail bridge, or \c INVALID_RAILTYPE
* @param roadtype The road type for a road bridge, or \c INVALID_ROADTYPE
*/
void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, uint8_t road_rail_type)
void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, RailType railtype, RoadType roadtype)
{
CloseWindowByClass(WC_BUILD_BRIDGE);
@@ -373,13 +386,13 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo
default: break; // water ways and air routes don't have bridge types
}
if (_ctrl_pressed && CheckBridgeAvailability(last_bridge_type, bridge_len).Succeeded()) {
Command<Commands::BuildBridge>::Post(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, CcBuildBridge, end, start, transport_type, last_bridge_type, road_rail_type);
Command<Commands::BuildBridge>::Post(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, CcBuildBridge, end, start, transport_type, last_bridge_type, railtype, roadtype);
return;
}
/* only query bridge building possibility once, result is the same for all bridges!
* returns CMD_ERROR on failure, and price on success */
CommandCost ret = Command<Commands::BuildBridge>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildBridge>()) | DoCommandFlag::QueryCost, end, start, transport_type, 0, road_rail_type);
CommandCost ret = Command<Commands::BuildBridge>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildBridge>()) | DoCommandFlag::QueryCost, end, start, transport_type, 0, railtype, roadtype);
GUIBridgeList bl;
if (!ret.Failed()) {
@@ -396,10 +409,10 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo
road_rt = GetRoadTypeRoad(start);
tram_rt = GetRoadTypeTram(start);
}
if (RoadTypeIsRoad((RoadType)road_rail_type)) {
road_rt = (RoadType)road_rail_type;
if (RoadTypeIsRoad(roadtype)) {
road_rt = roadtype;
} else {
tram_rt = (RoadType)road_rail_type;
tram_rt = roadtype;
}
if (road_rt != INVALID_ROADTYPE) infra_cost += (bridge_len + 2) * 2 * RoadBuildCost(road_rt);
@@ -407,7 +420,7 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo
break;
}
case TRANSPORT_RAIL: infra_cost = (bridge_len + 2) * RailBuildCost((RailType)road_rail_type); break;
case TRANSPORT_RAIL: infra_cost = (bridge_len + 2) * RailBuildCost(railtype); break;
default: break;
}
@@ -432,7 +445,7 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo
}
if (!bl.empty()) {
new BuildBridgeWindow(_build_bridge_desc, start, end, transport_type, road_rail_type, std::move(bl));
new BuildBridgeWindow(_build_bridge_desc, start, end, transport_type, railtype, roadtype, std::move(bl));
} else {
ShowErrorMessage(GetEncodedString(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE), TileX(end) * TILE_SIZE, TileY(end) * TILE_SIZE, ret);
}
+1 -1
View File
@@ -238,7 +238,7 @@ struct BuildDocksToolbarWindow : Window {
break;
case WID_DT_BUILD_AQUEDUCT: // Build aqueduct button
Command<Commands::BuildBridge>::Post(STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE, CcBuildBridge, tile, GetOtherAqueductEnd(tile), TRANSPORT_WATER, 0, 0);
Command<Commands::BuildBridge>::Post(STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE, CcBuildBridge, tile, GetOtherAqueductEnd(tile), TRANSPORT_WATER, 0, INVALID_RAILTYPE, INVALID_ROADTYPE);
break;
default: NOT_REACHED();
+3 -1
View File
@@ -10,6 +10,8 @@
#ifndef GUI_H
#define GUI_H
#include "rail_type.h"
#include "road_type.h"
#include "strings_type.h"
#include "vehicle_type.h"
#include "economy_type.h"
@@ -72,7 +74,7 @@ void ShowExtraViewportWindow(TileIndex tile = INVALID_TILE);
void ShowExtraViewportWindowForTileUnderCursor();
/* bridge_gui.cpp */
void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, uint8_t bridge_type);
void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, RailType railtype, RoadType roadtype);
/* music_gui.cpp */
void ShowMusicWindow();
+3 -3
View File
@@ -722,7 +722,7 @@ struct BuildRailToolbarWindow : Window {
break;
case WID_RAT_BUILD_TUNNEL:
Command<Commands::BuildTunnel>::Post(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE, CcBuildRailTunnel, tile, TRANSPORT_RAIL, _cur_railtype);
Command<Commands::BuildTunnel>::Post(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE, CcBuildRailTunnel, tile, TRANSPORT_RAIL, _cur_railtype, INVALID_ROADTYPE);
break;
case WID_RAT_CONVERT_RAIL:
@@ -753,7 +753,7 @@ struct BuildRailToolbarWindow : Window {
default: NOT_REACHED();
case DDSP_BUILD_BRIDGE:
if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_RAIL, _cur_railtype);
ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_RAIL, _cur_railtype, INVALID_ROADTYPE);
break;
case DDSP_PLACE_RAIL:
@@ -827,7 +827,7 @@ struct BuildRailToolbarWindow : Window {
void OnPlacePresize([[maybe_unused]] Point pt, TileIndex tile) override
{
Command<Commands::BuildTunnel>::Do(DoCommandFlag::Auto, tile, TRANSPORT_RAIL, _cur_railtype);
Command<Commands::BuildTunnel>::Do(DoCommandFlag::Auto, tile, TRANSPORT_RAIL, _cur_railtype, INVALID_ROADTYPE);
VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile);
}
+3 -3
View File
@@ -697,7 +697,7 @@ struct BuildRoadToolbarWindow : Window {
case WID_ROT_BUILD_TUNNEL:
Command<Commands::BuildTunnel>::Post(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE, CcBuildRoadTunnel,
tile, TRANSPORT_ROAD, _cur_roadtype);
tile, TRANSPORT_ROAD, INVALID_RAILTYPE, _cur_roadtype);
break;
case WID_ROT_CONVERT_ROAD:
@@ -780,7 +780,7 @@ struct BuildRoadToolbarWindow : Window {
default: NOT_REACHED();
case DDSP_BUILD_BRIDGE:
if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_ROAD, _cur_roadtype);
ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_ROAD, INVALID_RAILTYPE, _cur_roadtype);
break;
case DDSP_DEMOLISH_AREA:
@@ -862,7 +862,7 @@ struct BuildRoadToolbarWindow : Window {
void OnPlacePresize([[maybe_unused]] Point pt, TileIndex tile) override
{
Command<Commands::BuildTunnel>::Do(DoCommandFlag::Auto, tile, TRANSPORT_ROAD, _cur_roadtype);
Command<Commands::BuildTunnel>::Do(DoCommandFlag::Auto, tile, TRANSPORT_ROAD, INVALID_RAILTYPE, _cur_roadtype);
VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile);
}
+3 -3
View File
@@ -86,11 +86,11 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance &instance)
case ScriptVehicle::VT_ROAD:
ScriptObject::SetCallbackVariable(0, start.base());
ScriptObject::SetCallbackVariable(1, end.base());
return ScriptObject::Command<Commands::BuildBridge>::Do(&::_DoCommandReturnBuildBridge1, end, start, TRANSPORT_ROAD, bridge_type, ScriptRoad::GetCurrentRoadType());
return ScriptObject::Command<Commands::BuildBridge>::Do(&::_DoCommandReturnBuildBridge1, end, start, TRANSPORT_ROAD, bridge_type, INVALID_RAILTYPE, static_cast<::RoadType>(ScriptRoad::GetCurrentRoadType()));
case ScriptVehicle::VT_RAIL:
return ScriptObject::Command<Commands::BuildBridge>::Do(end, start, TRANSPORT_RAIL, bridge_type, ScriptRail::GetCurrentRailType());
return ScriptObject::Command<Commands::BuildBridge>::Do(end, start, TRANSPORT_RAIL, bridge_type, static_cast<::RailType>(ScriptRail::GetCurrentRailType()), INVALID_ROADTYPE);
case ScriptVehicle::VT_WATER:
return ScriptObject::Command<Commands::BuildBridge>::Do(end, start, TRANSPORT_WATER, bridge_type, 0);
return ScriptObject::Command<Commands::BuildBridge>::Do(end, start, TRANSPORT_WATER, bridge_type, INVALID_RAILTYPE, INVALID_ROADTYPE);
default: NOT_REACHED();
}
}
+2 -2
View File
@@ -90,10 +90,10 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance &instance)
if (vehicle_type == ScriptVehicle::VT_RAIL) {
/* For rail we do nothing special */
return ScriptObject::Command<Commands::BuildTunnel>::Do(start, TRANSPORT_RAIL, ScriptRail::GetCurrentRailType());
return ScriptObject::Command<Commands::BuildTunnel>::Do(start, TRANSPORT_RAIL, static_cast<::RailType>(ScriptRail::GetCurrentRailType()), INVALID_ROADTYPE);
} else {
ScriptObject::SetCallbackVariable(0, start.base());
return ScriptObject::Command<Commands::BuildTunnel>::Do(&::_DoCommandReturnBuildTunnel1, start, TRANSPORT_ROAD, ScriptRoad::GetCurrentRoadType());
return ScriptObject::Command<Commands::BuildTunnel>::Do(&::_DoCommandReturnBuildTunnel1, start, TRANSPORT_ROAD, INVALID_RAILTYPE, static_cast<::RoadType>(ScriptRoad::GetCurrentRoadType()));
}
}
+4 -4
View File
@@ -1352,8 +1352,8 @@ static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDi
/* Can we actually build the bridge? */
RoadType rt = GetTownRoadType();
if (Command<Commands::BuildBridge>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildBridge>()), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt).Succeeded()) {
Command<Commands::BuildBridge>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildBridge>()).Set(DoCommandFlag::Execute), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt);
if (Command<Commands::BuildBridge>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildBridge>()), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, INVALID_RAILTYPE, rt).Succeeded()) {
Command<Commands::BuildBridge>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildBridge>()).Set(DoCommandFlag::Execute), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, INVALID_RAILTYPE, rt);
return true;
}
}
@@ -1422,8 +1422,8 @@ static bool GrowTownWithTunnel(const Town *t, const TileIndex tile, const DiagDi
/* Attempt to build the tunnel. Return false if it fails to let the town build a road instead. */
RoadType rt = GetTownRoadType();
if (Command<Commands::BuildTunnel>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildTunnel>()), tile, TRANSPORT_ROAD, rt).Succeeded()) {
Command<Commands::BuildTunnel>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildTunnel>()).Set(DoCommandFlag::Execute), tile, TRANSPORT_ROAD, rt);
if (Command<Commands::BuildTunnel>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildTunnel>()), tile, TRANSPORT_ROAD, INVALID_RAILTYPE, rt).Succeeded()) {
Command<Commands::BuildTunnel>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildTunnel>()).Set(DoCommandFlag::Execute), tile, TRANSPORT_ROAD, INVALID_RAILTYPE, rt);
return true;
}
+6 -13
View File
@@ -304,16 +304,14 @@ static CommandCost CheckBuildAbove(TileIndex tile, DoCommandFlags flags, Axis ax
* @param tile_start start tile
* @param transport_type transport type.
* @param bridge_type bridge type (hi bh)
* @param road_rail_type rail type or road types.
* @param railtype rail type for rail bridge, or \c INVALID_RAILTYPE
* @param roadtype road type for road bridge, or \c INVALID_ROADTYPE
* @return the cost of this operation or an error
*/
CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex tile_start, TransportType transport_type, BridgeType bridge_type, uint8_t road_rail_type)
CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex tile_start, TransportType transport_type, BridgeType bridge_type, RailType railtype, RoadType roadtype)
{
CompanyID company = _current_company;
RailType railtype = INVALID_RAILTYPE;
RoadType roadtype = INVALID_ROADTYPE;
for (TileIndex t : {tile_start, tile_end}) {
if (!IsValidTile(t)) return CommandCost(STR_ERROR_BRIDGE_THROUGH_MAP_BORDER);
/* User cannot modify height of tiles with one coordinate equal to zero, they are always at the sea level, and you can't build bridge in the sea.
@@ -324,12 +322,10 @@ CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex t
/* type of bridge */
switch (transport_type) {
case TRANSPORT_ROAD:
roadtype = (RoadType)road_rail_type;
if (!ValParamRoadType(roadtype)) return CMD_ERROR;
break;
case TRANSPORT_RAIL:
railtype = (RailType)road_rail_type;
if (!ValParamRailType(railtype)) return CMD_ERROR;
break;
@@ -641,24 +637,21 @@ CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex t
* @param flags type of operation
* @param start_tile start tile of tunnel
* @param transport_type transport type
* @param road_rail_type railtype or roadtype
* @param railtype rail type for rail tunnel, or \c INVALID_RAILTYPE
* @param roadtype road type for road tunnel, or \c INVALID_ROADTYPE
* @return the cost of this operation or an error
*/
CommandCost CmdBuildTunnel(DoCommandFlags flags, TileIndex start_tile, TransportType transport_type, uint8_t road_rail_type)
CommandCost CmdBuildTunnel(DoCommandFlags flags, TileIndex start_tile, TransportType transport_type, RailType railtype, RoadType roadtype)
{
CompanyID company = _current_company;
RailType railtype = INVALID_RAILTYPE;
RoadType roadtype = INVALID_ROADTYPE;
_build_tunnel_endtile = TileIndex{};
switch (transport_type) {
case TRANSPORT_RAIL:
railtype = (RailType)road_rail_type;
if (!ValParamRailType(railtype)) return CMD_ERROR;
break;
case TRANSPORT_ROAD:
roadtype = (RoadType)road_rail_type;
if (!ValParamRoadType(roadtype)) return CMD_ERROR;
break;
+6 -4
View File
@@ -10,16 +10,18 @@
#ifndef TUNNELBRIDGE_CMD_H
#define TUNNELBRIDGE_CMD_H
#include "bridge_type.h"
#include "command_type.h"
#include "rail_type.h"
#include "road_type.h"
#include "transport_type.h"
#include "bridge.h"
CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex tile_start, TransportType transport_type, BridgeType bridge_type, uint8_t road_rail_type);
CommandCost CmdBuildTunnel(DoCommandFlags flags, TileIndex start_tile, TransportType transport_type, uint8_t road_rail_type);
CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex tile_start, TransportType transport_type, BridgeType bridge_type, RailType railtype, RoadType roadtype);
CommandCost CmdBuildTunnel(DoCommandFlags flags, TileIndex start_tile, TransportType transport_type, RailType railtype, RoadType roadtype);
DEF_CMD_TRAIT(Commands::BuildBridge, CmdBuildBridge, CommandFlags({CommandFlag::Deity, CommandFlag::Auto, CommandFlag::NoWater}), CommandType::LandscapeConstruction)
DEF_CMD_TRAIT(Commands::BuildTunnel, CmdBuildTunnel, CommandFlags({CommandFlag::Deity, CommandFlag::Auto}), CommandType::LandscapeConstruction)
void CcBuildBridge(Commands, const CommandCost &result, TileIndex end_tile, TileIndex tile_start, TransportType transport_type, BridgeType, uint8_t);
void CcBuildBridge(Commands, const CommandCost &result, TileIndex end_tile, TileIndex tile_start, TransportType transport_type, BridgeType, RailType, RoadType);
#endif /* TUNNELBRIDGE_CMD_H */