summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gui.h1
-rw-r--r--src/rail_gui.cpp9
-rw-r--r--src/station_cmd.cpp88
3 files changed, 69 insertions, 29 deletions
diff --git a/src/gui.h b/src/gui.h
index 290e33ec5..71be707a6 100644
--- a/src/gui.h
+++ b/src/gui.h
@@ -75,6 +75,7 @@ enum { // max 32 - 4 = 28 types
GUI_PlaceProc_WaterArea = 3 << 4,
GUI_PlaceProc_ConvertRailArea = 4 << 4,
GUI_PlaceProc_RockyArea = 5 << 4,
+ GUI_PlaceProc_RemoveFromStation = 6 << 4,
};
/* misc_gui.cpp */
diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp
index d6571e4f6..18fd4e0f6 100644
--- a/src/rail_gui.cpp
+++ b/src/rail_gui.cpp
@@ -151,7 +151,7 @@ void CcStation(bool success, TileIndex tile, uint32 p1, uint32 p2)
static void PlaceRail_Station(TileIndex tile)
{
if (_remove_button_clicked) {
- DoCommandP(tile, 0, 0, CcPlaySound1E, CMD_REMOVE_FROM_RAILROAD_STATION | CMD_MSG(STR_CANT_REMOVE_PART_OF_STATION));
+ VpStartPlaceSizing(tile, VPM_X_AND_Y | GUI_PlaceProc_RemoveFromStation);
} else if (_railstation.dragdrop) {
VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED);
VpSetPlaceSizingLimit(_patches.station_spread);
@@ -514,8 +514,13 @@ static void BuildRailToolbWndProc(Window *w, WindowEvent *e)
} else if ((e->we.place.userdata & 0xF) == VPM_X_AND_Y) {
if (GUIPlaceProcDragXY(e)) break;
- if ((e->we.place.userdata >> 4) == GUI_PlaceProc_ConvertRailArea >> 4)
+ if ((e->we.place.userdata >> 4) == GUI_PlaceProc_RemoveFromStation >> 4) {
+ DoCommandP(end_tile, start_tile, 0, CcPlaySound1E, CMD_REMOVE_FROM_RAILROAD_STATION | CMD_MSG(STR_CANT_REMOVE_PART_OF_STATION));
+ }
+
+ if ((e->we.place.userdata >> 4) == GUI_PlaceProc_ConvertRailArea >> 4) {
DoCommandP(end_tile, start_tile, _cur_railtype, CcPlaySound10, CMD_CONVERT_RAIL | CMD_MSG(STR_CANT_CONVERT_RAIL));
+ }
} else if (e->we.place.userdata == VPM_X_AND_Y_LIMITED) {
HandleStationPlacement(start_tile, end_tile);
} else {
diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp
index 7c0338985..74547ef2b 100644
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -1025,43 +1025,77 @@ restart:
* This allows for custom-built station with holes and weird layouts
* @param tile tile of station piece to remove
* @param flags operation to perform
- * @param p1 unused
+ * @param p1 start_tile
* @param p2 unused
*/
int32 CmdRemoveFromRailroadStation(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{
- SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+ TileIndex start = p1 == 0 ? tile : p1;
- // make sure the specified tile belongs to the current player, and that it is a railroad station.
- if (!IsTileType(tile, MP_STATION) || !IsRailwayStation(tile) || !_patches.nonuniform_stations) return CMD_ERROR;
- Station *st = GetStationByTile(tile);
- if (_current_player != OWNER_WATER && (!CheckOwnership(st->owner) || !EnsureNoVehicle(tile))) return CMD_ERROR;
+ /* Count of the number of tiles removed */
+ int quantity = 0;
- // if we reached here, it means we can actually delete it. do that.
- if (flags & DC_EXEC) {
- uint specindex = GetCustomStationSpecIndex(tile);
- Track track = GetRailStationTrack(tile);
- DoClearSquare(tile);
- st->rect.AfterRemoveTile(st, tile);
- SetSignalsOnBothDir(tile, track);
- YapfNotifyTrackLayoutChange(tile, track);
+ if (tile >= MapSize() || start >= MapSize()) return CMD_ERROR;
- DeallocateSpecFromStation(st, specindex);
+ /* make sure sx,sy are smaller than ex,ey */
+ int ex = TileX(tile);
+ int ey = TileY(tile);
+ int sx = TileX(start);
+ int sy = TileY(start);
+ if (ex < sx) Swap(ex, sx);
+ if (ey < sy) Swap(ey, sy);
+ tile = TileXY(sx, sy);
- // now we need to make the "spanned" area of the railway station smaller if we deleted something at the edges.
- // we also need to adjust train_tile.
- MakeRailwayStationAreaSmaller(st);
- st->MarkTilesDirty();
- UpdateStationSignCoord(st);
+ int size_x = ex - sx + 1;
+ int size_y = ey - sy + 1;
- // if we deleted the whole station, delete the train facility.
- if (st->train_tile == 0) {
- st->facilities &= ~FACIL_TRAIN;
- UpdateStationVirtCoordDirty(st);
- DeleteStationIfEmpty(st);
+ SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
+
+ /* Do the action for every tile into the area */
+ BEGIN_TILE_LOOP(tile2, size_x, size_y, tile) {
+ /* Make sure the specified tile belongs to the current player, and that it is a railroad station. */
+ if (!IsTileType(tile2, MP_STATION) || !IsRailwayStation(tile2) || !_patches.nonuniform_stations) {
+ continue;
}
- }
- return _price.remove_rail_station;
+
+ /* Check ownership of station */
+ Station *st = GetStationByTile(tile2);
+ if (_current_player != OWNER_WATER && (!CheckOwnership(st->owner) || !EnsureNoVehicle(tile2))) {
+ continue;
+ }
+
+ /* If we reached here, the tile is valid so increase the quantity of tiles we will remove */
+ quantity++;
+
+ if (flags & DC_EXEC) {
+ uint specindex = GetCustomStationSpecIndex(tile2);
+ Track track = GetRailStationTrack(tile2);
+ DoClearSquare(tile2);
+ st->rect.AfterRemoveTile(st, tile2);
+ SetSignalsOnBothDir(tile2, track);
+ YapfNotifyTrackLayoutChange(tile2, track);
+
+ DeallocateSpecFromStation(st, specindex);
+
+ // now we need to make the "spanned" area of the railway station smaller if we deleted something at the edges.
+ // we also need to adjust train_tile.
+ MakeRailwayStationAreaSmaller(st);
+ st->MarkTilesDirty();
+ UpdateStationSignCoord(st);
+
+ // if we deleted the whole station, delete the train facility.
+ if (st->train_tile == 0) {
+ st->facilities &= ~FACIL_TRAIN;
+ UpdateStationVirtCoordDirty(st);
+ DeleteStationIfEmpty(st);
+ }
+ }
+ } END_TILE_LOOP(tile2, size_x, size_y, tile)
+
+ /* If we've not removed any tiles, give an error */
+ if (quantity == 0) return CMD_ERROR;
+
+ return _price.remove_rail_station * quantity;
}