summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lang/english.txt1
-rw-r--r--src/rail_cmd.cpp55
-rw-r--r--src/rail_gui.cpp2
-rw-r--r--src/settings_gui.cpp1
-rw-r--r--src/settings_type.h1
-rw-r--r--src/table/settings.ini6
6 files changed, 56 insertions, 10 deletions
diff --git a/src/lang/english.txt b/src/lang/english.txt
index 8c341302a..fba9c9790 100644
--- a/src/lang/english.txt
+++ b/src/lang/english.txt
@@ -1295,6 +1295,7 @@ STR_CONFIG_SETTING_SMOOTH_ECONOMY :{LTBLUE}Enable
STR_CONFIG_SETTING_ALLOW_SHARES :{LTBLUE}Allow buying shares from other companies: {ORANGE}{STRING1}
STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :{LTBLUE}Percentage of leg profit to pay in feeder systems: {ORANGE}{STRING1}%
STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :{LTBLUE}When dragging, place signals every: {ORANGE}{STRING1} tile{P 0:1 "" s}
+STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE :{LTBLUE}When dragging, keep fixed distance between signals: {ORANGE}{STRING1}
STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE :{LTBLUE}Automatically build semaphores before: {ORANGE}{STRING1}
STR_CONFIG_SETTING_ENABLE_SIGNAL_GUI :{LTBLUE}Enable the signal GUI: {ORANGE}{STRING1}
STR_CONFIG_SETTING_DEFAULT_SIGNAL_TYPE :{LTBLUE}Signal type to build by default: {ORANGE}{STRING1}
diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp
index 1b60bfc6e..e8f92e51f 100644
--- a/src/rail_cmd.cpp
+++ b/src/rail_cmd.cpp
@@ -1198,6 +1198,7 @@ static bool CheckSignalAutoFill(TileIndex &tile, Trackdir &trackdir, int &signal
* - p2 = (bit 5) - 0 = build, 1 = remove signals
* - p2 = (bit 6) - 0 = selected stretch, 1 = auto fill
* - p2 = (bit 7- 9) - default signal type
+ * - p2 = (bit 10) - 0 = keep fixed distance, 1 = minimise gaps between signals
* - p2 = (bit 24-31) - user defined signals_density
* @param text unused
* @return the cost of this operation or an error
@@ -1212,6 +1213,7 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uin
bool semaphores = HasBit(p2, 4);
bool remove = HasBit(p2, 5);
bool autofill = HasBit(p2, 6);
+ bool minimise_gaps = HasBit(p2, 10);
byte signal_density = GB(p2, 24, 8);
if (p1 >= MapSize() || !ValParamTrackOrientation(track)) return CMD_ERROR;
@@ -1258,7 +1260,11 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uin
if (signals & SignalAgainstTrackdir(trackdir)) SetBit(signal_dir, 1);
/* signal_ctr - amount of tiles already processed
+ * last_used_ctr - amount of tiles before previously placed signal
* signals_density - setting to put signal on every Nth tile (double space on |, -- tracks)
+ * last_suitable_ctr - amount of tiles before last possible signal place
+ * last_suitable_tile - last tile where it is possible to place a signal
+ * last_suitable_trackdir - trackdir of the last tile
**********
* trackdir - trackdir to build with autorail
* semaphores - semaphores or signals
@@ -1266,11 +1272,15 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uin
* and convert all others to semaphore/signal
* remove - 1 remove signals, 0 build signals */
int signal_ctr = 0;
+ int last_used_ctr = INT_MIN; // initially INT_MIN to force building/removing at the first tile
+ int last_suitable_ctr = 0;
+ TileIndex last_suitable_tile = INVALID_TILE;
+ Trackdir last_suitable_trackdir = INVALID_TRACKDIR;
CommandCost last_error = CMD_ERROR;
bool had_success = false;
for (;;) {
/* only build/remove signals with the specified density */
- if (remove || signal_ctr % signal_density == 0) {
+ if (remove || minimise_gaps || signal_ctr % signal_density == 0) {
uint32 p1 = GB(TrackdirToTrack(trackdir), 0, 3);
SB(p1, 3, 1, mode);
SB(p1, 4, 1, semaphores);
@@ -1282,17 +1292,42 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uin
if (HasBit(signal_dir, 0)) signals |= SignalAlongTrackdir(trackdir);
if (HasBit(signal_dir, 1)) signals |= SignalAgainstTrackdir(trackdir);
- CommandCost ret = DoCommand(tile, p1, signals, flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS);
+ /* Test tiles in between for suitability as well if minimising gaps. */
+ bool test_only = minimise_gaps && signal_ctr < (last_used_ctr + signal_density);
+ CommandCost ret = DoCommand(tile, p1, signals, test_only ? flags & ~DC_EXEC : flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS);
- /* Be user-friendly and try placing signals as much as possible */
if (ret.Succeeded()) {
- had_success = true;
- total_cost.AddCost(ret);
- } else {
- /* The "No railway" error is the least important one. */
- if (ret.GetErrorMessage() != STR_ERROR_THERE_IS_NO_RAILROAD_TRACK ||
- last_error.GetErrorMessage() == INVALID_STRING_ID) {
- last_error = ret;
+ /* Remember last track piece where we can place a signal. */
+ last_suitable_ctr = signal_ctr;
+ last_suitable_tile = tile;
+ last_suitable_trackdir = trackdir;
+ } else if (!test_only && last_suitable_tile != INVALID_TILE) {
+ /* If a signal can't be placed, place it at the last possible position. */
+ SB(p1, 0, 3, TrackdirToTrack(last_suitable_trackdir));
+ ClrBit(p1, 17);
+
+ /* Pick the correct orientation for the track direction. */
+ signals = 0;
+ if (HasBit(signal_dir, 0)) signals |= SignalAlongTrackdir(last_suitable_trackdir);
+ if (HasBit(signal_dir, 1)) signals |= SignalAgainstTrackdir(last_suitable_trackdir);
+
+ ret = DoCommand(last_suitable_tile, p1, signals, flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS);
+ }
+
+ /* Collect cost. */
+ if (!test_only) {
+ /* Be user-friendly and try placing signals as much as possible */
+ if (ret.Succeeded()) {
+ had_success = true;
+ total_cost.AddCost(ret);
+ last_used_ctr = last_suitable_ctr;
+ last_suitable_tile = INVALID_TILE;
+ } else {
+ /* The "No railway" error is the least important one. */
+ if (ret.GetErrorMessage() != STR_ERROR_THERE_IS_NO_RAILROAD_TRACK ||
+ last_error.GetErrorMessage() == INVALID_STRING_ID) {
+ last_error = ret;
+ }
}
}
}
diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp
index 990812ad8..584622c36 100644
--- a/src/rail_gui.cpp
+++ b/src/rail_gui.cpp
@@ -390,12 +390,14 @@ static void HandleAutoSignalPlacement()
SB(p2, 6, 1, _ctrl_pressed);
SB(p2, 7, 3, _cur_signal_type);
SB(p2, 24, 8, _settings_client.gui.drag_signals_density);
+ SB(p2, 10, 1, !_settings_client.gui.drag_signals_fixed_distance);
} else {
SB(p2, 3, 1, 0);
SB(p2, 4, 1, (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC));
SB(p2, 6, 1, _ctrl_pressed);
SB(p2, 7, 3, _default_signal_type[_settings_client.gui.default_signal_type]);
SB(p2, 24, 8, _settings_client.gui.drag_signals_density);
+ SB(p2, 10, 1, !_settings_client.gui.drag_signals_fixed_distance);
}
/* _settings_client.gui.drag_signals_density is given as a parameter such that each user
diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp
index 308839d51..f0d6917b8 100644
--- a/src/settings_gui.cpp
+++ b/src/settings_gui.cpp
@@ -1451,6 +1451,7 @@ static SettingEntry _settings_construction_signals[] = {
SettingEntry("construction.signal_side"),
SettingEntry("gui.enable_signal_gui"),
SettingEntry("gui.drag_signals_density"),
+ SettingEntry("gui.drag_signals_fixed_distance"),
SettingEntry("gui.semaphore_build_before"),
SettingEntry("gui.default_signal_type"),
SettingEntry("gui.cycle_signal_types"),
diff --git a/src/settings_type.h b/src/settings_type.h
index 1f91a542a..c3825bdcf 100644
--- a/src/settings_type.h
+++ b/src/settings_type.h
@@ -102,6 +102,7 @@ struct GUISettings {
bool quick_goto; ///< Allow quick access to 'goto button' in vehicle orders window
bool auto_euro; ///< automatically switch to euro in 2002
byte drag_signals_density; ///< many signals density
+ bool drag_signals_fixed_distance; ///< keep fixed distance between signals when dragging
Year semaphore_build_before; ///< build semaphore signals automatically before this year
byte 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.ini b/src/table/settings.ini
index aec498f82..efa70b7f0 100644
--- a/src/table/settings.ini
+++ b/src/table/settings.ini
@@ -2256,6 +2256,12 @@ max = 20
str = STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY
proc = DragSignalsDensityChanged
+[SDTC_BOOL]
+var = gui.drag_signals_fixed_distance
+flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+def = false
+str = STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE
+
[SDTC_VAR]
var = gui.semaphore_build_before
type = SLE_INT32