From 88cfe6fc9cfe4056bbdf9f27f4575d130b142dd8 Mon Sep 17 00:00:00 2001 From: michi_cc Date: Tue, 17 Apr 2012 19:43:29 +0000 Subject: [PATCH] (svn r24129) -Feature [FS#3660]: Option to minimise signal distance when dragging over obstacles. (adf88) --- src/lang/english.txt | 1 + src/rail_cmd.cpp | 55 ++++++++++++++++++++++++++++++++++-------- src/rail_gui.cpp | 2 ++ src/settings_gui.cpp | 1 + src/settings_type.h | 1 + src/table/settings.ini | 6 +++++ 6 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index 8c341302ad..fba9c97905 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 1b60bfc6ef..e8f92e51fc 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 990812ad82..584622c36a 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 308839d51f..f0d6917b85 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 1f91a542a7..c3825bdcf8 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 aec498f820..efa70b7f04 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