mirror of https://github.com/OpenTTD/OpenTTD.git
Feature: Highlight waypoint tiles when adjacent or distant joining
This commit is contained in:
parent
84b53213af
commit
d7bf6b2c07
|
@ -422,6 +422,7 @@ struct BuildRailToolbarWindow : Window {
|
||||||
void Close() override
|
void Close() override
|
||||||
{
|
{
|
||||||
if (this->IsWidgetLowered(WID_RAT_BUILD_STATION)) SetViewportCatchmentStation(nullptr, true);
|
if (this->IsWidgetLowered(WID_RAT_BUILD_STATION)) SetViewportCatchmentStation(nullptr, true);
|
||||||
|
if (this->IsWidgetLowered(WID_RAT_BUILD_WAYPOINT)) SetViewportCatchmentWaypoint(nullptr, true);
|
||||||
if (_settings_client.gui.link_terraform_toolbar) CloseWindowById(WC_SCEN_LAND_GEN, 0, false);
|
if (_settings_client.gui.link_terraform_toolbar) CloseWindowById(WC_SCEN_LAND_GEN, 0, false);
|
||||||
CloseWindowById(WC_SELECT_STATION, 0);
|
CloseWindowById(WC_SELECT_STATION, 0);
|
||||||
this->Window::Close();
|
this->Window::Close();
|
||||||
|
@ -731,6 +732,7 @@ struct BuildRailToolbarWindow : Window {
|
||||||
void OnPlaceObjectAbort() override
|
void OnPlaceObjectAbort() override
|
||||||
{
|
{
|
||||||
if (this->IsWidgetLowered(WID_RAT_BUILD_STATION)) SetViewportCatchmentStation(nullptr, true);
|
if (this->IsWidgetLowered(WID_RAT_BUILD_STATION)) SetViewportCatchmentStation(nullptr, true);
|
||||||
|
if (this->IsWidgetLowered(WID_RAT_BUILD_WAYPOINT)) SetViewportCatchmentWaypoint(nullptr, true);
|
||||||
|
|
||||||
this->RaiseButtons();
|
this->RaiseButtons();
|
||||||
this->DisableWidget(WID_RAT_REMOVE);
|
this->DisableWidget(WID_RAT_REMOVE);
|
||||||
|
@ -757,6 +759,11 @@ struct BuildRailToolbarWindow : Window {
|
||||||
return ES_NOT_HANDLED;
|
return ES_NOT_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnRealtimeTick(uint delta_ms) override
|
||||||
|
{
|
||||||
|
if (this->IsWidgetLowered(WID_RAT_BUILD_WAYPOINT)) CheckRedrawWaypointCoverage(this);
|
||||||
|
}
|
||||||
|
|
||||||
static HotkeyList hotkeys;
|
static HotkeyList hotkeys;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2176,6 +2183,11 @@ struct BuildRailWaypointWindow : PickerWindowBase {
|
||||||
this->InvalidateData();
|
this->InvalidateData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnRealtimeTick(uint delta_ms) override
|
||||||
|
{
|
||||||
|
CheckRedrawWaypointCoverage(this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* static */ QueryString BuildRailWaypointWindow::editbox(BuildRailWaypointWindow::FILTER_LENGTH * MAX_CHAR_LENGTH, BuildRailWaypointWindow::FILTER_LENGTH);
|
/* static */ QueryString BuildRailWaypointWindow::editbox(BuildRailWaypointWindow::FILTER_LENGTH * MAX_CHAR_LENGTH, BuildRailWaypointWindow::FILTER_LENGTH);
|
||||||
|
|
|
@ -80,11 +80,12 @@ int DrawStationCoverageAreaText(int left, int right, int top, StationCoverageTyp
|
||||||
* Find stations adjacent to the current tile highlight area, so that existing coverage
|
* Find stations adjacent to the current tile highlight area, so that existing coverage
|
||||||
* area can be drawn.
|
* area can be drawn.
|
||||||
*/
|
*/
|
||||||
static void FindStationsAroundSelection()
|
template <typename T>
|
||||||
|
void FindStationsAroundSelection()
|
||||||
{
|
{
|
||||||
/* With distant join we don't know which station will be selected, so don't show any */
|
/* With distant join we don't know which station will be selected, so don't show any */
|
||||||
if (_ctrl_pressed) {
|
if (_ctrl_pressed) {
|
||||||
SetViewportCatchmentStation(nullptr, true);
|
SetViewportCatchmentSpecializedStation<T>(nullptr, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,15 +96,16 @@ static void FindStationsAroundSelection()
|
||||||
uint x = TileX(location.tile);
|
uint x = TileX(location.tile);
|
||||||
uint y = TileY(location.tile);
|
uint y = TileY(location.tile);
|
||||||
|
|
||||||
int max_c = 1;
|
/* Waypoints can only be built on existing rail tiles, so don't extend area if not highlighting a rail tile. */
|
||||||
|
int max_c = T::EXPECTED_FACIL == FACIL_WAYPOINT && !IsTileType(location.tile, MP_RAILWAY) ? 0 : 1;
|
||||||
TileArea ta(TileXY(std::max<int>(0, x - max_c), std::max<int>(0, y - max_c)), TileXY(std::min<int>(Map::MaxX(), x + location.w + max_c), std::min<int>(Map::MaxY(), y + location.h + max_c)));
|
TileArea ta(TileXY(std::max<int>(0, x - max_c), std::max<int>(0, y - max_c)), TileXY(std::min<int>(Map::MaxX(), x + location.w + max_c), std::min<int>(Map::MaxY(), y + location.h + max_c)));
|
||||||
|
|
||||||
Station *adjacent = nullptr;
|
T *adjacent = nullptr;
|
||||||
|
|
||||||
/* Direct loop instead of ForAllStationsAroundTiles as we are not interested in catchment area */
|
/* Direct loop instead of ForAllStationsAroundTiles as we are not interested in catchment area */
|
||||||
for (TileIndex tile : ta) {
|
for (TileIndex tile : ta) {
|
||||||
if (IsTileType(tile, MP_STATION) && GetTileOwner(tile) == _local_company) {
|
if (IsTileType(tile, MP_STATION) && GetTileOwner(tile) == _local_company) {
|
||||||
Station *st = Station::GetByTile(tile);
|
T *st = T::GetByTile(tile);
|
||||||
if (st == nullptr) continue;
|
if (st == nullptr) continue;
|
||||||
if (adjacent != nullptr && st != adjacent) {
|
if (adjacent != nullptr && st != adjacent) {
|
||||||
/* Multiple nearby, distant join is required. */
|
/* Multiple nearby, distant join is required. */
|
||||||
|
@ -113,7 +115,7 @@ static void FindStationsAroundSelection()
|
||||||
adjacent = st;
|
adjacent = st;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetViewportCatchmentStation(adjacent, true);
|
SetViewportCatchmentSpecializedStation<T>(adjacent, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -135,7 +137,25 @@ void CheckRedrawStationCoverage(const Window *w)
|
||||||
w->SetDirty();
|
w->SetDirty();
|
||||||
|
|
||||||
if (_settings_client.gui.station_show_coverage && _thd.drawstyle == HT_RECT) {
|
if (_settings_client.gui.station_show_coverage && _thd.drawstyle == HT_RECT) {
|
||||||
FindStationsAroundSelection();
|
FindStationsAroundSelection<Station>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckRedrawWaypointCoverage(const Window *w)
|
||||||
|
{
|
||||||
|
/* Test if ctrl state changed */
|
||||||
|
static bool _last_ctrl_pressed;
|
||||||
|
if (_ctrl_pressed != _last_ctrl_pressed) {
|
||||||
|
_thd.dirty = 0xff;
|
||||||
|
_last_ctrl_pressed = _ctrl_pressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_thd.dirty & 1) {
|
||||||
|
_thd.dirty &= ~1;
|
||||||
|
|
||||||
|
if (_thd.drawstyle == HT_RECT) {
|
||||||
|
FindStationsAroundSelection<Waypoint>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2255,7 +2275,7 @@ struct SelectStationWindow : Window {
|
||||||
|
|
||||||
void Close() override
|
void Close() override
|
||||||
{
|
{
|
||||||
if (_settings_client.gui.station_show_coverage) SetViewportCatchmentStation(nullptr, true);
|
SetViewportCatchmentSpecializedStation<T>(nullptr, true);
|
||||||
|
|
||||||
_thd.freeze = false;
|
_thd.freeze = false;
|
||||||
this->Window::Close();
|
this->Window::Close();
|
||||||
|
@ -2342,15 +2362,15 @@ struct SelectStationWindow : Window {
|
||||||
|
|
||||||
void OnMouseOver(Point pt, int widget) override
|
void OnMouseOver(Point pt, int widget) override
|
||||||
{
|
{
|
||||||
if (widget != WID_JS_PANEL || T::EXPECTED_FACIL == FACIL_WAYPOINT) {
|
if (widget != WID_JS_PANEL) {
|
||||||
SetViewportCatchmentStation(nullptr, true);
|
SetViewportCatchmentSpecializedStation<T>(nullptr, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Show coverage area of station under cursor */
|
/* Show coverage area of station under cursor */
|
||||||
auto it = this->vscroll->GetScrolledItemFromWidget(_stations_nearby_list, pt.y, this, WID_JS_PANEL, WidgetDimensions::scaled.framerect.top);
|
auto it = this->vscroll->GetScrolledItemFromWidget(_stations_nearby_list, pt.y, this, WID_JS_PANEL, WidgetDimensions::scaled.framerect.top);
|
||||||
const Station *st = it == _stations_nearby_list.end() || *it == NEW_STATION ? nullptr : Station::Get(*it);
|
const T *st = it == _stations_nearby_list.end() || *it == NEW_STATION ? nullptr : T::Get(*it);
|
||||||
SetViewportCatchmentStation(st, true);
|
SetViewportCatchmentSpecializedStation<T>(st, true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ enum StationCoverageType {
|
||||||
|
|
||||||
int DrawStationCoverageAreaText(int left, int right, int top, StationCoverageType sct, int rad, bool supplies);
|
int DrawStationCoverageAreaText(int left, int right, int top, StationCoverageType sct, int rad, bool supplies);
|
||||||
void CheckRedrawStationCoverage(const Window *w);
|
void CheckRedrawStationCoverage(const Window *w);
|
||||||
|
void CheckRedrawWaypointCoverage(const Window *w);
|
||||||
|
|
||||||
using StationPickerCmdProc = std::function<bool(bool test, StationID to_join)>;
|
using StationPickerCmdProc = std::function<bool(bool test, StationID to_join)>;
|
||||||
|
|
||||||
|
|
|
@ -992,7 +992,8 @@ enum TileHighlightType {
|
||||||
};
|
};
|
||||||
|
|
||||||
const Station *_viewport_highlight_station; ///< Currently selected station for coverage area highlight
|
const Station *_viewport_highlight_station; ///< Currently selected station for coverage area highlight
|
||||||
const Town *_viewport_highlight_town; ///< Currently selected town for coverage area highlight
|
const Waypoint *_viewport_highlight_waypoint; ///< Currently selected waypoint 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.
|
* Get tile highlight type of coverage area for a given tile.
|
||||||
|
@ -1005,6 +1006,9 @@ static TileHighlightType GetTileHighlightType(TileIndex t)
|
||||||
if (IsTileType(t, MP_STATION) && GetStationIndex(t) == _viewport_highlight_station->index) return THT_WHITE;
|
if (IsTileType(t, MP_STATION) && GetStationIndex(t) == _viewport_highlight_station->index) return THT_WHITE;
|
||||||
if (_viewport_highlight_station->TileIsInCatchment(t)) return THT_BLUE;
|
if (_viewport_highlight_station->TileIsInCatchment(t)) return THT_BLUE;
|
||||||
}
|
}
|
||||||
|
if (_viewport_highlight_waypoint != nullptr) {
|
||||||
|
if (IsTileType(t, MP_STATION) && GetStationIndex(t) == _viewport_highlight_waypoint->index) return THT_BLUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (_viewport_highlight_town != nullptr) {
|
if (_viewport_highlight_town != nullptr) {
|
||||||
if (IsTileType(t, MP_HOUSE)) {
|
if (IsTileType(t, MP_HOUSE)) {
|
||||||
|
@ -3511,11 +3515,18 @@ void MarkCatchmentTilesDirty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (_viewport_highlight_waypoint != nullptr) {
|
||||||
|
if (!_viewport_highlight_waypoint->IsInUse()) {
|
||||||
|
_viewport_highlight_waypoint = nullptr;
|
||||||
|
}
|
||||||
|
MarkWholeScreenDirty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetWindowDirtyForViewportCatchment()
|
static void SetWindowDirtyForViewportCatchment()
|
||||||
{
|
{
|
||||||
if (_viewport_highlight_station != nullptr) SetWindowDirty(WC_STATION_VIEW, _viewport_highlight_station->index);
|
if (_viewport_highlight_station != nullptr) SetWindowDirty(WC_STATION_VIEW, _viewport_highlight_station->index);
|
||||||
|
if (_viewport_highlight_waypoint != nullptr) SetWindowDirty(WC_WAYPOINT_VIEW, _viewport_highlight_waypoint->index);
|
||||||
if (_viewport_highlight_town != nullptr) SetWindowDirty(WC_TOWN_VIEW, _viewport_highlight_town->index);
|
if (_viewport_highlight_town != nullptr) SetWindowDirty(WC_TOWN_VIEW, _viewport_highlight_town->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3523,6 +3534,7 @@ static void ClearViewportCatchment()
|
||||||
{
|
{
|
||||||
MarkCatchmentTilesDirty();
|
MarkCatchmentTilesDirty();
|
||||||
_viewport_highlight_station = nullptr;
|
_viewport_highlight_station = nullptr;
|
||||||
|
_viewport_highlight_waypoint = nullptr;
|
||||||
_viewport_highlight_town = nullptr;
|
_viewport_highlight_town = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3546,6 +3558,26 @@ void SetViewportCatchmentStation(const Station *st, bool sel)
|
||||||
if (_viewport_highlight_station != nullptr) SetWindowDirty(WC_STATION_VIEW, _viewport_highlight_station->index);
|
if (_viewport_highlight_station != nullptr) SetWindowDirty(WC_STATION_VIEW, _viewport_highlight_station->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select or deselect waypoint for coverage area highlight.
|
||||||
|
* Selecting a waypoint will deselect a town.
|
||||||
|
* @param *wp Waypoint in question
|
||||||
|
* @param sel Select or deselect given waypoint
|
||||||
|
*/
|
||||||
|
void SetViewportCatchmentWaypoint(const Waypoint *wp, bool sel)
|
||||||
|
{
|
||||||
|
SetWindowDirtyForViewportCatchment();
|
||||||
|
if (sel && _viewport_highlight_waypoint != wp) {
|
||||||
|
ClearViewportCatchment();
|
||||||
|
_viewport_highlight_waypoint = wp;
|
||||||
|
MarkCatchmentTilesDirty();
|
||||||
|
} else if (!sel && _viewport_highlight_waypoint == wp) {
|
||||||
|
MarkCatchmentTilesDirty();
|
||||||
|
_viewport_highlight_waypoint = nullptr;
|
||||||
|
}
|
||||||
|
if (_viewport_highlight_waypoint != nullptr) SetWindowDirty(WC_WAYPOINT_VIEW, _viewport_highlight_waypoint->index);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select or deselect town for coverage area highlight.
|
* Select or deselect town for coverage area highlight.
|
||||||
* Selecting a town will deselect a station.
|
* Selecting a town will deselect a station.
|
||||||
|
|
|
@ -95,10 +95,27 @@ static inline void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset =
|
||||||
Point GetViewportStationMiddle(const Viewport *vp, const Station *st);
|
Point GetViewportStationMiddle(const Viewport *vp, const Station *st);
|
||||||
|
|
||||||
struct Station;
|
struct Station;
|
||||||
|
struct Waypoint;
|
||||||
struct Town;
|
struct Town;
|
||||||
|
|
||||||
void SetViewportCatchmentStation(const Station *st, bool sel);
|
void SetViewportCatchmentStation(const Station *st, bool sel);
|
||||||
|
void SetViewportCatchmentWaypoint(const Waypoint *wp, bool sel);
|
||||||
void SetViewportCatchmentTown(const Town *t, bool sel);
|
void SetViewportCatchmentTown(const Town *t, bool sel);
|
||||||
void MarkCatchmentTilesDirty();
|
void MarkCatchmentTilesDirty();
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void SetViewportCatchmentSpecializedStation(const T *st, bool sel);
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline void SetViewportCatchmentSpecializedStation(const Station *st, bool sel)
|
||||||
|
{
|
||||||
|
SetViewportCatchmentStation(st, sel);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline void SetViewportCatchmentSpecializedStation(const Waypoint *st, bool sel)
|
||||||
|
{
|
||||||
|
SetViewportCatchmentWaypoint(st, sel);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* VIEWPORT_FUNC_H */
|
#endif /* VIEWPORT_FUNC_H */
|
||||||
|
|
Loading…
Reference in New Issue