From b6733edd172cb8488f81245addf613152f8a8015 Mon Sep 17 00:00:00 2001 From: peter1138 Date: Fri, 22 Feb 2019 18:14:06 +0000 Subject: [PATCH] Feature: Add coverage area display for existing stations. --- src/lang/english.txt | 2 + src/script/api/game/game_window.hpp.sq | 1 + src/script/api/script_window.hpp | 1 + src/settings.cpp | 1 + src/station_gui.cpp | 16 ++++++ src/viewport.cpp | 77 +++++++++++++++++++++++++- src/viewport_func.h | 4 ++ src/widgets/station_widget.h | 1 + 8 files changed, 102 insertions(+), 1 deletion(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index fc50711692..83a28d8cdc 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -237,6 +237,8 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Select f STR_BUTTON_SORT_BY :{BLACK}Sort by STR_BUTTON_LOCATION :{BLACK}Location STR_BUTTON_RENAME :{BLACK}Rename +STR_BUTTON_CATCHMENT :{BLACK}Coverage +STR_TOOLTIP_CATCHMENT :{BLACK}Toggle coverage area display STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Close window STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Window title - drag this to move window diff --git a/src/script/api/game/game_window.hpp.sq b/src/script/api/game/game_window.hpp.sq index 162c0bf0c1..d1966e3d8d 100644 --- a/src/script/api/game/game_window.hpp.sq +++ b/src/script/api/game/game_window.hpp.sq @@ -1117,6 +1117,7 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SV_ROADVEHS, "WID_SV_ROADVEHS"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SV_SHIPS, "WID_SV_SHIPS"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SV_PLANES, "WID_SV_PLANES"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SV_CATCHMENT, "WID_SV_CATCHMENT"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_STL_CAPTION, "WID_STL_CAPTION"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_STL_LIST, "WID_STL_LIST"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_STL_SCROLLBAR, "WID_STL_SCROLLBAR"); diff --git a/src/script/api/script_window.hpp b/src/script/api/script_window.hpp index a56307cb0e..8c133e9983 100644 --- a/src/script/api/script_window.hpp +++ b/src/script/api/script_window.hpp @@ -2289,6 +2289,7 @@ public: WID_SV_ROADVEHS = ::WID_SV_ROADVEHS, ///< List of scheduled road vehs button. WID_SV_SHIPS = ::WID_SV_SHIPS, ///< List of scheduled ships button. WID_SV_PLANES = ::WID_SV_PLANES, ///< List of scheduled planes button. + WID_SV_CATCHMENT = ::WID_SV_CATCHMENT, ///< Toggle catchment area highlight. }; /** Widgets of the #CompanyStationsWindow class. */ diff --git a/src/settings.cpp b/src/settings.cpp index b111f87282..5c0dc4a984 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1320,6 +1320,7 @@ static bool ChangeMaxHeightLevel(int32 p1) static bool StationCatchmentChanged(int32 p1) { Station::RecomputeCatchmentForAll(); + MarkWholeScreenDirty(); return true; } diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 4e6b94caf6..1cc6a126ff 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -785,6 +785,7 @@ static const NWidgetPart _nested_station_view_widgets[] = { EndContainer(), NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SV_CLOSE_AIRPORT), SetMinimalSize(45, 12), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_STATION_VIEW_CLOSE_AIRPORT, STR_STATION_VIEW_CLOSE_AIRPORT_TOOLTIP), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SV_CATCHMENT), SetMinimalSize(14, 12), SetFill(0, 1), SetDataTip(STR_BUTTON_CATCHMENT, STR_TOOLTIP_CATCHMENT), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SV_TRAINS), SetMinimalSize(14, 12), SetFill(0, 1), SetDataTip(STR_TRAIN, STR_STATION_VIEW_SCHEDULED_TRAINS_TOOLTIP), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SV_ROADVEHS), SetMinimalSize(14, 12), SetFill(0, 1), SetDataTip(STR_LORRY, STR_STATION_VIEW_SCHEDULED_ROAD_VEHICLES_TOOLTIP), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SV_SHIPS), SetMinimalSize(14, 12), SetFill(0, 1), SetDataTip(STR_SHIP, STR_STATION_VIEW_SCHEDULED_SHIPS_TOOLTIP), @@ -1313,6 +1314,8 @@ struct StationViewWindow : public Window { DeleteWindowById(WC_ROADVEH_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_ROAD, this->owner, this->window_number).Pack(), false); DeleteWindowById(WC_SHIPS_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_SHIP, this->owner, this->window_number).Pack(), false); DeleteWindowById(WC_AIRCRAFT_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_AIRCRAFT, this->owner, this->window_number).Pack(), false); + + SetViewportCatchmentStation(Station::Get(this->window_number), false); } /** @@ -1402,6 +1405,10 @@ struct StationViewWindow : public Window { this->SetWidgetDisabledState(WID_SV_CLOSE_AIRPORT, !(st->facilities & FACIL_AIRPORT) || st->owner != _local_company || st->owner == OWNER_NONE); // Also consider SE, where _local_company == OWNER_NONE this->SetWidgetLoweredState(WID_SV_CLOSE_AIRPORT, (st->facilities & FACIL_AIRPORT) && (st->airport.flags & AIRPORT_CLOSED_block) != 0); + extern const Station *_viewport_highlight_station; + this->SetWidgetDisabledState(WID_SV_CATCHMENT, st->facilities == FACIL_NONE); + this->SetWidgetLoweredState(WID_SV_CATCHMENT, _viewport_highlight_station == st); + this->DrawWidgets(); if (!this->IsShaded()) { @@ -1883,6 +1890,10 @@ struct StationViewWindow : public Window { this->HandleCargoWaitingClick(this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SV_WAITING, WD_FRAMERECT_TOP, FONT_HEIGHT_NORMAL) - this->vscroll->GetPosition()); break; + case WID_SV_CATCHMENT: + SetViewportCatchmentStation(Station::Get(this->window_number), !this->IsWidgetLowered(WID_SV_CATCHMENT)); + break; + case WID_SV_LOCATION: if (_ctrl_pressed) { ShowExtraViewPortWindow(Station::Get(this->window_number)->xy); @@ -2247,6 +2258,11 @@ struct SelectStationWindow : Window { this->OnInvalidateData(0); } + ~SelectStationWindow() + { + if (_settings_client.gui.station_show_coverage) SetViewportCatchmentStation(nullptr, true); + } + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget != WID_JS_PANEL) return; diff --git a/src/viewport.cpp b/src/viewport.cpp index b3865f7639..c8ae46abdb 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -979,6 +979,44 @@ static void DrawAutorailSelection(const TileInfo *ti, uint autorail_type) DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : pal, ti, 7, foundation_part); } +enum TileHighlightType { + THT_NONE, + THT_WHITE, + THT_BLUE, +}; + +const Station *_viewport_highlight_station; ///< Currently selected station for coverage area highlight + +/** + * Get tile highlight type of coverage area for a given tile. + * @param t Tile that is being drawn + * @return Tile highlight type to draw + */ +static TileHighlightType GetTileHighlightType(TileIndex t) +{ + if (_viewport_highlight_station != nullptr) { + if (IsTileType(t, MP_STATION) && GetStationIndex(t) == _viewport_highlight_station->index) return THT_WHITE; + if (_viewport_highlight_station->TileIsInCatchment(t)) return THT_BLUE; + } + + return THT_NONE; +} + +/** + * Draw tile highlight for coverage area highlight. + * @param *ti TileInfo Tile that is being drawn + * @param tht Highlight type to draw. + */ +static void DrawTileHighlightType(const TileInfo *ti, TileHighlightType tht) +{ + switch (tht) { + default: + case THT_NONE: break; + case THT_WHITE: DrawTileSelectionRect(ti, PAL_NONE); break; + case THT_BLUE: DrawTileSelectionRect(ti, PALETTE_SEL_TILE_BLUE); break; + } +} + /** * Checks if the specified tile is selected and if so draws selection using correct selectionstyle. * @param *ti TileInfo Tile that is being drawn @@ -989,6 +1027,9 @@ static void DrawTileSelection(const TileInfo *ti) bool is_redsq = _thd.redsq == ti->tile; if (is_redsq) DrawTileSelectionRect(ti, PALETTE_TILE_RED_PULSATING); + TileHighlightType tht = GetTileHighlightType(ti->tile); + DrawTileHighlightType(ti, tht); + /* No tile selection active? */ if ((_thd.drawstyle & HT_DRAG_MASK) == HT_NONE) return; @@ -1043,7 +1084,7 @@ draw_inner: } /* Check if it's inside the outer area? */ - if (!is_redsq && _thd.outersize.x > 0 && + if (!is_redsq && tht == THT_NONE && _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. */ @@ -3342,3 +3383,37 @@ CommandCost CmdScrollViewport(TileIndex tile, DoCommandFlag flags, uint32 p1, ui } return CommandCost(); } + +static void MarkCatchmentTilesDirty() +{ + if (_viewport_highlight_station != nullptr) { + if (_viewport_highlight_station->catchment_tiles.tile == INVALID_TILE) { + MarkWholeScreenDirty(); + _viewport_highlight_station = nullptr; + } else { + BitmapTileIterator it(_viewport_highlight_station->catchment_tiles); + for (TileIndex tile = it; tile != INVALID_TILE; tile = ++it) { + MarkTileDirtyByTile(tile); + } + } + } +} + +/** + * Select or deselect station for coverage area highlight. + * @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 (sel && _viewport_highlight_station != st) { + MarkCatchmentTilesDirty(); + _viewport_highlight_station = st; + MarkCatchmentTilesDirty(); + } else if (!sel && _viewport_highlight_station == st) { + MarkCatchmentTilesDirty(); + _viewport_highlight_station = nullptr; + } + if (_viewport_highlight_station != nullptr) SetWindowDirty(WC_STATION_VIEW, _viewport_highlight_station->index); +} diff --git a/src/viewport_func.h b/src/viewport_func.h index 9bfb428900..12d59d5c0c 100644 --- a/src/viewport_func.h +++ b/src/viewport_func.h @@ -94,4 +94,8 @@ static inline void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset = Point GetViewportStationMiddle(const ViewPort *vp, const Station *st); +struct Station; + +void SetViewportCatchmentStation(const Station *st, bool sel); + #endif /* VIEWPORT_FUNC_H */ diff --git a/src/widgets/station_widget.h b/src/widgets/station_widget.h index 82fe392e33..f9b5b266ab 100644 --- a/src/widgets/station_widget.h +++ b/src/widgets/station_widget.h @@ -30,6 +30,7 @@ enum StationViewWidgets { WID_SV_ROADVEHS, ///< List of scheduled road vehs button. WID_SV_SHIPS, ///< List of scheduled ships button. WID_SV_PLANES, ///< List of scheduled planes button. + WID_SV_CATCHMENT, ///< Toggle catchment area highlight. }; /** Widgets of the #CompanyStationsWindow class. */