Make outer station catchment zoning use border highlight

This commit is contained in:
dP
2019-11-04 16:48:59 +03:00
parent 5a7f1e894a
commit b9e442a63a
5 changed files with 38 additions and 22 deletions

View File

@@ -96,16 +96,16 @@ void InitializeZoningMap() {
template <typename F>
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<ZoningBorder, uint8> GetTownZoneBorder(TileIndex tile) {
template <typename F>
std::pair<ZoningBorder, uint8> 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<ZoningBorder, uint8> GetTownZoneBorder(TileIndex tile) {
return std::make_pair(res, z);
}
std::pair<ZoningBorder, uint8> 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

View File

@@ -35,8 +35,10 @@ void InitializeZoningMap();
void UpdateTownZoning(Town *town, uint32 prev_edge);
std::pair<ZoningBorder, uint8> GetTownZoneBorder(TileIndex tile);
std::pair<ZoningBorder, uint8> GetTownAdvertisementBorder(TileIndex tile);
ZoningBorder GetAnyStationCatchmentBorder(TileIndex tlie);
// std::pair<ZoningBorder, uint8> GetTownAdvertisementBorder(TileIndex tile);
} // namespace citymania

View File

@@ -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()
{

View File

@@ -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<StationID, decltype(&Kdtree_StationXYFunc), uint16, int> StationKdtree;
class Kdtree_StationXYFunc {
public:
uint16 operator()(StationID stid, int dim) const;
};
typedef Kdtree<StationID, Kdtree_StationXYFunc, uint16, int> StationKdtree;
extern StationKdtree _station_kdtree;
/**

View File

@@ -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);
}