diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index 623a047d59..2b17fbe411 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -99,13 +99,13 @@ struct BuildAirToolbarWindow : Window { } } - virtual void OnPlaceObject(Point pt, TileIndex tile) { switch (this->last_user_action) { - case WID_AT_AIRPORT: - PlaceAirport(tile); + case WID_AT_AIRPORT: { + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_BUILD_STATION); break; + } case WID_AT_DEMOLISH: PlaceProc_DemolishArea(tile); @@ -122,8 +122,16 @@ struct BuildAirToolbarWindow : Window { virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) { - if (pt.x != -1 && select_proc == DDSP_DEMOLISH_AREA) { - GUIPlaceProcDragXY(select_proc, start_tile, end_tile); + if (pt.x == -1) return; + switch (select_proc) { + case DDSP_BUILD_STATION: + assert(start_tile == end_tile); + PlaceAirport(end_tile); + break; + case DDSP_DEMOLISH_AREA: + GUIPlaceProcDragXY(select_proc, start_tile, end_tile); + break; + default: NOT_REACHED(); } } diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index 89e925073a..de8016c2e5 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -26,6 +26,7 @@ #include "company_base.h" #include "hotkeys.h" #include "gui.h" +#include "bridge_map.h" #include "widgets/dock_widget.h" @@ -172,33 +173,21 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_LOCK: // Build lock button - DoCommandP(tile, 0, 0, CMD_BUILD_LOCK | CMD_MSG(STR_ERROR_CAN_T_BUILD_LOCKS), CcBuildDocks); + /* Reuse DDSP_REMOVE_TRUCKSTOP. */ + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_REMOVE_TRUCKSTOP); break; case WID_DT_DEMOLISH: // Demolish aka dynamite button PlaceProc_DemolishArea(tile); break; + case WID_DT_STATION: // Build station button + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_BUILD_STATION); + break; + case WID_DT_DEPOT: // Build depot button - DoCommandP(tile, _ship_depot_direction, 0, CMD_BUILD_SHIP_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_SHIP_DEPOT), CcBuildDocks); - break; - - case WID_DT_STATION: { // Build station button - uint32 p2 = (uint32)INVALID_STATION << 16; // no station to join - - /* tile is always the land tile, so need to evaluate _thd.pos */ - CommandContainer cmdcont = { tile, _ctrl_pressed, p2, CMD_BUILD_DOCK | CMD_MSG(STR_ERROR_CAN_T_BUILD_DOCK_HERE), CcBuildDocks, "" }; - - /* Determine the watery part of the dock. */ - DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile)); - TileIndex tile_to = (dir != INVALID_DIAGDIR ? TileAddByDiagDir(tile, ReverseDiagDir(dir)) : tile); - - ShowSelectStationIfNeeded(cmdcont, TileArea(tile, tile_to)); - break; - } - case WID_DT_BUOY: // Build buoy button - DoCommandP(tile, 0, 0, CMD_BUILD_BUOY | CMD_MSG(STR_ERROR_CAN_T_POSITION_BUOY_HERE), CcBuildDocks); + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_SINGLE_TILE); break; case WID_DT_RIVER: // Build river button (in scenario editor) @@ -206,7 +195,7 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_BUILD_AQUEDUCT: // Build aqueduct button - DoCommandP(tile, GetOtherAqueductEnd(tile), TRANSPORT_WATER << 15, CMD_BUILD_BRIDGE | CMD_MSG(STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE), CcBuildBridge); + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_BUILD_BRIDGE); break; default: NOT_REACHED(); @@ -215,7 +204,16 @@ struct BuildDocksToolbarWindow : Window { virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) { - VpSelectTilesWithMethod(pt.x, pt.y, select_method); + switch (last_clicked_widget) { + case WID_DT_BUILD_AQUEDUCT: + case WID_DT_LOCK: + case WID_DT_STATION: + this->OnPlacePresize(pt, TileVirtXY(pt.x, pt.y)); + break; + default: + VpSelectTilesWithMethod(pt.x, pt.y, select_method); + break; + } } virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) @@ -231,6 +229,42 @@ struct BuildDocksToolbarWindow : Window { case DDSP_CREATE_RIVER: DoCommandP(end_tile, start_tile, WATER_CLASS_RIVER, CMD_BUILD_CANAL | CMD_MSG(STR_ERROR_CAN_T_PLACE_RIVERS), CcBuildCanal); break; + case DDSP_BUILD_STATION: { + uint32 p2 = (uint32)INVALID_STATION << 16; // no station to join + + /* Tile is always the land tile, so need to evaluate _thd.pos. */ + CommandContainer cmdcont = { start_tile, _ctrl_pressed, p2, CMD_BUILD_DOCK | CMD_MSG(STR_ERROR_CAN_T_BUILD_DOCK_HERE), CcBuildDocks, "" }; + + //SetObjectToPlace(SPR_CURSOR_DOCK, PAL_NONE, HT_SPECIAL, this->window_class, this->window_number); + ShowSelectStationIfNeeded(cmdcont, TileArea(start_tile, end_tile)); + VpStartPreSizing(); + break; + } + + case DDSP_BUILD_BRIDGE: + DoCommandP(start_tile, GetOtherAqueductEnd(start_tile), TRANSPORT_WATER << 15, CMD_BUILD_BRIDGE | CMD_MSG(STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE), CcBuildBridge); + VpStartPreSizing(); + break; + + case DDSP_REMOVE_TRUCKSTOP: { // Reusing for locks. + TileIndex middle_tile = start_tile; + if (start_tile != end_tile) middle_tile = TileAddByDiagDir(start_tile, DiagdirBetweenTiles(start_tile, end_tile)); + DoCommandP(middle_tile, 0, 0, CMD_BUILD_LOCK | CMD_MSG(STR_ERROR_CAN_T_BUILD_LOCKS), CcBuildDocks); + VpStartPreSizing(); + break; + } + + case DDSP_SINGLE_TILE: + assert(start_tile == end_tile); + switch (last_clicked_widget) { + case WID_DT_BUOY: + DoCommandP(end_tile, 0, 0, CMD_BUILD_BUOY | CMD_MSG(STR_ERROR_CAN_T_POSITION_BUOY_HERE), CcBuildDocks); + break; + case WID_DT_DEPOT: // Build depot button + DoCommandP(end_tile, _ship_depot_direction, 0, CMD_BUILD_SHIP_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_SHIP_DEPOT), CcBuildDocks); + break; + default: NOT_REACHED(); + } default: break; } @@ -249,6 +283,7 @@ struct BuildDocksToolbarWindow : Window { virtual void OnPlacePresize(Point pt, TileIndex tile_from) { + if (!IsValidTile(tile_from)) return; TileIndex tile_to = tile_from; if (this->last_clicked_widget == WID_DT_BUILD_AQUEDUCT) { diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 45a62a7fd3..60519fd388 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -544,6 +544,19 @@ public: virtual void OnPlaceObject(Point pt, TileIndex tile) { + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_SINGLE_TILE); + } + + virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) + { + VpSelectTilesWithMethod(pt.x, pt.y, select_method); + } + + virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) + { + if (pt.x == -1) return; + assert(end_tile == start_tile); + bool success = true; /* We do not need to protect ourselves against "Random Many Industries" in this mode */ const IndustrySpec *indsp = GetIndustrySpec(this->selected_type); @@ -561,14 +574,14 @@ public: _generating_world = true; _ignore_restrictions = true; - DoCommandP(tile, (InteractiveRandomRange(indsp->num_table) << 8) | this->selected_type, seed, + DoCommandP(end_tile, (InteractiveRandomRange(indsp->num_table) << 8) | this->selected_type, seed, CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY), &CcBuildIndustry); cur_company.Restore(); _ignore_restrictions = false; _generating_world = false; } else { - success = DoCommandP(tile, (InteractiveRandomRange(indsp->num_table) << 8) | this->selected_type, seed, CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY)); + success = DoCommandP(end_tile, (InteractiveRandomRange(indsp->num_table) << 8) | this->selected_type, seed, CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY)); } /* If an industry has been built, just reset the cursor and the system */ diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 6b90d00a05..c8ed4a915c 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -252,22 +252,6 @@ static void GenericPlaceSignals(TileIndex tile) } } -/** - * Start placing a rail bridge. - * @param tile Position of the first tile of the bridge. - * @param w Rail toolbar window. - */ -static void PlaceRail_Bridge(TileIndex tile, Window *w) -{ - if (IsBridgeTile(tile)) { - TileIndex other_tile = GetOtherTunnelBridgeEnd(tile); - Point pt = {0, 0}; - w->OnPlaceMouseUp(VPM_X_OR_Y, DDSP_BUILD_BRIDGE, pt, other_tile, tile); - } else { - VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_BUILD_BRIDGE); - } -} - /** Command callback for building a tunnel */ void CcBuildRailTunnel(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) { @@ -632,9 +616,7 @@ struct BuildRailToolbarWindow : Window { break; case WID_RAT_BUILD_DEPOT: - DoCommandP(tile, _cur_railtype, _build_depot_direction, - CMD_BUILD_TRAIN_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT), - CcRailDepot); + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_SINGLE_TILE); break; case WID_RAT_BUILD_WAYPOINT: @@ -650,11 +632,11 @@ struct BuildRailToolbarWindow : Window { break; case WID_RAT_BUILD_BRIDGE: - PlaceRail_Bridge(tile, this); + VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_BUILD_BRIDGE); break; case WID_RAT_BUILD_TUNNEL: - DoCommandP(tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRailTunnel); + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_BUILD_BRIDGE); break; case WID_RAT_CONVERT_RAIL: @@ -670,6 +652,14 @@ struct BuildRailToolbarWindow : Window { /* no dragging if you have pressed the convert button */ if (FindWindowById(WC_BUILD_SIGNAL, 0) != NULL && _convert_signal_button && this->IsWidgetLowered(WID_RAT_BUILD_SIGNALS)) return; + switch (this->last_user_action) { + case WID_RAT_BUILD_TUNNEL: + this->OnPlacePresize(pt, TileVirtXY(pt.x, pt.y)); + return; + default: + break; + } + VpSelectTilesWithMethod(pt.x, pt.y, select_method); } @@ -678,9 +668,21 @@ struct BuildRailToolbarWindow : Window { if (pt.x != -1) { switch (select_proc) { default: NOT_REACHED(); + case DDSP_PLACE_AUTOROAD: + assert(this->last_user_action == WID_RAT_BUILD_BRIDGE); case DDSP_BUILD_BRIDGE: - if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); - ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_RAIL, _cur_railtype); + switch (this->last_user_action) { + case WID_RAT_BUILD_TUNNEL: + if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); + else VpStartPreSizing(); + DoCommandP(end_tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRailTunnel); + break; + case WID_RAT_BUILD_BRIDGE: + if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); + ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_RAIL, _cur_railtype); + break; + default: NOT_REACHED(); + } break; case DDSP_PLACE_RAIL: @@ -722,6 +724,14 @@ struct BuildRailToolbarWindow : Window { } } break; + + case DDSP_SINGLE_TILE: + assert(end_tile == start_tile); + assert(last_user_action == WID_RAT_BUILD_DEPOT); + DoCommandP(end_tile, _cur_railtype, _build_depot_direction, + CMD_BUILD_TRAIN_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT), + CcRailDepot); + break; } } } @@ -740,10 +750,19 @@ struct BuildRailToolbarWindow : Window { DeleteWindowByClass(WC_BUILD_BRIDGE); } - virtual void OnPlacePresize(Point pt, TileIndex tile) + virtual void OnPlacePresize(Point pt, TileIndex tile_from) { - DoCommand(tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, DC_AUTO, CMD_BUILD_TUNNEL); - VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile); + TileIndex tile_to = tile_from; + + if (this->last_user_action == WID_RAT_BUILD_BRIDGE) { + tile_to = IsBridgeTile(tile_from) ? GetOtherBridgeEnd(tile_from) : TileVirtXY(pt.x, pt.y); + } else { + assert(this->last_user_action == WID_RAT_BUILD_TUNNEL); + DoCommand(tile_from, _cur_railtype | (TRANSPORT_RAIL << 8), 0, DC_AUTO, CMD_BUILD_TUNNEL); + tile_to = _build_tunnel_endtile == 0 ? tile_from : _build_tunnel_endtile; + } + + VpSetPresizeRange(tile_from, tile_to); } virtual EventState OnCTRLStateChange() diff --git a/src/road_gui.cpp b/src/road_gui.cpp index e0b83758ca..f5266ff9fd 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -66,21 +66,6 @@ void CcPlaySound1D(const CommandCost &result, TileIndex tile, uint32 p1, uint32 if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_1F_SPLAT, tile); } -/** - * Callback to start placing a bridge. - * @param tile Start tile of the bridge. - */ -static void PlaceRoad_Bridge(TileIndex tile, Window *w) -{ - if (IsBridgeTile(tile)) { - TileIndex other_tile = GetOtherTunnelBridgeEnd(tile); - Point pt = {0, 0}; - w->OnPlaceMouseUp(VPM_X_OR_Y, DDSP_BUILD_BRIDGE, pt, other_tile, tile); - } else { - VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_BUILD_BRIDGE); - } -} - /** * Callback executed after a build road tunnel command has been called. * @@ -508,8 +493,7 @@ struct BuildRoadToolbarWindow : Window { break; case WID_ROT_DEPOT: - DoCommandP(tile, _cur_roadtype << 2 | _road_depot_orientation, 0, - CMD_BUILD_ROAD_DEPOT | CMD_MSG(_road_type_infos[_cur_roadtype].err_depot), CcRoadDepot); + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_SINGLE_TILE); break; case WID_ROT_BUS_STATION: @@ -521,12 +505,11 @@ struct BuildRoadToolbarWindow : Window { break; case WID_ROT_BUILD_BRIDGE: - PlaceRoad_Bridge(tile, this); + VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_BUILD_BRIDGE); break; case WID_ROT_BUILD_TUNNEL: - DoCommandP(tile, RoadTypeToRoadTypes(_cur_roadtype) | (TRANSPORT_ROAD << 8), 0, - CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRoadTunnel); + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_BUILD_BRIDGE); break; default: NOT_REACHED(); @@ -583,7 +566,6 @@ struct BuildRoadToolbarWindow : Window { /* Set dir = Y */ _place_road_flag |= RF_DIR_Y; } - break; default: @@ -599,8 +581,19 @@ struct BuildRoadToolbarWindow : Window { switch (select_proc) { default: NOT_REACHED(); case DDSP_BUILD_BRIDGE: - if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); - ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_ROAD, RoadTypeToRoadTypes(_cur_roadtype)); + switch (last_started_action) { + case WID_ROT_BUILD_TUNNEL: + if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); + else VpStartPreSizing(); + DoCommandP(end_tile, RoadTypeToRoadTypes(_cur_roadtype) | (TRANSPORT_ROAD << 8), 0, + CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRoadTunnel); + break; + case WID_ROT_BUILD_BRIDGE: + if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); + ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_ROAD, RoadTypeToRoadTypes(_cur_roadtype)); + break; + default: NOT_REACHED(); + } break; case DDSP_DEMOLISH_AREA: @@ -641,6 +634,14 @@ struct BuildRoadToolbarWindow : Window { DoCommandP(ta.tile, ta.w | ta.h << 8, ROADSTOP_TRUCK, CMD_REMOVE_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_remove_station[ROADSTOP_TRUCK]), CcPlaySound1D); break; } + + case DDSP_SINGLE_TILE: + /* Build depot. */ + assert(start_tile == end_tile); + assert(last_started_action == WID_ROT_DEPOT); + DoCommandP(start_tile, _cur_roadtype << 2 | _road_depot_orientation, 0, + CMD_BUILD_ROAD_DEPOT | CMD_MSG(_road_type_infos[_cur_roadtype].err_depot), CcRoadDepot); + break; } } } diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index be85e8a0b1..e87d16bb58 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -239,15 +239,9 @@ struct TerraformToolbarWindow : Window { break; case WID_TT_BUY_LAND: // Buy land button - DoCommandP(tile, OBJECT_OWNED_LAND, 0, CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_PURCHASE_THIS_LAND), CcPlaySound1E); - break; - case WID_TT_PLACE_SIGN: // Place sign button - PlaceProc_Sign(tile); - break; - case WID_TT_PLACE_OBJECT: // Place object button - PlaceProc_Object(tile); + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_SINGLE_TILE); break; default: NOT_REACHED(); @@ -270,6 +264,21 @@ struct TerraformToolbarWindow : Window { case DDSP_LEVEL_AREA: GUIPlaceProcDragXY(select_proc, start_tile, end_tile); break; + + case DDSP_SINGLE_TILE: + assert(start_tile == end_tile); + switch (this->last_user_action) { + case WID_TT_BUY_LAND: + DoCommandP(end_tile, OBJECT_OWNED_LAND, 0, CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_PURCHASE_THIS_LAND), CcPlaySound1E); + break; + case WID_TT_PLACE_SIGN: + PlaceProc_Sign(end_tile); + break; + case WID_TT_PLACE_OBJECT: + PlaceProc_Object(end_tile); + break; + default: NOT_REACHED(); + } } } } diff --git a/src/town_gui.cpp b/src/town_gui.cpp index e6ad46e33b..85bc255fee 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -1164,7 +1164,18 @@ public: virtual void OnPlaceObject(Point pt, TileIndex tile) { - this->ExecuteFoundTownCommand(tile, false, STR_ERROR_CAN_T_FOUND_TOWN_HERE, CcFoundTown); + VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_SINGLE_TILE); + } + + virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) + { + VpSelectTilesWithMethod(pt.x, pt.y, select_method); + } + + virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) + { + assert(start_tile == end_tile); + this->ExecuteFoundTownCommand(end_tile, false, STR_ERROR_CAN_T_FOUND_TOWN_HERE, CcFoundTown); } virtual void OnPlaceObjectAbort()