(svn r10437) -Feature: Automatic signal completion, enabled by pressing ctrl when dragging signals. Signals will continue following track until an existing signal, junction or station are reached. This currently replaces the existing use of ctrl-drag for changing existing signal type.

This commit is contained in:
peter1138 2007-07-04 17:21:28 +00:00
parent 156f149625
commit efef78f786
2 changed files with 98 additions and 8 deletions

View File

@ -738,6 +738,64 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32
return cost; return cost;
} }
static bool CheckSignalAutoFill(TileIndex &tile, Trackdir &trackdir, int &signal_ctr, bool remove)
{
tile = AddTileIndexDiffCWrap(tile, _trackdelta[trackdir]);
if (tile == INVALID_TILE) return false;
/* Check for track bits on the new tile */
uint32 ts = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0);
TrackdirBits trackdirbits = (TrackdirBits)(ts & TRACKDIR_BIT_MASK);
if (TracksOverlap(TrackdirBitsToTrackBits(trackdirbits))) return false;
trackdirbits &= TrackdirReachesTrackdirs(trackdir);
/* No track bits, must stop */
if (trackdirbits == TRACKDIR_BIT_NONE) return false;
/* Get the first track dir */
trackdir = RemoveFirstTrackdir(&trackdirbits);
/* Any left? It's a junction so we stop */
if (trackdirbits != TRACKDIR_BIT_NONE) return false;
switch (GetTileType(tile)) {
case MP_RAILWAY:
if (IsRailDepot(tile)) return false;
if (!remove && HasSignalOnTrack(tile, TrackdirToTrack(trackdir))) return false;
signal_ctr++;
if (IsDiagonalTrackdir(trackdir)) {
signal_ctr++;
/* Ensure signal_ctr even so X and Y pieces get signals */
CLRBIT(signal_ctr, 0);
}
return true;
case MP_STREET:
if (!IsLevelCrossing(tile)) return false;
signal_ctr += 2;
return true;
case MP_TUNNELBRIDGE: {
TileIndex orig_tile = tile;
/* Skip to end of tunnel or bridge */
if (IsBridge(tile)) {
if (GetBridgeTransportType(tile) != TRANSPORT_RAIL) return false;
if (GetBridgeRampDirection(tile) != TrackdirToExitdir(trackdir)) return false;
tile = GetOtherBridgeEnd(tile);
} else {
if (GetTunnelTransportType(tile) != TRANSPORT_RAIL) return false;
if (GetTunnelDirection(tile) != TrackdirToExitdir(trackdir)) return false;
tile = GetOtherTunnelEnd(tile);
}
signal_ctr += 2 + DistanceMax(orig_tile, tile) * 2;
return true;
}
default: return false;
}
}
/** Build many signals by dragging; AutoSignals /** Build many signals by dragging; AutoSignals
* @param tile start tile of drag * @param tile start tile of drag
* @param flags operation to perform * @param flags operation to perform
@ -747,6 +805,7 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32
* - p2 = (bit 3) - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle) * - p2 = (bit 3) - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle)
* - p2 = (bit 4) - 0 = signals, 1 = semaphores * - p2 = (bit 4) - 0 = signals, 1 = semaphores
* - p2 = (bit 5) - 0 = build, 1 = remove signals * - p2 = (bit 5) - 0 = build, 1 = remove signals
* - p2 = (bit 6) - 0 = selected stretch, 1 = auto fill
* - p2 = (bit 24-31) - user defined signals_density * - p2 = (bit 24-31) - user defined signals_density
*/ */
static CommandCost CmdSignalTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) static CommandCost CmdSignalTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
@ -756,11 +815,13 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, uint32 flags, uint32 p1,
byte signals; byte signals;
bool error = true; bool error = true;
TileIndex end_tile; TileIndex end_tile;
TileIndex start_tile = tile;
Track track = (Track)GB(p2, 0, 3); Track track = (Track)GB(p2, 0, 3);
bool mode = HASBIT(p2, 3); bool mode = HASBIT(p2, 3);
bool semaphores = HASBIT(p2, 4); bool semaphores = HASBIT(p2, 4);
bool remove = HASBIT(p2, 5); bool remove = HASBIT(p2, 5);
bool autofill = HASBIT(p2, 6);
Trackdir trackdir = TrackToTrackdir(track); Trackdir trackdir = TrackToTrackdir(track);
byte signal_density = GB(p2, 24, 8); byte signal_density = GB(p2, 24, 8);
@ -774,11 +835,15 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, uint32 flags, uint32 p1,
/* for vertical/horizontal tracks, double the given signals density /* for vertical/horizontal tracks, double the given signals density
* since the original amount will be too dense (shorter tracks) */ * since the original amount will be too dense (shorter tracks) */
if (!IsDiagonalTrack(track)) signal_density *= 2; signal_density *= 2;
if (CmdFailed(ValidateAutoDrag(&trackdir, tile, end_tile))) return CMD_ERROR; if (CmdFailed(ValidateAutoDrag(&trackdir, tile, end_tile))) return CMD_ERROR;
track = TrackdirToTrack(trackdir); /* trackdir might have changed, keep track in sync */ track = TrackdirToTrack(trackdir); /* trackdir might have changed, keep track in sync */
Trackdir start_trackdir = trackdir;
/* Autofill must start on a valid track to be able to avoid loops */
if (autofill && !HasTrack(tile, track)) return CMD_ERROR;
/* copy the signal-style of the first rail-piece if existing */ /* copy the signal-style of the first rail-piece if existing */
if (HasSignals(tile)) { if (HasSignals(tile)) {
@ -791,6 +856,10 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, uint32 flags, uint32 p1,
signals = SignalOnTrack(track); signals = SignalOnTrack(track);
} }
byte signal_dir = 0;
if (signals & SignalAlongTrackdir(trackdir)) SETBIT(signal_dir, 0);
if (signals & SignalAgainstTrackdir(trackdir)) SETBIT(signal_dir, 1);
/* signal_ctr - amount of tiles already processed /* signal_ctr - amount of tiles already processed
* signals_density - patch setting to put signal on every Nth tile (double space on |, -- tracks) * signals_density - patch setting to put signal on every Nth tile (double space on |, -- tracks)
********** **********
@ -802,10 +871,16 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, uint32 flags, uint32 p1,
signal_ctr = 0; signal_ctr = 0;
for (;;) { for (;;) {
/* only build/remove signals with the specified density */ /* only build/remove signals with the specified density */
if (signal_ctr % signal_density == 0) { if ((remove && autofill) || signal_ctr % signal_density == 0) {
uint32 p1 = GB(TrackdirToTrack(trackdir), 0, 3); uint32 p1 = GB(TrackdirToTrack(trackdir), 0, 3);
SB(p1, 3, 1, mode); SB(p1, 3, 1, mode);
SB(p1, 4, 1, semaphores); SB(p1, 4, 1, semaphores);
/* Pick the correct orientation for the track direction */
signals = 0;
if (HASBIT(signal_dir, 0)) signals |= SignalAlongTrackdir(trackdir);
if (HASBIT(signal_dir, 1)) signals |= SignalAgainstTrackdir(trackdir);
ret = DoCommand(tile, p1, signals, flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS); ret = DoCommand(tile, p1, signals, flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS);
/* Be user-friendly and try placing signals as much as possible */ /* Be user-friendly and try placing signals as much as possible */
@ -815,13 +890,24 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, uint32 flags, uint32 p1,
} }
} }
if (tile == end_tile) break; if (autofill) {
if (!CheckSignalAutoFill(tile, trackdir, signal_ctr, remove)) break;
tile += ToTileIndexDiff(_trackdelta[trackdir]); /* Prevent possible loops */
signal_ctr++; if (tile == start_tile && trackdir == start_trackdir) break;
} else {
if (tile == end_tile) break;
/* toggle railbit for the non-diagonal tracks (|, -- tracks) */ tile += ToTileIndexDiff(_trackdelta[trackdir]);
if (!IsDiagonalTrackdir(trackdir)) ToggleBitT(trackdir, 0); signal_ctr++;
/* toggle railbit for the non-diagonal tracks (|, -- tracks) */
if (IsDiagonalTrackdir(trackdir)) {
signal_ctr++;
} else {
ToggleBitT(trackdir, 0);
}
}
} }
return error ? CMD_ERROR : total_cost; return error ? CMD_ERROR : total_cost;
@ -837,6 +923,7 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, uint32 flags, uint32 p1,
* - p2 = (bit 3) - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle) * - p2 = (bit 3) - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle)
* - p2 = (bit 4) - 0 = signals, 1 = semaphores * - p2 = (bit 4) - 0 = signals, 1 = semaphores
* - p2 = (bit 5) - 0 = build, 1 = remove signals * - p2 = (bit 5) - 0 = build, 1 = remove signals
* - p2 = (bit 6) - 0 = selected stretch, 1 = auto fill
* - p2 = (bit 24-31) - user defined signals_density * - p2 = (bit 24-31) - user defined signals_density
* @see CmdSignalTrackHelper * @see CmdSignalTrackHelper
*/ */
@ -900,6 +987,7 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint3
* - p2 = (bit 3) - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle) * - p2 = (bit 3) - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle)
* - p2 = (bit 4) - 0 = signals, 1 = semaphores * - p2 = (bit 4) - 0 = signals, 1 = semaphores
* - p2 = (bit 5) - 0 = build, 1 = remove signals * - p2 = (bit 5) - 0 = build, 1 = remove signals
* - p2 = (bit 6) - 0 = selected stretch, 1 = auto fill
* - p2 = (bit 24-31) - user defined signals_density * - p2 = (bit 24-31) - user defined signals_density
* @see CmdSignalTrackHelper * @see CmdSignalTrackHelper
*/ */

View File

@ -373,8 +373,10 @@ static void HandleAutoSignalPlacement()
return; return;
} }
SB(p2, 3, 1, _ctrl_pressed); /* XXX Steal ctrl for autosignal function, until we get some GUI */
SB(p2, 3, 1, 0);
SB(p2, 4, 1, _cur_year < _patches.semaphore_build_before); SB(p2, 4, 1, _cur_year < _patches.semaphore_build_before);
SB(p2, 6, 1, _ctrl_pressed);
SB(p2, 24, 8, _patches.drag_signals_density); SB(p2, 24, 8, _patches.drag_signals_density);
/* _patches.drag_signals_density is given as a parameter such that each user /* _patches.drag_signals_density is given as a parameter such that each user