summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKuhnovic <68320206+Kuhnovic@users.noreply.github.com>2021-01-07 10:17:05 +0100
committerGitHub <noreply@github.com>2021-01-07 10:17:05 +0100
commita3a792837220390735b44536762b0127f05b7a63 (patch)
treea3a4ba762b4b3da4ae7678a5bb837dd3cdf2b1c5
parent1b675e7075d1c2375cc8da5a928fb6b7be6317d5 (diff)
downloadopenttd-a3a792837220390735b44536762b0127f05b7a63.tar.xz
Feature: option to auto remove signals when in the way during rail construction (#8274)
-rw-r--r--src/lang/english.txt2
-rw-r--r--src/rail_cmd.cpp26
-rw-r--r--src/rail_gui.cpp10
-rw-r--r--src/settings_gui.cpp1
-rw-r--r--src/settings_type.h1
-rw-r--r--src/table/settings.ini8
6 files changed, 38 insertions, 10 deletions
diff --git a/src/lang/english.txt b/src/lang/english.txt
index 8d8a12871..c92d03cb6 100644
--- a/src/lang/english.txt
+++ b/src/lang/english.txt
@@ -1451,6 +1451,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_EXPENSES_LAYOUT :Group expenses in company finance window: {STRING2}
STR_CONFIG_SETTING_EXPENSES_LAYOUT_HELPTEXT :Define the layout for the company expenses window
+STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS :Automatically remove signals during rail construction: {STRING2}
+STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS_HELPTEXT :Automatically remove signals during rail construction if the signals are in the way. Note that this can potentially lead to train crashes.
STR_CONFIG_SETTING_SOUND_TICKER :News ticker: {STRING2}
STR_CONFIG_SETTING_SOUND_TICKER_HELPTEXT :Play sound for summarised news messages
diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp
index 34ad07d52..8af7871fc 100644
--- a/src/rail_cmd.cpp
+++ b/src/rail_cmd.cpp
@@ -262,10 +262,6 @@ static CommandCost CheckTrackCombination(TileIndex tile, TrackBits to_build, uin
return_cmd_error(STR_ERROR_ALREADY_BUILT);
}
- /* Let's see if we may build this */
- if (HasSignals(tile) && future != TRACK_BIT_HORZ && future != TRACK_BIT_VERT) {
- return_cmd_error(STR_ERROR_MUST_REMOVE_SIGNALS_FIRST);
- }
/* Normally, we may overlap and any combination is valid */
return CommandCost();
}
@@ -432,7 +428,9 @@ static inline bool ValParamTrackOrientation(Track track)
* @param tile tile to build on
* @param flags operation to perform
* @param p1 railtype of being built piece (normal, mono, maglev)
- * @param p2 rail track to build
+ * @param p2 various bitstuffed elements
+ * - (bit 0- 2) - track-orientation, valid values: 0-5 (@see Track)
+ * - (bit 3) - 0 = error on signal in the way, 1 = auto remove signals when in the way
* @param text unused
* @return the cost of this operation or an error
*/
@@ -440,6 +438,7 @@ CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, u
{
RailType railtype = Extract<RailType, 0, 6>(p1);
Track track = Extract<Track, 0, 3>(p2);
+ bool auto_remove_signals = HasBit(p2, 3);
CommandCost cost(EXPENSES_CONSTRUCTION);
if (!ValParamRailtype(railtype) || !ValParamTrackOrientation(track)) return CMD_ERROR;
@@ -460,6 +459,19 @@ CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, u
if (ret.Succeeded()) ret = EnsureNoTrainOnTrack(tile, track);
if (ret.Failed()) return ret;
+ if (HasSignals(tile) && TracksOverlap(GetTrackBits(tile) | TrackToTrackBits(track))) {
+ /* If adding the new track causes any overlap, all signals must be removed first */
+ if (!auto_remove_signals) return_cmd_error(STR_ERROR_MUST_REMOVE_SIGNALS_FIRST);
+
+ for (Track track_it = TRACK_BEGIN; track_it < TRACK_END; track_it++) {
+ if (HasTrack(tile, track_it) && HasSignalOnTrack(tile, track_it)) {
+ CommandCost ret_remove_signals = DoCommand(tile, track_it, 0, flags, CMD_REMOVE_SIGNALS);
+ if (ret_remove_signals.Failed()) return ret_remove_signals;
+ cost.AddCost(ret_remove_signals);
+ }
+ }
+ }
+
ret = CheckRailSlope(tileh, trackbit, GetTrackBits(tile), tile);
if (ret.Failed()) return ret;
cost.AddCost(ret);
@@ -868,6 +880,7 @@ static CommandCost ValidateAutoDrag(Trackdir *trackdir, TileIndex start, TileInd
* - p2 = (bit 6-8) - track-orientation, valid values: 0-5 (Track enum)
* - p2 = (bit 9) - 0 = build, 1 = remove tracks
* - p2 = (bit 10) - 0 = build up to an obstacle, 1 = fail if an obstacle is found (used for AIs).
+ * - p2 = (bit 11) - 0 = error on signal in the way, 1 = auto remove signals when in the way
* @param text unused
* @return the cost of this operation or an error
*/
@@ -876,6 +889,7 @@ static CommandCost CmdRailTrackHelper(TileIndex tile, DoCommandFlag flags, uint3
CommandCost total_cost(EXPENSES_CONSTRUCTION);
Track track = Extract<Track, 6, 3>(p2);
bool remove = HasBit(p2, 9);
+ bool auto_remove_signals = HasBit(p2, 11);
RailType railtype = Extract<RailType, 0, 6>(p2);
if ((!remove && !ValParamRailtype(railtype)) || !ValParamTrackOrientation(track)) return CMD_ERROR;
@@ -889,7 +903,7 @@ static CommandCost CmdRailTrackHelper(TileIndex tile, DoCommandFlag flags, uint3
bool had_success = false;
CommandCost last_error = CMD_ERROR;
for (;;) {
- CommandCost ret = DoCommand(tile, remove ? 0 : railtype, TrackdirToTrack(trackdir), flags, remove ? CMD_REMOVE_SINGLE_RAIL : CMD_BUILD_SINGLE_RAIL);
+ CommandCost ret = DoCommand(tile, remove ? 0 : railtype, TrackdirToTrack(trackdir) | (auto_remove_signals << 3), flags, remove ? CMD_REMOVE_SINGLE_RAIL : CMD_BUILD_SINGLE_RAIL);
if (ret.Failed()) {
last_error = ret;
diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp
index 788189dcc..7529efcec 100644
--- a/src/rail_gui.cpp
+++ b/src/rail_gui.cpp
@@ -91,7 +91,7 @@ void CcPlaySound_SPLAT_RAIL(const CommandCost &result, TileIndex tile, uint32 p1
static void GenericPlaceRail(TileIndex tile, int cmd)
{
- DoCommandP(tile, _cur_railtype, cmd,
+ DoCommandP(tile, _cur_railtype, cmd | (_settings_client.gui.auto_remove_signals << 3),
_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),
@@ -107,10 +107,11 @@ static void GenericPlaceRail(TileIndex tile, int cmd)
*/
static void PlaceExtraDepotRail(TileIndex tile, DiagDirection dir, Track track)
{
- if (GetRailTileType(tile) != RAIL_TILE_NORMAL) return;
+ if (GetRailTileType(tile) == RAIL_TILE_DEPOT) return;
+ if (GetRailTileType(tile) == RAIL_TILE_SIGNALS && !_settings_client.gui.auto_remove_signals) return;
if ((GetTrackBits(tile) & DiagdirReachesTracks(dir)) == 0) return;
- DoCommandP(tile, _cur_railtype, track, CMD_BUILD_SINGLE_RAIL);
+ DoCommandP(tile, _cur_railtype, track | (_settings_client.gui.auto_remove_signals << 3), CMD_BUILD_SINGLE_RAIL);
}
/** Additional pieces of track to add at the entrance of a depot. */
@@ -350,7 +351,8 @@ static void BuildRailClick_Remove(Window *w)
static void DoRailroadTrack(int mode)
{
- DoCommandP(TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), _cur_railtype | (mode << 6),
+ uint32 p2 = _cur_railtype | (mode << 6) | (_settings_client.gui.auto_remove_signals << 11);
+ DoCommandP(TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2,
_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),
diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp
index 77be428c9..751cf1a7d 100644
--- a/src/settings_gui.cpp
+++ b/src/settings_gui.cpp
@@ -1599,6 +1599,7 @@ static SettingsContainer &GetSettingsTree()
company->Add(new SettingEntry("gui.default_signal_type"));
company->Add(new SettingEntry("gui.cycle_signal_types"));
company->Add(new SettingEntry("gui.drag_signals_fixed_distance"));
+ company->Add(new SettingEntry("gui.auto_remove_signals"));
company->Add(new SettingEntry("gui.new_nonstop"));
company->Add(new SettingEntry("gui.stop_location"));
company->Add(new SettingEntry("gui.starting_colour"));
diff --git a/src/settings_type.h b/src/settings_type.h
index 5729a50be..219888a73 100644
--- a/src/settings_type.h
+++ b/src/settings_type.h
@@ -147,6 +147,7 @@ struct GUISettings {
uint8 osk_activation; ///< Mouse gesture to trigger the OSK.
byte starting_colour; ///< default color scheme for the company to start a new game with
bool show_newgrf_name; ///< Show the name of the NewGRF in the build vehicle window
+ bool auto_remove_signals; ///< automatically remove signals when in the way during rail construction
uint16 console_backlog_timeout; ///< the minimum amount of time items should be in the console backlog before they will be removed in ~3 seconds granularity.
uint16 console_backlog_length; ///< the minimum amount of items in the console backlog before items will be removed.
diff --git a/src/table/settings.ini b/src/table/settings.ini
index 517f2fb44..97c892b0b 100644
--- a/src/table/settings.ini
+++ b/src/table/settings.ini
@@ -2859,6 +2859,14 @@ strhelp = STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT
strval = STR_COLOUR_DARK_BLUE
[SDTC_BOOL]
+var = gui.auto_remove_signals
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+def = false
+str = STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS
+strhelp = STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS_HELPTEXT
+cat = SC_ADVANCED
+
+[SDTC_BOOL]
var = gui.prefer_teamchat
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
def = false