From a3890d4e5f97d78080143fe87433dfcfb0714634 Mon Sep 17 00:00:00 2001 From: Pavel Stupnikov Date: Tue, 4 Feb 2020 01:38:22 +0300 Subject: [PATCH] Draw border highlight as ground sprites instead of a sortable ones --- src/citymania/zoning.cpp | 57 ++++++++++++++++++++++++++++++++++++++++ src/citymania/zoning.hpp | 16 +++++++++++ src/rev.cpp | 2 +- src/viewport.cpp | 11 ++++++-- src/zoning_cmd.cpp | 16 ++++++----- 5 files changed, 93 insertions(+), 9 deletions(-) diff --git a/src/citymania/zoning.cpp b/src/citymania/zoning.cpp index 0d137ee9e4..38c06d2930 100644 --- a/src/citymania/zoning.cpp +++ b/src/citymania/zoning.cpp @@ -10,6 +10,15 @@ #include "../viewport_func.h" #include "../zoning.h" +/** Enumeration of multi-part foundations */ +enum FoundationPart { + FOUNDATION_PART_NONE = 0xFF, ///< Neither foundation nor groundsprite drawn yet. + FOUNDATION_PART_NORMAL = 0, ///< First part (normal foundation or no foundation) + FOUNDATION_PART_HALFTILE = 1, ///< Second part (halftile foundation) + FOUNDATION_PART_END +}; +extern void DrawSelectionSprite(SpriteID image, PaletteID pal, const TileInfo *ti, int z_offset, FoundationPart foundation_part); // viewport.cpp + namespace citymania { struct TileZoning { @@ -18,6 +27,54 @@ struct TileZoning { TileZoning *_mz = nullptr; +const byte _tileh_to_sprite[32] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, + 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 17, 0, 15, 18, 0, +}; + + +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; + if (b) { + DrawSelectionSprite(tile_sprite + b - 1, color, ti, 7, FOUNDATION_PART_NORMAL); + } + if (border & ZoningBorder::TOP_CORNER) + DrawSelectionSprite(tile_sprite + 15, color, ti, 7, FOUNDATION_PART_NORMAL); + if (border & ZoningBorder::RIGHT_CORNER) + DrawSelectionSprite(tile_sprite + 16, color, ti, 7, FOUNDATION_PART_NORMAL); + if (border & ZoningBorder::BOTTOM_CORNER) + DrawSelectionSprite(tile_sprite + 17, color, ti, 7, FOUNDATION_PART_NORMAL); + if (border & ZoningBorder::LEFT_CORNER) + DrawSelectionSprite(tile_sprite + 18, color, ti, 7, FOUNDATION_PART_NORMAL); +} + +TileHighlight GetTileHighlight(const TileInfo *ti) { + TileHighlight th; + if (_zoning.outer == CHECKTOWNZONES) { + auto p = GetTownZoneBorder(ti->tile); + th.border = p.first; + switch (p.second) { + default: th.border_color = SPR_PALETTE_ZONING_WHITE; break; // Tz0 + case 2: th.border_color = SPR_PALETTE_ZONING_YELLOW; break; // Tz1 + case 3: th.border_color = SPR_PALETTE_ZONING_ORANGE; break; // Tz2 + case 4: th.border_color = SPR_PALETTE_ZONING_ORANGE; break; // Tz3 + case 5: th.border_color = SPR_PALETTE_ZONING_RED; break; // Tz4 - center + }; + } else if (_zoning.outer == CHECKBULUNSER || _zoning.outer == CHECKINDUNSER) { + // handled in house drawing + } else if (_zoning.outer == CHECKSTACATCH) { + th.border = citymania::GetAnyStationCatchmentBorder(ti->tile); + th.border_color = SPR_PALETTE_ZONING_LIGHT_BLUE; + } + return th; +} + +void DrawTileSelection(const TileInfo *ti, const TileHighlight &th) { + if (th.border != ZoningBorder::NONE) + DrawBorderSprites(ti, th.border, th.border_color); +} + void AllocateZoningMap(uint map_size) { free(_mz); _mz = CallocT(map_size); diff --git a/src/citymania/zoning.hpp b/src/citymania/zoning.hpp index 6971087679..5d540357ba 100644 --- a/src/citymania/zoning.hpp +++ b/src/citymania/zoning.hpp @@ -4,9 +4,12 @@ #include "../core/enum_type.hpp" #include "../gfx_type.h" #include "../industry_type.h" +#include "../tile_cmd.h" #include "../tile_type.h" #include "../town_type.h" +#include "../table/sprites.h" + namespace citymania { ////enum class ZoningBorder : unt8 { @@ -22,6 +25,14 @@ enum ZoningBorder: uint8 { LEFT_CORNER = 128, }; +class TileHighlight { +public: + SpriteID ground_pal = PAL_NONE; + SpriteID structure_pal = PAL_NONE; + ZoningBorder border = ZoningBorder::NONE; + SpriteID border_color; +}; + DECLARE_ENUM_AS_BIT_SET(ZoningBorder); // enum class AdvertisementZone: uint8 { @@ -32,6 +43,9 @@ DECLARE_ENUM_AS_BIT_SET(ZoningBorder); // }; +TileHighlight GetTileHighlight(const TileInfo *ti); +void DrawTileSelection(const TileInfo *ti, const TileHighlight &th); + void AllocateZoningMap(uint map_size); void InitializeZoningMap(); @@ -44,6 +58,8 @@ ZoningBorder GetAnyStationCatchmentBorder(TileIndex tlie); // SpriteID GetTownTileZoningPalette(TileIndex tile); SpriteID GetIndustryTileZoningPalette(TileIndex tile, Industry *ind); + + } // namespace citymania #endif diff --git a/src/rev.cpp b/src/rev.cpp index 07939457f0..16bc31d965 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[] = "!!VERSION!! !!DATE!!"; +const char _citymania_version[] = "20200203-master-md10a631d93 03.02.20"; diff --git a/src/viewport.cpp b/src/viewport.cpp index aebb587c98..4bdd7fbf2c 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -99,6 +99,8 @@ #include "zoning.h" #include "industry_type.h" +#include "citymania/zoning.hpp" + #include "safeguards.h" Point _tile_fract_coords; @@ -202,6 +204,8 @@ struct ViewportDrawer { FoundationPart foundation_part; ///< Currently active foundation for ground sprite drawing. int *last_foundation_child[FOUNDATION_PART_END]; ///< Tail of ChildSprite list of the foundations. (index into child_screen_sprites_to_draw) Point foundation_offset[FOUNDATION_PART_END]; ///< Pixel offset for ground sprites on the foundations. + + citymania::TileHighlight zoning; }; static void MarkViewportDirty(const ViewPort *vp, int left, int top, int right, int bottom); @@ -557,7 +561,7 @@ static void AddTileSpriteToDraw(SpriteID image, PaletteID pal, int32 x, int32 y, * @param extra_offs_x Pixel X offset for the sprite position. * @param extra_offs_y Pixel Y offset for the sprite position. */ -static void AddChildSpriteToFoundation(SpriteID image, PaletteID pal, const SubSprite *sub, FoundationPart foundation_part, int extra_offs_x, int extra_offs_y) +void AddChildSpriteToFoundation(SpriteID image, PaletteID pal, const SubSprite *sub, FoundationPart foundation_part, int extra_offs_x, int extra_offs_y) { assert(IsInsideMM(foundation_part, 0, FOUNDATION_PART_END)); assert(_vd.foundation[foundation_part] != -1); @@ -911,7 +915,7 @@ static void AddStringToDraw(int x, int y, StringID string, uint64 params_1, uint * @param z_offset Z offset relative to the groundsprite. Only used for the sprite position, not for sprite sorting. * @param foundation_part Foundation part the sprite belongs to. */ -static void DrawSelectionSprite(SpriteID image, PaletteID pal, const TileInfo *ti, int z_offset, FoundationPart foundation_part) +void DrawSelectionSprite(SpriteID image, PaletteID pal, const TileInfo *ti, int z_offset, FoundationPart foundation_part) { /* FIXME: This is not totally valid for some autorail highlights that extend over the edges of the tile. */ if (_vd.foundation[foundation_part] == -1) { @@ -1114,6 +1118,9 @@ static void DrawTileSelection(const TileInfo *ti) /* Highlight tiles insede local authority of selected towns. */ HighlightTownLocalAuthorityTiles(ti); + auto cmth = citymania::GetTileHighlight(ti); + citymania::DrawTileSelection(ti, cmth); + /* Draw a red error square? */ bool is_redsq = _thd.redsq == ti->tile; if (is_redsq) DrawTileSelectionRect(ti, PALETTE_TILE_RED_PULSATING); diff --git a/src/zoning_cmd.cpp b/src/zoning_cmd.cpp index 3be28d4aa6..fd53cd6f8c 100644 --- a/src/zoning_cmd.cpp +++ b/src/zoning_cmd.cpp @@ -418,19 +418,23 @@ void DrawBorderSprites(const TileInfo *ti, citymania::ZoningBorder border, Sprit * the tile to draw on. */ void DrawTileZoning(const TileInfo *ti) { + + // AddSortableSpriteToDraw((SPR_FLAT_BARE_LAND|(1U << PALETTE_MODIFIER_TRANSPARENT)) + _tileh_to_sprite[ti->tileh], + // SPR_RECOLOUR_RED, ti->x, ti->y, 0x10, 0x10, 1, ti->z); + // AddSortableSpriteToDraw(SPR_FLAT_BARE_LAND + _tileh_to_sprite[ti->tileh], SPR_RECOLOUR_RED, ti->x, ti->y, 0x10, 0x10, 1, ti->z + 7, false); if(_zoning.outer == CHECKNOTHING && _zoning.inner == CHECKNOTHING) return; //nothing to do if (_game_mode != GM_NORMAL || ti->tile >= MapSize() || IsTileType(ti->tile, MP_VOID)) return; //check invalid if (_zoning.outer != CHECKNOTHING){ if (_zoning.outer == CHECKTOWNZONES) { - auto p = citymania::GetTownZoneBorder(ti->tile); - if (p.first && p.second) { - DrawBorderSprites(ti, p.first, GetTownZoneBorderColor(p.second)); - } + // auto p = citymania::GetTownZoneBorder(ti->tile); + // if (p.first && p.second) { + // DrawBorderSprites(ti, p.first, GetTownZoneBorderColor(p.second)); + // } } else if (_zoning.outer == CHECKBULUNSER || _zoning.outer == CHECKINDUNSER) { // handled in house drawing } else if (_zoning.outer == CHECKSTACATCH) { - auto b = citymania::GetAnyStationCatchmentBorder(ti->tile); - DrawBorderSprites(ti, b, SPR_PALETTE_ZONING_LIGHT_BLUE); + // 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); }