diff options
Diffstat (limited to 'src/rail_gui.cpp')
-rw-r--r-- | src/rail_gui.cpp | 92 |
1 files changed, 74 insertions, 18 deletions
diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index ed1bd0ac0..254be5a81 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -49,6 +49,8 @@ static bool _convert_signal_button; ///< convert signal button in the s static SignalVariant _cur_signal_variant; ///< set the signal variant (for signal GUI) static SignalType _cur_signal_type; ///< set the signal type (for signal GUI) +extern TileIndex _rail_track_endtile; // rail_cmd.cpp + /* Map the setting: default_signal_type to the corresponding signal type */ static const SignalType _default_signal_type[] = {SIGTYPE_NORMAL, SIGTYPE_PBS, SIGTYPE_PBS_ONEWAY}; @@ -88,9 +90,9 @@ void CcPlaySound1E(const CommandCost &result, TileIndex tile, uint32 p1, uint32 if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_20_SPLAT_2, tile); } -static void GenericPlaceRail(TileIndex tile, int cmd) +static bool GenericPlaceRail(TileIndex tile, Track track) { - DoCommandP(tile, _cur_railtype, cmd, + return DoCommandP(tile, _cur_railtype, track, _remove_button_clicked ? CMD_REMOVE_SINGLE_RAIL | CMD_MSG(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK) : CMD_BUILD_SINGLE_RAIL | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK), @@ -279,6 +281,17 @@ void CcBuildRailTunnel(const CommandCost &result, TileIndex tile, uint32 p1, uin } /** + * Place a rail tunnel. + * @param tile Position of the first tile of the tunnel. + */ +static void PlaceRail_Tunnel(TileIndex tile) +{ + if (DoCommandP(tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRailTunnel)) { + StoreRailPlacementEndpoints(tile, _build_tunnel_endtile, TileX(tile) == TileX(_build_tunnel_endtile) ? TRACK_Y : TRACK_X, false); + } +} + +/** * Toggles state of the Remove button of Build rail toolbar * @param w window the button belongs to */ @@ -346,9 +359,9 @@ static void BuildRailClick_Remove(Window *w) } } -static void DoRailroadTrack(int mode) +static bool DoRailroadTrack(TileIndex start_tile, TileIndex end_tile, Track track) { - DoCommandP(TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), _cur_railtype | (mode << 4), + return DoCommandP(start_tile, end_tile, _cur_railtype | (track << 4), _remove_button_clicked ? CMD_REMOVE_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK) : CMD_BUILD_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK)); @@ -356,14 +369,15 @@ static void DoRailroadTrack(int mode) static void HandleAutodirPlacement() { - int trackstat = _thd.drawstyle & HT_DIR_MASK; // 0..5 - - if (_thd.drawstyle & HT_RAIL) { // one tile case - GenericPlaceRail(TileVirtXY(_thd.selend.x, _thd.selend.y), trackstat); - return; + Track track = (Track)(_thd.drawstyle & HT_DIR_MASK); // 0..5 + TileIndex start_tile = TileVirtXY(_thd.selstart.x, _thd.selstart.y); + TileIndex end_tile = TileVirtXY(_thd.selend.x, _thd.selend.y); + + if (_thd.drawstyle & HT_RAIL ? + GenericPlaceRail(end_tile, track) : // one tile case + DoRailroadTrack(start_tile, end_tile, track)) { // longer track + StoreRailPlacementEndpoints(start_tile, _rail_track_endtile, track, true); } - - DoRailroadTrack(trackstat); } /** @@ -409,6 +423,20 @@ static void HandleAutoSignalPlacement() CcPlaySound1E); } +typedef CursorID (RailtypeInfo::Cursor::* RailCursorType); + +static const RailCursorType RAIL_CURSOR_NS = &RailtypeInfo::Cursor::rail_ns; +static const RailCursorType RAIL_CURSOR_X = &RailtypeInfo::Cursor::rail_swne; +static const RailCursorType RAIL_CURSOR_EW = &RailtypeInfo::Cursor::rail_ew; +static const RailCursorType RAIL_CURSOR_Y = &RailtypeInfo::Cursor::rail_nwse; +static const RailCursorType RAIL_CURSOR_AUTORAIL = &RailtypeInfo::Cursor::autorail; + +void HandleRailPlacePushButton(Window *w, int widget, RailCursorType cursor, HighLightStyle mode) +{ + if (_ctrl_pressed) mode |= HT_POLY; + HandlePlacePushButton(w, widget, GetRailTypeInfo(_cur_railtype)->cursor.*cursor, mode); +} + /** Rail toolbar management class. */ struct BuildRailToolbarWindow : Window { @@ -490,6 +518,24 @@ struct BuildRailToolbarWindow : Window { } } + virtual void DrawWidget(const Rect &r, int widget) const + { + switch (widget) { + case WID_RAT_BUILD_NS: + case WID_RAT_BUILD_X: + case WID_RAT_BUILD_EW: + case WID_RAT_BUILD_Y: + case WID_RAT_AUTORAIL: + if (this->IsWidgetLowered(widget) && _thd.place_mode & HT_POLY) { + DrawSprite(SPR_BLOT, PALETTE_TO_WHITE, r.left + WD_IMGBTN_LEFT, r.top + WD_IMGBTN_TOP); + } + break; + + default: + break; + } + } + virtual void SetStringParameters(int widget) const { if (widget == WID_RAT_CAPTION) { @@ -511,27 +557,27 @@ struct BuildRailToolbarWindow : Window { _remove_button_clicked = false; switch (widget) { case WID_RAT_BUILD_NS: - HandlePlacePushButton(this, WID_RAT_BUILD_NS, GetRailTypeInfo(_cur_railtype)->cursor.rail_ns, HT_LINE | HT_DIR_VL); + HandleRailPlacePushButton(this, WID_RAT_BUILD_NS, RAIL_CURSOR_NS, HT_LINE | HT_DIR_VL); this->last_user_action = widget; break; case WID_RAT_BUILD_X: - HandlePlacePushButton(this, WID_RAT_BUILD_X, GetRailTypeInfo(_cur_railtype)->cursor.rail_swne, HT_LINE | HT_DIR_X); + HandleRailPlacePushButton(this, WID_RAT_BUILD_X, RAIL_CURSOR_X, HT_LINE | HT_DIR_X); this->last_user_action = widget; break; case WID_RAT_BUILD_EW: - HandlePlacePushButton(this, WID_RAT_BUILD_EW, GetRailTypeInfo(_cur_railtype)->cursor.rail_ew, HT_LINE | HT_DIR_HL); + HandleRailPlacePushButton(this, WID_RAT_BUILD_EW, RAIL_CURSOR_EW, HT_LINE | HT_DIR_HL); this->last_user_action = widget; break; case WID_RAT_BUILD_Y: - HandlePlacePushButton(this, WID_RAT_BUILD_Y, GetRailTypeInfo(_cur_railtype)->cursor.rail_nwse, HT_LINE | HT_DIR_Y); + HandleRailPlacePushButton(this, WID_RAT_BUILD_Y, RAIL_CURSOR_Y, HT_LINE | HT_DIR_Y); this->last_user_action = widget; break; case WID_RAT_AUTORAIL: - HandlePlacePushButton(this, WID_RAT_AUTORAIL, GetRailTypeInfo(_cur_railtype)->cursor.autorail, HT_RAIL); + HandleRailPlacePushButton(this, WID_RAT_AUTORAIL, RAIL_CURSOR_AUTORAIL, HT_RAIL); this->last_user_action = widget; break; @@ -607,6 +653,14 @@ struct BuildRailToolbarWindow : Window { virtual void OnPlaceObject(Point pt, TileIndex tile) { + /* Test if we are in "polyline" mode. */ + if (_thd.drawstyle & HT_POLY) { + /* There is no drag-dropping while in "polyline" mode, we build the track + * immidiately after pushing mouse button down. */ + HandleAutodirPlacement(); + return; + } + switch (this->last_user_action) { case WID_RAT_BUILD_NS: VpStartPlaceSizing(tile, VPM_FIX_VERTICAL | VPM_RAILDIRS, DDSP_PLACE_RAIL); @@ -655,7 +709,7 @@ struct BuildRailToolbarWindow : Window { break; case WID_RAT_BUILD_TUNNEL: - DoCommandP(tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRailTunnel); + PlaceRail_Tunnel(tile); break; case WID_RAT_CONVERT_RAIL: @@ -758,13 +812,15 @@ struct BuildRailToolbarWindow : Window { }; const uint16 _railtoolbar_autorail_keys[] = {'5', 'A' | WKC_GLOBAL_HOTKEY, 0}; +const uint16 _railtoolbar_polyline_autorail_keys[] = {'5' | WKC_CTRL, 'A' | WKC_GLOBAL_HOTKEY | WKC_CTRL, 0}; Hotkey<BuildRailToolbarWindow> BuildRailToolbarWindow::railtoolbar_hotkeys[] = { Hotkey<BuildRailToolbarWindow>('1', "build_ns", WID_RAT_BUILD_NS), Hotkey<BuildRailToolbarWindow>('2', "build_x", WID_RAT_BUILD_X), Hotkey<BuildRailToolbarWindow>('3', "build_ew", WID_RAT_BUILD_EW), Hotkey<BuildRailToolbarWindow>('4', "build_y", WID_RAT_BUILD_Y), - Hotkey<BuildRailToolbarWindow>(_railtoolbar_autorail_keys, "autorail", WID_RAT_AUTORAIL), + Hotkey<BuildRailToolbarWindow>(_railtoolbar_autorail_keys, "autorail", WID_RAT_AUTORAIL), // without CTRL + Hotkey<BuildRailToolbarWindow>(_railtoolbar_polyline_autorail_keys, "polyrail", WID_RAT_AUTORAIL), // with CTRL Hotkey<BuildRailToolbarWindow>('6', "demolish", WID_RAT_DEMOLISH), Hotkey<BuildRailToolbarWindow>('7', "depot", WID_RAT_BUILD_DEPOT), Hotkey<BuildRailToolbarWindow>('8', "waypoint", WID_RAT_BUILD_WAYPOINT), |