diff options
-rw-r--r-- | src/gui.h | 1 | ||||
-rw-r--r-- | src/rail_gui.cpp | 9 | ||||
-rw-r--r-- | src/station_cmd.cpp | 88 |
3 files changed, 69 insertions, 29 deletions
@@ -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; } |