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

Function MaskWireBits

src/elrail.cpp:125–172  ·  view source on GitHub ↗

* Masks out track bits when neighbouring tiles are unelectrified. */

Source from the content-addressed store, hash-verified

123 * Masks out track bits when neighbouring tiles are unelectrified.
124 */
125static TrackBits MaskWireBits(TileIndex t, TrackBits tracks)
126{
127 /* Single track bits are never masked out. */
128 if (HasAtMostOneBit(tracks)) [[likely]] return tracks;
129
130 if (!IsPlainRailTile(t)) return tracks;
131
132 TrackdirBits neighbour_tdb = TRACKDIR_BIT_NONE;
133 for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) {
134 /* If the neighbour tile is either not electrified or has no tracks that can be reached
135 * from this tile, mark all trackdirs that can be reached from the neighbour tile
136 * as needing no catenary. We make an exception for blocked station tiles with a matching
137 * axis that still display wires to preserve visual continuity. */
138 TileIndex next_tile = TileAddByDiagDir(t, d);
139 RailType rt = GetTileRailType(next_tile);
140 if (rt == INVALID_RAILTYPE || !HasRailCatenary(rt) ||
141 ((TrackStatusToTrackBits(GetTileTrackStatus(next_tile, TRANSPORT_RAIL, 0)) & DiagdirReachesTracks(d)) == TRACK_BIT_NONE &&
142 (!HasStationTileRail(next_tile) || GetRailStationAxis(next_tile) != DiagDirToAxis(d) || !CanStationTileHaveWires(next_tile)))) {
143 neighbour_tdb |= DiagdirReachesTrackdirs(ReverseDiagDir(d));
144 }
145 }
146
147 /* If the tracks from either a diagonal crossing or don't overlap, both
148 * trackdirs have to be marked to mask the corresponding track bit. Else
149 * one marked trackdir is enough the mask the track bit. */
150 TrackBits mask;
151 if (tracks == TRACK_BIT_CROSS || !TracksOverlap(tracks)) {
152 /* If the tracks form either a diagonal crossing or don't overlap, both
153 * trackdirs have to be marked to mask the corresponding track bit. */
154 mask = ~(TrackBits)((neighbour_tdb & (neighbour_tdb >> 8)) & TRACK_BIT_MASK);
155 /* If that results in no masked tracks and it is not a diagonal crossing,
156 * require only one marked trackdir to mask. */
157 if (tracks != TRACK_BIT_CROSS && (mask & TRACK_BIT_MASK) == TRACK_BIT_MASK) mask = ~TrackdirBitsToTrackBits(neighbour_tdb);
158 } else {
159 /* Require only one marked trackdir to mask the track. */
160 mask = ~TrackdirBitsToTrackBits(neighbour_tdb);
161 /* If that results in an empty set, require both trackdirs for diagonal track. */
162 if ((tracks & mask) == TRACK_BIT_NONE) {
163 if ((neighbour_tdb & TRACKDIR_BIT_X_NE) == 0 || (neighbour_tdb & TRACKDIR_BIT_X_SW) == 0) mask |= TRACK_BIT_X;
164 if ((neighbour_tdb & TRACKDIR_BIT_Y_NW) == 0 || (neighbour_tdb & TRACKDIR_BIT_Y_SE) == 0) mask |= TRACK_BIT_Y;
165 /* If that still is not enough, require both trackdirs for any track. */
166 if ((tracks & mask) == TRACK_BIT_NONE) mask = ~(TrackBits)((neighbour_tdb & (neighbour_tdb >> 8)) & TRACK_BIT_MASK);
167 }
168 }
169
170 /* Mask the tracks only if at least one track bit would remain. */
171 return (tracks & mask) != TRACK_BIT_NONE ? tracks & mask : tracks;
172}
173
174/**
175 * Get the base wire sprite to use.

Callers 1

DrawRailCatenaryRailwayFunction · 0.85

Calls 15

HasAtMostOneBitFunction · 0.85
IsPlainRailTileFunction · 0.85
TileAddByDiagDirFunction · 0.85
GetTileRailTypeFunction · 0.85
HasRailCatenaryFunction · 0.85
TrackStatusToTrackBitsFunction · 0.85
GetTileTrackStatusFunction · 0.85
DiagdirReachesTracksFunction · 0.85
HasStationTileRailFunction · 0.85
GetRailStationAxisFunction · 0.85
DiagDirToAxisFunction · 0.85
CanStationTileHaveWiresFunction · 0.85

Tested by

no test coverage detected