diff --git a/src/lang/extra/english.txt b/src/lang/extra/english.txt index 9899cb5b35..cab5541111 100644 --- a/src/lang/extra/english.txt +++ b/src/lang/extra/english.txt @@ -816,6 +816,9 @@ STR_CONFIG_SETTING_SCENARIO_HOUSE_IGNORE_ZONES_ANYWHERE :Anywhere STR_CONFIG_SETTING_DRAG_SIGNALS_SKIP_STATIONS :When auto-fill dragging, continue past stations/waypoints: {STRING2} STR_CONFIG_SETTING_DRAG_SIGNALS_SKIP_STATIONS_HELPTEXT :Select the behaviour of signal placement when Ctrl+dragging signals. If disabled, signal placement stops when reaching a station/waypoint tile. If enabled, signal placement continues on the far side of rail stations/waypoints +STR_CONFIG_SETTING_DRAG_SIGNALS_STOP_RESTRICTED_SIGNAL :When removing signals using auto-fill drag, stop at restricted signals: {STRING2} +STR_CONFIG_SETTING_DRAG_SIGNALS_STOP_RESTRICTED_SIGNAL_HELPTEXT :Select the behaviour of signal placement when removing signal using Ctrl+dragging. If enabled, removal of signals stops when reaching a signal with an attached routing restriction program + STR_CONFIG_SETTING_NETWORK_CHANGE_NOT_ALLOWED :{WHITE}Can't change setting... STR_CONFIG_SETTING_NETWORK_CHANGE_NOT_ALLOWED_NEWGRF :{WHITE}...setting is observed by a NewGRF @@ -1959,6 +1962,7 @@ STR_ERROR_CAN_T_BUILD_ROAD_WAYPOINT :{WHITE}Can't bu STR_ERROR_CAN_T_REMOVE_ROAD_WAYPOINT :{WHITE}Can't remove road waypoint here... STR_ERROR_MUST_REMOVE_ROADWAYPOINT_FIRST :{WHITE}Must remove road waypoint first STR_ERROR_UNSUITABLE_SIGNAL_TYPE :{WHITE}... unsuitable signal type +STR_ERROR_RESTRICTED_SIGNAL :{WHITE}... signal has attached routing restriction program STR_ERROR_SIGNAL_CHANGES :{WHITE}Number of programmable pre-signal evaluations exceeded limit STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Bridge is too low for station diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index be75995918..dc277f2515 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -1473,17 +1473,18 @@ static void ReReserveTrainPath(Train *v) * @param tile tile where to build the signals * @param flags operation to perform * @param p1 various bitstuffed elements - * - p1 = (bit 0-2) - track-orientation, valid values: 0-5 (Track enum) - * - p1 = (bit 3) - 1 = override signal/semaphore, or pre/exit/combo signal or (for bit 7) toggle variant (CTRL-toggle) - * - p1 = (bit 4) - 0 = signals, 1 = semaphores - * - p1 = (bit 5-7) - type of the signal, for valid values see enum SignalType in rail_map.h - * - p1 = (bit 8) - convert the present signal type and variant - * - p1 = (bit 9-10)- cycle through which signal sets? - * - p1 = (bit 15-16)-cycle the signal direction this many times - * - p1 = (bit 17) - 1 = don't modify an existing signal but don't fail either, 0 = always set new signal type - * - p1 = (bit 18) - permit creation of/conversion to bidirectionally signalled bridges/tunnels - * - p1 = (bit 19-22)-signal style - * - p1 = (bit 23-27)-signal spacing + * - p1 = (bit 0-2) - track-orientation, valid values: 0-5 (Track enum) + * - p1 = (bit 3) - 1 = override signal/semaphore, or pre/exit/combo signal or (for bit 7) toggle variant (CTRL-toggle) + * - p1 = (bit 4) - 0 = signals, 1 = semaphores + * - p1 = (bit 5-7) - type of the signal, for valid values see enum SignalType in rail_map.h + * - p1 = (bit 8) - convert the present signal type and variant + * - p1 = (bit 9-10) - cycle through which signal sets? + * - p1 = (bit 15-16) - cycle the signal direction this many times + * - p1 = (bit 17) - 1 = don't modify an existing signal but don't fail either, 0 = always set new signal type + * - p1 = (bit 18) - permit creation of/conversion to bidirectionally signalled bridges/tunnels + * - p1 = (bit 19-22) - signal style + * - p1 = (bit 23-27) - signal spacing + * - p1 = (bit 28) - disallow removing restricted signals * @param p2 used for CmdBuildManySignals() to copy direction of first signal * @param text unused * @return the cost of this operation or an error @@ -1983,6 +1984,7 @@ static bool CheckSignalAutoFill(TileIndex &tile, Trackdir &trackdir, int &signal * - p2 = (bit 24-31) - user defined signals_density * @param p3 various bitstuffed elements * - p3 = (bit 0) - 1 = skip over rail stations/waypoints, 0 = stop at rail stations/waypoints + * - p3 = (bit 1) - 1 = stop at restricted signals on remove, 0 = allow removing restricted signals * @param text unused * @return the cost of this operation or an error */ @@ -2000,6 +2002,7 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uin uint8_t signal_density = GB(p2, 24, 8); uint8_t signal_style = GB(p2, 11, 4); bool allow_station = HasBit(p3, 0); + bool no_remove_restricted_signal = HasBit(p3, 1); if (p1 >= MapSize() || !ValParamTrackOrientation(track)) return CMD_ERROR; TileIndex end_tile = p1; @@ -2088,6 +2091,7 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uin SB(param1, 19, 4, signal_style); if (!remove && signal_ctr == 0) SetBit(param1, 17); if (!remove) SB(param1, 23, 5, Clamp(GB(p2, 24, 8), 1, 16)); + if (remove && no_remove_restricted_signal) SetBit(param1, 28); /* Pick the correct orientation for the track direction */ signals = 0; @@ -2107,6 +2111,9 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uin last_suitable_ctr = signal_ctr; last_suitable_tile = tile; last_suitable_trackdir = trackdir; + } else if (ret.GetErrorMessage() == STR_ERROR_RESTRICTED_SIGNAL) { + last_error = ret; + break; } else if (!test_only && last_suitable_tile != INVALID_TILE && ret.GetErrorMessage() != STR_ERROR_CANNOT_MODIFY_TRACK_TRAIN_APPROACHING) { /* If a signal can't be placed, place it at the last possible position. */ SB(param1, 0, 3, TrackdirToTrack(last_suitable_trackdir)); @@ -2183,6 +2190,7 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uin * - p2 = (bit 24-31) - user defined signals_density * @param p3 various bitstuffed elements * - p3 = (bit 0) - 1 = skip over rail stations/waypoints, 0 = stop at rail stations/waypoints + * - p3 = (bit 1) - 1 = stop at restricted signals on remove, 0 = allow removing restricted signals * @param text unused * @return the cost of this operation or an error * @see CmdSignalTrackHelper @@ -2196,10 +2204,9 @@ CommandCost CmdBuildSignalTrack(TileIndex tile, DoCommandFlag flags, uint32_t p1 * Remove signals * @param tile coordinates where signal is being deleted from * @param flags operation to perform - * @param p1 various bitstuffed elements, only track information is used + * @param p1 various bitstuffed elements, only relevant bits shown, see CmdBuildSingleSignal for full list * - (bit 0- 2) - track-orientation, valid values: 0-5 (Track enum) - * - (bit 3) - override signal/semaphore, or pre/exit/combo signal (CTRL-toggle) - * - (bit 4) - 0 = signals, 1 = semaphores + * - (bit 28) - disallow removing restricted signals * @param p2 unused * @param text unused * @return the cost of this operation or an error @@ -2207,6 +2214,7 @@ CommandCost CmdBuildSignalTrack(TileIndex tile, DoCommandFlag flags, uint32_t p1 CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32_t p1, uint32_t p2, const char *text) { Track track = Extract(p1); + bool no_remove_restricted = HasBit(p1, 28); Money cost = _price[PR_CLEAR_SIGNALS]; if (IsTileType(tile, MP_TUNNELBRIDGE)) { @@ -2216,6 +2224,7 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32_t } if (!IsTunnelBridgeWithSignalSimulation(tile)) return_cmd_error(STR_ERROR_THERE_ARE_NO_SIGNALS); TileIndex end = GetOtherTunnelBridgeEnd(tile); + if (no_remove_restricted && (IsTunnelBridgeRestrictedSignal(tile) || IsTunnelBridgeRestrictedSignal(end))) return_cmd_error(STR_ERROR_RESTRICTED_SIGNAL); CommandCost ret = TunnelBridgeIsFree(tile, end, nullptr, TBIFM_ACROSS_ONLY); if (ret.Failed()) return ret; @@ -2227,6 +2236,7 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32_t if (!HasSignalOnTrack(tile, track)) { return_cmd_error(STR_ERROR_THERE_ARE_NO_SIGNALS); } + if (no_remove_restricted && GetExistingTraceRestrictProgram(tile, track) != nullptr) return_cmd_error(STR_ERROR_RESTRICTED_SIGNAL); } /* Only water can remove signals from anyone */ @@ -2326,6 +2336,7 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32_t * - p2 = (bit 24-31) - user defined signals_density * @param p3 various bitstuffed elements * - p3 = (bit 0) - 1 = skip over rail stations/waypoints, 0 = stop at rail stations/waypoints + * - p3 = (bit 1) - 1 = stop at restricted signals on remove, 0 = allow removing restricted signals * @param text unused * @return the cost of this operation or an error * @see CmdSignalTrackHelper diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index e742e07b34..6995f9afee 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -496,6 +496,7 @@ static void HandleAutoSignalPlacement() SB(p2, 10, 1, !_settings_client.gui.drag_signals_fixed_distance); } SB(p3, 0, 1, _settings_client.gui.drag_signals_skip_stations); + SB(p3, 1, 1, _ctrl_pressed && _settings_client.gui.drag_signals_stop_restricted_signal); /* _settings_client.gui.drag_signals_density is given as a parameter such that each user * in a network game can specify their own signal density */ diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 957a904c0b..cbcc900d3a 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -2356,6 +2356,7 @@ static SettingsContainer &GetSettingsTree() signals->Add(new SettingEntry("gui.cycle_signal_types")); signals->Add(new SettingEntry("gui.drag_signals_fixed_distance")); signals->Add(new SettingEntry("gui.drag_signals_skip_stations")); + signals->Add(new SettingEntry("gui.drag_signals_stop_restricted_signal")); signals->Add(new SettingEntry("gui.auto_remove_signals")); signals->Add(new SettingEntry("gui.show_restricted_signal_recolour")); signals->Add(new SettingEntry("gui.show_all_signal_default")); diff --git a/src/settings_type.h b/src/settings_type.h index 29ea37b86f..f43fb3da69 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -262,6 +262,7 @@ struct GUISettings : public TimeSettings { uint8_t drag_signals_density; ///< many signals density bool drag_signals_fixed_distance; ///< keep fixed distance between signals when dragging bool drag_signals_skip_stations; ///< continue past station/waypoint tiles when auto-fill dragging signals + bool drag_signals_stop_restricted_signal; ///< when removing signals using auto-fill drag, sto pwhen reaching a signal with an attached routing restriction CalTime::Year semaphore_build_before; ///< build semaphore signals automatically before this year uint8_t news_message_timeout; ///< how much longer than the news message "age" should we keep the message in the history bool show_track_reservation; ///< highlight reserved tracks. diff --git a/src/table/settings/gui_settings.ini b/src/table/settings/gui_settings.ini index 743255a60f..854a1459f8 100644 --- a/src/table/settings/gui_settings.ini +++ b/src/table/settings/gui_settings.ini @@ -1096,6 +1096,14 @@ str = STR_CONFIG_SETTING_DRAG_SIGNALS_SKIP_STATIONS strhelp = STR_CONFIG_SETTING_DRAG_SIGNALS_SKIP_STATIONS_HELPTEXT cat = SC_EXPERT +[SDTC_BOOL] +var = gui.drag_signals_stop_restricted_signal +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_PATCH +def = true +str = STR_CONFIG_SETTING_DRAG_SIGNALS_STOP_RESTRICTED_SIGNAL +strhelp = STR_CONFIG_SETTING_DRAG_SIGNALS_STOP_RESTRICTED_SIGNAL_HELPTEXT +cat = SC_EXPERT + [SDTC_VAR] var = gui.semaphore_build_before type = SLE_INT32