|
|
@ -230,70 +230,6 @@ static uint SkipToEndOfTunnel(TrackPathFinder* tpf, TileIndex tile, DiagDirectio
|
|
|
|
return flotr.tile;
|
|
|
|
return flotr.tile;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection direction);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Most code of the "Normal" case of TPF Mode 1; for signals special tricks
|
|
|
|
|
|
|
|
* have to be done, but those happen in TPFMode1; this is just to prevent
|
|
|
|
|
|
|
|
* gotos ;). */
|
|
|
|
|
|
|
|
static inline void TPFMode1_NormalCase(TrackPathFinder* tpf, TileIndex tile, TileIndex tile_org, DiagDirection direction)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/* Check in case of rail if the owner is the same */
|
|
|
|
|
|
|
|
if (tpf->tracktype == TRANSPORT_RAIL) {
|
|
|
|
|
|
|
|
/* don't enter train depot from the back */
|
|
|
|
|
|
|
|
if (IsTileDepotType(tile, TRANSPORT_RAIL) && GetRailDepotDirection(tile) == direction) return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (IsTileType(tile_org, MP_RAILWAY) || IsTileType(tile_org, MP_STATION) || IsTileType(tile_org, MP_TUNNELBRIDGE))
|
|
|
|
|
|
|
|
if (IsTileType(tile, MP_RAILWAY) || IsTileType(tile, MP_STATION) || IsTileType(tile, MP_TUNNELBRIDGE))
|
|
|
|
|
|
|
|
if (GetTileOwner(tile_org) != GetTileOwner(tile)) return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* check if the new tile can be entered from that direction */
|
|
|
|
|
|
|
|
if (tpf->tracktype == TRANSPORT_ROAD) {
|
|
|
|
|
|
|
|
/* road stops and depots now have a track (r4419)
|
|
|
|
|
|
|
|
* don't enter road stop from the back */
|
|
|
|
|
|
|
|
if (IsStandardRoadStopTile(tile) && ReverseDiagDir(GetRoadStopDir(tile)) != direction) return;
|
|
|
|
|
|
|
|
/* don't enter road depot from the back */
|
|
|
|
|
|
|
|
if (IsTileDepotType(tile, TRANSPORT_ROAD) && ReverseDiagDir(GetRoadDepotDirection(tile)) != direction) return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Check if the new tile is a tunnel or bridge head and that the direction
|
|
|
|
|
|
|
|
* and transport type match */
|
|
|
|
|
|
|
|
if (IsTileType(tile, MP_TUNNELBRIDGE)) {
|
|
|
|
|
|
|
|
if (GetTunnelBridgeDirection(tile) != direction ||
|
|
|
|
|
|
|
|
GetTunnelBridgeTransportType(tile) != tpf->tracktype) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tpf->rd.cur_length++;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint bits = GetTileTrackStatus(tile, tpf->tracktype, tpf->sub_type);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((byte)bits != tpf->var2) {
|
|
|
|
|
|
|
|
bits &= _tpfmode1_and[direction];
|
|
|
|
|
|
|
|
bits |= bits >> 8;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
bits &= 0xBF;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (bits != 0) {
|
|
|
|
|
|
|
|
if (!tpf->disable_tile_hash || (tpf->rd.cur_length <= 64 && (KillFirstBit(bits) == 0 || ++tpf->rd.depth <= 7))) {
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
|
|
|
int i = FIND_FIRST_BIT(bits);
|
|
|
|
|
|
|
|
bits = KillFirstBit(bits);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tpf->the_dir = (Trackdir)((_otherdir_mask[direction] & (byte)(1 << i)) ? (i + 8) : i);
|
|
|
|
|
|
|
|
RememberData rd = tpf->rd;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (TPFSetTileBit(tpf, tile, tpf->the_dir) &&
|
|
|
|
|
|
|
|
!tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, &tpf->rd.pft_var6) ) {
|
|
|
|
|
|
|
|
TPFMode1(tpf, tile, _tpf_new_direction[tpf->the_dir]);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
tpf->rd = rd;
|
|
|
|
|
|
|
|
} while (bits != 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection direction)
|
|
|
|
static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection direction)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
TileIndex tile_org = tile;
|
|
|
|
TileIndex tile_org = tile;
|
|
|
@ -330,40 +266,53 @@ static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection directi
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tile += TileOffsByDiagDir(direction);
|
|
|
|
tile += TileOffsByDiagDir(direction);
|
|
|
|
|
|
|
|
|
|
|
|
TPFMode1_NormalCase(tpf, tile, tile_org, direction);
|
|
|
|
/* Check in case of rail if the owner is the same */
|
|
|
|
|
|
|
|
if (tpf->tracktype == TRANSPORT_RAIL) {
|
|
|
|
|
|
|
|
/* don't enter train depot from the back */
|
|
|
|
|
|
|
|
if (IsTileDepotType(tile, TRANSPORT_RAIL) && GetRailDepotDirection(tile) == direction) return;
|
|
|
|
|
|
|
|
|
|
|
|
/* the next is only used when signals are checked.
|
|
|
|
if (IsTileType(tile_org, MP_RAILWAY) || IsTileType(tile_org, MP_STATION) || IsTileType(tile_org, MP_TUNNELBRIDGE))
|
|
|
|
* seems to go in 2 directions simultaneously */
|
|
|
|
if (IsTileType(tile, MP_RAILWAY) || IsTileType(tile, MP_STATION) || IsTileType(tile, MP_TUNNELBRIDGE))
|
|
|
|
|
|
|
|
if (GetTileOwner(tile_org) != GetTileOwner(tile)) return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* if i can get rid of this, tail end recursion can be used to minimize
|
|
|
|
/* check if the new tile can be entered from that direction */
|
|
|
|
* stack space dramatically. */
|
|
|
|
if (tpf->tracktype == TRANSPORT_ROAD) {
|
|
|
|
|
|
|
|
/* road stops and depots now have a track (r4419)
|
|
|
|
|
|
|
|
* don't enter road stop from the back */
|
|
|
|
|
|
|
|
if (IsStandardRoadStopTile(tile) && ReverseDiagDir(GetRoadStopDir(tile)) != direction) return;
|
|
|
|
|
|
|
|
/* don't enter road depot from the back */
|
|
|
|
|
|
|
|
if (IsTileDepotType(tile, TRANSPORT_ROAD) && ReverseDiagDir(GetRoadDepotDirection(tile)) != direction) return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* If we are doing signal setting, we must reverse at evere tile, so we
|
|
|
|
/* Check if the new tile is a tunnel or bridge head and that the direction
|
|
|
|
* iterate all the tracks in a signal block, even when a normal train would
|
|
|
|
* and transport type match */
|
|
|
|
* not reach it (for example, when two lines merge */
|
|
|
|
if (IsTileType(tile, MP_TUNNELBRIDGE)) {
|
|
|
|
if (tpf->hasbit_13)
|
|
|
|
if (GetTunnelBridgeDirection(tile) != direction ||
|
|
|
|
|
|
|
|
GetTunnelBridgeTransportType(tile) != tpf->tracktype) {
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
direction = ReverseDiagDir(direction);
|
|
|
|
tpf->rd.cur_length++;
|
|
|
|
tile += TileOffsByDiagDir(direction);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint bits = GetTileTrackStatus(tile, tpf->tracktype, tpf->sub_type);
|
|
|
|
uint bits = GetTileTrackStatus(tile, tpf->tracktype, tpf->sub_type);
|
|
|
|
bits |= (bits >> 8);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((byte)bits != tpf->var2) {
|
|
|
|
if ((byte)bits != tpf->var2) {
|
|
|
|
bits &= _bits_mask[direction];
|
|
|
|
bits &= _tpfmode1_and[direction];
|
|
|
|
|
|
|
|
bits |= bits >> 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bits &= 0xBF;
|
|
|
|
bits &= 0xBF;
|
|
|
|
if (bits == 0)
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (bits != 0) {
|
|
|
|
|
|
|
|
if (!tpf->disable_tile_hash || (tpf->rd.cur_length <= 64 && (KillFirstBit(bits) == 0 || ++tpf->rd.depth <= 7))) {
|
|
|
|
do {
|
|
|
|
do {
|
|
|
|
uint i = FIND_FIRST_BIT(bits);
|
|
|
|
int i = FIND_FIRST_BIT(bits);
|
|
|
|
bits = KillFirstBit(bits);
|
|
|
|
bits = KillFirstBit(bits);
|
|
|
|
|
|
|
|
|
|
|
|
tpf->the_dir = (Trackdir)((_otherdir_mask[direction] & (byte)(1 << i)) ? (i + 8) : i);
|
|
|
|
tpf->the_dir = (Trackdir)((_otherdir_mask[direction] & (byte)(1 << i)) ? (i + 8) : i);
|
|
|
|
RememberData rd = tpf->rd;
|
|
|
|
RememberData rd = tpf->rd;
|
|
|
|
|
|
|
|
|
|
|
|
if (TPFSetTileBit(tpf, tile, tpf->the_dir) &&
|
|
|
|
if (TPFSetTileBit(tpf, tile, tpf->the_dir) &&
|
|
|
|
!tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, &tpf->rd.pft_var6) ) {
|
|
|
|
!tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, &tpf->rd.pft_var6) ) {
|
|
|
|
TPFMode1(tpf, tile, _tpf_new_direction[tpf->the_dir]);
|
|
|
|
TPFMode1(tpf, tile, _tpf_new_direction[tpf->the_dir]);
|
|
|
@ -371,6 +320,8 @@ static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection directi
|
|
|
|
tpf->rd = rd;
|
|
|
|
tpf->rd = rd;
|
|
|
|
} while (bits != 0);
|
|
|
|
} while (bits != 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void FollowTrack(TileIndex tile, uint16 flags, uint sub_type, DiagDirection direction, TPFEnumProc *enum_proc, TPFAfterProc *after_proc, void *data)
|
|
|
|
void FollowTrack(TileIndex tile, uint16 flags, uint sub_type, DiagDirection direction, TPFEnumProc *enum_proc, TPFAfterProc *after_proc, void *data)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -391,7 +342,6 @@ void FollowTrack(TileIndex tile, uint16 flags, uint sub_type, DiagDirection dire
|
|
|
|
tpf.var2 = HasBit(flags, 15) ? 0x43 : 0xFF; // 0x8000
|
|
|
|
tpf.var2 = HasBit(flags, 15) ? 0x43 : 0xFF; // 0x8000
|
|
|
|
|
|
|
|
|
|
|
|
tpf.disable_tile_hash = HasBit(flags, 12); // 0x1000
|
|
|
|
tpf.disable_tile_hash = HasBit(flags, 12); // 0x1000
|
|
|
|
tpf.hasbit_13 = HasBit(flags, 13); // 0x2000
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tpf.tracktype = (TransportType)(flags & 0xFF);
|
|
|
|
tpf.tracktype = (TransportType)(flags & 0xFF);
|
|
|
|