summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bridge_gui.cpp38
-rw-r--r--src/dock_gui.cpp8
-rw-r--r--src/rail_gui.cpp4
-rw-r--r--src/road_cmd.cpp130
-rw-r--r--src/road_cmd.h8
-rw-r--r--src/road_gui.cpp75
-rw-r--r--src/road_map.h13
-rw-r--r--src/road_type.h16
-rw-r--r--src/roadveh_cmd.cpp2
-rw-r--r--src/script/api/script_bridge.cpp27
-rw-r--r--src/script/api/script_marine.cpp4
-rw-r--r--src/script/api/script_road.cpp9
-rw-r--r--src/script/api/script_tunnel.cpp23
-rw-r--r--src/town_cmd.cpp16
-rw-r--r--src/transport_type.h2
-rw-r--r--src/tunnelbridge_cmd.cpp40
-rw-r--r--src/tunnelbridge_cmd.h6
-rw-r--r--src/water_cmd.cpp26
-rw-r--r--src/water_cmd.h5
-rw-r--r--src/water_map.h2
20 files changed, 180 insertions, 274 deletions
diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp
index 38ff698eb..77261932b 100644
--- a/src/bridge_gui.cpp
+++ b/src/bridge_gui.cpp
@@ -60,16 +60,14 @@ void CcBuildBridge(Commands cmd, const CommandCost &result, TileIndex end_tile,
if (result.Failed()) return;
if (_settings_client.sound.confirm) SndPlayTileFx(SND_27_CONSTRUCTION_BRIDGE, end_tile);
- auto [tile, p1, p2, text] = EndianBufferReader::ToValue<CommandTraits<CMD_BUILD_BRIDGE>::Args>(data);
-
- TransportType transport_type = Extract<TransportType, 15, 2>(p2);
+ auto [tile, tile_start, transport_type, bridge_type, road_rail_type] = EndianBufferReader::ToValue<CommandTraits<CMD_BUILD_BRIDGE>::Args>(data);
if (transport_type == TRANSPORT_ROAD) {
DiagDirection end_direction = ReverseDiagDir(GetTunnelBridgeDirection(end_tile));
ConnectRoadToStructure(end_tile, end_direction);
- DiagDirection start_direction = ReverseDiagDir(GetTunnelBridgeDirection(p1));
- ConnectRoadToStructure(p1, start_direction);
+ DiagDirection start_direction = ReverseDiagDir(GetTunnelBridgeDirection(tile_start));
+ ConnectRoadToStructure(tile_start, start_direction);
}
}
@@ -86,7 +84,8 @@ private:
/* Internal variables */
TileIndex start_tile;
TileIndex end_tile;
- uint32 type;
+ TransportType transport_type;
+ byte road_rail_type;
GUIBridgeList *bridges;
int bridgetext_offset; ///< Horizontal offset of the text describing the bridge properties in #WID_BBS_BRIDGE_LIST relative to the left edge.
Scrollbar *vscroll;
@@ -111,13 +110,13 @@ private:
void BuildBridge(uint8 i)
{
- switch ((TransportType)(this->type >> 15)) {
+ switch (this->transport_type) {
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;
}
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, {});
+ this->end_tile, this->start_tile, this->transport_type, this->bridges->at(i).index, this->road_rail_type);
}
/** Sort the builable bridges */
@@ -134,19 +133,20 @@ private:
}
public:
- BuildBridgeWindow(WindowDesc *desc, TileIndex start, TileIndex end, uint32 br_type, GUIBridgeList *bl) : Window(desc),
+ BuildBridgeWindow(WindowDesc *desc, TileIndex start, TileIndex end, TransportType transport_type, byte road_rail_type, GUIBridgeList *bl) : Window(desc),
start_tile(start),
end_tile(end),
- type(br_type),
+ transport_type(transport_type),
+ road_rail_type(road_rail_type),
bridges(bl)
{
this->CreateNestedTree();
this->vscroll = this->GetScrollbar(WID_BBS_SCROLLBAR);
/* Change the data, or the caption of the gui. Set it to road or rail, accordingly. */
- this->GetWidget<NWidgetCore>(WID_BBS_CAPTION)->widget_data = (GB(this->type, 15, 2) == TRANSPORT_ROAD) ? STR_SELECT_ROAD_BRIDGE_CAPTION : STR_SELECT_RAIL_BRIDGE_CAPTION;
- this->FinishInitNested(GB(br_type, 15, 2)); // Initializes 'this->bridgetext_offset'.
+ this->GetWidget<NWidgetCore>(WID_BBS_CAPTION)->widget_data = (transport_type == TRANSPORT_ROAD) ? STR_SELECT_ROAD_BRIDGE_CAPTION : STR_SELECT_RAIL_BRIDGE_CAPTION;
+ this->FinishInitNested(transport_type); // Initializes 'this->bridgetext_offset'.
- this->parent = FindWindowById(WC_BUILD_TOOLBAR, GB(this->type, 15, 2));
+ this->parent = FindWindowById(WC_BUILD_TOOLBAR, transport_type);
this->bridges->SetListing(this->last_sorting);
this->bridges->SetSortFuncs(this->sorter_funcs);
this->bridges->NeedResort();
@@ -361,12 +361,6 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo
{
CloseWindowByClass(WC_BUILD_BRIDGE);
- /* Data type for the bridge.
- * Bit 16,15 = transport type,
- * 14..8 = road/rail types,
- * 7..0 = type of bridge */
- uint32 type = (transport_type << 15) | (road_rail_type << 8);
-
/* The bridge length without ramps. */
const uint bridge_len = GetTunnelBridgeLength(start, end);
@@ -382,14 +376,14 @@ 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<CMD_BUILD_BRIDGE>::Post(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, transport_type, last_bridge_type, road_rail_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;
- CommandCost ret = Command<CMD_BUILD_BRIDGE>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_BRIDGE>()) | DC_QUERY_COST, end, start, type, {});
+ CommandCost ret = Command<CMD_BUILD_BRIDGE>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_BRIDGE>()) | DC_QUERY_COST, end, start, transport_type, 0, road_rail_type);
GUIBridgeList *bl = nullptr;
if (ret.Failed()) {
@@ -449,7 +443,7 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo
}
if (bl != nullptr && bl->size() != 0) {
- new BuildBridgeWindow(&_build_bridge_desc, start, end, type, bl);
+ new BuildBridgeWindow(&_build_bridge_desc, start, end, transport_type, road_rail_type, bl);
} else {
delete bl;
ShowErrorMessage(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, errmsg, WL_INFO, TileX(end) * TILE_SIZE, TileY(end) * TILE_SIZE);
diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp
index cdcb4ea84..d8cd7c5d4 100644
--- a/src/dock_gui.cpp
+++ b/src/dock_gui.cpp
@@ -196,7 +196,7 @@ struct BuildDocksToolbarWindow : Window {
break;
case WID_DT_LOCK: // Build lock button
- Command<CMD_BUILD_LOCK>::Post(STR_ERROR_CAN_T_BUILD_LOCKS, CcBuildDocks, tile, 0, 0, {});
+ Command<CMD_BUILD_LOCK>::Post(STR_ERROR_CAN_T_BUILD_LOCKS, CcBuildDocks, tile);
break;
case WID_DT_DEMOLISH: // Demolish aka dynamite button
@@ -234,7 +234,7 @@ struct BuildDocksToolbarWindow : Window {
break;
case WID_DT_BUILD_AQUEDUCT: // Build aqueduct button
- Command<CMD_BUILD_BRIDGE>::Post(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, 0, 0);
break;
default: NOT_REACHED();
@@ -254,10 +254,10 @@ struct BuildDocksToolbarWindow : Window {
GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
break;
case DDSP_CREATE_WATER:
- 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, {});
+ 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, false);
break;
case DDSP_CREATE_RIVER:
- 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), {});
+ Command<CMD_BUILD_CANAL>::Post(STR_ERROR_CAN_T_PLACE_RIVERS, CcPlaySound_CONSTRUCTION_WATER, end_tile, start_tile, WATER_CLASS_RIVER, _ctrl_pressed);
break;
default: break;
diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp
index a8e8b68b4..bac59d747 100644
--- a/src/rail_gui.cpp
+++ b/src/rail_gui.cpp
@@ -648,7 +648,7 @@ struct BuildRailToolbarWindow : Window {
break;
case WID_RAT_BUILD_TUNNEL:
- Command<CMD_BUILD_TUNNEL>::Post(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, TRANSPORT_RAIL, _cur_railtype);
break;
case WID_RAT_CONVERT_RAIL:
@@ -746,7 +746,7 @@ struct BuildRailToolbarWindow : Window {
void OnPlacePresize(Point pt, TileIndex tile) override
{
- Command<CMD_BUILD_TUNNEL>::Do(DC_AUTO, tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, {});
+ Command<CMD_BUILD_TUNNEL>::Do(DC_AUTO, tile, TRANSPORT_RAIL, _cur_railtype);
VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile);
}
diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp
index ece49676b..e160a2b84 100644
--- a/src/road_cmd.cpp
+++ b/src/road_cmd.cpp
@@ -606,14 +606,13 @@ static CommandCost CheckRoadSlope(Slope tileh, RoadBits *pieces, RoadBits existi
* Build a piece of road.
* @param flags operation to perform
* @param tile tile where to build road
- * @param p1 bit 0..3 road pieces to build (RoadBits)
- * bit 4..9 road type
- * bit 11..12 disallowed directions to toggle
- * @param p2 the town that is building the road (0 if not applicable)
- * @param text unused
+ * @param pieces road pieces to build (RoadBits)
+ * @param rt road type
+ * @param toggle_drd disallowed directions to toggle
+ * @param town_id the town that is building the road (0 if not applicable)
* @return the cost of this operation or an error
*/
-CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
+CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, RoadBits pieces, RoadType rt, DisallowedRoadDirections toggle_drd, TownID town_id)
{
CompanyID company = _current_company;
CommandCost cost(EXPENSES_CONSTRUCTION);
@@ -623,10 +622,10 @@ CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32
/* Road pieces are max 4 bitset values (NE, NW, SE, SW) and town can only be non-zero
* if a non-company is building the road */
- if ((Company::IsValidID(company) && p2 != 0) || (company == OWNER_TOWN && !Town::IsValidID(p2)) || (company == OWNER_DEITY && p2 != 0)) return CMD_ERROR;
+ if ((Company::IsValidID(company) && town_id != 0) || (company == OWNER_TOWN && !Town::IsValidID(town_id)) || (company == OWNER_DEITY && town_id != 0)) return CMD_ERROR;
if (company != OWNER_TOWN) {
const Town *town = CalcClosestTownFromTile(tile);
- p2 = (town != nullptr) ? town->index : INVALID_TOWN;
+ town_id = (town != nullptr) ? town->index : INVALID_TOWN;
if (company == OWNER_DEITY) {
company = OWNER_TOWN;
@@ -638,16 +637,10 @@ CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32
}
}
- RoadBits pieces = Extract<RoadBits, 0, 4>(p1);
-
/* do not allow building 'zero' road bits, code wouldn't handle it */
- if (pieces == ROAD_NONE) return CMD_ERROR;
-
- RoadType rt = Extract<RoadType, 4, 6>(p1);
+ if (pieces == ROAD_NONE || !IsEnumValid(pieces) || !IsEnumValid(toggle_drd)) return CMD_ERROR;
if (!ValParamRoadType(rt)) return CMD_ERROR;
- DisallowedRoadDirections toggle_drd = Extract<DisallowedRoadDirections, 11, 2>(p1);
-
Slope tileh = GetTileSlope(tile);
RoadTramType rtt = GetRoadTramType(rt);
@@ -785,7 +778,7 @@ CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32
/* Always add road to the roadtypes (can't draw without it) */
bool reserved = HasBit(GetRailReservationTrackBits(tile), railtrack);
- MakeRoadCrossing(tile, company, company, GetTileOwner(tile), roaddir, GetRailType(tile), rtt == RTT_ROAD ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, p2);
+ MakeRoadCrossing(tile, company, company, GetTileOwner(tile), roaddir, GetRailType(tile), rtt == RTT_ROAD ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, town_id);
SetCrossingReservation(tile, reserved);
UpdateLevelCrossing(tile, false);
MarkTileDirtyByTile(tile);
@@ -870,7 +863,7 @@ do_clear:;
if (HasPowerOnRoad(rt, existing_rt)) {
rt = existing_rt;
} else if (HasPowerOnRoad(existing_rt, rt)) {
- CommandCost ret = Command<CMD_CONVERT_ROAD>::Do(flags, tile, tile, rt, {});
+ CommandCost ret = Command<CMD_CONVERT_ROAD>::Do(flags, tile, tile, rt);
if (ret.Failed()) return ret;
cost.AddCost(ret);
} else {
@@ -895,7 +888,7 @@ do_clear:;
if (existing == ROAD_NONE || rttype == ROAD_TILE_CROSSING) {
SetRoadType(tile, rtt, rt);
SetRoadOwner(tile, rtt, company);
- if (rtt == RTT_ROAD) SetTownIndex(tile, p2);
+ if (rtt == RTT_ROAD) SetTownIndex(tile, town_id);
}
if (rttype != ROAD_TILE_CROSSING) SetRoadBits(tile, existing | pieces, rtt);
break;
@@ -927,7 +920,7 @@ do_clear:;
}
default:
- MakeRoadNormal(tile, pieces, (rtt == RTT_ROAD) ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, p2, company, company);
+ MakeRoadNormal(tile, pieces, (rtt == RTT_ROAD) ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, town_id, company, company);
break;
}
@@ -971,49 +964,40 @@ static bool CanConnectToRoad(TileIndex tile, RoadType rt, DiagDirection dir)
* Build a long piece of road.
* @param flags operation to perform
* @param start_tile start tile of drag (the building cost will appear over this tile)
- * @param p1 end tile of drag
- * @param p2 various bitstuffed elements
- * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1). Only used if bit 6 is set or if we are building a single tile
- * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2). Only used if bit 6 is set or if we are building a single tile
- * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4)
- * - p2 = (bit 3..8) - road type
- * - p2 = (bit 10) - set road direction
- * - p2 = (bit 11) - defines two different behaviors for this command:
- * - 0 = Build up to an obstacle. Do not build the first and last roadbits unless they can be connected to something, or if we are building a single tile
- * - 1 = Fail if an obstacle is found. Always take into account bit 0 and 1. This behavior is used for scripts
- * @param text unused
+ * @param end_tile end tile of drag
+ * @param rt road type
+ * @param axis direction
+ * @param drd set road direction
+ * @param start_half start tile starts in the 2nd half of tile (p2 & 1). Only used if \c is_ai is set or if we are building a single tile
+ * @param end_half end tile starts in the 2nd half of tile (p2 & 2). Only used if \c is_ai is set or if we are building a single tile
+ * @param is_ai defines two different behaviors for this command:
+ * - false = Build up to an obstacle. Do not build the first and last roadbits unless they can be connected to something, or if we are building a single tile
+ * - true = Fail if an obstacle is found. Always take into account start_half and end_half. This behavior is used for scripts
* @return the cost of this operation or an error
*/
-CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 p1, uint32 p2, const std::string &text)
+CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex start_tile, TileIndex end_tile, RoadType rt, Axis axis, DisallowedRoadDirections drd, bool start_half, bool end_half, bool is_ai)
{
- DisallowedRoadDirections drd = DRD_NORTHBOUND;
+ if (end_tile >= MapSize()) return CMD_ERROR;
- if (p1 >= MapSize()) return CMD_ERROR;
- TileIndex end_tile = p1;
+ if (!ValParamRoadType(rt) || !IsEnumValid(axis) || !IsEnumValid(drd)) return CMD_ERROR;
- RoadType rt = Extract<RoadType, 3, 6>(p2);
- if (!ValParamRoadType(rt)) return CMD_ERROR;
-
- Axis axis = Extract<Axis, 2, 1>(p2);
/* Only drag in X or Y direction dictated by the direction variable */
if (axis == AXIS_X && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis
if (axis == AXIS_Y && TileX(start_tile) != TileX(end_tile)) return CMD_ERROR; // y-axis
DiagDirection dir = AxisToDiagDir(axis);
- /* Swap direction, also the half-tile drag var (bit 0 and 1) */
- if (start_tile > end_tile || (start_tile == end_tile && HasBit(p2, 0))) {
+ /* Swap direction, also the half-tile drag vars. */
+ if (start_tile > end_tile || (start_tile == end_tile && start_half)) {
dir = ReverseDiagDir(dir);
- p2 ^= 3;
- drd = DRD_SOUTHBOUND;
+ std::swap(start_half, end_half);
+ if (drd == DRD_NORTHBOUND || drd == DRD_SOUTHBOUND) drd ^= DRD_BOTH;
}
/* On the X-axis, we have to swap the initial bits, so they
* will be interpreted correctly in the GTTS. Furthermore
* when you just 'click' on one tile to build them. */
- if ((axis == AXIS_Y) == (start_tile == end_tile && HasBit(p2, 0) == HasBit(p2, 1))) drd ^= DRD_BOTH;
- /* No disallowed direction bits have to be toggled */
- if (!HasBit(p2, 10)) drd = DRD_NONE;
+ if ((drd == DRD_NORTHBOUND || drd == DRD_SOUTHBOUND) && (axis == AXIS_Y) == (start_tile == end_tile && start_half == end_half)) drd ^= DRD_BOTH;
CommandCost cost(EXPENSES_CONSTRUCTION);
CommandCost last_error = CMD_ERROR;
@@ -1021,7 +1005,6 @@ CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 p
bool had_bridge = false;
bool had_tunnel = false;
bool had_success = false;
- bool is_ai = HasBit(p2, 11);
/* Start tile is the first tile clicked by the user. */
for (;;) {
@@ -1037,11 +1020,11 @@ CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 p
}
} else {
/* Road parts only have to be built at the start tile or at the end tile. */
- if (tile == end_tile && !HasBit(p2, 1)) bits &= DiagDirToRoadBits(ReverseDiagDir(dir));
- if (tile == start_tile && HasBit(p2, 0)) bits &= DiagDirToRoadBits(dir);
+ if (tile == end_tile && !end_half) bits &= DiagDirToRoadBits(ReverseDiagDir(dir));
+ if (tile == start_tile && start_half) bits &= DiagDirToRoadBits(dir);
}
- CommandCost ret = Command<CMD_BUILD_ROAD>::Do(flags, tile, drd << 11 | rt << 4 | bits, 0, {});
+ CommandCost ret = Command<CMD_BUILD_ROAD>::Do(flags, tile, bits, rt, drd, 0);
if (ret.Failed()) {
last_error = ret;
if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT) {
@@ -1080,36 +1063,28 @@ CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 p
* Remove a long piece of road.
* @param flags operation to perform
* @param start_tile start tile of drag
- * @param p1 end tile of drag
- * @param p2 various bitstuffed elements
- * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1)
- * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2)
- * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4)
- * - p2 = (bit 3 - 8) - road type
- * @param text unused
+ * @param end_tile end tile of drag
+ * @param rt road type
+ * @param axis direction
+ * @param start_half start tile starts in the 2nd half of tile
+ * @param end_half end tile starts in the 2nd half of tile (p2 & 2)
* @return the cost of this operation or an error
*/
-CommandCost CmdRemoveLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 p1, uint32 p2, const std::string &text)
+CommandCost CmdRemoveLongRoad(DoCommandFlag flags, TileIndex start_tile, TileIndex end_tile, RoadType rt, Axis axis, bool start_half, bool end_half)
{
CommandCost cost(EXPENSES_CONSTRUCTION);
- if (p1 >= MapSize()) return CMD_ERROR;
+ if (end_tile >= MapSize()) return CMD_ERROR;
+ if (!ValParamRoadType(rt) || !IsEnumValid(axis)) return CMD_ERROR;
- TileIndex end_tile = p1;
- RoadType rt = Extract<RoadType, 3, 6>(p2);
- if (!ValParamRoadType(rt)) return CMD_ERROR;
-
- Axis axis = Extract<Axis, 2, 1>(p2);
/* Only drag in X or Y direction dictated by the direction variable */
if (axis == AXIS_X && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis
if (axis == AXIS_Y && TileX(start_tile) != TileX(end_tile)) return CMD_ERROR; // y-axis
- /* Swap start and ending tile, also the half-tile drag var (bit 0 and 1) */
- if (start_tile > end_tile || (start_tile == end_tile && HasBit(p2, 0))) {
- TileIndex t = start_tile;
- start_tile = end_tile;
- end_tile = t;
- p2 ^= IsInsideMM(p2 & 3, 1, 3) ? 3 : 0;
+ /* Swap start and ending tile, also the half-tile drag vars. */
+ if (start_tile > end_tile || (start_tile == end_tile && start_half)) {
+ std::swap(start_tile, end_tile);
+ std::swap(start_half, end_half);
}
Money money_available = GetAvailableMoneyForCommand();
@@ -1121,8 +1096,8 @@ CommandCost CmdRemoveLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32
for (;;) {
RoadBits bits = AxisToRoadBits(axis);
- if (tile == end_tile && !HasBit(p2, 1)) bits &= ROAD_NW | ROAD_NE;
- if (tile == start_tile && HasBit(p2, 0)) bits &= ROAD_SE | ROAD_SW;
+ if (tile == end_tile && !end_half) bits &= ROAD_NW | ROAD_NE;
+ if (tile == start_tile && start_half) bits &= ROAD_SE | ROAD_SW;
/* try to remove the halves. */
if (bits != 0) {
@@ -1132,7 +1107,7 @@ CommandCost CmdRemoveLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32
if (flags & DC_EXEC) {
money_spent += ret.GetCost();
if (money_spent > 0 && money_spent > money_available) {
- _additional_cash_required = Command<CMD_REMOVE_LONG_ROAD>::Do(flags & ~DC_EXEC, start_tile, end_tile, p2, {}).GetCost();
+ _additional_cash_required = Command<CMD_REMOVE_LONG_ROAD>::Do(flags & ~DC_EXEC, start_tile, end_tile, rt, axis, start_half, end_half).GetCost();
return cost;
}
RemoveRoad(tile, flags, bits, rtt, true, false);
@@ -2342,17 +2317,12 @@ static void ConvertRoadTypeOwner(TileIndex tile, uint num_pieces, Owner owner, R
*
* @param flags operation to perform
* @param tile end tile of road conversion drag
- * @param p1 start tile of drag
- * @param p2 various bitstuffed elements:
- * - p2 = (bit 0..5) new roadtype to convert to.
- * @param text unused
+ * @param area_start start tile of drag
+ * @param to_type new roadtype to convert to.
* @return the cost of this operation or an error
*/
-CommandCost CmdConvertRoad(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
+CommandCost CmdConvertRoad(DoCommandFlag flags, TileIndex tile, TileIndex area_start, RoadType to_type)
{
- RoadType to_type = Extract<RoadType, 0, 6>(p2);
-
- TileIndex area_start = p1;
TileIndex area_end = tile;
if (!ValParamRoadType(to_type)) return CMD_ERROR;
diff --git a/src/road_cmd.h b/src/road_cmd.h
index 0cab1252f..3c142bdfe 100644
--- a/src/road_cmd.h
+++ b/src/road_cmd.h
@@ -17,11 +17,11 @@
void DrawRoadDepotSprite(int x, int y, DiagDirection dir, RoadType rt);
void UpdateNearestTownForRoadTiles(bool invalidate);
-CommandProc CmdBuildLongRoad;
-CommandProc CmdRemoveLongRoad;
-CommandProc CmdBuildRoad;
+CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex start_tile, TileIndex end_tile, RoadType rt, Axis axis, DisallowedRoadDirections drd, bool start_half, bool end_half, bool is_ai);
+CommandCost CmdRemoveLongRoad(DoCommandFlag flags, TileIndex start_tile, TileIndex end_tile, RoadType rt, Axis axis, bool start_half, bool end_half);
+CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, RoadBits pieces, RoadType rt, DisallowedRoadDirections toggle_drd, TownID town_id);
CommandCost CmdBuildRoadDepot(DoCommandFlag flags, TileIndex tile, RoadType rt, DiagDirection dir);
-CommandProc CmdConvertRoad;
+CommandCost CmdConvertRoad(DoCommandFlag flags, TileIndex tile, TileIndex area_start, RoadType to_type);
DEF_CMD_TRAIT(CMD_BUILD_LONG_ROAD, CmdBuildLongRoad, CMD_AUTO | CMD_NO_WATER | CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION)
DEF_CMD_TRAIT(CMD_REMOVE_LONG_ROAD, CmdRemoveLongRoad, CMD_AUTO | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION) // towns may disallow removing road bits (as they are connected) in test, but in exec they're removed and thus removing is allowed.
diff --git a/src/road_gui.cpp b/src/road_gui.cpp
index beba949e4..1aa0b59ac 100644
--- a/src/road_gui.cpp
+++ b/src/road_gui.cpp
@@ -47,22 +47,10 @@ static void ShowRoadDepotPicker(Window *parent);
static bool _remove_button_clicked;
static bool _one_way_button_clicked;
-/**
- * Define the values of the RoadFlags
- * @see CmdBuildLongRoad
- */
-enum RoadFlags {
- RF_NONE = 0x00,
- RF_START_HALFROAD_Y = 0x01, // The start tile in Y-dir should have only a half road
- RF_END_HALFROAD_Y = 0x02, // The end tile in Y-dir should have only a half road
- RF_DIR_Y = 0x04, // The direction is Y-dir
- RF_DIR_X = RF_NONE, // Dummy; Dir X is set when RF_DIR_Y is not set
- RF_START_HALFROAD_X = 0x08, // The start tile in X-dir should have only a half road
- RF_END_HALFROAD_X = 0x10, // The end tile in X-dir should have only a half road
-};
-DECLARE_ENUM_AS_BIT_SET(RoadFlags)
-
-static RoadFlags _place_road_flag;
+static Axis _place_road_dir;
+static bool _place_road_start_half_x;
+static bool _place_road_start_half_y;
+static bool _place_road_end_half;
static RoadType _cur_roadtype;
@@ -124,7 +112,7 @@ void ConnectRoadToStructure(TileIndex tile, DiagDirection direction)
/* if there is a roadpiece just outside of the station entrance, build a connecting route */
if (IsNormalRoadTile(tile)) {
if (GetRoadBits(tile, GetRoadTramType(_cur_roadtype)) != ROAD_NONE) {
- Command<CMD_BUILD_ROAD>::Post(tile, _cur_roadtype << 4 | DiagDirToRoadBits(ReverseDiagDir(direction)), 0, {});
+ Command<CMD_BUILD_ROAD>::Post(tile, DiagDirToRoadBits(ReverseDiagDir(direction)), _cur_roadtype, DRD_NONE, 0);
}
}
}
@@ -523,21 +511,21 @@ struct BuildRoadToolbarWindow : Window {
_one_way_button_clicked = RoadTypeIsRoad(this->roadtype) ? this->IsWidgetLowered(WID_ROT_ONE_WAY) : false;
switch (this->last_started_action) {
case WID_ROT_ROAD_X:
- _place_road_flag = RF_DIR_X;
- if (_tile_fract_coords.x >= 8) _place_road_flag |= RF_START_HALFROAD_X;
+ _place_road_dir = AXIS_X;
+ _place_road_start_half_x = _tile_fract_coords.x >= 8;
VpStartPlaceSizing(tile, VPM_FIX_Y, DDSP_PLACE_ROAD_X_DIR);
break;
case WID_ROT_ROAD_Y:
- _place_road_flag = RF_DIR_Y;
- if (_tile_fract_coords.y >= 8) _place_road_flag |= RF_START_HALFROAD_Y;
+ _place_road_dir = AXIS_Y;
+ _place_road_start_half_y = _tile_fract_coords.y >= 8;
VpStartPlaceSizing(tile, VPM_FIX_X, DDSP_PLACE_ROAD_Y_DIR);
break;
case WID_ROT_AUTOROAD:
- _place_road_flag = RF_NONE;
- if (_tile_fract_coords.x >= 8) _place_road_flag |= RF_START_HALFROAD_X;
- if (_tile_fract_coords.y >= 8) _place_road_flag |= RF_START_HALFROAD_Y;
+ _place_road_dir = INVALID_AXIS;
+ _place_road_start_half_x = _tile_fract_coords.x >= 8;
+ _place_road_start_half_y = _tile_fract_coords.y >= 8;
VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_PLACE_AUTOROAD);
break;
@@ -564,7 +552,7 @@ struct BuildRoadToolbarWindow : Window {
case WID_ROT_BUILD_TUNNEL:
Command<CMD_BUILD_TUNNEL>::Post(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE, CcBuildRoadTunnel,
- tile, _cur_roadtype | (TRANSPORT_ROAD << 8), 0, {});
+ tile, TRANSPORT_ROAD, _cur_roadtype);
break;
case WID_ROT_CONVERT_ROAD:
@@ -603,30 +591,26 @@ struct BuildRoadToolbarWindow : Window {
* bits and if needed we set them again. */
switch (select_proc) {
case DDSP_PLACE_ROAD_X_DIR:
- _place_road_flag &= ~RF_END_HALFROAD_X;
- if (pt.x & 8) _place_road_flag |= RF_END_HALFROAD_X;
+ _place_road_end_half = pt.x & 8;
break;
case DDSP_PLACE_ROAD_Y_DIR:
- _place_road_flag &= ~RF_END_HALFROAD_Y;
- if (pt.y & 8) _place_road_flag |= RF_END_HALFROAD_Y;
+ _place_road_end_half = pt.y & 8;
break;
case DDSP_PLACE_AUTOROAD:
- _place_road_flag &= ~(RF_END_HALFROAD_Y | RF_END_HALFROAD_X);
- if (pt.y & 8) _place_road_flag |= RF_END_HALFROAD_Y;
- if (pt.x & 8) _place_road_flag |= RF_END_HALFROAD_X;
-
/* For autoroad we need to update the
* direction of the road */
if (_thd.size.x > _thd.size.y || (_thd.size.x == _thd.size.y &&
( (_tile_fract_coords.x < _tile_fract_coords.y && (_tile_fract_coords.x + _tile_fract_coords.y) < 16) ||
(_tile_fract_coords.x > _tile_fract_coords.y && (_tile_fract_coords.x + _tile_fract_coords.y) > 16) ))) {
/* Set dir = X */
- _place_road_flag &= ~RF_DIR_Y;
+ _place_road_dir = AXIS_X;
+ _place_road_end_half = pt.x & 8;
} else {
/* Set dir = Y */
- _place_road_flag |= RF_DIR_Y;
+ _place_road_dir = AXIS_Y;
+ _place_road_end_half = pt.y & 8;
}
break;
@@ -654,25 +638,18 @@ struct BuildRoadToolbarWindow : Window {
case DDSP_PLACE_ROAD_X_DIR:
case DDSP_PLACE_ROAD_Y_DIR:
- case DDSP_PLACE_AUTOROAD:
- /* Flag description:
- * Use the first three bits (0x07) if dir == Y
- * else use the last 2 bits (X dir has
- * not the 3rd bit set) */
-
- /* 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));
+ case DDSP_PLACE_AUTOROAD: {
+ bool start_half = _place_road_dir == AXIS_Y ? _place_road_start_half_y : _place_road_start_half_y;
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), {});
+ start_tile, end_tile, _cur_roadtype, _place_road_dir, start_half, _place_road_end_half);
} 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), {});
+ start_tile, end_tile, _cur_roadtype, _place_road_dir, _one_way_button_clicked ? DRD_NORTHBOUND : DRD_NONE, start_tile, _place_road_end_half, false);
}
break;
+ }
case DDSP_BUILD_BUSSTOP:
case DDSP_REMOVE_BUSSTOP:
@@ -699,7 +676,7 @@ struct BuildRoadToolbarWindow : Window {
break;
case DDSP_CONVERT_ROAD:
- Command<CMD_CONVERT_ROAD>::Post(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;
}
}
@@ -707,7 +684,7 @@ struct BuildRoadToolbarWindow : Window {
void OnPlacePresize(Point pt, TileIndex tile) override
{
- Command<CMD_BUILD_TUNNEL>::Do(DC_AUTO, tile, _cur_roadtype | (TRANSPORT_ROAD << 8), 0, {});
+ Command<CMD_BUILD_TUNNEL>::Do(DC_AUTO, tile, TRANSPORT_ROAD, _cur_roadtype);
VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile);
}
diff --git a/src/road_map.h b/src/road_map.h
index 22d0fa54d..4cb9125ea 100644
--- a/src/road_map.h
+++ b/src/road_map.h
@@ -15,6 +15,7 @@
#include "rail_type.h"
#include "road_func.h"
#include "tile_map.h"
+#include "road_type.h"
/** The different types of road tiles. */
@@ -281,18 +282,6 @@ static inline bool HasTownOwnedRoad(TileIndex t)
return HasTileRoadType(t, RTT_ROAD) && IsRoadOwner(t, RTT_ROAD, OWNER_TOWN);
}
-/** Which directions are disallowed ? */
-enum DisallowedRoadDirections {
- DRD_NONE, ///< None of the directions are disallowed
- DRD_SOUTHBOUND, ///< All southbound traffic is disallowed
- DRD_NORTHBOUND, ///< All northbound traffic is disallowed
- DRD_BOTH, ///< All directions are disallowed
- DRD_END, ///< Sentinel
-};
-DECLARE_ENUM_AS_BIT_SET(DisallowedRoadDirections)
-/** Helper information for extract tool. */
-template <> struct EnumPropsT<DisallowedRoadDirections> : MakeEnumPropsT<DisallowedRoadDirections, byte, DRD_NONE, DRD_END, DRD_END, 2> {};
-
/**
* Gets the disallowed directions
* @param t the tile to get the directions from
diff --git a/src/road_type.h b/src/road_type.h
index 969b141ba..a792db7ba 100644
--- a/src/road_type.h
+++ b/src/road_type.h
@@ -19,7 +19,7 @@ typedef uint32 RoadTypeLabel;
*
* @note currently only ROADTYPE_ROAD and ROADTYPE_TRAM are supported.
*/
-enum RoadType {
+enum RoadType : byte {
ROADTYPE_BEGIN = 0, ///< Used for iterations
ROADTYPE_ROAD = 0, ///< Basic road type
ROADTYPE_TRAM = 1, ///< Trams
@@ -47,7 +47,7 @@ DECLARE_ENUM_AS_BIT_SET(RoadTypes)
* This enumeration defines the possible road parts which
* can be build on a tile.
*/
-enum RoadBits {
+enum RoadBits : byte {
ROAD_NONE = 0U, ///< No road-part is build
ROAD_NW = 1U, ///< North-west part
ROAD_SW = 2U, ///< South-west part
@@ -68,4 +68,16 @@ enum RoadBits {
DECLARE_ENUM_AS_BIT_SET(RoadBits)
template <> struct EnumPropsT<RoadBits> : MakeEnumPropsT<RoadBits, byte, ROAD_NONE, ROAD_END, ROAD_NONE, 4> {};
+/** Which directions are disallowed ? */
+enum DisallowedRoadDirections : byte {
+ DRD_NONE, ///< None of the directions are disallowed
+ DRD_SOUTHBOUND, ///< All southbound traffic is disallowed
+ DRD_NORTHBOUND, ///< All northbound traffic is disallowed
+ DRD_BOTH, ///< All directions are disallowed
+ DRD_END, ///< Sentinel
+};
+DECLARE_ENUM_AS_BIT_SET(DisallowedRoadDirections)
+/** Helper information for extract tool. */
+template <> struct EnumPropsT<DisallowedRoadDirections> : MakeEnumPropsT<DisallowedRoadDirections, byte, DRD_NONE, DRD_END, DRD_END, 2> {};
+
#endif /* ROAD_TYPE_H */
diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp
index 0b8d9deff..c1e510273 100644
--- a/src/roadveh_cmd.cpp
+++ b/src/roadveh_cmd.cpp
@@ -1131,7 +1131,7 @@ static bool CanBuildTramTrackOnTile(CompanyID c, TileIndex t, RoadType rt, RoadB
/* The 'current' company is not necessarily the owner of the vehicle. */
Backup<CompanyID> cur_company(_current_company, c, FILE_LINE);
- CommandCost ret = Command<CMD_BUILD_ROAD>::Do(DC_NO_WATER, t, rt << 4 | r, 0, {});
+ CommandCost ret = Command<CMD_BUILD_ROAD>::Do(DC_NO_WATER, t, r, rt, DRD_NONE, 0);
cur_company.Restore();
return ret.Succeeded();
diff --git a/src/script/api/script_bridge.cpp b/src/script/api/script_bridge.cpp
index dc357c255..fbea9fb12 100644
--- a/src/script/api/script_bridge.cpp
+++ b/src/script/api/script_bridge.cpp
@@ -80,30 +80,17 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance)
EnforcePrecondition(false, vehicle_type != ScriptVehicle::VT_ROAD || ScriptRoad::IsRoadTypeAvailable(ScriptRoad::GetCurrentRoadType()));
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY || vehicle_type == ScriptVehicle::VT_ROAD);
- uint type = 0;
switch (vehicle_type) {
case ScriptVehicle::VT_ROAD:
- type |= (TRANSPORT_ROAD << 15);
- type |= (ScriptRoad::GetCurrentRoadType() << 8);
- break;
+ ScriptObject::SetCallbackVariable(0, start);
+ ScriptObject::SetCallbackVariable(1, end);
+ return ScriptObject::Command<CMD_BUILD_BRIDGE>::Do(&::_DoCommandReturnBuildBridge1, end, start, TRANSPORT_ROAD, bridge_id, ScriptRoad::GetCurrentRoadType());
case ScriptVehicle::VT_RAIL:
- type |= (TRANSPORT_RAIL << 15);
- type |= (ScriptRail::GetCurrentRailType() << 8);
- break;
+ return ScriptObject::Command<CMD_BUILD_BRIDGE>::Do(end, start, TRANSPORT_RAIL, bridge_id, ScriptRail::GetCurrentRailType());
case ScriptVehicle::VT_WATER:
- type |= (TRANSPORT_WATER << 15);
- break;
+ return ScriptObject::Command<CMD_BUILD_BRIDGE>::Do(end, start, TRANSPORT_WATER, bridge_id, 0);
default: NOT_REACHED();
}
-
- /* For rail and water we do nothing special */
- if (vehicle_type == ScriptVehicle::VT_RAIL || vehicle_type == ScriptVehicle::VT_WATER) {
- return ScriptObject::Command<CMD_BUILD_BRIDGE>::Do(end, start, type | bridge_id, {});
- }
-
- ScriptObject::SetCallbackVariable(0, start);
- ScriptObject::SetCallbackVariable(1, end);
- return ScriptObject::Command<CMD_BUILD_BRIDGE>::Do(&::_DoCommandReturnBuildBridge1, end, start, type | bridge_id, {});
}
/* static */ bool ScriptBridge::_BuildBridgeRoad1()
@@ -115,7 +102,7 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance)
DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start);
DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
- return ScriptObject::Command<CMD_BUILD_ROAD>::Do(&::_DoCommandReturnBuildBridge2, start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (ScriptRoad::GetCurrentRoadType() << 4), 0, {});
+ return ScriptObject::Command<CMD_BUILD_ROAD>::Do(&::_DoCommandReturnBuildBridge2, start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2), (::RoadType)ScriptRoad::GetCurrentRoadType(), DRD_NONE, 0);
}
/* static */ bool ScriptBridge::_BuildBridgeRoad2()
@@ -127,7 +114,7 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance)
DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start);
DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
- return ScriptObject::Command<CMD_BUILD_ROAD>::Do(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1) | (ScriptRoad::GetCurrentRoadType() << 4), 0, {});
+ return ScriptObject::Command<CMD_BUILD_ROAD>::Do(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1), (::RoadType)ScriptRoad::GetCurrentRoadType(), DRD_NONE, 0);
}
/* static */ bool ScriptBridge::RemoveBridge(TileIndex tile)
diff --git a/src/script/api/script_marine.cpp b/src/script/api/script_marine.cpp
index 809323394..059157e27 100644
--- a/src/script/api/script_marine.cpp
+++ b/src/script/api/script_marine.cpp
@@ -108,7 +108,7 @@
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
EnforcePrecondition(false, ::IsValidTile(tile));
- return ScriptObject::Command<CMD_BUILD_LOCK>::Do(tile, 0, 0, {});
+ return ScriptObject::Command<CMD_BUILD_LOCK>::Do(tile);
}
/* static */ bool ScriptMarine::BuildCanal(TileIndex tile)
@@ -116,7 +116,7 @@
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
EnforcePrecondition(false, ::IsValidTile(tile));
- return ScriptObject::Command<CMD_BUILD_CANAL>::Do(tile, tile, WATER_CLASS_CANAL, {});
+ return ScriptObject::Command<CMD_BUILD_CANAL>::Do(tile, tile, WATER_CLASS_CANAL, false);
}
/* static */ bool ScriptMarine::RemoveWaterDepot(TileIndex tile)
diff --git a/src/script/api/script_road.cpp b/src/script/api/script_road.cpp
index c629396b7..297a8f56c 100644
--- a/src/script/api/script_road.cpp
+++ b/src/script/api/script_road.cpp
@@ -129,7 +129,7 @@
EnforcePrecondition(false, ::IsValidTile(end_tile));
EnforcePrecondition(false, IsRoadTypeAvailable(road_type));
- return ScriptObject::Command<CMD_CONVERT_ROAD>::Do(start_tile, end_tile, (::RoadType)road_type, {});
+ return ScriptObject::Command<CMD_CONVERT_ROAD>::Do(start_tile, end_tile, (::RoadType)road_type);
}
/* Helper functions for ScriptRoad::CanBuildConnectedRoadParts(). */
@@ -495,7 +495,8 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD
EnforcePrecondition(false, !one_way || RoadTypeIsRoad(ScriptObject::GetRoadType()));
EnforcePrecondition(false, IsRoadTypeAvailable(GetCurrentRoadType()));
- return ScriptObject::Command<CMD_BUILD_LONG_ROAD>::Do(start, end, (::TileY(start) != ::TileY(end) ? 4 : 0) | (((start < end) == !full) ? 1 : 2) | (ScriptObject::GetRoadType() << 3) | ((one_way ? 1 : 0) << 10) | 1 << 11, {});
+ Axis axis = ::TileY(start) != ::TileY(end) ? AXIS_Y : AXIS_X;
+ return ScriptObject::Command<CMD_BUILD_LONG_ROAD>::Do(start, end, ScriptObject::GetRoadType(), axis, one_way ? DRD_NORTHBOUND : DRD_NONE, (start < end) == !full, (start < end) != !full, true);
}
/* static */ bool ScriptRoad::BuildRoad(TileIndex start, TileIndex end)
@@ -570,7 +571,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD
EnforcePrecondition(false, ::TileX(start) == ::TileX(end) || ::TileY(start) == ::TileY(end));
EnforcePrecondition(false, IsRoadTypeAvailable(GetCurrentRoadType()));
- return ScriptObject::Command<CMD_REMOVE_LONG_ROAD>::Do(start, end, (::TileY(start) != ::TileY(end) ? 4 : 0) | (start < end ? 1 : 2) | (ScriptObject::GetRoadType() << 3), {});
+ return ScriptObject::Command<CMD_REMOVE_LONG_ROAD>::Do(start, end, ScriptObject::GetRoadType(), ::TileY(start) != ::TileY(end) ? AXIS_Y : AXIS_X, start < end, start >= end);
}
/* static */ bool ScriptRoad::RemoveRoadFull(TileIndex start, TileIndex end)
@@ -582,7 +583,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD
EnforcePrecondition(false, ::TileX(start) == ::TileX(end) || ::TileY(start) == ::TileY(end));
EnforcePrecondition(false, IsRoadTypeAvailable(GetCurrentRoadType()));
- return ScriptObject::Command<CMD_REMOVE_LONG_ROAD>::Do(start, end, (::TileY(start) != ::TileY(end) ? 4 : 0) | (start < end ? 2 : 1) | (ScriptObject::GetRoadType() << 3), {});
+ return ScriptObject::Command<CMD_REMOVE_LONG_ROAD>::Do(start, end, ScriptObject::GetRoadType(), ::TileY(start) != ::TileY(end) ? AXIS_Y : AXIS_X, start >= end, start < end);
}
/* static */ bool ScriptRoad::RemoveRoadDepot(TileIndex tile)
diff --git a/src/script/api/script_tunnel.cpp b/src/script/api/script_tunnel.cpp
index ea9cbc518..8529f908d 100644
--- a/src/script/api/script_tunnel.cpp
+++ b/src/script/api/script_tunnel.cpp
@@ -88,22 +88,13 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance)
EnforcePrecondition(false, vehicle_type != ScriptVehicle::VT_ROAD || ScriptRoad::IsRoadTypeAvailable(ScriptRoad::GetCurrentRoadType()));
EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY || vehicle_type == ScriptVehicle::VT_ROAD);
- uint type = 0;
- if (vehicle_type == ScriptVehicle::VT_ROAD) {
- type |= (TRANSPORT_ROAD << 8);
- type |= ScriptRoad::GetCurrentRoadType();
- } else {
- type |= (TRANSPORT_RAIL << 8);
- type |= ScriptRail::GetCurrentRailType();
- }
-
- /* For rail we do nothing special */
if (vehicle_type == ScriptVehicle::VT_RAIL) {
- return ScriptObject::Command<CMD_BUILD_TUNNEL>::Do(start, type, 0, {});
+ /* For rail we do nothing special */
+ return ScriptObject::Command<CMD_BUILD_TUNNEL>::Do(start, TRANSPORT_RAIL, ScriptRail::GetCurrentRailType());
+ } else {
+ ScriptObject::SetCallbackVariable(0, start);
+ return ScriptObject::Command<CMD_BUILD_TUNNEL>::Do(&::_DoCommandReturnBuildTunnel1, start, TRANSPORT_ROAD, ScriptRoad::GetCurrentRoadType());
}
-
- ScriptObject::SetCallbackVariable(0, start);
- return ScriptObject::Command<CMD_BUILD_TUNNEL>::Do(&::_DoCommandReturnBuildTunnel1, start, type, 0, {});
}
/* static */ bool ScriptTunnel::_BuildTunnelRoad1()
@@ -115,7 +106,7 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance)
DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start);
DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
- return ScriptObject::Command<CMD_BUILD_ROAD>::Do(&::_DoCommandReturnBuildTunnel2, start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (ScriptObject::GetRoadType() << 4), 0, {});
+ return ScriptObject::Command<CMD_BUILD_ROAD>::Do(&::_DoCommandReturnBuildTunnel2, start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2), ScriptRoad::GetRoadType(), DRD_NONE, 0);
}
/* static */ bool ScriptTunnel::_BuildTunnelRoad2()
@@ -127,7 +118,7 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance)
DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start);
DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
- return ScriptObject::Command<CMD_BUILD_ROAD>::Do(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1) | (ScriptObject::GetRoadType() << 4), 0, {});
+ return ScriptObject::Command<CMD_BUILD_ROAD>::Do(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1), ScriptRoad::GetRoadType(), DRD_NONE, 0);
}
/* static */ bool ScriptTunnel::RemoveTunnel(TileIndex tile)
diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp
index 8e87739d3..7a564d48a 100644
--- a/src/town_cmd.cpp
+++ b/src/town_cmd.cpp
@@ -943,7 +943,7 @@ static bool IsRoadAllowedHere(Town *t, TileIndex tile, DiagDirection dir)
* If that fails clear the land, and if that fails exit.
* This is to make sure that we can build a road here later. */
RoadType rt = GetTownRoadType(t);
- if (Command<CMD_BUILD_ROAD>::Do(DC_AUTO | DC_NO_WATER, tile, ((dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? ROAD_Y : ROAD_X) | (rt << 4), 0, {}).Failed() &&
+ if (Command<CMD_BUILD_ROAD>::Do(DC_AUTO | DC_NO_WATER, tile, (dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? ROAD_Y : ROAD_X, rt, DRD_NONE, 0).Failed() &&
Command<CMD_LANDSCAPE_CLEAR>::Do(DC_AUTO | DC_NO_WATER, tile, 0, 0, {}).Failed()) {
return false;
}
@@ -1112,7 +1112,7 @@ static bool GrowTownWithExtraHouse(Town *t, TileIndex tile)
static bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd)
{
RoadType rt = GetTownRoadType(t);
- if (Command<CMD_BUILD_ROAD>::Do(DC_EXEC | DC_AUTO | DC_NO_WATER, tile, rcmd | (rt << 4), t->index, {}).Succeeded()) {
+ if (Command<CMD_BUILD_ROAD>::Do(DC_EXEC | DC_AUTO | DC_NO_WATER, tile, rcmd, rt, DRD_NONE, t->index).Succeeded()) {
_grow_town_result = GROWTH_SUCCEED;
return true;
}
@@ -1159,7 +1159,7 @@ static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, con
if (IsTileType(next_tile, MP_RAILWAY) && !_settings_game.economy.allow_town_level_crossings) return false;
/* If a road tile can be built, the construction is allowed. */
- return Command<CMD_BUILD_ROAD>::Do(DC_AUTO | DC_NO_WATER, next_tile, rcmd | (rt << 4), t->index, {}).Succeeded();
+ return Command<CMD_BUILD_ROAD>::Do(DC_AUTO | DC_NO_WATER, next_tile, rcmd, rt, DRD_NONE, t->index).Succeeded();
}
/**
@@ -1227,8 +1227,8 @@ static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDi
/* Can we actually build the bridge? */
RoadType rt = GetTownRoadType(t);
- if (Command<CMD_BUILD_BRIDGE>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_BRIDGE>()), tile, bridge_tile, bridge_type | rt << 8 | TRANSPORT_ROAD << 15, {}).Succeeded()) {
- Command<CMD_BUILD_BRIDGE>::Do(DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_BRIDGE>()), tile, bridge_tile, bridge_type | rt << 8 | TRANSPORT_ROAD << 15, {});
+ if (Command<CMD_BUILD_BRIDGE>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_BRIDGE>()), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt).Succeeded()) {
+ Command<CMD_BUILD_BRIDGE>::Do(DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_BRIDGE>()), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt);
_grow_town_result = GROWTH_SUCCEED;
return true;
}
@@ -1298,8 +1298,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(t);
- if (Command<CMD_BUILD_TUNNEL>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_TUNNEL>()), tile, rt | (TRANSPORT_ROAD << 8), 0, {}).Succeeded()) {
- Command<CMD_BUILD_TUNNEL>::Do(DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_TUNNEL>()), tile, rt | (TRANSPORT_ROAD << 8), 0, {});
+ if (Command<CMD_BUILD_TUNNEL>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_TUNNEL>()), tile, TRANSPORT_ROAD, rt).Succeeded()) {
+ Command<CMD_BUILD_TUNNEL>::Do(DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_TUNNEL>()), tile, TRANSPORT_ROAD, rt);
_grow_town_result = GROWTH_SUCCEED;
return true;
}
@@ -1739,7 +1739,7 @@ static bool GrowTown(Town *t)
if (!IsTileType(tile, MP_HOUSE) && IsTileFlat(tile)) {
if (Command<CMD_LANDSCAPE_CLEAR>::Do(DC_AUTO | DC_NO_WATER, tile, 0, 0, {}).Succeeded()) {
RoadType rt = GetTownRoadType(t);
- Command<CMD_BUILD_ROAD>::Do(DC_EXEC | DC_AUTO, tile, GenRandomRoadBits() | (rt << 4), t->index, {});
+ Command<CMD_BUILD_ROAD>::Do(DC_EXEC | DC_AUTO, tile, GenRandomRoadBits(), rt, DRD_NONE, t->index);
cur_company.Restore();
return true;
}
diff --git a/src/transport_type.h b/src/transport_type.h
index b244e48b3..172649aba 100644
--- a/src/transport_type.h
+++ b/src/transport_type.h
@@ -16,7 +16,7 @@
typedef uint16 UnitID;
/** Available types of transport */
-enum TransportType {
+enum TransportType : byte {
/* These constants are for now linked to the representation of bridges
* and tunnels, so they can be used by GetTileTrackStatus_TunnelBridge.
* In an ideal world, these constants would be used everywhere when
diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp
index 85c611ae5..14ff79854 100644
--- a/src/tunnelbridge_cmd.cpp
+++ b/src/tunnelbridge_cmd.cpp
@@ -251,38 +251,31 @@ static Money TunnelBridgeClearCost(TileIndex tile, Price base_price)
/**
* Build a Bridge
* @param flags type of operation
- * @param end_tile end tile
- * @param p1 packed start tile coords (~ dx)
- * @param p2 various bitstuffed elements
- * - p2 = (bit 0- 7) - bridge type (hi bh)
- * - p2 = (bit 8-13) - rail type or road types.
- * - p2 = (bit 15-16) - transport type.
- * @param text unused
+ * @param tile_end end tile
+ * @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.
* @return the cost of this operation or an error
*/
-CommandCost CmdBuildBridge(DoCommandFlag flags, TileIndex end_tile, uint32 p1, uint32 p2, const std::string &text)
+CommandCost CmdBuildBridge(DoCommandFlag flags, TileIndex tile_end, TileIndex tile_start, TransportType transport_type, BridgeType bridge_type, byte road_rail_type)
{
CompanyID company = _current_company;
RailType railtype = INVALID_RAILTYPE;
RoadType roadtype = INVALID_ROADTYPE;
- /* unpack parameters */
- BridgeType bridge_type = GB(p2, 0, 8);
-
- if (!IsValidTile(p1)) return_cmd_error(STR_ERROR_BRIDGE_THROUGH_MAP_BORDER);
-
- TransportType transport_type = Extract<TransportType, 15, 2>(p2);
+ if (!IsValidTile(tile_start)) return_cmd_error(STR_ERROR_BRIDGE_THROUGH_MAP_BORDER);
/* type of bridge */
switch (transport_type) {
case TRANSPORT_ROAD:
- roadtype = Extract<RoadType, 8, 6>(p2);
+ roadtype = (RoadType)road_rail_type;
if (!ValParamRoadType(roadtype)) return CMD_ERROR;
break;
case TRANSPORT_RAIL:
- railtype = Extract<RailType, 8, 6>(p2);
+ railtype = (RailType)road_rail_type;
if (!ValParamRailtype(railtype)) return CMD_ERROR;
break;
@@ -293,8 +286,6 @@ CommandCost CmdBuildBridge(DoCommandFlag flags, TileIndex end_tile, uint32 p1, u
/* Airports don't have bridges. */
return CMD_ERROR;
}
- TileIndex tile_start = p1;
- TileIndex tile_end = end_tile;
if (company == OWNER_DEITY) {
if (transport_type != TRANSPORT_ROAD) return CMD_ERROR;
@@ -627,28 +618,25 @@ CommandCost CmdBuildBridge(DoCommandFlag flags, TileIndex end_tile, uint32 p1, u
* Build Tunnel.
* @param flags type of operation
* @param start_tile start tile of tunnel
- * @param p1 bit 0-5 railtype or roadtype
- * bit 8-9 transport type
- * @param p2 unused
- * @param text unused
+ * @param transport_type transport type
+ * @param road_rail_type railtype or roadtype
* @return the cost of this operation or an error
*/
-CommandCost CmdBuildTunnel(DoCommandFlag flags, TileIndex start_tile, uint32 p1, uint32 p2, const std::string &text)
+CommandCost CmdBuildTunnel(DoCommandFlag flags, TileIndex start_tile, TransportType transport_type, byte road_rail_type)
{
CompanyID company = _current_company;
- TransportType transport_type = Extract<TransportType, 8, 2>(p1);
RailType railtype = INVALID_RAILTYPE;
RoadType roadtype = INVALID_ROADTYPE;
_build_tunnel_endtile = 0;
switch (transport_type) {
case TRANSPORT_RAIL:
- railtype = Extract<RailType, 0, 6>(p1);
+ railtype = (RailType)road_rail_type;
if (!ValParamRailtype(railtype)) return CMD_ERROR;
break;
case TRANSPORT_ROAD:
- roadtype = Extract<RoadType, 0, 6>(p1);
+ roadtype = (RoadType)road_rail_type;
if (!ValParamRoadType(roadtype)) return CMD_ERROR;
break;
diff --git a/src/tunnelbridge_cmd.h b/src/tunnelbridge_cmd.h
index 6c78db48b..ae924cf69 100644
--- a/src/tunnelbridge_cmd.h
+++ b/src/tunnelbridge_cmd.h
@@ -11,9 +11,11 @@
#define TUNNELBRIDGE_CMD_H
#include "command_type.h"
+#include "transport_type.h"
+#include "bridge.h"
-CommandProc CmdBuildBridge;
-CommandProc CmdBuildTunnel;
+CommandCost CmdBuildBridge(DoCommandFlag flags, TileIndex tile_end, TileIndex tile_start, TransportType transport_type, BridgeType bridge_type, byte road_rail_type);
+CommandCost CmdBuildTunnel(DoCommandFlag flags, TileIndex start_tile, TransportType transport_type, byte road_rail_type);
DEF_CMD_TRAIT(CMD_BUILD_BRIDGE, CmdBuildBridge, CMD_DEITY | CMD_AUTO | CMD_NO_WATER, CMDT_LANDSCAPE_CONSTRUCTION)
DEF_CMD_TRAIT(CMD_BUILD_TUNNEL, CmdBuildTunnel, CMD_DEITY | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION)
diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp
index 3c96f79ad..ee911312e 100644
--- a/src/water_cmd.cpp
+++ b/src/water_cmd.cpp
@@ -411,12 +411,9 @@ static CommandCost RemoveLock(TileIndex tile, DoCommandFlag flags)
* Builds a lock.
* @param flags type of operation
* @param tile tile where to place the lock
- * @param p1 unused
- * @param p2 unused
- * @param text unused
* @return the cost of this operation or an error
*/
-CommandCost CmdBuildLock(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
+CommandCost CmdBuildLock(DoCommandFlag flags, TileIndex tile)
{
DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile));
if (dir == INVALID_DIAGDIR) return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
@@ -435,34 +432,31 @@ bool RiverModifyDesertZone(TileIndex tile, void *)
* Build a piece of canal.
* @param flags type of operation
* @param tile end tile of stretch-dragging
- * @param p1 start tile of stretch-dragging
- * @param p2 various bitstuffed data
- * bits 0-1: waterclass to build. sea and river can only be built in scenario editor
- * bit 2: Whether to use the Orthogonal (0) or Diagonal (1) iterator.
- * @param text unused
+ * @param start_tile start tile of stretch-dragging
+ * @param wc waterclass to build. sea and river can only be built in scenario editor
+ * @param diagonal Whether to use the Orthogonal (0) or Diagonal (1) iterator.
* @return the cost of this operation or an error
*/
-CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
+CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, WaterClass wc, bool diagonal)
{
- WaterClass wc = Extract<WaterClass, 0, 2>(p2);
- if (p1 >= MapSize() || wc == WATER_CLASS_INVALID) return CMD_ERROR;
+ if (start_tile >= MapSize() || !IsEnumValid(wc)) return CMD_ERROR;
/* Outside of the editor you can only build canals, not oceans */
if (wc != WATER_CLASS_CANAL && _game_mode != GM_EDITOR) return CMD_ERROR;
/* Outside the editor you can only drag canals, and not areas */
if (_game_mode != GM_EDITOR) {
- TileArea ta(tile, (TileIndex)p1);
+ TileArea ta(tile, start_tile);
if (ta.w != 1 && ta.h != 1) return CMD_ERROR;
}
CommandCost cost(EXPENSES_CONSTRUCTION);
std::unique_ptr<TileIterator> iter;
- if (HasBit(p2, 2)) {
- iter = std::make_unique<DiagonalTileIterator>(tile, (TileIndex)p1);
+ if (diagonal) {
+ iter = std::make_unique<DiagonalTileIterator>(tile, start_tile);
} else {
- iter = std::make_unique<OrthogonalTileIterator>(tile, (TileIndex)p1);
+ iter = std::make_unique<OrthogonalTileIterator>(tile, start_tile);
}
for (; *iter != INVALID_TILE; ++(*iter)) {
diff --git a/src/water_cmd.h b/src/water_cmd.h
index 4d3375aa3..1c5679032 100644
--- a/src/water_cmd.h
+++ b/src/water_cmd.h
@@ -11,10 +11,11 @@
#define WATER_CMD_H
#include "command_type.h"
+#include "water_map.h"
CommandCost CmdBuildShipDepot(DoCommandFlag flags, TileIndex tile, Axis axis);
-CommandProc CmdBuildCanal;
-CommandProc CmdBuildLock;
+CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, WaterClass wc, bool diagonal);
+CommandCost CmdBuildLock(DoCommandFlag flags, TileIndex tile);
DEF_CMD_TRAIT(CMD_BUILD_SHIP_DEPOT, CmdBuildShipDepot, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION)
DEF_CMD_TRAIT(CMD_BUILD_CANAL, CmdBuildCanal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION)
diff --git a/src/water_map.h b/src/water_map.h
index 22e54e967..793d07c8a 100644
--- a/src/water_map.h
+++ b/src/water_map.h
@@ -44,7 +44,7 @@ enum WaterTileType {
};
/** classes of water (for #WATER_TILE_CLEAR water tile type). */
-enum WaterClass {
+enum WaterClass : byte {
WATER_CLASS_SEA, ///< Sea.
WATER_CLASS_CANAL, ///< Canal.
WATER_CLASS_RIVER, ///< River.