diff --git a/.version b/.version index 927070056a..dfacec3366 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -1.10.0-beta2 +1.10.0-RC1 diff --git a/source.list b/source.list index 2e4e0635c5..7e6b32f9c3 100644 --- a/source.list +++ b/source.list @@ -620,6 +620,8 @@ citymania/base64.h citymania/base64.cpp citymania/highlight.hpp citymania/highlight.cpp +citymania/station_gui.hpp +citymania/station_gui.cpp newgrf_revisions.hpp # Save/Load handlers diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index fa206decc8..0814c93daa 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -29,11 +29,13 @@ #include "widgets/airport_widget.h" +#include "citymania/station_gui.hpp" + #include "safeguards.h" static AirportClassID _selected_airport_class; ///< the currently visible airport class -static int _selected_airport_index; ///< the index of the selected airport in the current class or -1 +int _selected_airport_index; ///< the index of the selected airport in the current class or -1 static byte _selected_airport_layout; ///< selected airport layout number. static void ShowBuildAirportPicker(Window *parent); @@ -54,6 +56,11 @@ void CcBuildAirport(const CommandCost &result, TileIndex tile, uint32 p1, uint32 */ static void PlaceAirport(TileIndex tile) { + if (_settings_client.gui.cm_use_improved_station_join) { + citymania::PlaceAirport(tile); + return; + } + if (_selected_airport_index == -1) return; uint32 p2 = _ctrl_pressed; SB(p2, 16, 16, INVALID_STATION); // no station to join @@ -148,6 +155,8 @@ struct BuildAirToolbarWindow : Window { DeleteWindowById(WC_BUILD_STATION, TRANSPORT_AIR); DeleteWindowById(WC_SELECT_STATION, 0); + + citymania::AbortStationPlacement(); } static HotkeyList hotkeys; diff --git a/src/citymania/highlight.cpp b/src/citymania/highlight.cpp index 147a3b4a7d..32c2b78fef 100644 --- a/src/citymania/highlight.cpp +++ b/src/citymania/highlight.cpp @@ -3,6 +3,7 @@ #include "highlight.hpp" #include "../core/math_func.hpp" +#include "../command_func.h" #include "../house.h" #include "../industry.h" #include "../landscape.h" @@ -12,6 +13,9 @@ #include "../viewport_func.h" #include "../zoning.h" +#include "station_gui.hpp" + + /** Enumeration of multi-part foundations */ enum FoundationPart { FOUNDATION_PART_NONE = 0xFF, ///< Neither foundation nor groundsprite drawn yet. @@ -23,7 +27,7 @@ extern void DrawSelectionSprite(SpriteID image, PaletteID pal, const TileInfo *t extern const Station *_viewport_highlight_station; extern TileHighlightData _thd; extern bool IsInsideSelectedRectangle(int x, int y); -extern void MarkCatchmentTilesDirty(); + namespace citymania { struct TileZoning { @@ -35,9 +39,12 @@ struct TileZoning { static TileZoning *_mz = nullptr; static IndustryType _industry_forbidden_tiles = INVALID_INDUSTRYTYPE; -StationBuildingStatus _station_building_status = StationBuildingStatus::NEW; -const Station *_station_to_join = nullptr; -TileArea _station_to_join_area; + +extern StationBuildingStatus _station_building_status; +extern const Station *_station_to_join; +extern const Station *_highlight_station_to_join; +extern TileArea _highlight_join_area; + // struct { // int w; // int h; @@ -136,34 +143,31 @@ SpriteID GetTintBySelectionColour(SpriteID colour, bool deep=false) { } static void SetStationSelectionHighlight(const TileInfo *ti, TileHighlight &th) { - bool draw_coverage = false; - bool draw_selection = false; - if ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT && _thd.outersize.x > 0) { - // we have station selected - draw_selection = true; - draw_coverage = _settings_client.gui.station_show_coverage; - } + bool draw_selection = ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT && _thd.outersize.x > 0); + const Station *highlight_station = _viewport_highlight_station; + + if (_highlight_station_to_join) highlight_station = _highlight_station_to_join; if (draw_selection) { auto b = CalcTileBorders(ti->tile, [](TileIndex t) { auto x = TileX(t) * TILE_SIZE, y = TileY(t) * TILE_SIZE; return IsInsideSelectedRectangle(x, y); }); - if (b.first != ZoningBorder::NONE) { - const SpriteID pal[] = {SPR_PALETTE_ZONING_RED, SPR_PALETTE_ZONING_YELLOW, SPR_PALETTE_ZONING_LIGHT_BLUE, SPR_PALETTE_ZONING_GREEN}; - auto color = pal[(int)_station_building_status]; + const SpriteID pal[] = {SPR_PALETTE_ZONING_RED, SPR_PALETTE_ZONING_YELLOW, SPR_PALETTE_ZONING_LIGHT_BLUE, SPR_PALETTE_ZONING_GREEN}; + auto color = pal[(int)_station_building_status]; + if (b.first != ZoningBorder::NONE) th.add_border(b.first, color); + if (IsInsideSelectedRectangle(TileX(ti->tile) * TILE_SIZE, TileY(ti->tile) * TILE_SIZE)) { th.ground_pal = GetTintBySelectionColour(color); return; } } - auto highlight_station = _station_to_join ? _station_to_join : _viewport_highlight_station; - auto coverage_getter = [draw_coverage, highlight_station](TileIndex t) { + auto coverage_getter = [draw_selection, highlight_station](TileIndex t) { auto x = TileX(t) * TILE_SIZE, y = TileY(t) * TILE_SIZE; if (highlight_station && IsTileType(t, MP_STATION) && GetStationIndex(t) == highlight_station->index) return 2; - if (draw_coverage && highlight_station && highlight_station->TileIsInCatchment(t)) return 1; - if (draw_coverage && IsInsideBS(x, _thd.pos.x + _thd.offs.x, _thd.size.x + _thd.outersize.x) && + if (_settings_client.gui.station_show_coverage && highlight_station && highlight_station->TileIsInCatchment(t)) return 1; + if (draw_selection && _settings_client.gui.station_show_coverage && IsInsideBS(x, _thd.pos.x + _thd.offs.x, _thd.size.x + _thd.outersize.x) && IsInsideBS(y, _thd.pos.y + _thd.offs.y, _thd.size.y + _thd.outersize.y)) return 1; return 0; }; @@ -176,9 +180,9 @@ static void SetStationSelectionHighlight(const TileInfo *ti, TileHighlight &th) th.ground_pal = th.structure_pal = pal2[b.second]; } - if (_station_to_join) { + if (_highlight_join_area.tile != INVALID_TILE) { auto b = CalcTileBorders(ti->tile, [](TileIndex t) { - return _station_to_join_area.Contains(t) ? 1 : 0; + return _highlight_join_area.Contains(t) ? 1 : 0; }); th.add_border(b.first, SPR_PALETTE_ZONING_LIGHT_BLUE); if (b.second) { @@ -422,73 +426,4 @@ void SetIndustryForbiddenTilesHighlight(IndustryType type) { _industry_forbidden_tiles = type; } -// void SetStationTileSelectSize(int w, int h, int catchment) { -// _station_select.w = w; -// _station_select.h = h; -// _station_select.catchment = catchment; -// } - -void SetStationBiildingStatus(StationBuildingStatus status) { - _station_building_status = status; -}; - -static const int MAX_TILE_EXTENT_LEFT = ZOOM_LVL_BASE * TILE_PIXELS; ///< Maximum left extent of tile relative to north corner. -static const int MAX_TILE_EXTENT_RIGHT = ZOOM_LVL_BASE * TILE_PIXELS; ///< Maximum right extent of tile relative to north corner. -static const int MAX_TILE_EXTENT_TOP = ZOOM_LVL_BASE * MAX_BUILDING_PIXELS; ///< Maximum top extent of tile relative to north corner (not considering bridges). -static const int MAX_TILE_EXTENT_BOTTOM = ZOOM_LVL_BASE * (TILE_PIXELS + 2 * TILE_HEIGHT); ///< Maximum bottom extent of tile relative to north corner (worst case: #SLOPE_STEEP_N). - -void MarkTileAreaDirty(const TileArea &ta) { - if (ta.tile == INVALID_TILE) return; - auto x = TileX(ta.tile); - auto y = TileY(ta.tile); - Point p1 = RemapCoords(x * TILE_SIZE, y * TILE_SIZE, TileHeight(ta.tile) * TILE_HEIGHT); - Point p2 = RemapCoords((x + ta.w) * TILE_SIZE, (y + ta.h) * TILE_SIZE, TileHeight(TileXY(x + ta.w - 1, y + ta.h - 1)) * TILE_HEIGHT); - Point p3 = RemapCoords((x + ta.w) * TILE_SIZE, y * TILE_SIZE, TileHeight(TileXY(x + ta.w - 1, y)) * TILE_HEIGHT); - Point p4 = RemapCoords(x * TILE_SIZE, (y + ta.h) * TILE_SIZE, TileHeight(TileXY(x, y + ta.h - 1)) * TILE_HEIGHT); - MarkAllViewportsDirty( - p3.x - MAX_TILE_EXTENT_LEFT, - p4.x - MAX_TILE_EXTENT_TOP, - p1.y + MAX_TILE_EXTENT_RIGHT, - p2.y + MAX_TILE_EXTENT_BOTTOM); - // TILE_AREA_LOOP(tile, ta) { - // MarkTileDirtyByTile(tile); - // } -} - -static void UpdateStationToJoinArea() { - auto &r = _station_to_join->rect; - auto d = (int)_settings_game.station.station_spread - 1; - TileArea ta( - TileXY(max(r.right - d, 0), - max(r.bottom - d, 0)), - TileXY(min(r.left + d, MapSizeX() - 1), - min(r.top + d, MapSizeY() - 1)) - ); - if (_station_to_join_area.tile == ta.tile && - _station_to_join_area.w == ta.w && - _station_to_join_area.h == ta.h) return; - _station_to_join_area = ta; - MarkTileAreaDirty(_station_to_join_area); -} - -void MarkCoverageHighlightDirty() { - MarkCatchmentTilesDirty(); -} - -void SetStationToJoin(const Station *station) { - if (_station_to_join == station) { - _station_to_join = nullptr; - MarkTileAreaDirty(_station_to_join_area); - _station_to_join_area.Clear(); - } else { - _station_to_join = station; - UpdateStationToJoinArea(); - } -} - -const Station *GetStationToJoin() { - return _station_to_join; -} - - } // namespace citymania diff --git a/src/citymania/highlight.hpp b/src/citymania/highlight.hpp index 69c12ca5b4..2d5f50e1b7 100644 --- a/src/citymania/highlight.hpp +++ b/src/citymania/highlight.hpp @@ -1,10 +1,9 @@ -#ifndef CITYMANIA_ZONING_HPP -#define CITYMANIA_ZONING_HPP +#ifndef CITYMANIA_HIGHLIGHT_HPP +#define CITYMANIA_HIGHLIGHT_HPP #include "../core/enum_type.hpp" #include "../gfx_type.h" #include "../industry_type.h" -#include "../station_type.h" #include "../tile_cmd.h" #include "../tile_type.h" #include "../town_type.h" @@ -27,13 +26,6 @@ enum ZoningBorder: uint8 { FULL = TOP_LEFT | TOP_RIGHT | BOTTOM_LEFT | BOTTOM_RIGHT, }; -enum class StationBuildingStatus { - IMPOSSIBLE = 0, - QUERY = 1, - JOIN = 2, - NEW = 3, -}; - class TileHighlight { public: SpriteID ground_pal = PAL_NONE; @@ -66,18 +58,14 @@ DECLARE_ENUM_AS_BIT_SET(ZoningBorder); // }; -void SetStationBiildingStatus(StationBuildingStatus status); TileHighlight GetTileHighlight(const TileInfo *ti); void DrawTileSelection(const TileInfo *ti, const TileHighlight &th); -void SetStationTileSelectSize(int w, int h, int catchment); - void AllocateZoningMap(uint map_size); void InitializeZoningMap(); void UpdateTownZoning(Town *town, uint32 prev_edge); - std::pair GetTownZoneBorder(TileIndex tile); ZoningBorder GetAnyStationCatchmentBorder(TileIndex tlie); // std::pair GetTownAdvertisementBorder(TileIndex tile); @@ -86,9 +74,7 @@ SpriteID GetTownTileZoningPalette(TileIndex tile); SpriteID GetIndustryTileZoningPalette(TileIndex tile, Industry *ind); void SetIndustryForbiddenTilesHighlight(IndustryType type); -void SetStationToJoin(const Station *station); -const Station *GetStationToJoin(); -void MarkCoverageHighlightDirty(); + } // namespace citymania diff --git a/src/citymania/station_gui.cpp b/src/citymania/station_gui.cpp new file mode 100644 index 0000000000..de3960dcb7 --- /dev/null +++ b/src/citymania/station_gui.cpp @@ -0,0 +1,369 @@ +#include "../stdafx.h" + +#include "station_gui.hpp" + +#include "../core/math_func.hpp" +#include "../command_type.h" +#include "../command_func.h" +#include "../company_func.h" +#include "../landscape.h" +#include "../newgrf_station.h" // StationClassID +#include "../station_base.h" +#include "../tilehighlight_type.h" +#include "../viewport_func.h" +#include "../viewport_kdtree.h" +#include "../window_gui.h" +#include "../zoom_type.h" +#include "../zoom_func.h" + +extern const Station *_viewport_highlight_station; +extern TileHighlightData _thd; +extern void MarkCatchmentTilesDirty(); + +extern DiagDirection _road_station_picker_orientation; +extern bool CheckDriveThroughRoadStopDirection(TileArea area, RoadBits r); +extern DiagDirection AutodetectRoadObjectDirection(TileIndex tile); +extern DiagDirection AutodetectDriveThroughRoadStopDirection(TileArea area); +extern bool CheckClickOnViewportSign(const ViewPort *vp, int x, int y, const ViewportSign *sign); +extern Rect ExpandRectWithViewportSignMargins(Rect r, ZoomLevel zoom); +extern ViewportSignKdtree _viewport_sign_kdtree; +AirportClassID _selected_airport_class; +extern int _selected_airport_index; +byte _selected_airport_layout; + +extern RailType _cur_railtype; // rail_gui.cpp + +struct RailStationGUISettings { + Axis orientation; ///< Currently selected rail station orientation + + bool newstations; ///< Are custom station definitions available? + StationClassID station_class; ///< Currently selected custom station class (if newstations is \c true ) + byte station_type; ///< %Station type within the currently selected custom station class (if newstations is \c true ) + byte station_count; ///< Number of custom stations (if newstations is \c true ) +}; +extern RailStationGUISettings _railstation; //rail_gui.cpp + +namespace citymania { + +StationBuildingStatus _station_building_status = StationBuildingStatus::NEW; +const Station *_station_to_join = nullptr; +const Station *_highlight_station_to_join = nullptr; +TileArea _highlight_join_area; + +void CheckRedrawStationCoverage(); + +// void SetStationTileSelectSize(int w, int h, int catchment) { +// _station_select.w = w; +// _station_select.h = h; +// _station_select.catchment = catchment; +// } + +void SetStationBiildingStatus(StationBuildingStatus status) { + _station_building_status = status; +}; + +static const int MAX_TILE_EXTENT_LEFT = ZOOM_LVL_BASE * TILE_PIXELS; ///< Maximum left extent of tile relative to north corner. +static const int MAX_TILE_EXTENT_RIGHT = ZOOM_LVL_BASE * TILE_PIXELS; ///< Maximum right extent of tile relative to north corner. +static const int MAX_TILE_EXTENT_TOP = ZOOM_LVL_BASE * MAX_BUILDING_PIXELS; ///< Maximum top extent of tile relative to north corner (not considering bridges). +static const int MAX_TILE_EXTENT_BOTTOM = ZOOM_LVL_BASE * (TILE_PIXELS + 2 * TILE_HEIGHT); ///< Maximum bottom extent of tile relative to north corner (worst case: #SLOPE_STEEP_N). + +void MarkTileAreaDirty(const TileArea &ta) { + if (ta.tile == INVALID_TILE) return; + auto x = TileX(ta.tile); + auto y = TileY(ta.tile); + Point p1 = RemapCoords(x * TILE_SIZE, y * TILE_SIZE, TileHeight(ta.tile) * TILE_HEIGHT); + Point p2 = RemapCoords((x + ta.w) * TILE_SIZE, (y + ta.h) * TILE_SIZE, TileHeight(TileXY(x + ta.w - 1, y + ta.h - 1)) * TILE_HEIGHT); + Point p3 = RemapCoords((x + ta.w) * TILE_SIZE, y * TILE_SIZE, TileHeight(TileXY(x + ta.w - 1, y)) * TILE_HEIGHT); + Point p4 = RemapCoords(x * TILE_SIZE, (y + ta.h) * TILE_SIZE, TileHeight(TileXY(x, y + ta.h - 1)) * TILE_HEIGHT); + MarkAllViewportsDirty( + p3.x - MAX_TILE_EXTENT_LEFT, + p4.x - MAX_TILE_EXTENT_TOP, + p1.y + MAX_TILE_EXTENT_RIGHT, + p2.y + MAX_TILE_EXTENT_BOTTOM); +} + +static void UpdateHiglightJoinArea(const Station *station) { + if (!station) { + MarkTileAreaDirty(_highlight_join_area); + _highlight_join_area.tile = INVALID_TILE; + return; + } + auto &r = _station_to_join->rect; + auto d = (int)_settings_game.station.station_spread - 1; + TileArea ta( + TileXY(max(r.right - d, 0), + max(r.bottom - d, 0)), + TileXY(min(r.left + d, MapSizeX() - 1), + min(r.top + d, MapSizeY() - 1)) + ); + if (_highlight_join_area.tile == ta.tile && + _highlight_join_area.w == ta.w && + _highlight_join_area.h == ta.h) return; + MarkTileAreaDirty(_highlight_join_area); + _highlight_join_area = ta; + MarkTileAreaDirty(_highlight_join_area); +} + +static void MarkCoverageAreaDirty(const Station *station) { + MarkTileAreaDirty(station->catchment_tiles); +} + +void MarkCoverageHighlightDirty() { + MarkCatchmentTilesDirty(); +} + +void SetHighlightStationToJoin(const Station *station, bool with_area) { + UpdateHiglightJoinArea(with_area ? station : nullptr); + + if (_highlight_station_to_join == station) return; + + if (_highlight_station_to_join && _settings_client.gui.station_show_coverage) + MarkCoverageAreaDirty(_highlight_station_to_join); + _highlight_station_to_join = station; + if (_highlight_station_to_join && _settings_client.gui.station_show_coverage) + MarkCoverageAreaDirty(_highlight_station_to_join); +} + +void OnStationTileSetChange(const Station *station, bool adding, StationType type) { + if (station == _highlight_station_to_join) { + if (_highlight_join_area.tile != INVALID_TILE) + UpdateHiglightJoinArea(_station_to_join); + if (_settings_client.gui.station_show_coverage) + MarkCoverageAreaDirty(_highlight_station_to_join); + } + if (station == _viewport_highlight_station) MarkCoverageAreaDirty(_viewport_highlight_station); +} + +CommandContainer _last_station_bulid_cmd; + +void OnStationPartBuilt(const Station *station, TileIndex tile, uint32 p1, uint32 p2) { + if (_current_company != _local_company) return; + if (tile != _last_station_bulid_cmd.tile || + p1 != _last_station_bulid_cmd.p1 || + p2 != _last_station_bulid_cmd.p2) return; + _station_to_join = station; + CheckRedrawStationCoverage(); +} + +const Station *CheckClickOnDeadStationSign() { + int x = _cursor.pos.x; + int y = _cursor.pos.y; + Window *w = FindWindowFromPt(x, y); + if (w == nullptr) return nullptr; + ViewPort *vp = IsPtInWindowViewport(w, x, y); + + if (!HasBit(_display_opt, DO_SHOW_STATION_NAMES) && !IsInvisibilitySet(TO_SIGNS)) + return nullptr; + + x = ScaleByZoom(x - vp->left, vp->zoom) + vp->virtual_left; + y = ScaleByZoom(y - vp->top, vp->zoom) + vp->virtual_top; + + Rect search_rect{ x - 1, y - 1, x + 1, y + 1 }; + search_rect = ExpandRectWithViewportSignMargins(search_rect, vp->zoom); + + const Station *last_st = nullptr; + _viewport_sign_kdtree.FindContained(search_rect.left, search_rect.top, search_rect.right, search_rect.bottom, [&](const ViewportSignKdtreeItem & item) { + if (item.type != ViewportSignKdtreeItem::VKI_STATION) return; + auto st = Station::Get(item.id.station); + if (st->IsInUse()) return; + if (_local_company != st->owner) return; + if (CheckClickOnViewportSign(vp, x, y, &st->sign)) last_st = st; + }); + return last_st; +} + +bool CheckStationJoin(TileIndex start_tile, TileIndex end_tile) { + // if (_ctrl_pressed && start_tile == end_tile) { + if (_ctrl_pressed) { + if (IsTileType (start_tile, MP_STATION)) { + citymania::SelectStationToJoin(Station::GetByTile(start_tile)); + return true; + } + auto st = CheckClickOnDeadStationSign(); + if (st) { + citymania::SelectStationToJoin(st); + return true; + } + } + return false; +} + +void JoinAndBuild(CommandContainer cmdcont) { + auto join_to = _highlight_station_to_join; + uint32 adj_bit = ((_ctrl_pressed || join_to) ? 1 : 0); + auto cmd = (cmdcont.cmd & CMD_ID_MASK); + if (cmd == CMD_BUILD_RAIL_STATION) { + SB(cmdcont.p1, 24, 1, adj_bit); + } else if (cmd == CMD_BUILD_ROAD_STOP) { + SB(cmdcont.p2, 2, 1, adj_bit); + } else if (cmd == CMD_BUILD_DOCK) { + SB(cmdcont.p1, 0, 1, adj_bit); + } else if (cmd == CMD_BUILD_AIRPORT) { + SB(cmdcont.p2, 0, 1, adj_bit); + } + if (_ctrl_pressed) SB(cmdcont.p2, 16, 16, NEW_STATION); + else if (join_to) SB(cmdcont.p2, 16, 16, join_to->index); + else SB(cmdcont.p2, 16, 16, INVALID_STATION); + + _last_station_bulid_cmd = cmdcont; + DoCommandP(&cmdcont); +} + +void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, uint32 cmd) { + uint8 ddir = _road_station_picker_orientation; + SB(p2, 16, 16, INVALID_STATION); // no station to join + TileArea ta(start_tile, end_tile); + + if (CheckStationJoin(start_tile, end_tile)) return; + + if (ddir >= DIAGDIR_END) { + if (ddir < DIAGDIR_END + 2) { + SetBit(p2, 1); // It's a drive-through stop. + ddir -= DIAGDIR_END; // Adjust picker result to actual direction. + // When placed on road autorotate anyway + if (ddir == DIAGDIR_SE) { + if (!CheckDriveThroughRoadStopDirection(ta, ROAD_Y)) + ddir = DIAGDIR_NE; + } else { + if (!CheckDriveThroughRoadStopDirection(ta, ROAD_X)) + ddir = DIAGDIR_SE; + } + } + else if (ddir == DIAGDIR_END + 2) { + ddir = AutodetectRoadObjectDirection(start_tile); + } + else if (ddir == DIAGDIR_END + 3) { + SetBit(p2, 1); // It's a drive-through stop. + ddir = AutodetectDriveThroughRoadStopDirection(ta); + } + } + p2 |= ddir << 3; // Set the DiagDirecion into p2 bits 3 and 4. + + CommandContainer cmdcont = { ta.tile, (uint32)(ta.w | ta.h << 8), p2, cmd, CcRoadStop, "" }; + JoinAndBuild(cmdcont); +} + +void HandleStationPlacement(TileIndex start, TileIndex end) +{ + if (CheckStationJoin(start, end)) return; + + TileArea ta(start, end); + uint numtracks = ta.w; + uint platlength = ta.h; + + if (_railstation.orientation == AXIS_X) Swap(numtracks, platlength); + + uint32 p1 = _cur_railtype | _railstation.orientation << 6 | numtracks << 8 | platlength << 16 | _ctrl_pressed << 24; + uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16; + + CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION), CcStation, "" }; + JoinAndBuild(cmdcont); +} + +void PlaceDock(TileIndex tile) { + if (CheckStationJoin(tile, tile)) return; + + uint32 p2 = (uint32)INVALID_STATION << 16; // no station to join + + /* tile is always the land tile, so need to evaluate _thd.pos */ + CommandContainer cmdcont = { tile, _ctrl_pressed, p2, CMD_BUILD_DOCK | CMD_MSG(STR_ERROR_CAN_T_BUILD_DOCK_HERE), CcBuildDocks, "" }; + + /* Determine the watery part of the dock. */ + // DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile)); + // TileIndex tile_to = (dir != INVALID_DIAGDIR ? TileAddByDiagDir(tile, ReverseDiagDir(dir)) : tile); + + JoinAndBuild(cmdcont); +} + +void PlaceAirport(TileIndex tile) { + if (CheckStationJoin(tile, tile)) return; + + if (_selected_airport_index == -1) return; + + uint32 p2 = _ctrl_pressed; + SB(p2, 16, 16, INVALID_STATION); // no station to join + + uint32 p1 = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index)->GetIndex(); + p1 |= _selected_airport_layout << 8; + CommandContainer cmdcont = { tile, p1, p2, CMD_BUILD_AIRPORT | CMD_MSG(STR_ERROR_CAN_T_BUILD_AIRPORT_HERE), CcBuildAirport, "" }; + JoinAndBuild(cmdcont); +} + +static void FindStationsAroundSelection(const TileArea &location) +{ + /* Extended area by one tile */ + int x = TileX(location.tile); + int y = TileY(location.tile); + + TileArea ta(TileXY(max(0, x - 1), max(0, y - 1)), TileXY(min(MapMaxX() - 1, x + location.w + 1), min(MapMaxY() - 1, y + location.h + 1))); + + Station *adjacent = nullptr; + + /* Direct loop instead of FindStationsAroundTiles as we are not interested in catchment area */ + TILE_AREA_LOOP(tile, ta) { + if (IsTileType(tile, MP_STATION) && GetTileOwner(tile) == _local_company) { + Station *st = Station::GetByTile(tile); + if (st == nullptr) continue; + + int tx = TileX(tile); + int ty = TileY(tile); + bool is_corner = ((tx == x - 1 || tx == x + location.w + 1) && (ty == y - 1 || ty == y + location.h + 1)); + + if (adjacent && is_corner) continue; + adjacent = st; + if (!is_corner) break; + } + } + SetHighlightStationToJoin(adjacent, false); + _station_building_status = (adjacent == nullptr ? StationBuildingStatus::NEW : StationBuildingStatus::JOIN); +} + +void CheckRedrawStationCoverage() { + static bool last_ctrl_pressed = false; + static TileArea last_location; + static bool last_station_mode = false; + static bool last_coverage = false; + TileArea location(TileVirtXY(_thd.pos.x, _thd.pos.y), _thd.size.x / TILE_SIZE - 1, _thd.size.y / TILE_SIZE - 1); + bool station_mode = ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT && _thd.outersize.x > 0); + bool location_changed = (location.tile != last_location.tile || location.w != last_location.w || location.h != last_location.h); + bool mode_changed = (last_station_mode != station_mode); + // if (!location_changed && _ctrl_pressed == last_ctrl_pressed && !mode_changed) + // return; + + // last_ctrl_pressed = _ctrl_pressed; + // last_location = location; + // last_station_mode = station_mode; + + if (_ctrl_pressed) { + Station *st = nullptr; + if (IsTileType(location.tile, MP_STATION) && GetTileOwner(location.tile) == _local_company) + st = Station::GetByTile(location.tile); + + SetHighlightStationToJoin(st, _station_to_join && st == _station_to_join); + _station_building_status = (st == nullptr ? StationBuildingStatus::NEW : StationBuildingStatus::JOIN); + } else { + if (_station_to_join) { + SetHighlightStationToJoin(_station_to_join, true); + _station_building_status = StationBuildingStatus::JOIN; + } else { + FindStationsAroundSelection(location); + } + } +} + + +void SelectStationToJoin(const Station *station) { + if (_station_to_join == station) + _station_to_join = nullptr; + else + _station_to_join = station; + CheckRedrawStationCoverage(); +} + +void AbortStationPlacement() { + _station_to_join = nullptr; + SetHighlightStationToJoin(nullptr, false); +} + + +} // namespace citymania diff --git a/src/citymania/station_gui.hpp b/src/citymania/station_gui.hpp new file mode 100644 index 0000000000..f92d590355 --- /dev/null +++ b/src/citymania/station_gui.hpp @@ -0,0 +1,35 @@ +#ifndef CITYMANIA_STATION_GUI_HPP +#define CITYMANIA_STATION_GUI_HPP + +#include "../core/geometry_type.hpp" +#include "../command_type.h" +#include "../station_type.h" + +namespace citymania { + +enum class StationBuildingStatus { + IMPOSSIBLE = 0, + QUERY = 1, + JOIN = 2, + NEW = 3, +}; + +// void SetStationBiildingStatus(StationBuildingStatus status); +// void SetStationTileSelectSize(int w, int h, int catchment); + +void OnStationTileSetChange(const Station *station, bool adding, StationType type); +void OnStationPartBuilt(const Station *station, TileIndex tile, uint32 p1, uint32 p2); +void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, uint32 cmd); +void HandleStationPlacement(TileIndex start, TileIndex end); +void PlaceDock(TileIndex tile); +void PlaceAirport(TileIndex tile); + +void SelectStationToJoin(const Station *station); +// const Station *GetStationToJoin(); +void MarkCoverageHighlightDirty(); +void CheckRedrawStationCoverage(); +void AbortStationPlacement(); + +} // namespace citymania + +#endif diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index 9907d890f2..ccaf48b2d2 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -31,6 +31,8 @@ #include "table/sprites.h" #include "table/strings.h" +#include "citymania/station_gui.hpp" + #include "safeguards.h" static void ShowBuildDockStationPicker(Window *parent); @@ -194,6 +196,12 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_STATION: { // Build station button + + if (_settings_client.gui.cm_use_improved_station_join) { + citymania::PlaceDock(tile); + break; + } + uint32 p2 = (uint32)INVALID_STATION << 16; // no station to join /* tile is always the land tile, so need to evaluate _thd.pos */ @@ -257,6 +265,8 @@ struct BuildDocksToolbarWindow : Window { DeleteWindowById(WC_BUILD_DEPOT, TRANSPORT_WATER); DeleteWindowById(WC_SELECT_STATION, 0); DeleteWindowByClass(WC_BUILD_BRIDGE); + + citymania::AbortStationPlacement(); } void OnPlacePresize(Point pt, TileIndex tile_from) override @@ -455,6 +465,7 @@ public: this->LowerWidget(_settings_client.gui.station_show_coverage + BDSW_LT_OFF); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); this->SetDirty(); + citymania::MarkCoverageHighlightDirty(); break; } } diff --git a/src/lang/english.txt b/src/lang/english.txt index 161299b7b7..394c3fb4cf 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -483,6 +483,7 @@ STR_NEWS_MENU_DELETE_ALL_MESSAGES :Delete all mess ############ range for about menu starts STR_ABOUT_MENU_LAND_BLOCK_INFO :Land area information STR_ABOUT_MENU_SEPARATOR :CityMania +STR_ABOUT_MENU_LOGIN_WINDOW :Server Login STR_ABOUT_MENU_TOGGLE_CONSOLE :Toggle console STR_ABOUT_MENU_AI_DEBUG :AI/Game script debug STR_ABOUT_MENU_SCREENSHOT :Screenshot @@ -491,7 +492,6 @@ STR_ABOUT_MENU_ABOUT_OPENTTD :About 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite aligner STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Toggle bounding boxes STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS :Toggle colouring of dirty blocks -STR_ABOUT_MENU_LOGIN_WINDOW :Login Window ############ range ends here ############ range for ordinal numbers used for the place in the highscore window @@ -1448,6 +1448,8 @@ STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS :Keep building t STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS_HELPTEXT :Keep the building tools for bridges, tunnels, etc. open after use STR_CONFIG_SETTING_PERSISTENT_DEPOTTOOLS :Keep depot building tools active after usage: {STRING2} STR_CONFIG_SETTING_PERSISTENT_DEPOTTOOLS_HELPTEXT :Keep the building tools for road, train and ship depots (reversible by placing with Ctrl). +STR_CM_CONFIG_SETTING_IMPROVED_STATION_JOIN :Use improved station joining controls: {STRING2} +STR_CM_CONFIG_SETTING_IMPROVED_STATION_JOIN_HELPTEXT :Use Ctrl-click on station tile to select or deselect station to join. If station has no tiles Ctrl-click its sign. Ctrl-click empty tile for a new station. Also recently built station is automatically selected as a station to join. STR_CONFIG_SETTING_EXPENSES_LAYOUT :Group expenses in company finance window: {STRING2} STR_CONFIG_SETTING_EXPENSES_LAYOUT_HELPTEXT :Define the layout for the company expenses window diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 11bc9ed37e..3351e0be7d 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -38,10 +38,12 @@ #include "widgets/rail_widget.h" +#include "citymania/station_gui.hpp" + #include "safeguards.h" -static RailType _cur_railtype; ///< Rail type of the current build-rail toolbar. +RailType _cur_railtype; ///< Rail type of the current build-rail toolbar. static bool _remove_button_clicked; ///< Flag whether 'remove' toggle-button is currently enabled static DiagDirection _build_depot_direction; ///< Currently selected depot direction static byte _waypoint_count = 1; ///< Number of waypoint types @@ -68,7 +70,7 @@ struct RailStationGUISettings { byte station_type; ///< %Station type within the currently selected custom station class (if newstations is \c true ) byte station_count; ///< Number of custom stations (if newstations is \c true ) }; -static RailStationGUISettings _railstation; ///< Settings of the station builder GUI +RailStationGUISettings _railstation; ///< Settings of the station builder GUI static void HandleStationPlacement(TileIndex start, TileIndex end); @@ -943,6 +945,8 @@ struct BuildRailToolbarWindow : Window { DeleteWindowById(WC_BUILD_WAYPOINT, TRANSPORT_RAIL); DeleteWindowById(WC_SELECT_STATION, 0); DeleteWindowByClass(WC_BUILD_BRIDGE); + + citymania::AbortStationPlacement(); } void OnPlacePresize(Point pt, TileIndex tile) override @@ -1078,6 +1082,11 @@ Window *ShowBuildRailToolbar(RailType railtype) static void HandleStationPlacement(TileIndex start, TileIndex end) { + if (_settings_client.gui.cm_use_improved_station_join) { + citymania::HandleStationPlacement(start, end); + return; + } + TileArea ta(start, end); uint numtracks = ta.w; uint platlength = ta.h; @@ -1212,8 +1221,8 @@ public: int rad = (_settings_game.station.modified_catchment) ? CA_TRAIN : CA_UNMODIFIED; - //if (_settings_client.gui.station_show_coverage) SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad); - SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad); // always let cm zoning know we're selecting station + if (_settings_client.gui.cm_use_improved_station_join || _settings_client.gui.station_show_coverage) + SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad); for (uint bits = 0; bits < 7; bits++) { bool disable = bits >= _settings_game.station.station_spread; @@ -1518,6 +1527,7 @@ public: this->SetWidgetLoweredState(WID_BRAS_HIGHLIGHT_ON, _settings_client.gui.station_show_coverage); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); this->SetDirty(); + citymania::MarkCoverageHighlightDirty(); break; case WID_BRAS_NEWST_LIST: { diff --git a/src/rev.cpp b/src/rev.cpp index a971433ca2..46f0074b6d 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[] = "20200215-master-m5217e7c98b 15.02.20"; +const char _citymania_version[] = "20200222-master-mbac6a8a794 23.02.20"; diff --git a/src/rev.cpp.in b/src/rev.cpp.in index 07939457f0..d5cd527b10 100644 --- a/src/rev.cpp.in +++ b/src/rev.cpp.in @@ -35,7 +35,7 @@ bool IsReleasedVersion() * * shows a "M", if the binary is made from modified source code. */ -const char _openttd_revision[] = "1.10.0-beta2"; +const char _openttd_revision[] = "1.10.0-RC1"; /** * The text version of OpenTTD's build date. @@ -48,7 +48,7 @@ const char _openttd_build_date[] = __DATE__ " " __TIME__; /** * The git revision hash of this version. */ -const char _openttd_revision_hash[] = "18f03a300b12bb022fb3273ff6273c430b28f787"; +const char _openttd_revision_hash[] = "49d2a07f667b8e9a8d984b35b2a41302c70c3c1e"; /** * Let us know if current build was modified. This detection diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 82ec2bf9ca..e0fc4be8db 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -39,7 +39,7 @@ #include "table/strings.h" -#include "citymania/highlight.hpp" +#include "citymania/station_gui.hpp" #include "safeguards.h" @@ -69,7 +69,7 @@ static RoadFlags _place_road_flag; static RoadType _cur_roadtype; static DiagDirection _road_depot_orientation; -static DiagDirection _road_station_picker_orientation; +DiagDirection _road_station_picker_orientation; void CcPlaySound_SPLAT_OTHER(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { @@ -220,7 +220,7 @@ static DiagDirection TileFractCoordsToDiagDir() { /* * Selects orientation for road object (depot, terminal station) */ -static DiagDirection AutodetectRoadObjectDirection(TileIndex tile) { +DiagDirection AutodetectRoadObjectDirection(TileIndex tile) { RoadBits bits = FindRoadsToConnect(tile); if (HasExactlyOneBit(bits)) { return RoadBitsToDiagDir(bits); @@ -244,7 +244,7 @@ static DiagDirection AutodetectRoadObjectDirection(TileIndex tile) { NOT_REACHED(); } -static bool CheckDriveThroughRoadStopDirection(TileArea area, RoadBits r) { +bool CheckDriveThroughRoadStopDirection(TileArea area, RoadBits r) { TILE_AREA_LOOP(tile, area) { if (GetTileType(tile) != MP_ROAD) continue; if (GetRoadTileType(tile) != ROAD_TILE_NORMAL) continue; @@ -259,7 +259,7 @@ static bool CheckDriveThroughRoadStopDirection(TileArea area, RoadBits r) { * @param area road stop area * @return selected direction */ -static DiagDirection AutodetectDriveThroughRoadStopDirection(TileArea area) { +DiagDirection AutodetectDriveThroughRoadStopDirection(TileArea area) { bool se_suits, ne_suits; // Check which direction is available @@ -288,16 +288,15 @@ static DiagDirection AutodetectDriveThroughRoadStopDirection(TileArea area) { */ static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, uint32 cmd) { + if (_settings_client.gui.cm_use_improved_station_join) { + citymania::PlaceRoadStop(start_tile, end_tile, p2, cmd); + return; + } + uint8 ddir = _road_station_picker_orientation; SB(p2, 16, 16, INVALID_STATION); // no station to join TileArea ta(start_tile, end_tile); - if (_ctrl_pressed && start_tile == end_tile && IsTileType (start_tile, MP_STATION)) { - /* Select station to join */ - citymania::SetStationToJoin(Station::GetByTile(end_tile)); - return; - } - if (ddir >= DIAGDIR_END) { if (ddir < DIAGDIR_END + 2) { SetBit(p2, 1); // It's a drive-through stop. @@ -722,6 +721,8 @@ struct BuildRoadToolbarWindow : Window { DeleteWindowById(WC_BUILD_DEPOT, TRANSPORT_ROAD); DeleteWindowById(WC_SELECT_STATION, 0); DeleteWindowByClass(WC_BUILD_BRIDGE); + + citymania::AbortStationPlacement(); } void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) override @@ -1255,11 +1256,8 @@ struct BuildRoadStationWindow : public PickerWindowBase { int rad = _settings_game.station.modified_catchment ? ((this->window_class == WC_BUS_STATION) ? CA_BUS : CA_TRUCK) : CA_UNMODIFIED; SetTileSelectSize(1, 1); - // if (_settings_client.gui.station_show_coverage) { - SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad); - // } else { - // SetTileSelectSize(1, 1); - // } + if (_settings_client.gui.cm_use_improved_station_join || _settings_client.gui.station_show_coverage) + SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad); /* 'Accepts' and 'Supplies' texts. */ StationCoverageType sct = (this->window_class == WC_BUS_STATION) ? SCT_PASSENGERS_ONLY : SCT_NON_PASSENGERS_ONLY; diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 9fc9fffa03..26fc8fb62f 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -1579,6 +1579,7 @@ static SettingsContainer &GetSettingsTree() construction->Add(new SettingEntry("gui.quick_goto")); construction->Add(new SettingEntry("gui.default_rail_type")); construction->Add(new SettingEntry("gui.disable_unsuitable_building")); + construction->Add(new SettingEntry("gui.cm_use_improved_station_join")); } interface->Add(new SettingEntry("gui.autosave")); diff --git a/src/settings_type.h b/src/settings_type.h index 2b4a6fc68b..16db741d9e 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -149,6 +149,7 @@ struct GUISettings { bool station_show_coverage; ///< whether to highlight coverage area bool persistent_buildingtools; ///< keep the building tools active after usage bool persistent_depottools; ///< keep the depot building tools active after usage + bool cm_use_improved_station_join; ///< use ctrl-clicking station tiles to join instead of popup window bool expenses_layout; ///< layout of expenses window uint32 last_newgrf_count; ///< the numbers of NewGRFs we found during the last scan byte missing_strings_threshold; ///< the number of missing strings before showing the warning diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 385072b956..040f115acc 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -58,6 +58,8 @@ #include "table/strings.h" +#include "citymania/station_gui.hpp" + #include "safeguards.h" /** @@ -770,6 +772,7 @@ void Station::AfterStationTileSetChange(bool adding, StationType type) DeleteStationIfEmpty(this); } + citymania::OnStationTileSetChange(this, adding, type); } CommandCost ClearTile_Station(TileIndex tile, DoCommandFlag flags); @@ -1955,6 +1958,7 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin if (st != nullptr) { st->AfterStationTileSetChange(true, type ? STATION_TRUCK: STATION_BUS); + citymania::OnStationPartBuilt(st, tile, p1, p2); } return cost; } diff --git a/src/station_gui.cpp b/src/station_gui.cpp index c6e6b86bb2..f2ff9c4ae7 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -39,7 +39,7 @@ #include #include -#include "citymania/highlight.hpp" +#include "citymania/station_gui.hpp" #include "safeguards.h" @@ -105,8 +105,7 @@ static void FindStationsAroundSelection() { /* With distant join we don't know which station will be selected, so don't show any */ if (_ctrl_pressed) { - // SetViewportCatchmentStation(nullptr, true); - // citymania::SetStationBiildingStatus(citymania::StationBulidingStatus::JOIN); + SetViewportCatchmentStation(nullptr, true); return; } @@ -121,7 +120,6 @@ static void FindStationsAroundSelection() TileArea ta(TileXY(max(0, x - max_c), max(0, y - max_c)), TileXY(min(MapMaxX(), x + location.w + max_c), min(MapMaxY(), y + location.h + max_c))); Station *adjacent = nullptr; - auto cmbp = citymania::StationBuildingStatus::NEW; /* Direct loop instead of FindStationsAroundTiles as we are not interested in catchment area */ TILE_AREA_LOOP(tile, ta) { @@ -131,14 +129,12 @@ static void FindStationsAroundSelection() if (adjacent != nullptr && st != adjacent) { /* Multiple nearby, distant join is required. */ adjacent = nullptr; - cmbp =(_ctrl_pressed ? citymania::StationBuildingStatus::QUERY : citymania::StationBuildingStatus::IMPOSSIBLE); break; } adjacent = st; } } SetViewportCatchmentStation(adjacent, true); - citymania::SetStationBiildingStatus(citymania::StationBuildingStatus::JOIN); } /** @@ -148,7 +144,10 @@ static void FindStationsAroundSelection() */ void CheckRedrawStationCoverage(const Window *w) { - return; // CM has better redraw handling + if (_settings_client.gui.cm_use_improved_station_join) { + citymania::CheckRedrawStationCoverage(); + return; + } /* Test if ctrl state changed */ static bool _last_ctrl_pressed; if (_ctrl_pressed != _last_ctrl_pressed) { @@ -2430,7 +2429,6 @@ struct SelectStationWindow : WindowPopup { { if (widget != WID_JS_PANEL || T::EXPECTED_FACIL == FACIL_WAYPOINT) { SetViewportCatchmentStation(nullptr, true); - citymania::SetStationBiildingStatus(citymania::StationBuildingStatus::QUERY); return; } @@ -2438,11 +2436,9 @@ struct SelectStationWindow : WindowPopup { uint st_index = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_JS_PANEL, WD_FRAMERECT_TOP); if (st_index == 0 || st_index > _stations_nearby_list.size()) { SetViewportCatchmentStation(nullptr, true); - citymania::SetStationBiildingStatus(citymania::StationBuildingStatus::NEW); } else { st_index--; SetViewportCatchmentStation(Station::Get(_stations_nearby_list[st_index]), true); - citymania::SetStationBiildingStatus(citymania::StationBuildingStatus::JOIN); } } }; @@ -2499,20 +2495,6 @@ static bool StationJoinerNeeded(const CommandContainer &cmd, TileArea ta) template void ShowSelectBaseStationIfNeeded(const CommandContainer &cmd, TileArea ta) { - // CM No need to show window anymore - auto join_to = citymania::GetStationToJoin(); - auto cmd2 = cmd; - SetBit(cmd2.p2, 2); - if (_ctrl_pressed) SB(cmd2.p2, 16, 16, NEW_STATION); - else if (join_to) SB(cmd2.p2, 16, 16, join_to->index); - else { - SB(cmd2.p2, 16, 16, INVALID_STATION); - ClrBit(cmd2.p2, 2); - } - - DoCommandP(&cmd2); - return; - if (StationJoinerNeeded(cmd, ta)) { if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); new SelectStationWindow(&_select_station_desc, cmd, ta); diff --git a/src/table/settings.ini b/src/table/settings.ini index cd4cc2a5f3..c38279748b 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -3192,6 +3192,14 @@ str = STR_CONFIG_SETTING_PERSISTENT_DEPOTTOOLS strhelp = STR_CONFIG_SETTING_PERSISTENT_DEPOTTOOLS_HELPTEXT cat = SC_BASIC +[SDTC_BOOL] +var = gui.cm_use_improved_station_join +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +def = false +str = STR_CM_CONFIG_SETTING_IMPROVED_STATION_JOIN +strhelp = STR_CM_CONFIG_SETTING_IMPROVED_STATION_JOIN_HELPTEXT +cat = SC_BASIC + [SDTC_BOOL] var = gui.expenses_layout flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index edab136511..f32414ac51 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -92,7 +92,7 @@ static CallBackFunction _last_started_action = CBF_NONE; ///< Last started user #if 0 // CM /** * Drop down list entry for showing a checked/unchecked toggle item. - */ + */ class DropDownListCheckedItem : public DropDownListStringItem { uint checkmark_width; public: @@ -2365,7 +2365,7 @@ static Hotkey maintoolbar_hotkeys[] = { Hotkey('I', "trees", MTHK_TREES), Hotkey((uint16)0, "zoning", MTHK_ZONING), Hotkey((uint16)0, "login_window", MTHK_LOGINWINDOW), - Hotkey((uint16)0, "settings_advanced", MTHK_SETTINGS_ADV), + Hotkey((uint16)0, "settings_adIanced", MTHK_SETTINGS_ADV), Hotkey((uint16)0, "newgrf_window", MTHK_NEWGRF), Hotkey((uint16)0, "sign_list", MTHK_SIGN_LIST), Hotkey((uint16)0, "land_info", MTHK_LANDINFO), diff --git a/src/viewport.cpp b/src/viewport.cpp index ba94dbfb94..1d65756130 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -1368,7 +1368,7 @@ void ViewportAddString(const DrawPixelInfo *dpi, ZoomLevel small_from, const Vie } } -static Rect ExpandRectWithViewportSignMargins(Rect r, ZoomLevel zoom) +Rect ExpandRectWithViewportSignMargins(Rect r, ZoomLevel zoom) { /* Pessimistically always use normal font, but also assume small font is never larger in either dimension */ const int fh = FONT_HEIGHT_NORMAL; @@ -2187,7 +2187,7 @@ void SetSelectionRed(bool b) * @param sign the sign to check * @return true if the sign was hit */ -static bool CheckClickOnViewportSign(const ViewPort *vp, int x, int y, const ViewportSign *sign) +bool CheckClickOnViewportSign(const ViewPort *vp, int x, int y, const ViewportSign *sign) { bool small = (vp->zoom >= ZOOM_LVL_OUT_16X); int sign_half_width = ScaleByZoom((small ? sign->width_small : sign->width_normal) / 2, vp->zoom);