MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / CmdBuildSingleSignal

Function CmdBuildSingleSignal

src/rail_cmd.cpp:1049–1194  ·  view source on GitHub ↗

* Build signals, alternate between double/single, signal/semaphore, * pre/exit/combo-signals, and what-else not. If the rail piece does not * have any signals, signal cycling is ignored * @param flags operation to perform * @param tile tile where to build the signals * @param track track-orientation * @param sigtype type of the signal * @param sigvar variant of signal type (normal/semaphore

Source from the content-addressed store, hash-verified

1047 * @todo p2 should be replaced by two bits for "along" and "against" the track.
1048 */
1049CommandCost CmdBuildSingleSignal(DoCommandFlags flags, TileIndex tile, Track track, SignalType sigtype, SignalVariant sigvar, bool convert_signal, bool skip_existing_signals, bool ctrl_pressed, SignalType cycle_start, SignalType cycle_stop, uint8_t num_dir_cycle, uint8_t signals_copy)
1050{
1051 if (sigtype > SIGTYPE_LAST || sigvar > SIG_SEMAPHORE) return CMD_ERROR;
1052 if (cycle_start > cycle_stop || cycle_stop > SIGTYPE_LAST) return CMD_ERROR;
1053
1054 if (ctrl_pressed) sigvar = (SignalVariant)(sigvar ^ SIG_SEMAPHORE);
1055
1056 /* You can only build signals on plain rail tiles, and the selected track must exist */
1057 if (!ValParamTrackOrientation(track) || !IsPlainRailTile(tile) ||
1058 !HasTrack(tile, track)) {
1059 return CommandCost(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK);
1060 }
1061 /* Protect against invalid signal copying */
1062 if (signals_copy != 0 && (signals_copy & SignalOnTrack(track)) == 0) return CMD_ERROR;
1063
1064 CommandCost ret = CheckTileOwnership(tile);
1065 if (ret.Failed()) return ret;
1066
1067 /* See if this is a valid track combination for signals (no overlap) */
1068 if (TracksOverlap(GetTrackBits(tile))) return CommandCost(STR_ERROR_NO_SUITABLE_RAILROAD_TRACK);
1069
1070 /* In case we don't want to change an existing signal, return without error. */
1071 if (skip_existing_signals && HasSignalOnTrack(tile, track)) return CommandCost();
1072
1073 /* you can not convert a signal if no signal is on track */
1074 if (convert_signal && !HasSignalOnTrack(tile, track)) return CommandCost(STR_ERROR_THERE_ARE_NO_SIGNALS);
1075
1076 CommandCost cost;
1077 if (!HasSignalOnTrack(tile, track)) {
1078 /* build new signals */
1079 cost = CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_SIGNALS]);
1080 } else {
1081 if (signals_copy != 0 && sigvar != GetSignalVariant(tile, track)) {
1082 /* convert signals <-> semaphores */
1083 cost = CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_SIGNALS] + _price[PR_CLEAR_SIGNALS]);
1084
1085 } else if (convert_signal) {
1086 /* convert button pressed */
1087 if (ctrl_pressed || GetSignalVariant(tile, track) != sigvar) {
1088 /* it costs money to change signal variant (light or semaphore) */
1089 cost = CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_SIGNALS] + _price[PR_CLEAR_SIGNALS]);
1090 } else {
1091 /* it is free to change signal type (block, exit, entry, combo, path, etc) */
1092 cost = CommandCost();
1093 }
1094
1095 } else {
1096 /* it is free to change orientation or number of signals on the tile (for block/presignals which allow signals in both directions) */
1097 cost = CommandCost();
1098 }
1099 }
1100
1101 if (flags.Test(DoCommandFlag::Execute)) {
1102 Train *v = nullptr;
1103 /* The new/changed signal could block our path. As this can lead to
1104 * stale reservations, we clear the path reservation here and try
1105 * to redo it later on. */
1106 if (HasReservedTracks(tile, TrackToTrackBits(track))) {

Callers

nothing calls this directly

Calls 15

ValParamTrackOrientationFunction · 0.85
IsPlainRailTileFunction · 0.85
CommandCostClass · 0.85
SignalOnTrackFunction · 0.85
CheckTileOwnershipFunction · 0.85
TracksOverlapFunction · 0.85
GetTrackBitsFunction · 0.85
HasSignalOnTrackFunction · 0.85
GetSignalVariantFunction · 0.85
HasReservedTracksFunction · 0.85
TrackToTrackBitsFunction · 0.85
GetTrainForReservationFunction · 0.85

Tested by

no test coverage detected