15 #include "tunnel_map.h" |
15 #include "tunnel_map.h" |
16 #include "settings_type.h" |
16 #include "settings_type.h" |
17 #include "depot.h" |
17 #include "depot.h" |
18 #include "tunnelbridge_map.h" |
18 #include "tunnelbridge_map.h" |
19 #include "core/random_func.hpp" |
19 #include "core/random_func.hpp" |
|
20 #include "tunnelbridge.h" |
20 |
21 |
21 /* remember which tiles we have already visited so we don't visit them again. */ |
22 /* remember which tiles we have already visited so we don't visit them again. */ |
22 static bool TPFSetTileBit(TrackPathFinder *tpf, TileIndex tile, int dir) |
23 static bool TPFSetTileBit(TrackPathFinder *tpf, TileIndex tile, int dir) |
23 { |
24 { |
24 uint hash, val, offs; |
25 uint hash, val, offs; |
190 tpf->rd = rd; |
191 tpf->rd = rd; |
191 } while (ClrBit(bits, i) != 0); |
192 } while (ClrBit(bits, i) != 0); |
192 |
193 |
193 } |
194 } |
194 |
195 |
195 |
|
196 /* Returns the end tile and the length of a tunnel. The length does not |
|
197 * include the starting tile (entry), it does include the end tile (exit). |
|
198 */ |
|
199 FindLengthOfTunnelResult FindLengthOfTunnel(TileIndex tile, DiagDirection dir) |
|
200 { |
|
201 TileIndexDiff delta = TileOffsByDiagDir(dir); |
|
202 uint z = GetTileZ(tile); |
|
203 FindLengthOfTunnelResult flotr; |
|
204 |
|
205 flotr.length = 0; |
|
206 |
|
207 dir = ReverseDiagDir(dir); |
|
208 do { |
|
209 flotr.length++; |
|
210 tile += delta; |
|
211 } while( |
|
212 !IsTunnelTile(tile) || |
|
213 GetTunnelBridgeDirection(tile) != dir || |
|
214 GetTileZ(tile) != z |
|
215 ); |
|
216 |
|
217 flotr.tile = tile; |
|
218 return flotr; |
|
219 } |
|
220 |
|
221 /** |
196 /** |
222 * Checks if any vehicle can enter/leave tile in given diagdir |
197 * Checks if any vehicle can enter/leave tile in given diagdir |
223 * Checks only for rail/road depots and road non-drivethrough stations |
198 * Checks only for rail/road depots and road non-drivethrough stations |
224 * @param tile tile to check |
199 * @param tile tile to check |
225 * @param side side of tile we are trying to leave/enter |
200 * @param side side of tile we are trying to leave/enter |
255 DiagDirection dir = GetTunnelBridgeDirection(tile); |
230 DiagDirection dir = GetTunnelBridgeDirection(tile); |
256 /* entering tunnel / bridge? */ |
231 /* entering tunnel / bridge? */ |
257 if (dir == direction) { |
232 if (dir == direction) { |
258 TileIndex endtile = GetOtherTunnelBridgeEnd(tile); |
233 TileIndex endtile = GetOtherTunnelBridgeEnd(tile); |
259 |
234 |
260 tpf->rd.cur_length += DistanceManhattan(tile, endtile); |
235 tpf->rd.cur_length += GetTunnelBridgeLength(tile, endtile) + 1; |
261 |
236 |
262 TPFSetTileBit(tpf, tile, 14); |
237 TPFSetTileBit(tpf, tile, 14); |
263 TPFSetTileBit(tpf, endtile, 14); |
238 TPFSetTileBit(tpf, endtile, 14); |
264 |
239 |
265 tile = endtile; |
240 tile = endtile; |
663 /* If the tile is the entry tile of a tunnel, and we're not going out of the tunnel, |
638 /* If the tile is the entry tile of a tunnel, and we're not going out of the tunnel, |
664 * need to find the exit of the tunnel. */ |
639 * need to find the exit of the tunnel. */ |
665 if (IsTileType(tile, MP_TUNNELBRIDGE)) { |
640 if (IsTileType(tile, MP_TUNNELBRIDGE)) { |
666 if (IsTunnel(tile)) { |
641 if (IsTunnel(tile)) { |
667 if (GetTunnelBridgeDirection(tile) != ReverseDiagDir(direction)) { |
642 if (GetTunnelBridgeDirection(tile) != ReverseDiagDir(direction)) { |
668 FindLengthOfTunnelResult flotr; |
|
669 |
|
670 /* We are not just driving out of the tunnel */ |
643 /* We are not just driving out of the tunnel */ |
671 if (GetTunnelBridgeDirection(tile) != direction || |
644 if (GetTunnelBridgeDirection(tile) != direction || |
672 GetTunnelBridgeTransportType(tile) != tpf->tracktype) { |
645 GetTunnelBridgeTransportType(tile) != tpf->tracktype) { |
673 /* We are not driving into the tunnel, or it is an invalid tunnel */ |
646 /* We are not driving into the tunnel, or it is an invalid tunnel */ |
674 continue; |
647 continue; |
675 } |
648 } |
676 if (!HasBit(tpf->railtypes, GetRailType(tile))) { |
649 if (!HasBit(tpf->railtypes, GetRailType(tile))) { |
677 bits = TRACK_BIT_NONE; |
650 bits = TRACK_BIT_NONE; |
678 break; |
651 break; |
679 } |
652 } |
680 flotr = FindLengthOfTunnel(tile, direction); |
653 |
681 si.cur_length += flotr.length * DIAG_FACTOR; |
654 TileIndex endtile = GetOtherTunnelEnd(tile); |
682 tile = flotr.tile; |
655 si.cur_length += DIAG_FACTOR * (GetTunnelBridgeLength(tile, endtile) + 1); |
|
656 tile = endtile; |
683 /* tile now points to the exit tile of the tunnel */ |
657 /* tile now points to the exit tile of the tunnel */ |
684 } |
658 } |
685 } else { // IsBridge(tile) |
659 } else { // IsBridge(tile) |
686 TileIndex tile_end; |
660 TileIndex tile_end; |
687 if (GetTunnelBridgeDirection(tile) != ReverseDiagDir(direction)) { |
661 if (GetTunnelBridgeDirection(tile) != ReverseDiagDir(direction)) { |