diff options
author | Erich Eckner <git@eckner.net> | 2018-10-30 11:13:12 +0100 |
---|---|---|
committer | Erich Eckner <git@eckner.net> | 2022-01-16 21:58:15 +0100 |
commit | 0c5ba5b7bf9a9dfa78c026f4da656940a460f47d (patch) | |
tree | d2a44494bbd70425b8f9e0e22b8c4e4dd8223001 /src/station_cmd.cpp | |
parent | 523901887827768d6bff347ddb57787b295cc9e1 (diff) | |
download | openttd-0c5ba5b7bf9a9dfa78c026f4da656940a460f47d.tar.xz |
underground patch applied
Diffstat (limited to 'src/station_cmd.cpp')
-rw-r--r-- | src/station_cmd.cpp | 71 |
1 files changed, 48 insertions, 23 deletions
diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 5a91fa474..d833b0ef7 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -11,6 +11,7 @@ #include "aircraft.h" #include "bridge_map.h" #include "cmd_helper.h" +#include "layer_func.h" #include "viewport_func.h" #include "viewport_kdtree.h" #include "command_func.h" @@ -104,21 +105,24 @@ bool IsHangar(TileIndex t) * @return Succeeded command (if zero or one station found) or failed command (for two or more stations found). */ template <class T> -CommandCost GetStationAround(TileArea ta, StationID closest_station, CompanyID company, T **st) +CommandCost GetStationAround(TileArea ta, StationID closest_station, CompanyID company, T **st, bool layers=false) { ta.Expand(1); /* check around to see if there are any stations there owned by the company */ - for (TileIndex tile_cur : ta) { - if (IsTileType(tile_cur, MP_STATION)) { - StationID t = GetStationIndex(tile_cur); - if (!T::IsValidID(t) || Station::Get(t)->owner != company) continue; - if (closest_station == INVALID_STATION) { - closest_station = t; - } else if (closest_station != t) { - return_cmd_error(STR_ERROR_ADJOINS_MORE_THAN_ONE_EXISTING); + FOR_ALL_LAYERS(layer) { + for (TileIndex tile_cur : ta) { + if (IsTileType(tile_cur, MP_STATION)) { + StationID t = GetStationIndex(tile_cur); + if (!T::IsValidID(t) || Station::Get(t)->owner != company) continue; + if (closest_station == INVALID_STATION) { + closest_station = t; + } else if (closest_station != t) { + return_cmd_error(STR_ERROR_ADJOINS_MORE_THAN_ONE_EXISTING); + } } } + if (!layers) break; } *st = (closest_station == INVALID_STATION) ? nullptr : T::Get(closest_station); return CommandCost(); @@ -1073,11 +1077,13 @@ CommandCost CanExpandRailStation(const BaseStation *st, TileArea &new_ta, Axis a TileArea cur_ta = st->train_station; /* determine new size of train station region.. */ - int x = std::min(TileX(cur_ta.tile), TileX(new_ta.tile)); - int y = std::min(TileY(cur_ta.tile), TileY(new_ta.tile)); - new_ta.w = std::max(TileX(cur_ta.tile) + cur_ta.w, TileX(new_ta.tile) + new_ta.w) - x; - new_ta.h = std::max(TileY(cur_ta.tile) + cur_ta.h, TileY(new_ta.tile) + new_ta.h) - y; - new_ta.tile = TileXY(x, y); + /* Фактически, подземная станция ("эскалатор") больше ширины карты. + * Поэтому проверям размер в пределах одного слоя */ + int topx = std::min(LayerX(cur_ta.tile), LayerX(new_ta.tile)); + int topy = std::min(LayerY(cur_ta.tile), LayerY(new_ta.tile)); + new_ta.w = std::max(LayerX(cur_ta.tile) + cur_ta.w, LayerX(new_ta.tile) + new_ta.w) - topx; + new_ta.h = std::max(LayerY(cur_ta.tile) + cur_ta.h, LayerY(new_ta.tile) + new_ta.h) - topy; + new_ta.tile = TileXY(topx, topy); /* make sure the final size is not too big. */ if (new_ta.w > _settings_game.station.station_spread || new_ta.h > _settings_game.station.station_spread) { @@ -1149,7 +1155,7 @@ void GetStationLayout(byte *layout, uint numtracks, uint plat_len, const Station * @return command cost with the error or 'okay' */ template <class T, StringID error_message> -CommandCost FindJoiningBaseStation(StationID existing_station, StationID station_to_join, bool adjacent, TileArea ta, T **st) +CommandCost FindJoiningBaseStation(StationID existing_station, StationID station_to_join, bool adjacent, TileArea ta, T **st, bool layers=false) { assert(*st == nullptr); bool check_surrounding = true; @@ -1175,7 +1181,7 @@ CommandCost FindJoiningBaseStation(StationID existing_station, StationID station if (check_surrounding) { /* Make sure there is no more than one other station around us that is owned by us. */ - CommandCost ret = GetStationAround(ta, existing_station, _current_company, st); + CommandCost ret = GetStationAround(ta, existing_station, _current_company, st, layers); if (ret.Failed()) return ret; } @@ -1194,9 +1200,9 @@ CommandCost FindJoiningBaseStation(StationID existing_station, StationID station * @param st 'return' pointer for the found station * @return command cost with the error or 'okay' */ -static CommandCost FindJoiningStation(StationID existing_station, StationID station_to_join, bool adjacent, TileArea ta, Station **st) +static CommandCost FindJoiningStation(StationID existing_station, StationID station_to_join, bool adjacent, TileArea ta, Station **st, bool layers=false) { - return FindJoiningBaseStation<Station, STR_ERROR_MUST_REMOVE_RAILWAY_STATION_FIRST>(existing_station, station_to_join, adjacent, ta, st); + return FindJoiningBaseStation<Station, STR_ERROR_MUST_REMOVE_RAILWAY_STATION_FIRST>(existing_station, station_to_join, adjacent, ta, st, layers); } /** @@ -1332,8 +1338,10 @@ CommandCost CmdBuildRailStation(DoCommandFlag flags, TileIndex tile_org, RailTyp byte numtracks_orig; Track track; + TileIndex top_tile = TopTile(new_location.tile); st->train_station = new_location; - st->AddFacility(FACIL_TRAIN, new_location.tile); + st->train_station.tile = top_tile; + st->AddFacility(FACIL_TRAIN, tile_org); st->rect.BeforeAddRect(tile_org, w_org, h_org, StationRect::ADD_TRY); @@ -1711,11 +1719,16 @@ CommandCost RemoveRailStation(T *st, DoCommandFlag flags, Money removal_cost) /* determine width and height of platforms */ TileArea ta = st->train_station; - assert(ta.w != 0 && ta.h != 0); + /* TileArea is top finite area */ + assert(IsTopTile(ta.tile)); + assert(ta.IsFinite()); CommandCost cost(EXPENSES_CONSTRUCTION); + /* Check all layers */ + FOR_ALL_LAYERS(layer) /* clear all areas of the station */ - for (TileIndex tile : ta) { + for (TileIndex top_tile : ta) { + TileIndex tile = top_tile + layer * LayerSize(); /* only remove tiles that are actually train station tiles */ if (st->TileBelongsToRailStation(tile)) { std::vector<T*> affected_stations; // dummy @@ -2060,13 +2073,21 @@ CommandCost CmdRemoveRoadStop(DoCommandFlag flags, TileIndex tile, uint8 width, /* Bankrupting company is not supposed to remove roads, there may be road vehicles. */ if (remove_road && (flags & DC_BANKRUPT)) return CMD_ERROR; - TileArea roadstop_area(tile, width, height); + /* Это территория удаления остановок (НЕ самих остановок) */ + TileArea roadstop_area(TopTile(tile), width, height); + + /* TileArea is top finite area */ + assert(IsTopTile(roadstop_area.tile)); + assert(roadstop_area.IsFinite()); CommandCost cost(EXPENSES_CONSTRUCTION); CommandCost last_error(STR_ERROR_THERE_IS_NO_STATION); bool had_success = false; - for (TileIndex cur_tile : roadstop_area) { + /* Check all layers */ + FOR_ALL_LAYERS(layer) + for (TileIndex top_tile : roadstop_area) { + TileIndex cur_tile = top_tile + layer * LayerSize(); /* Make sure the specified tile is a road stop of the correct type */ if (!IsTileType(cur_tile, MP_STATION) || !IsRoadStop(cur_tile) || GetRoadStopType(cur_tile) != stop_type) continue; @@ -2230,6 +2251,10 @@ CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, byte airport_ty if (w > _settings_game.station.station_spread || h > _settings_game.station.station_spread) { return_cmd_error(STR_ERROR_STATION_TOO_SPREAD_OUT); } + /* can't make underground airport */ + if (IsUnderground(tile)) { + return_cmd_error(STR_ERROR_UNDERGROUND_CAN_T_BUILD_UNDER_GROUND); + } AirportTileTableIterator iter(as->table[layout], tile); CommandCost cost = CheckFlatLandAirport(iter, flags); |