diff options
Diffstat (limited to 'src/station.cpp')
-rw-r--r-- | src/station.cpp | 64 |
1 files changed, 51 insertions, 13 deletions
diff --git a/src/station.cpp b/src/station.cpp index 43b659476..edfbf7d49 100644 --- a/src/station.cpp +++ b/src/station.cpp @@ -13,6 +13,7 @@ #include "company_func.h" #include "company_base.h" #include "roadveh.h" +#include "layer_func.h" #include "viewport_func.h" #include "date_func.h" #include "command_func.h" @@ -24,6 +25,7 @@ #include "roadstop_base.h" #include "industry.h" #include "core/random_func.hpp" +#include "cargodest_func.h" #include "table/strings.h" @@ -93,6 +95,9 @@ Station::~Station() if (v->last_station_visited == this->index) { v->last_station_visited = INVALID_STATION; } + if (v->last_station_loaded == this->index) { + v->last_station_loaded = INVALID_STATION; + } } /* Clear the persistent storage. */ @@ -118,6 +123,7 @@ Station::~Station() } CargoPacket::InvalidateAllFrom(this->index); + InvalidateStationRouteLinks(this); } @@ -307,8 +313,8 @@ static bool FindIndustryToDeliver(TileIndex ind_tile, void *user_data) if (riv->industries_near->Contains(ind)) return false; /* Only process tiles in the station acceptance rectangle */ - int x = TileX(ind_tile); - int y = TileY(ind_tile); + int x = LayerX(ind_tile); + int y = LayerY(ind_tile); if (x < riv->rect.left || x > riv->rect.right || y < riv->rect.top || y > riv->rect.bottom) return false; /* Include only industries that can accept cargo */ @@ -338,7 +344,8 @@ void Station::RecomputeIndustriesNear() }; /* Compute maximum extent of acceptance rectangle wrt. station sign */ - TileIndex start_tile = this->xy; + /* Охватываем верхнюю территорию */ + TileIndex start_tile = TopTile(this->xy); uint max_radius = max( max(DistanceManhattan(start_tile, TileXY(riv.rect.left, riv.rect.top)), DistanceManhattan(start_tile, TileXY(riv.rect.left, riv.rect.bottom))), max(DistanceManhattan(start_tile, TileXY(riv.rect.right, riv.rect.top)), DistanceManhattan(start_tile, TileXY(riv.rect.right, riv.rect.bottom))) @@ -373,7 +380,7 @@ void StationRect::MakeEmpty() /** * Determines whether a given point (x, y) is within a certain distance of * the station rectangle. - * @note x and y are in Tile coordinates + * @note x and y are in Tile coordinates (in top layer) * @param x X coordinate * @param y Y coordinate * @param distance The maximum distance a point may have (L1 norm) @@ -385,6 +392,23 @@ bool StationRect::PtInExtendedRect(int x, int y, int distance) const this->top - distance <= y && y <= this->bottom + distance; } +/** + * Determines whether a tile area intersects the station rectangle with a given offset. + * @param area The tile area to test. + * @param distance Offset the station rect is grown on all sides (L1 norm). + * @return True if the tile area intersects with the station rectangle. + */ +bool StationRect::AreaInExtendedRect(const TileArea& area, int distance) const +{ + int area_left = TileX(area.tile); + int area_right = area_left + area.w; + int area_top = TileY(area.tile); + int area_bottom = area_top + area.h; + + return this->left - distance <= area_right && area_left <= this->right + distance && + this->top - distance <= area_bottom && area_top <= this->bottom + distance; +} + bool StationRect::IsEmpty() const { return this->left == 0 || this->left > this->right || this->top > this->bottom; @@ -392,8 +416,10 @@ bool StationRect::IsEmpty() const CommandCost StationRect::BeforeAddTile(TileIndex tile, StationRectMode mode) { - int x = TileX(tile); - int y = TileY(tile); + /* Станция может находится на любом уровне. + * Но охватывает только поверхность */ + int x = LayerX(tile); + int y = LayerY(tile); if (this->IsEmpty()) { /* we are adding the first station tile */ if (mode != ADD_TEST) { @@ -446,18 +472,25 @@ CommandCost StationRect::BeforeAddRect(TileIndex tile, int w, int h, StationRect */ /* static */ bool StationRect::ScanForStationTiles(StationID st_id, int left_a, int top_a, int right_a, int bottom_a) { + /* Станция может находится на любом уровне. + * Значит надо обойти все слои */ TileArea ta(TileXY(left_a, top_a), TileXY(right_a, bottom_a)); - TILE_AREA_LOOP(tile, ta) { - if (IsTileType(tile, MP_STATION) && GetStationIndex(tile) == st_id) return true; - } + FOR_ALL_LAYERS(layer) { + ta.tile += layer * LayerSize(); + TILE_AREA_LOOP(tile, ta) { + if (IsTileType(tile, MP_STATION) && GetStationIndex(tile) == st_id) return true; + } + } return false; } bool StationRect::AfterRemoveTile(BaseStation *st, TileIndex tile) { - int x = TileX(tile); - int y = TileY(tile); + /* Станция может находится на любом уровне. + * Но охватывает только поверхность */ + int x = LayerX(tile); + int y = LayerY(tile); /* look if removed tile was on the bounding rect edge * and try to reduce the rect by this edge @@ -506,8 +539,13 @@ bool StationRect::AfterRemoveTile(BaseStation *st, TileIndex tile) bool StationRect::AfterRemoveRect(BaseStation *st, TileArea ta) { - assert(this->PtInExtendedRect(TileX(ta.tile), TileY(ta.tile))); - assert(this->PtInExtendedRect(TileX(ta.tile) + ta.w - 1, TileY(ta.tile) + ta.h - 1)); + /* Станция может находится на любом уровне. + * Но охватывает только поверхность */ + int topx = LayerX(ta.tile); + int topy = LayerY(ta.tile); + + assert(this->PtInExtendedRect(topx, topy)); + assert(this->PtInExtendedRect(topx + ta.w - 1, topy + ta.h - 1)); bool empty = this->AfterRemoveTile(st, ta.tile); if (ta.w != 1 || ta.h != 1) empty = empty || this->AfterRemoveTile(st, TILE_ADDXY(ta.tile, ta.w - 1, ta.h - 1)); |