summaryrefslogtreecommitdiff
path: root/src/station.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/station.cpp')
-rw-r--r--src/station.cpp64
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));