diff --git a/src/citymania/zoning.cpp b/src/citymania/zoning.cpp index fb0d0e736e..dba6c355fd 100644 --- a/src/citymania/zoning.cpp +++ b/src/citymania/zoning.cpp @@ -23,9 +23,12 @@ namespace citymania { struct TileZoning { uint8 town_zone : 3; + uint8 industry_fund_result : 2; + IndustryType industry_fund_type; }; -TileZoning *_mz = nullptr; +static TileZoning *_mz = nullptr; +static IndustryType _industry_forbidden_tiles = INVALID_INDUSTRYTYPE; const byte _tileh_to_sprite[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, @@ -33,6 +36,45 @@ const byte _tileh_to_sprite[32] = { }; +template +uint8 Get(uint32 x, uint32 y, F getter) { + if (x >= MapSizeX() || y >= MapSizeY()) return 0; + return getter(TileXY(x, y)); +} + +template +std::pair CalcTileBorders(TileIndex tile, F getter) { + auto x = TileX(tile), y = TileY(tile); + ZoningBorder res = ZoningBorder::NONE; + auto z = getter(tile); + if (z == 0) + return std::make_pair(res, 0); + auto tr = Get(x - 1, y, getter); + auto tl = Get(x, y - 1, getter); + auto bl = Get(x + 1, y, getter); + auto br = Get(x, y + 1, getter); + if (tr < z) res |= ZoningBorder::TOP_RIGHT; + if (tl < z) res |= ZoningBorder::TOP_LEFT; + if (bl < z) res |= ZoningBorder::BOTTOM_LEFT; + if (br < z) res |= ZoningBorder::BOTTOM_RIGHT; + if (tr == z && tl == z && Get(x - 1, y - 1, getter) < z) res |= ZoningBorder::TOP_CORNER; + if (tr == z && br == z && Get(x - 1, y + 1, getter) < z) res |= ZoningBorder::RIGHT_CORNER; + if (br == z && bl == z && Get(x + 1, y + 1, getter) < z) res |= ZoningBorder::BOTTOM_CORNER; + if (tl == z && bl == z && Get(x + 1, y - 1, getter) < z) res |= ZoningBorder::LEFT_CORNER; + return std::make_pair(res, z); +} + + +bool CanBuildIndustryOnTileCached(IndustryType type, TileIndex tile) { + if (_mz[tile].industry_fund_type != type || !_mz[tile].industry_fund_result) { + bool res = CanBuildIndustryOnTile(type, tile); + _mz[tile].industry_fund_type = type; + _mz[tile].industry_fund_result = res ? 2 : 1; + return res; + } + return (_mz[tile].industry_fund_result == 2); +} + void DrawBorderSprites(const TileInfo *ti, ZoningBorder border, SpriteID color) { auto b = (uint8)border & 15; auto tile_sprite = SPR_BORDER_HIGHLIGHT_BASE + _tileh_to_sprite[ti->tileh] * 19; @@ -128,6 +170,18 @@ TileHighlight GetTileHighlight(const TileInfo *ti) { auto pal = GetIndustryZoningPalette(ti->tile); if (pal) th.ground_pal = th.structure_pal = PALETTE_TINT_RED_DEEP; } + + if (_settings_client.gui.show_industry_forbidden_tiles && + _industry_forbidden_tiles != INVALID_INDUSTRYTYPE) { + auto b = CalcTileBorders(ti->tile, [](TileIndex t) { return !CanBuildIndustryOnTileCached(_industry_forbidden_tiles, t); }); + if(b.first != ZoningBorder::NONE) { + th.border = b.first; + th.border_color = SPR_PALETTE_ZONING_RED; + } + if (!CanBuildIndustryOnTileCached(_industry_forbidden_tiles, ti->tile)) + th.ground_pal = th.structure_pal = PALETTE_TINT_RED; + } + return th; } @@ -198,6 +252,10 @@ void UpdateTownZoning(Town *town, uint32 prev_edge) { // TODO mark dirty only if zoning is on TILE_AREA_LOOP(tile, area) { uint8 group = GetTownZone(town, tile); + + if (_mz[tile].town_zone != group) + _mz[tile].industry_fund_result = 0; + if (_mz[tile].town_zone > group) { if (recalc) { _mz[tile].town_zone = GetAnyTownZone(tile); @@ -217,35 +275,6 @@ void InitializeZoningMap() { UpdateTownZoning(t, 0); } } - -template -uint8 Get(uint32 x, uint32 y, F getter) { - if (x >= MapSizeX() || y >= MapSizeY()) return 0; - return getter(TileXY(x, y)); -} - -template -std::pair CalcTileBorders(TileIndex tile, F getter) { - auto x = TileX(tile), y = TileY(tile); - ZoningBorder res = ZoningBorder::NONE; - auto z = getter(tile); - if (z == 0) - return std::make_pair(res, 0); - auto tr = Get(x - 1, y, getter); - auto tl = Get(x, y - 1, getter); - auto bl = Get(x + 1, y, getter); - auto br = Get(x, y + 1, getter); - if (tr < z) res |= ZoningBorder::TOP_RIGHT; - if (tl < z) res |= ZoningBorder::TOP_LEFT; - if (bl < z) res |= ZoningBorder::BOTTOM_LEFT; - if (br < z) res |= ZoningBorder::BOTTOM_RIGHT; - if (tr == z && tl == z && Get(x - 1, y - 1, getter) < z) res |= ZoningBorder::TOP_CORNER; - if (tr == z && br == z && Get(x - 1, y + 1, getter) < z) res |= ZoningBorder::RIGHT_CORNER; - if (br == z && bl == z && Get(x + 1, y + 1, getter) < z) res |= ZoningBorder::BOTTOM_CORNER; - if (tl == z && bl == z && Get(x + 1, y - 1, getter) < z) res |= ZoningBorder::LEFT_CORNER; - return std::make_pair(res, z); -} - std::pair GetTownZoneBorder(TileIndex tile) { return CalcTileBorders(tile, [](TileIndex t) { return _mz[t].town_zone; }); } @@ -261,4 +290,12 @@ ZoningBorder GetAnyStationCatchmentBorder(TileIndex tile) { return border; } +void SetIndustryForbiddenTilesHighlight(IndustryType type) { + if (_settings_client.gui.show_industry_forbidden_tiles && + _industry_forbidden_tiles != type) { + MarkWholeScreenDirty(); + } + _industry_forbidden_tiles = type; +} + } // namespace citymania diff --git a/src/citymania/zoning.hpp b/src/citymania/zoning.hpp index c346c7c786..851e186596 100644 --- a/src/citymania/zoning.hpp +++ b/src/citymania/zoning.hpp @@ -61,7 +61,7 @@ ZoningBorder GetAnyStationCatchmentBorder(TileIndex tlie); // SpriteID GetTownTileZoningPalette(TileIndex tile); SpriteID GetIndustryTileZoningPalette(TileIndex tile, Industry *ind); - +void SetIndustryForbiddenTilesHighlight(IndustryType type); } // namespace citymania diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 20ded0f822..29a4939e7d 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -44,6 +44,8 @@ #include +#include "citymania/zoning.hpp" + #include "safeguards.h" bool _ignore_restrictions; @@ -335,7 +337,7 @@ class BuildIndustryWindow : public Window { if (this->selected_index == -1) { this->selected_index = 0; this->selected_type = this->index[0]; - SetIndustryForbiddenTilesHighlight(this->selected_type); + citymania::SetIndustryForbiddenTilesHighlight(this->selected_type); } this->vscroll->SetCount(this->count); @@ -418,7 +420,7 @@ public: ~BuildIndustryWindow() { - SetIndustryForbiddenTilesHighlight(INVALID_INDUSTRYTYPE); + citymania::SetIndustryForbiddenTilesHighlight(INVALID_INDUSTRYTYPE); } void OnInit() override @@ -607,7 +609,7 @@ public: if (y < this->count) { // Is it within the boundaries of available data? this->selected_index = y; this->selected_type = this->index[y]; - SetIndustryForbiddenTilesHighlight(this->selected_type); + citymania::SetIndustryForbiddenTilesHighlight(this->selected_type); const IndustrySpec *indsp = (this->selected_type == INVALID_INDUSTRYTYPE) ? nullptr : GetIndustrySpec(this->selected_type); this->SetDirty(); diff --git a/src/rev.cpp b/src/rev.cpp index f507c0b488..7872b64cb3 100644 --- a/src/rev.cpp +++ b/src/rev.cpp @@ -83,4 +83,4 @@ const byte _openttd_revision_tagged = 1; const uint32 _openttd_newgrf_version = 1 << 28 | 10 << 24 | 0 << 20 | 0 << 19 | 28004; -const char _citymania_version[] = "20200204-master-ma3890d4e5f 04.02.20"; +const char _citymania_version[] = "20200205-master-mabbc38728e 05.02.20"; diff --git a/src/tilehighlight_func.h b/src/tilehighlight_func.h index 9aee5da7b1..5ae06113c9 100644 --- a/src/tilehighlight_func.h +++ b/src/tilehighlight_func.h @@ -31,8 +31,6 @@ void VpSetPlaceSizingLimit(int limit); void UpdateTileSelection(); -void SetIndustryForbiddenTilesHighlight(IndustryType type); - RailSnapMode GetRailSnapMode(); void SetRailSnapMode(RailSnapMode mode); diff --git a/src/viewport.cpp b/src/viewport.cpp index 4671cd5e08..510f8fc258 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -219,8 +219,6 @@ bool _draw_dirty_blocks = false; uint _dirty_block_colour = 0; static VpSpriteSorter _vp_sprite_sorter = nullptr; -static IndustryType _industry_forbidden_tiles = INVALID_INDUSTRYTYPE; - static RailSnapMode _rail_snap_mode = RSM_NO_SNAP; ///< Type of rail track snapping (polyline tool). static LineSnapPoints _tile_snap_points; ///< Tile to which a rail track will be snapped to (polyline tool). static LineSnapPoints _rail_snap_points; ///< Set of points where a rail track will be snapped to (polyline tool). @@ -1185,22 +1183,6 @@ static void DrawTileSelection(const TileInfo *ti) } } -void SetIndustryForbiddenTilesHighlight(IndustryType type) { - if (_settings_client.gui.show_industry_forbidden_tiles && - _industry_forbidden_tiles != type) { - MarkWholeScreenDirty(); - } - _industry_forbidden_tiles = type; -} - -static void DrawIndustryForbiddenTiles(const TileInfo *ti) { - if (_settings_client.gui.show_industry_forbidden_tiles && - _industry_forbidden_tiles != INVALID_INDUSTRYTYPE && - !CanBuildIndustryOnTile(_industry_forbidden_tiles, ti->tile)) { - DrawTileSelectionRect(ti, PALETTE_SEL_TILE_RED); - } -} - /** * Returns the y coordinate in the viewport coordinate system where the given * tile is painted. @@ -1329,7 +1311,6 @@ static void ViewportAddLandscape() if (tile_info.tile != INVALID_TILE){ DrawTileZoning(&tile_info); citymania::DrawTileSelection(&tile_info, _vd.cm_highlight); - DrawIndustryForbiddenTiles(&tile_info); DrawTileSelection(&tile_info); } }