diff --git a/src/citymania/zoning.cpp b/src/citymania/zoning.cpp index 428bd834c5..8774e85d02 100644 --- a/src/citymania/zoning.cpp +++ b/src/citymania/zoning.cpp @@ -96,16 +96,16 @@ void InitializeZoningMap() { template uint8 Get(uint32 x, uint32 y, F getter) { if (x >= MapSizeX() || y >= MapSizeY()) return 0; - return getter(_mz[TileXY(x, y)]); + return getter(TileXY(x, y)); } -std::pair GetTownZoneBorder(TileIndex tile) { +template +std::pair CalcTileBorders(TileIndex tile, F getter) { auto x = TileX(tile), y = TileY(tile); ZoningBorder res = ZoningBorder::NONE; - auto z = _mz[tile].town_zone; + auto z = getter(tile); if (z == 0) return std::make_pair(res, 0); - auto getter = [](TileZoning tz) { return tz.town_zone; }; auto tr = Get(x - 1, y, getter); auto tl = Get(x, y - 1, getter); auto bl = Get(x + 1, y, getter); @@ -121,4 +121,19 @@ std::pair GetTownZoneBorder(TileIndex tile) { return std::make_pair(res, z); } +std::pair GetTownZoneBorder(TileIndex tile) { + return CalcTileBorders(tile, [](TileIndex t) { return _mz[t].town_zone; }); +} + +ZoningBorder GetAnyStationCatchmentBorder(TileIndex tile) { + ZoningBorder border = ZoningBorder::NONE; + StationFinder morestations(TileArea(tile, 1, 1)); + for (Station *st: *morestations.GetStations()) { + border |= CalcTileBorders(tile, [st](TileIndex t) {return st->TileIsInCatchment(t) ? 1 : 0; }).first; + } + if (border & ZoningBorder::TOP_CORNER && border & (ZoningBorder::TOP_LEFT | ZoningBorder::TOP_RIGHT)) + border &= ~ZoningBorder::TOP_CORNER; + return border; +} + } // namespace citymania diff --git a/src/citymania/zoning.hpp b/src/citymania/zoning.hpp index f21b8c25ac..2ab9611817 100644 --- a/src/citymania/zoning.hpp +++ b/src/citymania/zoning.hpp @@ -35,8 +35,10 @@ void InitializeZoningMap(); void UpdateTownZoning(Town *town, uint32 prev_edge); + std::pair GetTownZoneBorder(TileIndex tile); -std::pair GetTownAdvertisementBorder(TileIndex tile); +ZoningBorder GetAnyStationCatchmentBorder(TileIndex tlie); +// std::pair GetTownAdvertisementBorder(TileIndex tile); } // namespace citymania diff --git a/src/station.cpp b/src/station.cpp index 1cbd4a57b3..033aca4637 100644 --- a/src/station.cpp +++ b/src/station.cpp @@ -39,8 +39,12 @@ StationPool _station_pool("Station"); INSTANTIATE_POOL_METHODS(Station) +Kdtree_StationXYFunc kd_station_func; +StationKdtree _station_kdtree(kd_station_func); -StationKdtree _station_kdtree(Kdtree_StationXYFunc); +uint16 Kdtree_StationXYFunc::operator()(StationID stid, int dim) const { + return (dim == 0) ? TileX(BaseStation::Get(stid)->xy) : TileY(BaseStation::Get(stid)->xy); +} void RebuildStationKdtree() { diff --git a/src/station_kdtree.h b/src/station_kdtree.h index 321bbacc6f..d74b5bf307 100644 --- a/src/station_kdtree.h +++ b/src/station_kdtree.h @@ -15,8 +15,12 @@ #include "station_base.h" #include "map_func.h" -inline uint16 Kdtree_StationXYFunc(StationID stid, int dim) { return (dim == 0) ? TileX(BaseStation::Get(stid)->xy) : TileY(BaseStation::Get(stid)->xy); } -typedef Kdtree StationKdtree; +class Kdtree_StationXYFunc { +public: + uint16 operator()(StationID stid, int dim) const; +}; + +typedef Kdtree StationKdtree; extern StationKdtree _station_kdtree; /** diff --git a/src/zoning_cmd.cpp b/src/zoning_cmd.cpp index d14a5c919c..592885db71 100644 --- a/src/zoning_cmd.cpp +++ b/src/zoning_cmd.cpp @@ -148,18 +148,11 @@ bool IsAreaWithinAcceptanceZoneOfStation(TileArea area) { * @return true if a station is found */ bool IsTileWithinAcceptanceZoneOfStation(TileIndex tile) { - int catchment = _settings_game.station.station_spread + (_settings_game.station.modified_catchment ? MAX_CATCHMENT : CA_UNMODIFIED); - - StationFinder morestations(TileArea(TileXY(TileX(tile) - catchment / 2, TileY(tile) - catchment / 2), - catchment, catchment)); + StationFinder morestations(TileArea(tile, 1, 1)); for (Station *st: *morestations.GetStations()) { - Rect rect = st->GetCatchmentRect(); - if ((uint)rect.left <= TileX(tile) && TileX(tile) <= (uint)rect.right - && (uint)rect.top <= TileY(tile) && TileY(tile) <= (uint)rect.bottom ) - { + if (st->TileIsInCatchment(tile)) return true; - } } return false; } @@ -210,11 +203,6 @@ SpriteID TileZoneCheckBuildEvaluation(TileIndex tile, Owner owner) { if (IsTileType(tile, MP_STATION)){ return INVALID_SPRITE_ID; } - // For provided goods - StationFinder stations(TileArea(tile, 1, 1)); - if (!stations.GetStations()->empty()) { - return SPR_PALETTE_ZONING_GREEN; - } // For accepted goods if (IsTileWithinAcceptanceZoneOfStation(tile)){ return SPR_PALETTE_ZONING_LIGHT_BLUE; @@ -447,6 +435,9 @@ void DrawTileZoning(const TileInfo *ti) { if (p.first && p.second) { DrawBorderSprites(ti, p.first, GetTownZoneBorderColor(p.second)); } + } else if (_zoning.outer == CHECKSTACATCH) { + auto b = citymania::GetAnyStationCatchmentBorder(ti->tile); + DrawBorderSprites(ti, b, SPR_PALETTE_ZONING_LIGHT_BLUE); } else { DrawZoningSprites(SPR_SELECT_TILE, TileZoningSpriteEvaluation(ti->tile, _local_company, _zoning.outer), ti); }