From 81d335b081db006ddb883e2452f73984442f9823 Mon Sep 17 00:00:00 2001 From: peter1138 Date: Sat, 30 Mar 2019 16:59:43 +0000 Subject: Feature: Add station coverage area display for towns. --- src/script/api/game/game_window.hpp.sq | 1 + src/script/api/script_window.hpp | 1 + src/town_gui.cpp | 18 ++++++++++++ src/viewport.cpp | 51 +++++++++++++++++++++++++++++++++- src/viewport_func.h | 2 ++ src/widgets/town_widget.h | 1 + 6 files changed, 73 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/script/api/game/game_window.hpp.sq b/src/script/api/game/game_window.hpp.sq index d1966e3d8..3d190f44f 100644 --- a/src/script/api/game/game_window.hpp.sq +++ b/src/script/api/game/game_window.hpp.sq @@ -1261,6 +1261,7 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TV_CENTER_VIEW, "WID_TV_CENTER_VIEW"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TV_SHOW_AUTHORITY, "WID_TV_SHOW_AUTHORITY"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TV_CHANGE_NAME, "WID_TV_CHANGE_NAME"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TV_CATCHMENT, "WID_TV_CATCHMENT"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TV_EXPAND, "WID_TV_EXPAND"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TV_DELETE, "WID_TV_DELETE"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TF_NEW_TOWN, "WID_TF_NEW_TOWN"); diff --git a/src/script/api/script_window.hpp b/src/script/api/script_window.hpp index 8c133e998..47c848888 100644 --- a/src/script/api/script_window.hpp +++ b/src/script/api/script_window.hpp @@ -2500,6 +2500,7 @@ public: WID_TV_CENTER_VIEW = ::WID_TV_CENTER_VIEW, ///< Center the main view on this town. WID_TV_SHOW_AUTHORITY = ::WID_TV_SHOW_AUTHORITY, ///< Show the town authority window. WID_TV_CHANGE_NAME = ::WID_TV_CHANGE_NAME, ///< Change the name of this town. + WID_TV_CATCHMENT = ::WID_TV_CATCHMENT, ///< Toggle catchment area highlight. WID_TV_EXPAND = ::WID_TV_EXPAND, ///< Expand this town (scenario editor only). WID_TV_DELETE = ::WID_TV_DELETE, ///< Delete this town (scenario editor only). }; diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 07f0d638d..ebc696994 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -321,11 +321,24 @@ public: this->SetWidgetDisabledState(WID_TV_CHANGE_NAME, _networking && !_network_server); } + ~TownViewWindow() + { + SetViewportCatchmentTown(Town::Get(this->window_number), false); + } + void SetStringParameters(int widget) const override { if (widget == WID_TV_CAPTION) SetDParam(0, this->town->index); } + void OnPaint() override + { + extern const Town *_viewport_highlight_town; + this->SetWidgetLoweredState(WID_TV_CATCHMENT, _viewport_highlight_town == this->town); + + this->DrawWidgets(); + } + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_TV_INFO) return; @@ -432,6 +445,10 @@ public: ShowQueryString(STR_TOWN_NAME, STR_TOWN_VIEW_RENAME_TOWN_BUTTON, MAX_LENGTH_TOWN_NAME_CHARS, this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT | QSF_LEN_IN_CHARS); break; + case WID_TV_CATCHMENT: + SetViewportCatchmentTown(Town::Get(this->window_number), !this->IsWidgetLowered(WID_TV_CATCHMENT)); + break; + case WID_TV_EXPAND: { // expand town - only available on Scenario editor /* Warn the user if towns are not allowed to build roads, but do this only once per OpenTTD run. */ static bool _warn_town_no_roads = false; @@ -552,6 +569,7 @@ static const NWidgetPart _nested_town_game_view_widgets[] = { NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_SHOW_AUTHORITY), SetMinimalSize(80, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_TOWN_VIEW_LOCAL_AUTHORITY_BUTTON, STR_TOWN_VIEW_LOCAL_AUTHORITY_TOOLTIP), NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_CHANGE_NAME), SetMinimalSize(80, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_BUTTON_RENAME, STR_TOWN_VIEW_RENAME_TOOLTIP), EndContainer(), + NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TV_CATCHMENT), SetMinimalSize(14, 12), SetFill(0, 1), SetDataTip(STR_BUTTON_CATCHMENT, STR_TOOLTIP_CATCHMENT), NWidget(WWT_RESIZEBOX, COLOUR_BROWN), EndContainer(), }; diff --git a/src/viewport.cpp b/src/viewport.cpp index 27e8f2eca..8ec315b16 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -983,9 +983,11 @@ enum TileHighlightType { THT_NONE, THT_WHITE, THT_BLUE, + THT_RED, }; const Station *_viewport_highlight_station; ///< Currently selected station for coverage area highlight +const Town *_viewport_highlight_town; ///< Currently selected town for coverage area highlight /** * Get tile highlight type of coverage area for a given tile. @@ -999,6 +1001,24 @@ static TileHighlightType GetTileHighlightType(TileIndex t) if (_viewport_highlight_station->TileIsInCatchment(t)) return THT_BLUE; } + if (_viewport_highlight_town != nullptr) { + if (IsTileType(t, MP_HOUSE)) { + if (GetTownIndex(t) == _viewport_highlight_town->index) { + TileHighlightType type = THT_RED; + for (const Station *st : _viewport_highlight_town->stations_near) { + if (st->owner != _current_company) continue; + if (st->TileIsInCatchment(t)) return THT_BLUE; + } + return type; + } + } else if (IsTileType(t, MP_STATION)) { + for (const Station *st : _viewport_highlight_town->stations_near) { + if (st->owner != _current_company) continue; + if (GetStationIndex(t) == st->index) return THT_WHITE; + } + } + } + return THT_NONE; } @@ -1014,6 +1034,7 @@ static void DrawTileHighlightType(const TileInfo *ti, TileHighlightType tht) case THT_NONE: break; case THT_WHITE: DrawTileSelectionRect(ti, PAL_NONE); break; case THT_BLUE: DrawTileSelectionRect(ti, PALETTE_SEL_TILE_BLUE); break; + case THT_RED: DrawTileSelectionRect(ti, PALETTE_TILE_RED_PULSATING); break; } } @@ -1084,7 +1105,7 @@ draw_inner: } /* Check if it's inside the outer area? */ - if (!is_redsq && tht == THT_NONE && _thd.outersize.x > 0 && + if (!is_redsq && (tht == THT_NONE || tht == THT_RED) && _thd.outersize.x > 0 && IsInsideBS(ti->x, _thd.pos.x + _thd.offs.x, _thd.size.x + _thd.outersize.x) && IsInsideBS(ti->y, _thd.pos.y + _thd.offs.y, _thd.size.y + _thd.outersize.y)) { /* Draw a blue rect. */ @@ -3388,6 +3409,10 @@ CommandCost CmdScrollViewport(TileIndex tile, DoCommandFlag flags, uint32 p1, ui static void MarkCatchmentTilesDirty() { + if (_viewport_highlight_town != nullptr) { + MarkWholeScreenDirty(); + return; + } if (_viewport_highlight_station != nullptr) { if (_viewport_highlight_station->catchment_tiles.tile == INVALID_TILE) { MarkWholeScreenDirty(); @@ -3403,15 +3428,18 @@ static void MarkCatchmentTilesDirty() /** * Select or deselect station for coverage area highlight. + * Selecting a station will deselect a town. * @param *st Station in question * @param sel Select or deselect given station */ void SetViewportCatchmentStation(const Station *st, bool sel) { if (_viewport_highlight_station != nullptr) SetWindowDirty(WC_STATION_VIEW, _viewport_highlight_station->index); + if (_viewport_highlight_town != nullptr) SetWindowDirty(WC_TOWN_VIEW, _viewport_highlight_town->index); if (sel && _viewport_highlight_station != st) { MarkCatchmentTilesDirty(); _viewport_highlight_station = st; + _viewport_highlight_town = nullptr; MarkCatchmentTilesDirty(); } else if (!sel && _viewport_highlight_station == st) { MarkCatchmentTilesDirty(); @@ -3419,3 +3447,24 @@ void SetViewportCatchmentStation(const Station *st, bool sel) } if (_viewport_highlight_station != nullptr) SetWindowDirty(WC_STATION_VIEW, _viewport_highlight_station->index); } + +/** + * Select or deselect town for coverage area highlight. + * Selecting a town will deselect a station. + * @param *t Town in question + * @param sel Select or deselect given town + */ +void SetViewportCatchmentTown(const Town *t, bool sel) +{ + if (_viewport_highlight_town != nullptr) SetWindowDirty(WC_TOWN_VIEW, _viewport_highlight_town->index); + if (_viewport_highlight_station != nullptr) SetWindowDirty(WC_STATION_VIEW, _viewport_highlight_station->index); + if (sel && _viewport_highlight_town != t) { + _viewport_highlight_station = nullptr; + _viewport_highlight_town = t; + MarkWholeScreenDirty(); + } else if (!sel && _viewport_highlight_town == t) { + _viewport_highlight_town = nullptr; + MarkWholeScreenDirty(); + } + if (_viewport_highlight_town != nullptr) SetWindowDirty(WC_TOWN_VIEW, _viewport_highlight_town->index); +} diff --git a/src/viewport_func.h b/src/viewport_func.h index 12d59d5c0..8b23cc02a 100644 --- a/src/viewport_func.h +++ b/src/viewport_func.h @@ -95,7 +95,9 @@ static inline void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset = Point GetViewportStationMiddle(const ViewPort *vp, const Station *st); struct Station; +struct Town; void SetViewportCatchmentStation(const Station *st, bool sel); +void SetViewportCatchmentTown(const Town *t, bool sel); #endif /* VIEWPORT_FUNC_H */ diff --git a/src/widgets/town_widget.h b/src/widgets/town_widget.h index 4f5443c36..2559423ce 100644 --- a/src/widgets/town_widget.h +++ b/src/widgets/town_widget.h @@ -39,6 +39,7 @@ enum TownViewWidgets { WID_TV_CENTER_VIEW, ///< Center the main view on this town. WID_TV_SHOW_AUTHORITY, ///< Show the town authority window. WID_TV_CHANGE_NAME, ///< Change the name of this town. + WID_TV_CATCHMENT, ///< Toggle catchment area highlight. WID_TV_EXPAND, ///< Expand this town (scenario editor only). WID_TV_DELETE, ///< Delete this town (scenario editor only). }; -- cgit v1.2.3-54-g00ecf