summaryrefslogtreecommitdiff
path: root/src/station_cmd.cpp
diff options
context:
space:
mode:
authorErich Eckner <git@eckner.net>2018-10-30 11:13:12 +0100
committerErich Eckner <git@eckner.net>2022-01-16 21:58:15 +0100
commit0c5ba5b7bf9a9dfa78c026f4da656940a460f47d (patch)
treed2a44494bbd70425b8f9e0e22b8c4e4dd8223001 /src/station_cmd.cpp
parent523901887827768d6bff347ddb57787b295cc9e1 (diff)
downloadopenttd-0c5ba5b7bf9a9dfa78c026f4da656940a460f47d.tar.xz
underground patch applied
Diffstat (limited to 'src/station_cmd.cpp')
-rw-r--r--src/station_cmd.cpp71
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);