(svn r9914) -Codechange: prepare GTTS and the pathfinders to handle multiple road types on a single tile.

This commit is contained in:
rubidium 2007-05-24 22:41:50 +00:00
parent b82676be2a
commit 440d723d84
32 changed files with 108 additions and 81 deletions

View File

@ -67,7 +67,7 @@ enum {
static TrackBits GetRailTrackStatus(TileIndex tile) static TrackBits GetRailTrackStatus(TileIndex tile)
{ {
uint32 r = GetTileTrackStatus(tile, TRANSPORT_RAIL); uint32 r = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0);
return (TrackBits)(byte) (r | r >> 8); return (TrackBits)(byte) (r | r >> 8);
} }
@ -1862,7 +1862,7 @@ static bool AiDoFollowTrack(const Player* p)
arpfd.tile2 = p->ai.cur_tile_a; arpfd.tile2 = p->ai.cur_tile_a;
arpfd.flag = false; arpfd.flag = false;
arpfd.count = 0; arpfd.count = 0;
FollowTrack(p->ai.cur_tile_a + TileOffsByDiagDir(p->ai.cur_dir_a), 0x2000 | TRANSPORT_RAIL, (DiagDirection)(p->ai.cur_dir_a ^ 2), FollowTrack(p->ai.cur_tile_a + TileOffsByDiagDir(p->ai.cur_dir_a), 0x2000 | TRANSPORT_RAIL, 0, (DiagDirection)(p->ai.cur_dir_a ^ 2),
(TPFEnumProc*)AiEnumFollowTrack, NULL, &arpfd); (TPFEnumProc*)AiEnumFollowTrack, NULL, &arpfd);
return arpfd.count > 8; return arpfd.count > 8;
} }
@ -2824,13 +2824,13 @@ static bool AiCheckRoadFinished(Player *p)
tile = TILE_MASK(p->ai.cur_tile_a + TileOffsByDiagDir(dir)); tile = TILE_MASK(p->ai.cur_tile_a + TileOffsByDiagDir(dir));
if (IsRoadStopTile(tile) || IsTileDepotType(tile, TRANSPORT_ROAD)) return false; if (IsRoadStopTile(tile) || IsTileDepotType(tile, TRANSPORT_ROAD)) return false;
bits = GetTileTrackStatus(tile, TRANSPORT_ROAD) & _ai_road_table_and[dir]; bits = GetTileTrackStatus(tile, TRANSPORT_ROAD, ROADTYPES_ROAD) & _ai_road_table_and[dir];
if (bits == 0) return false; if (bits == 0) return false;
are.best_dist = (uint)-1; are.best_dist = (uint)-1;
for_each_bit(i, bits) { for_each_bit(i, bits) {
FollowTrack(tile, 0x3000 | TRANSPORT_ROAD, (DiagDirection)_dir_by_track[i], (TPFEnumProc*)AiEnumFollowRoad, NULL, &are); FollowTrack(tile, 0x3000 | TRANSPORT_ROAD, ROADTYPES_ROAD, (DiagDirection)_dir_by_track[i], (TPFEnumProc*)AiEnumFollowRoad, NULL, &are);
} }
if (DistanceManhattan(tile, are.dest) <= are.best_dist) return false; if (DistanceManhattan(tile, are.dest) <= are.best_dist) return false;

View File

@ -764,7 +764,7 @@ static void ClickTile_Clear(TileIndex tile)
/* not used */ /* not used */
} }
static uint32 GetTileTrackStatus_Clear(TileIndex tile, TransportType mode) static uint32 GetTileTrackStatus_Clear(TileIndex tile, TransportType mode, uint sub_mode)
{ {
return 0; return 0;
} }

View File

@ -713,7 +713,7 @@ static void DisasterTick_Submarine(Vehicle *v)
tile = v->tile + TileOffsByDiagDir(DirToDiagDir(v->direction)); tile = v->tile + TileOffsByDiagDir(DirToDiagDir(v->direction));
if (IsValidTile(tile)) { if (IsValidTile(tile)) {
TrackdirBits r = (TrackdirBits)GetTileTrackStatus(tile, TRANSPORT_WATER); TrackdirBits r = (TrackdirBits)GetTileTrackStatus(tile, TRANSPORT_WATER, 0);
if (TrackdirBitsToTrackBits(r) == TRACK_BIT_ALL && !CHANCE16(1, 90)) { if (TrackdirBitsToTrackBits(r) == TRACK_BIT_ALL && !CHANCE16(1, 90)) {
GetNewVehiclePosResult gp = GetNewVehiclePos(v); GetNewVehiclePosResult gp = GetNewVehiclePos(v);

View File

@ -63,7 +63,7 @@ static void ChangeTileOwner_Dummy(TileIndex tile, PlayerID old_player, PlayerID
/* not used */ /* not used */
} }
static uint32 GetTileTrackStatus_Dummy(TileIndex tile, TransportType mode) static uint32 GetTileTrackStatus_Dummy(TileIndex tile, TransportType mode, uint sub_mode)
{ {
return 0; return 0;
} }

View File

@ -735,7 +735,7 @@ static void ClickTile_Industry(TileIndex tile)
ShowIndustryViewWindow(GetIndustryIndex(tile)); ShowIndustryViewWindow(GetIndustryIndex(tile));
} }
static uint32 GetTileTrackStatus_Industry(TileIndex tile, TransportType mode) static uint32 GetTileTrackStatus_Industry(TileIndex tile, TransportType mode, uint sub_mode)
{ {
return 0; return 0;
} }

View File

@ -274,9 +274,9 @@ void DoClearSquare(TileIndex tile)
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
} }
uint32 GetTileTrackStatus(TileIndex tile, TransportType mode) uint32 GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode)
{ {
return _tile_type_procs[GetTileType(tile)]->get_tile_track_status_proc(tile, mode); return _tile_type_procs[GetTileType(tile)]->get_tile_track_status_proc(tile, mode, sub_mode);
} }
void ChangeTileOwner(TileIndex tile, PlayerID old_player, PlayerID new_player) void ChangeTileOwner(TileIndex tile, PlayerID old_player, PlayerID new_player)

View File

@ -44,7 +44,7 @@ void DrawFoundation(TileInfo *ti, uint f);
void DoClearSquare(TileIndex tile); void DoClearSquare(TileIndex tile);
void RunTileLoop(); void RunTileLoop();
uint32 GetTileTrackStatus(TileIndex tile, TransportType mode); uint32 GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode);
void GetAcceptedCargo(TileIndex tile, AcceptedCargo ac); void GetAcceptedCargo(TileIndex tile, AcceptedCargo ac);
void ChangeTileOwner(TileIndex tile, PlayerID old_player, PlayerID new_player); void ChangeTileOwner(TileIndex tile, PlayerID old_player, PlayerID new_player);
void AnimateTile(TileIndex tile); void AnimateTile(TileIndex tile);

View File

@ -307,7 +307,7 @@ static uint32 GetRailContinuationInfo(TileIndex tile)
uint i; uint i;
for (i = 0; i < lengthof(x_dir); i++, dir++, diagdir++) { for (i = 0; i < lengthof(x_dir); i++, dir++, diagdir++) {
uint32 ts = GetTileTrackStatus(tile + TileOffsByDir(*dir), TRANSPORT_RAIL); uint32 ts = GetTileTrackStatus(tile + TileOffsByDir(*dir), TRANSPORT_RAIL, 0);
if (ts != 0) { if (ts != 0) {
/* If there is any track on the tile, set the bit in the second byte */ /* If there is any track on the tile, set the bit in the second byte */
SETBIT(res, i + 8); SETBIT(res, i + 8);

View File

@ -523,6 +523,7 @@ static void NPFFollowTrack(AyStar* aystar, OpenListNode* current)
uint32 ts; uint32 ts;
TrackdirBits trackdirbits; TrackdirBits trackdirbits;
TransportType type = (TransportType)aystar->user_data[NPF_TYPE]; TransportType type = (TransportType)aystar->user_data[NPF_TYPE];
uint subtype = aystar->user_data[NPF_SUB_TYPE];
bool override_dst_check = false; bool override_dst_check = false;
/* Initialize to 0, so we can jump out (return) somewhere an have no neighbours */ /* Initialize to 0, so we can jump out (return) somewhere an have no neighbours */
aystar->num_neighbours = 0; aystar->num_neighbours = 0;
@ -622,7 +623,7 @@ static void NPFFollowTrack(AyStar* aystar, OpenListNode* current)
* the back */ * the back */
ts = TrackdirToTrackdirBits(DiagdirToDiagTrackdir(ReverseDiagDir(exitdir))); ts = TrackdirToTrackdirBits(DiagdirToDiagTrackdir(ReverseDiagDir(exitdir)));
} else { } else {
ts = GetTileTrackStatus(dst_tile, type); ts = GetTileTrackStatus(dst_tile, type, subtype);
} }
trackdirbits = (TrackdirBits)(ts & TRACKDIR_BIT_MASK); /* Filter out signal status and the unused bits */ trackdirbits = (TrackdirBits)(ts & TRACKDIR_BIT_MASK); /* Filter out signal status and the unused bits */
@ -670,7 +671,7 @@ static void NPFFollowTrack(AyStar* aystar, OpenListNode* current)
* multiple targets that are spread around, we should perform a breadth first * multiple targets that are spread around, we should perform a breadth first
* search by specifiying CalcZero as our heuristic. * search by specifiying CalcZero as our heuristic.
*/ */
static NPFFoundTargetData NPFRouteInternal(AyStarNode* start1, AyStarNode* start2, NPFFindStationOrTileData* target, AyStar_EndNodeCheck target_proc, AyStar_CalculateH heuristic_proc, TransportType type, Owner owner, RailTypeMask railtypes, uint reverse_penalty) static NPFFoundTargetData NPFRouteInternal(AyStarNode* start1, AyStarNode* start2, NPFFindStationOrTileData* target, AyStar_EndNodeCheck target_proc, AyStar_CalculateH heuristic_proc, TransportType type, uint sub_type, Owner owner, RailTypeMask railtypes, uint reverse_penalty)
{ {
int r; int r;
NPFFoundTargetData result; NPFFoundTargetData result;
@ -709,6 +710,7 @@ static NPFFoundTargetData NPFRouteInternal(AyStarNode* start1, AyStarNode* start
/* Initialize user_data */ /* Initialize user_data */
_npf_aystar.user_data[NPF_TYPE] = type; _npf_aystar.user_data[NPF_TYPE] = type;
_npf_aystar.user_data[NPF_SUB_TYPE] = sub_type;
_npf_aystar.user_data[NPF_OWNER] = owner; _npf_aystar.user_data[NPF_OWNER] = owner;
_npf_aystar.user_data[NPF_RAILTYPES] = railtypes; _npf_aystar.user_data[NPF_RAILTYPES] = railtypes;
@ -728,7 +730,7 @@ static NPFFoundTargetData NPFRouteInternal(AyStarNode* start1, AyStarNode* start
return result; return result;
} }
NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailTypeMask railtypes) NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, NPFFindStationOrTileData* target, TransportType type, uint sub_type, Owner owner, RailTypeMask railtypes)
{ {
AyStarNode start1; AyStarNode start1;
AyStarNode start2; AyStarNode start2;
@ -742,15 +744,15 @@ NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir track
start2.direction = trackdir2; start2.direction = trackdir2;
start2.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR; start2.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR;
return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, type, owner, railtypes, 0); return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, type, sub_type, owner, railtypes, 0);
} }
NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailTypeMask railtypes) NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, uint sub_type, Owner owner, RailTypeMask railtypes)
{ {
return NPFRouteToStationOrTileTwoWay(tile, trackdir, INVALID_TILE, INVALID_TRACKDIR, target, type, owner, railtypes); return NPFRouteToStationOrTileTwoWay(tile, trackdir, INVALID_TILE, INVALID_TRACKDIR, target, type, sub_type, owner, railtypes);
} }
NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, Owner owner, RailTypeMask railtypes, uint reverse_penalty) NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, uint sub_type, Owner owner, RailTypeMask railtypes, uint reverse_penalty)
{ {
AyStarNode start1; AyStarNode start1;
AyStarNode start2; AyStarNode start2;
@ -766,15 +768,15 @@ NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir t
/* perform a breadth first search. Target is NULL, /* perform a breadth first search. Target is NULL,
* since we are just looking for any depot...*/ * since we are just looking for any depot...*/
return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), NULL, NPFFindDepot, NPFCalcZero, type, owner, railtypes, reverse_penalty); return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), NULL, NPFFindDepot, NPFCalcZero, type, sub_type, owner, railtypes, reverse_penalty);
} }
NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailTypeMask railtypes) NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, uint sub_type, Owner owner, RailTypeMask railtypes)
{ {
return NPFRouteToDepotBreadthFirstTwoWay(tile, trackdir, INVALID_TILE, INVALID_TRACKDIR, type, owner, railtypes, 0); return NPFRouteToDepotBreadthFirstTwoWay(tile, trackdir, INVALID_TILE, INVALID_TRACKDIR, type, sub_type, owner, railtypes, 0);
} }
NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailTypeMask railtypes) NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, uint sub_type, Owner owner, RailTypeMask railtypes)
{ {
/* Okay, what we're gonna do. First, we look at all depots, calculate /* Okay, what we're gonna do. First, we look at all depots, calculate
* the manhatten distance to get to each depot. We then sort them by * the manhatten distance to get to each depot. We then sort them by
@ -823,6 +825,7 @@ NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir,
/* Initialize user_data */ /* Initialize user_data */
_npf_aystar.user_data[NPF_TYPE] = type; _npf_aystar.user_data[NPF_TYPE] = type;
_npf_aystar.user_data[NPF_SUB_TYPE] = sub_type;
_npf_aystar.user_data[NPF_OWNER] = owner; _npf_aystar.user_data[NPF_OWNER] = owner;
/* Initialize Start Node */ /* Initialize Start Node */

View File

@ -46,6 +46,7 @@ struct NPFFindStationOrTileData {
/* Indices into AyStar.userdata[] */ /* Indices into AyStar.userdata[] */
enum { enum {
NPF_TYPE = 0, ///< Contains a TransportTypes value NPF_TYPE = 0, ///< Contains a TransportTypes value
NPF_SUB_TYPE, ///< Contains the sub transport type
NPF_OWNER, ///< Contains an Owner value NPF_OWNER, ///< Contains an Owner value
NPF_RAILTYPES, ///< Contains a bitmask the compatible RailTypes of the engine when NPF_TYPE == TRANSPORT_RAIL. Unused otherwise. NPF_RAILTYPES, ///< Contains a bitmask the compatible RailTypes of the engine when NPF_TYPE == TRANSPORT_RAIL. Unused otherwise.
}; };
@ -76,28 +77,28 @@ struct NPFFoundTargetData {
/* Will search from the given tile and direction, for a route to the given /* Will search from the given tile and direction, for a route to the given
* station for the given transport type. See the declaration of * station for the given transport type. See the declaration of
* NPFFoundTargetData above for the meaning of the result. */ * NPFFoundTargetData above for the meaning of the result. */
NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailTypeMask railtypes); NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, uint sub_type, Owner owner, RailTypeMask railtypes);
/* Will search as above, but with two start nodes, the second being the /* Will search as above, but with two start nodes, the second being the
* reverse. Look at the NPF_FLAG_REVERSE flag in the result node to see which * reverse. Look at the NPF_FLAG_REVERSE flag in the result node to see which
* direction was taken (NPFGetBit(result.node, NPF_FLAG_REVERSE)) */ * direction was taken (NPFGetBit(result.node, NPF_FLAG_REVERSE)) */
NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailTypeMask railtypes); NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, NPFFindStationOrTileData* target, TransportType type, uint sub_type, Owner owner, RailTypeMask railtypes);
/* Will search a route to the closest depot. */ /* Will search a route to the closest depot. */
/* Search using breadth first. Good for little track choice and inaccurate /* Search using breadth first. Good for little track choice and inaccurate
* heuristic, such as railway/road.*/ * heuristic, such as railway/road.*/
NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailTypeMask railtypes); NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, uint sub_type, Owner owner, RailTypeMask railtypes);
/* Same as above but with two start nodes, the second being the reverse. Call /* Same as above but with two start nodes, the second being the reverse. Call
* NPFGetBit(result.node, NPF_FLAG_REVERSE) to see from which node the path * NPFGetBit(result.node, NPF_FLAG_REVERSE) to see from which node the path
* orginated. All pathfs from the second node will have the given * orginated. All pathfs from the second node will have the given
* reverse_penalty applied (NPF_TILE_LENGTH is the equivalent of one full * reverse_penalty applied (NPF_TILE_LENGTH is the equivalent of one full
* tile). * tile).
*/ */
NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, Owner owner, RailTypeMask railtypes, uint reverse_penalty); NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, uint sub_type, Owner owner, RailTypeMask railtypes, uint reverse_penalty);
/* Search by trying each depot in order of Manhattan Distance. Good for lots /* Search by trying each depot in order of Manhattan Distance. Good for lots
* of choices and accurate heuristics, such as water. */ * of choices and accurate heuristics, such as water. */
NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailTypeMask railtypes); NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, uint sub_type, Owner owner, RailTypeMask railtypes);
void NPFFillWithOrderData(NPFFindStationOrTileData* fstd, Vehicle* v); void NPFFillWithOrderData(NPFFindStationOrTileData* fstd, Vehicle* v);

View File

@ -364,7 +364,8 @@ typedef uint GetSlopeZProc(TileIndex tile, uint x, uint y);
typedef int32 ClearTileProc(TileIndex tile, byte flags); typedef int32 ClearTileProc(TileIndex tile, byte flags);
typedef void GetAcceptedCargoProc(TileIndex tile, AcceptedCargo res); typedef void GetAcceptedCargoProc(TileIndex tile, AcceptedCargo res);
typedef void GetTileDescProc(TileIndex tile, TileDesc *td); typedef void GetTileDescProc(TileIndex tile, TileDesc *td);
/* GetTileTrackStatusProcs return a value that contains the possible tracks /**
* GetTileTrackStatusProcs return a value that contains the possible tracks
* that can be taken on a given tile by a given transport. The return value is * that can be taken on a given tile by a given transport. The return value is
* composed as follows: 0xaabbccdd. ccdd and aabb are bitmasks of trackdirs, * composed as follows: 0xaabbccdd. ccdd and aabb are bitmasks of trackdirs,
* where bit n corresponds to trackdir n. ccdd are the trackdirs that are * where bit n corresponds to trackdir n. ccdd are the trackdirs that are
@ -382,8 +383,12 @@ typedef void GetTileDescProc(TileIndex tile, TileDesc *td);
* are a track, the fourth bit is the direction. these give 12 (or 14) * are a track, the fourth bit is the direction. these give 12 (or 14)
* possible options: 0-5 and 8-13, so we need 14 bits for a trackdir bitmask * possible options: 0-5 and 8-13, so we need 14 bits for a trackdir bitmask
* above. * above.
* @param tile the tile to get the track status from
* @param mode the mode of transportation
* @param sub_mode used to differentiate between different kinds within the mode
* @return the above mentions track status information
*/ */
typedef uint32 GetTileTrackStatusProc(TileIndex tile, TransportType mode); typedef uint32 GetTileTrackStatusProc(TileIndex tile, TransportType mode, uint sub_mode);
typedef void GetProducedCargoProc(TileIndex tile, CargoID *b); typedef void GetProducedCargoProc(TileIndex tile, CargoID *b);
typedef void ClickTileProc(TileIndex tile); typedef void ClickTileProc(TileIndex tile);
typedef void AnimateTileProc(TileIndex tile); typedef void AnimateTileProc(TileIndex tile);

View File

@ -153,7 +153,7 @@ static void TPFMode2(TrackPathFinder* tpf, TileIndex tile, DiagDirection directi
if (++tpf->rd.cur_length > 50) if (++tpf->rd.cur_length > 50)
return; return;
bits = GetTileTrackStatus(tile, tpf->tracktype); bits = GetTileTrackStatus(tile, tpf->tracktype, tpf->sub_type);
bits = (byte)((bits | (bits >> 8)) & _bits_mask[direction]); bits = (byte)((bits | (bits >> 8)) & _bits_mask[direction]);
if (bits == 0) if (bits == 0)
return; return;
@ -322,7 +322,7 @@ static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection directi
tpf->rd.cur_length++; tpf->rd.cur_length++;
bits = GetTileTrackStatus(tile, tpf->tracktype); bits = GetTileTrackStatus(tile, tpf->tracktype, tpf->sub_type);
if ((byte)bits != tpf->var2) { if ((byte)bits != tpf->var2) {
bits &= _tpfmode1_and[direction]; bits &= _tpfmode1_and[direction];
@ -363,7 +363,7 @@ static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection directi
direction = ReverseDiagDir(direction); direction = ReverseDiagDir(direction);
tile += TileOffsByDiagDir(direction); tile += TileOffsByDiagDir(direction);
bits = GetTileTrackStatus(tile, tpf->tracktype); bits = GetTileTrackStatus(tile, tpf->tracktype, tpf->sub_type);
bits |= (bits >> 8); bits |= (bits >> 8);
if ( (byte)bits != tpf->var2) { if ( (byte)bits != tpf->var2) {
@ -388,7 +388,7 @@ static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection directi
} while (bits != 0); } while (bits != 0);
} }
void FollowTrack(TileIndex tile, uint16 flags, 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)
{ {
TrackPathFinder tpf; TrackPathFinder tpf;
@ -411,6 +411,7 @@ void FollowTrack(TileIndex tile, uint16 flags, DiagDirection direction, TPFEnumP
tpf.tracktype = (TransportType)(flags & 0xFF); tpf.tracktype = (TransportType)(flags & 0xFF);
tpf.sub_type = sub_type;
if (HASBIT(flags, 11)) { if (HASBIT(flags, 11)) {
tpf.rd.pft_var6 = 0xFF; tpf.rd.pft_var6 = 0xFF;
@ -783,7 +784,7 @@ start_at:
if (!IsTileType(tile, MP_RAILWAY) || !IsPlainRailTile(tile)) { if (!IsTileType(tile, MP_RAILWAY) || !IsPlainRailTile(tile)) {
/* We found a tile which is not a normal railway tile. /* We found a tile which is not a normal railway tile.
* Determine which tracks that exist on this tile. */ * Determine which tracks that exist on this tile. */
uint32 ts = GetTileTrackStatus(tile, TRANSPORT_RAIL) & _tpfmode1_and[direction]; uint32 ts = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0) & _tpfmode1_and[direction];
bits = TrackdirBitsToTrackBits((TrackdirBits)(ts & TRACKDIR_BIT_MASK)); bits = TrackdirBitsToTrackBits((TrackdirBits)(ts & TRACKDIR_BIT_MASK));
/* Check that the tile contains exactly one track */ /* Check that the tile contains exactly one track */

View File

@ -57,6 +57,8 @@ struct TrackPathFinder {
TrackdirByte the_dir; TrackdirByte the_dir;
TransportTypeByte tracktype; TransportTypeByte tracktype;
uint sub_type;
byte var2; byte var2;
bool disable_tile_hash; bool disable_tile_hash;
bool hasbit_13; bool hasbit_13;
@ -67,7 +69,7 @@ struct TrackPathFinder {
TrackPathFinderLink links[0x400]; ///< hopefully, this is enough. TrackPathFinderLink links[0x400]; ///< hopefully, this is enough.
}; };
void FollowTrack(TileIndex tile, uint16 flags, 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);
struct FindLengthOfTunnelResult { struct FindLengthOfTunnelResult {
TileIndex tile; TileIndex tile;

View File

@ -1716,7 +1716,7 @@ bool UpdateSignalsOnSegment(TileIndex tile, DiagDirection direction)
ssd.cur = ssd.presignal_exits = ssd.presignal_exits_free = 0; ssd.cur = ssd.presignal_exits = ssd.presignal_exits_free = 0;
ssd.has_presignal = false; ssd.has_presignal = false;
FollowTrack(tile, 0xC000 | TRANSPORT_RAIL, direction, SetSignalsEnumProc, SetSignalsAfterProc, &ssd); FollowTrack(tile, 0xC000 | TRANSPORT_RAIL, 0, direction, SetSignalsEnumProc, SetSignalsAfterProc, &ssd);
ChangeSignalStates(&ssd); ChangeSignalStates(&ssd);
/* remember the result only for the first iteration. */ /* remember the result only for the first iteration. */
@ -1908,7 +1908,7 @@ set_ground:
} }
static uint32 GetTileTrackStatus_Track(TileIndex tile, TransportType mode) static uint32 GetTileTrackStatus_Track(TileIndex tile, TransportType mode, uint sub_mode)
{ {
if (mode != TRANSPORT_RAIL) return 0; if (mode != TRANSPORT_RAIL) return 0;

View File

@ -168,7 +168,7 @@ static void GenericPlaceSignals(TileIndex tile)
byte trackstat; byte trackstat;
uint i; uint i;
trackstat = (byte)GetTileTrackStatus(tile, TRANSPORT_RAIL); trackstat = (byte)GetTileTrackStatus(tile, TRANSPORT_RAIL, 0);
if (trackstat & TRACK_BIT_VERT) // N-S direction if (trackstat & TRACK_BIT_VERT) // N-S direction
trackstat = (_tile_fract_coords.x <= _tile_fract_coords.y) ? TRACK_BIT_RIGHT : TRACK_BIT_LEFT; trackstat = (_tile_fract_coords.x <= _tile_fract_coords.y) ? TRACK_BIT_RIGHT : TRACK_BIT_LEFT;

View File

@ -1111,9 +1111,8 @@ static const byte _road_trackbits[16] = {
0x0, 0x0, 0x0, 0x10, 0x0, 0x2, 0x8, 0x1A, 0x0, 0x4, 0x1, 0x15, 0x20, 0x26, 0x29, 0x3F, 0x0, 0x0, 0x0, 0x10, 0x0, 0x2, 0x8, 0x1A, 0x0, 0x4, 0x1, 0x15, 0x20, 0x26, 0x29, 0x3F,
}; };
static uint32 GetTileTrackStatus_Road(TileIndex tile, TransportType mode) static uint32 GetTileTrackStatus_Road(TileIndex tile, TransportType mode, uint sub_mode)
{ {
RoadType rt = ROADTYPE_ROAD;
switch (mode) { switch (mode) {
case TRANSPORT_RAIL: case TRANSPORT_RAIL:
@ -1121,10 +1120,12 @@ static uint32 GetTileTrackStatus_Road(TileIndex tile, TransportType mode)
return GetCrossingRailBits(tile) * 0x101; return GetCrossingRailBits(tile) * 0x101;
case TRANSPORT_ROAD: case TRANSPORT_ROAD:
if (!HASBIT(GetRoadTypes(tile), rt)) return 0; if ((GetRoadTypes(tile) & sub_mode) == 0) return 0;
switch (GetRoadTileType(tile)) { switch (GetRoadTileType(tile)) {
case ROAD_TILE_NORMAL: case ROAD_TILE_NORMAL: {
RoadType rt = (RoadType)FindFirstBit(sub_mode);
return HasRoadWorks(tile) ? 0 : _road_trackbits[GetRoadBits(tile, rt)] * 0x101; return HasRoadWorks(tile) ? 0 : _road_trackbits[GetRoadBits(tile, rt)] * 0x101;
}
case ROAD_TILE_CROSSING: { case ROAD_TILE_CROSSING: {
uint32 r = AxisToTrackBits(GetCrossingRoadAxis(tile)) * 0x101; uint32 r = AxisToTrackBits(GetCrossingRoadAxis(tile)) * 0x101;

View File

@ -55,7 +55,7 @@ TrackBits GetAnyRoadTrackBits(TileIndex tile, RoadType rt)
return TRACK_BIT_NONE; return TRACK_BIT_NONE;
} }
r = GetTileTrackStatus(tile, TRANSPORT_ROAD); r = GetTileTrackStatus(tile, TRANSPORT_ROAD, RoadTypeToRoadTypes(rt));
return (TrackBits)(byte)(r | (r >> 8)); return (TrackBits)(byte)(r | (r >> 8));
} }

View File

@ -173,6 +173,9 @@ int32 CmdBuildRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
v->u.road.state = RVSB_IN_DEPOT; v->u.road.state = RVSB_IN_DEPOT;
v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL; v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
v->u.road.roadtype = ROADTYPE_ROAD;
v->u.road.compatible_roadtypes = RoadTypeToRoadTypes(v->u.road.roadtype);
v->spritenum = rvi->image_index; v->spritenum = rvi->image_index;
v->cargo_type = rvi->cargo_type; v->cargo_type = rvi->cargo_type;
v->cargo_subtype = 0; v->cargo_subtype = 0;
@ -353,7 +356,7 @@ static const Depot* FindClosestRoadDepot(const Vehicle* v)
/* See where we are now */ /* See where we are now */
Trackdir trackdir = GetVehicleTrackdir(v); Trackdir trackdir = GetVehicleTrackdir(v);
ftd = NPFRouteToDepotBreadthFirst(v->tile, trackdir, TRANSPORT_ROAD, v->owner, INVALID_RAILTYPE); ftd = NPFRouteToDepotBreadthFirst(v->tile, trackdir, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, v->owner, INVALID_RAILTYPE);
if (ftd.best_bird_dist == 0) { if (ftd.best_bird_dist == 0) {
return GetDepotByTile(ftd.node.tile); /* Target found */ return GetDepotByTile(ftd.node.tile); /* Target found */
} else { } else {
@ -368,7 +371,7 @@ static const Depot* FindClosestRoadDepot(const Vehicle* v)
/* search in all directions */ /* search in all directions */
for (DiagDirection i = DIAGDIR_BEGIN; i != DIAGDIR_END; i++) { for (DiagDirection i = DIAGDIR_BEGIN; i != DIAGDIR_END; i++) {
FollowTrack(tile, 0x2000 | TRANSPORT_ROAD, i, EnumRoadSignalFindDepot, NULL, &rfdd); FollowTrack(tile, 0x2000 | TRANSPORT_ROAD, v->u.road.compatible_roadtypes, i, EnumRoadSignalFindDepot, NULL, &rfdd);
} }
if (rfdd.best_length == (uint)-1) return NULL; if (rfdd.best_length == (uint)-1) return NULL;
@ -933,7 +936,7 @@ static bool FindRoadVehToOvertake(OvertakeData *od)
{ {
uint32 bits; uint32 bits;
bits = GetTileTrackStatus(od->tile, TRANSPORT_ROAD) & 0x3F; bits = GetTileTrackStatus(od->tile, TRANSPORT_ROAD, od->v->u.road.compatible_roadtypes) & 0x3F;
if (!(od->tilebits & bits) || (bits & 0x3C) || (bits & 0x3F3F0000)) if (!(od->tilebits & bits) || (bits & 0x3C) || (bits & 0x3F3F0000))
return true; return true;
@ -959,7 +962,7 @@ static void RoadVehCheckOvertake(Vehicle *v, Vehicle *u)
/* Check if vehicle is in a road stop, depot, tunnel or bridge or not on a straight road */ /* Check if vehicle is in a road stop, depot, tunnel or bridge or not on a straight road */
if (v->u.road.state >= RVSB_IN_ROAD_STOP || !IsStraightRoadTrackdir((Trackdir)(v->u.road.state & RVSB_TRACKDIR_MASK))) return; if (v->u.road.state >= RVSB_IN_ROAD_STOP || !IsStraightRoadTrackdir((Trackdir)(v->u.road.state & RVSB_TRACKDIR_MASK))) return;
tt = GetTileTrackStatus(v->tile, TRANSPORT_ROAD) & 0x3F; tt = GetTileTrackStatus(v->tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes) & 0x3F;
if ((tt & 3) == 0) return; if ((tt & 3) == 0) return;
if ((tt & 0x3C) != 0) return; if ((tt & 0x3C) != 0) return;
@ -1030,11 +1033,11 @@ static bool EnumRoadTrackFindDist(TileIndex tile, void* data, Trackdir trackdir,
return false; return false;
} }
static inline NPFFoundTargetData PerfNPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailTypeMask railtypes) static inline NPFFoundTargetData PerfNPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, uint sub_type, Owner owner, RailTypeMask railtypes)
{ {
void* perf = NpfBeginInterval(); void* perf = NpfBeginInterval();
NPFFoundTargetData ret = NPFRouteToStationOrTile(tile, trackdir, target, type, owner, railtypes); NPFFoundTargetData ret = NPFRouteToStationOrTile(tile, trackdir, target, type, sub_type, owner, railtypes);
int t = NpfEndInterval(perf); int t = NpfEndInterval(perf);
DEBUG(yapf, 4, "[NPFR] %d us - %d rounds - %d open - %d closed -- ", t, 0, _aystar_stats_open_size, _aystar_stats_closed_size); DEBUG(yapf, 4, "[NPFR] %d us - %d rounds - %d open - %d closed -- ", t, 0, _aystar_stats_open_size, _aystar_stats_closed_size);
return ret; return ret;
@ -1056,7 +1059,7 @@ static Trackdir RoadFindPathToDest(Vehicle* v, TileIndex tile, DiagDirection ent
FindRoadToChooseData frd; FindRoadToChooseData frd;
Trackdir best_track; Trackdir best_track;
uint32 r = GetTileTrackStatus(tile, TRANSPORT_ROAD); uint32 r = GetTileTrackStatus(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes);
TrackdirBits signal = (TrackdirBits)GB(r, 16, 16); TrackdirBits signal = (TrackdirBits)GB(r, 16, 16);
TrackdirBits trackdirs = (TrackdirBits)GB(r, 0, 16); TrackdirBits trackdirs = (TrackdirBits)GB(r, 0, 16);
@ -1131,7 +1134,7 @@ static Trackdir RoadFindPathToDest(Vehicle* v, TileIndex tile, DiagDirection ent
trackdir = DiagdirToDiagTrackdir(enterdir); trackdir = DiagdirToDiagTrackdir(enterdir);
//debug("Finding path. Enterdir: %d, Trackdir: %d", enterdir, trackdir); //debug("Finding path. Enterdir: %d, Trackdir: %d", enterdir, trackdir);
ftd = PerfNPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, &fstd, TRANSPORT_ROAD, v->owner, INVALID_RAILTYPE); ftd = PerfNPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, &fstd, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, v->owner, INVALID_RAILTYPE);
if (ftd.best_trackdir == INVALID_TRACKDIR) { if (ftd.best_trackdir == INVALID_TRACKDIR) {
/* We are already at our target. Just do something /* We are already at our target. Just do something
* @todo: maybe display error? * @todo: maybe display error?
@ -1181,7 +1184,7 @@ do_it:;
if (best_track == INVALID_TRACKDIR) best_track = (Trackdir)i; // in case we don't find the path, just pick a track if (best_track == INVALID_TRACKDIR) best_track = (Trackdir)i; // in case we don't find the path, just pick a track
frd.maxtracklen = (uint)-1; frd.maxtracklen = (uint)-1;
frd.mindist = (uint)-1; frd.mindist = (uint)-1;
FollowTrack(tile, 0x2000 | TRANSPORT_ROAD, _road_pf_directions[i], EnumRoadTrackFindDist, NULL, &frd); FollowTrack(tile, 0x2000 | TRANSPORT_ROAD, v->u.road.compatible_roadtypes, _road_pf_directions[i], EnumRoadTrackFindDist, NULL, &frd);
if (frd.mindist < best_dist || (frd.mindist == best_dist && frd.maxtracklen < best_maxlen)) { if (frd.mindist < best_dist || (frd.mindist == best_dist && frd.maxtracklen < best_maxlen)) {
best_dist = frd.mindist; best_dist = frd.mindist;
@ -1214,7 +1217,7 @@ static uint RoadFindPathToStop(const Vehicle *v, TileIndex tile)
fstd.dest_coords = tile; fstd.dest_coords = tile;
fstd.station_index = INVALID_STATION; // indicates that the destination is a tile, not a station fstd.station_index = INVALID_STATION; // indicates that the destination is a tile, not a station
dist = NPFRouteToStationOrTile(v->tile, trackdir, &fstd, TRANSPORT_ROAD, v->owner, INVALID_RAILTYPE).best_path_dist; dist = NPFRouteToStationOrTile(v->tile, trackdir, &fstd, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, v->owner, INVALID_RAILTYPE).best_path_dist;
/* change units from NPF_TILE_LENGTH to # of tiles */ /* change units from NPF_TILE_LENGTH to # of tiles */
if (dist != UINT_MAX) if (dist != UINT_MAX)
dist = (dist + NPF_TILE_LENGTH - 1) / NPF_TILE_LENGTH; dist = (dist + NPF_TILE_LENGTH - 1) / NPF_TILE_LENGTH;

View File

@ -43,7 +43,7 @@ static const TrackBits _ship_sometracks[4] = {
static TrackBits GetTileShipTrackStatus(TileIndex tile) static TrackBits GetTileShipTrackStatus(TileIndex tile)
{ {
uint32 r = GetTileTrackStatus(tile, TRANSPORT_WATER); uint32 r = GetTileTrackStatus(tile, TRANSPORT_WATER, 0);
return TrackdirBitsToTrackBits((TrackdirBits)(TRACKDIR_BIT_MASK & (r | r >> 8))); return TrackdirBitsToTrackBits((TrackdirBits)(TRACKDIR_BIT_MASK & (r | r >> 8)));
} }
@ -114,7 +114,7 @@ static const Depot* FindClosestShipDepot(const Vehicle* v)
if (_patches.new_pathfinding_all) { if (_patches.new_pathfinding_all) {
NPFFoundTargetData ftd; NPFFoundTargetData ftd;
Trackdir trackdir = GetVehicleTrackdir(v); Trackdir trackdir = GetVehicleTrackdir(v);
ftd = NPFRouteToDepotTrialError(v->tile, trackdir, TRANSPORT_WATER, v->owner, INVALID_RAILTYPE); ftd = NPFRouteToDepotTrialError(v->tile, trackdir, TRANSPORT_WATER, 0, v->owner, INVALID_RAILTYPE);
if (ftd.best_bird_dist == 0) { if (ftd.best_bird_dist == 0) {
best_depot = GetDepotByTile(ftd.node.tile); /* Found target */ best_depot = GetDepotByTile(ftd.node.tile); /* Found target */
} else { } else {
@ -479,7 +479,7 @@ static uint FindShipTrack(Vehicle *v, TileIndex tile, DiagDirection dir, TrackBi
pfs.best_bird_dist = (uint)-1; pfs.best_bird_dist = (uint)-1;
pfs.best_length = (uint)-1; pfs.best_length = (uint)-1;
FollowTrack(tile, 0x3800 | TRANSPORT_WATER, (DiagDirection)_ship_search_directions[i][dir], (TPFEnumProc*)ShipTrackFollower, NULL, &pfs); FollowTrack(tile, 0x3800 | TRANSPORT_WATER, 0, (DiagDirection)_ship_search_directions[i][dir], (TPFEnumProc*)ShipTrackFollower, NULL, &pfs);
if (best_track != INVALID_TRACK) { if (best_track != INVALID_TRACK) {
if (pfs.best_bird_dist != 0) { if (pfs.best_bird_dist != 0) {
@ -514,7 +514,7 @@ static inline NPFFoundTargetData PerfNPFRouteToStationOrTile(TileIndex tile, Tra
{ {
void* perf = NpfBeginInterval(); void* perf = NpfBeginInterval();
NPFFoundTargetData ret = NPFRouteToStationOrTile(tile, trackdir, target, type, owner, railtypes); NPFFoundTargetData ret = NPFRouteToStationOrTile(tile, trackdir, target, type, 0, owner, railtypes);
int t = NpfEndInterval(perf); int t = NpfEndInterval(perf);
DEBUG(yapf, 4, "[NPFW] %d us - %d rounds - %d open - %d closed -- ", t, 0, _aystar_stats_open_size, _aystar_stats_closed_size); DEBUG(yapf, 4, "[NPFW] %d us - %d rounds - %d open - %d closed -- ", t, 0, _aystar_stats_open_size, _aystar_stats_closed_size);
return ret; return ret;
@ -597,7 +597,7 @@ static Direction ShipGetNewDirection(Vehicle *v, int x, int y)
static TrackBits GetAvailShipTracks(TileIndex tile, int dir) static TrackBits GetAvailShipTracks(TileIndex tile, int dir)
{ {
uint32 r = GetTileTrackStatus(tile, TRANSPORT_WATER); uint32 r = GetTileTrackStatus(tile, TRANSPORT_WATER, 0);
return (TrackBits)((r | r >> 8) & _ship_sometracks[dir]); return (TrackBits)((r | r >> 8) & _ship_sometracks[dir]);
} }

View File

@ -2132,7 +2132,7 @@ static void GetTileDesc_Station(TileIndex tile, TileDesc *td)
} }
static uint32 GetTileTrackStatus_Station(TileIndex tile, TransportType mode) static uint32 GetTileTrackStatus_Station(TileIndex tile, TransportType mode, uint sub_mode)
{ {
switch (mode) { switch (mode) {
case TRANSPORT_RAIL: case TRANSPORT_RAIL:
@ -2154,7 +2154,7 @@ static uint32 GetTileTrackStatus_Station(TileIndex tile, TransportType mode)
break; break;
case TRANSPORT_ROAD: case TRANSPORT_ROAD:
if (IsRoadStopTile(tile)) { if ((GetRoadTypes(tile) & sub_mode) != 0 && IsRoadStopTile(tile)) {
return AxisToTrackBits(DiagDirToAxis(GetRoadStopDir(tile))) * 0x101; return AxisToTrackBits(DiagDirToAxis(GetRoadStopDir(tile))) * 0x101;
} }
break; break;

View File

@ -563,7 +563,7 @@ static void GetTileDesc_Town(TileIndex tile, TileDesc *td)
td->owner = OWNER_TOWN; td->owner = OWNER_TOWN;
} }
static uint32 GetTileTrackStatus_Town(TileIndex tile, TransportType mode) static uint32 GetTileTrackStatus_Town(TileIndex tile, TransportType mode, uint sub_mode)
{ {
/* not used */ /* not used */
return 0; return 0;

View File

@ -1937,7 +1937,7 @@ static TrainFindDepotData FindClosestTrainDepot(Vehicle *v, int max_distance)
Trackdir trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last)); Trackdir trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last));
assert(trackdir != INVALID_TRACKDIR); assert(trackdir != INVALID_TRACKDIR);
NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, last->tile, trackdir_rev, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes, NPF_INFINITE_PENALTY); NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, last->tile, trackdir_rev, TRANSPORT_RAIL, 0, v->owner, v->u.rail.compatible_railtypes, NPF_INFINITE_PENALTY);
if (ftd.best_bird_dist == 0) { if (ftd.best_bird_dist == 0) {
/* Found target */ /* Found target */
tfdd.tile = ftd.node.tile; tfdd.tile = ftd.node.tile;
@ -2302,7 +2302,7 @@ static Track ChooseTrainTrack(Vehicle* v, TileIndex tile, DiagDirection enterdir
Trackdir trackdir = GetVehicleTrackdir(v); Trackdir trackdir = GetVehicleTrackdir(v);
assert(trackdir != 0xff); assert(trackdir != 0xff);
NPFFoundTargetData ftd = NPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes); NPFFoundTargetData ftd = NPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, 0, v->owner, v->u.rail.compatible_railtypes);
if (ftd.best_trackdir == 0xff) { if (ftd.best_trackdir == 0xff) {
/* We are already at our target. Just do something /* We are already at our target. Just do something
@ -2412,7 +2412,7 @@ static bool CheckReverseTrain(Vehicle *v)
assert(trackdir != 0xff); assert(trackdir != 0xff);
assert(trackdir_rev != 0xff); assert(trackdir_rev != 0xff);
ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, last->tile, trackdir_rev, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes); ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, last->tile, trackdir_rev, &fstd, TRANSPORT_RAIL, 0, v->owner, v->u.rail.compatible_railtypes);
if (ftd.best_bird_dist != 0) { if (ftd.best_bird_dist != 0) {
/* We didn't find anything, just keep on going straight ahead */ /* We didn't find anything, just keep on going straight ahead */
reverse_best = false; reverse_best = false;
@ -2920,7 +2920,7 @@ static void TrainController(Vehicle *v, bool update_image)
/* Get the status of the tracks in the new tile and mask /* Get the status of the tracks in the new tile and mask
* away the bits that aren't reachable. */ * away the bits that aren't reachable. */
uint32 ts = GetTileTrackStatus(gp.new_tile, TRANSPORT_RAIL) & _reachable_tracks[enterdir]; uint32 ts = GetTileTrackStatus(gp.new_tile, TRANSPORT_RAIL, 0) & _reachable_tracks[enterdir];
/* Combine the from & to directions. /* Combine the from & to directions.
* Now, the lower byte contains the track status, and the byte at bit 16 contains * Now, the lower byte contains the track status, and the byte at bit 16 contains
@ -3265,7 +3265,7 @@ static bool TrainCheckIfLineEnds(Vehicle *v)
/* Calculate next tile */ /* Calculate next tile */
tile += TileOffsByDiagDir(dir); tile += TileOffsByDiagDir(dir);
// determine the track status on the next tile. // determine the track status on the next tile.
uint32 ts = GetTileTrackStatus(tile, TRANSPORT_RAIL) & _reachable_tracks[dir]; uint32 ts = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0) & _reachable_tracks[dir];
/* Calc position within the current tile ?? */ /* Calc position within the current tile ?? */
uint x = v->x_pos & 0xF; uint x = v->x_pos & 0xF;

View File

@ -648,7 +648,7 @@ static void ClickTile_Trees(TileIndex tile)
/* not used */ /* not used */
} }
static uint32 GetTileTrackStatus_Trees(TileIndex tile, TransportType mode) static uint32 GetTileTrackStatus_Trees(TileIndex tile, TransportType mode, uint sub_mode)
{ {
return 0; return 0;
} }

View File

@ -1236,13 +1236,15 @@ static void ClickTile_TunnelBridge(TileIndex tile)
} }
static uint32 GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode) static uint32 GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode, uint sub_mode)
{ {
if (IsTunnel(tile)) { if (IsTunnel(tile)) {
if (GetTunnelTransportType(tile) != mode) return 0; if (GetTunnelTransportType(tile) != mode) return 0;
if (GetTunnelTransportType(tile) == TRANSPORT_ROAD && (GetRoadTypes(tile) & sub_mode) == 0) return 0;
return AxisToTrackBits(DiagDirToAxis(GetTunnelDirection(tile))) * 0x101; return AxisToTrackBits(DiagDirToAxis(GetTunnelDirection(tile))) * 0x101;
} else { } else {
if (GetBridgeTransportType(tile) != mode) return 0; if (GetBridgeTransportType(tile) != mode) return 0;
if (GetBridgeTransportType(tile) == TRANSPORT_ROAD && (GetRoadTypes(tile) & sub_mode) == 0) return 0;
return AxisToTrackBits(DiagDirToAxis(GetBridgeRampDirection(tile))) * 0x101; return AxisToTrackBits(DiagDirToAxis(GetBridgeRampDirection(tile))) * 0x101;
} }
} }

View File

@ -319,7 +319,7 @@ static void TileLoop_Unmovable(TileIndex tile)
} }
static uint32 GetTileTrackStatus_Unmovable(TileIndex tile, TransportType mode) static uint32 GetTileTrackStatus_Unmovable(TileIndex tile, TransportType mode, uint sub_mode)
{ {
return 0; return 0;
} }

View File

@ -239,8 +239,13 @@ void AfterLoadVehicles()
FOR_ALL_VEHICLES(v) { FOR_ALL_VEHICLES(v) {
switch (v->type) { switch (v->type) {
case VEH_ROAD:
v->cur_image = GetRoadVehImage(v, v->direction);
v->u.road.roadtype = ROADTYPE_ROAD;
v->u.road.compatible_roadtypes = RoadTypeToRoadTypes(v->u.road.roadtype);
break;
case VEH_TRAIN: v->cur_image = GetTrainImage(v, v->direction); break; case VEH_TRAIN: v->cur_image = GetTrainImage(v, v->direction); break;
case VEH_ROAD: v->cur_image = GetRoadVehImage(v, v->direction); break;
case VEH_SHIP: v->cur_image = GetShipImage(v, v->direction); break; case VEH_SHIP: v->cur_image = GetShipImage(v, v->direction); break;
case VEH_AIRCRAFT: case VEH_AIRCRAFT:
if (IsNormalAircraft(v)) { if (IsNormalAircraft(v)) {

View File

@ -8,6 +8,7 @@
#include "oldpool.h" #include "oldpool.h"
#include "order.h" #include "order.h"
#include "rail.h" #include "rail.h"
#include "road.h"
/** The returned bits of VehicleEnterTile. */ /** The returned bits of VehicleEnterTile. */
enum VehicleEnterTileStatus { enum VehicleEnterTileStatus {
@ -188,6 +189,9 @@ struct VehicleRoad {
byte reverse_ctr; byte reverse_ctr;
struct RoadStop *slot; struct RoadStop *slot;
byte slot_age; byte slot_age;
RoadType roadtype;
RoadTypes compatible_roadtypes;
}; };
struct VehicleSpecial { struct VehicleSpecial {

View File

@ -725,7 +725,7 @@ void TileLoop_Water(TileIndex tile)
} }
} }
static uint32 GetTileTrackStatus_Water(TileIndex tile, TransportType mode) static uint32 GetTileTrackStatus_Water(TileIndex tile, TransportType mode, uint sub_mode)
{ {
static const byte coast_tracks[] = {0, 32, 4, 0, 16, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0}; static const byte coast_tracks[] = {0, 32, 4, 0, 16, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0};

View File

@ -45,7 +45,7 @@ struct CFollowTrackT : public FollowTrack_t
{ {
m_old_tile = old_tile; m_old_tile = old_tile;
m_old_td = old_td; m_old_td = old_td;
assert((GetTileTrackStatus(m_old_tile, TT()) & TrackdirToTrackdirBits(m_old_td)) != 0); assert((GetTileTrackStatus(m_old_tile, TT(), m_veh->u.road.compatible_roadtypes) & TrackdirToTrackdirBits(m_old_td)) != 0);
m_exitdir = TrackdirToExitdir(m_old_td); m_exitdir = TrackdirToExitdir(m_old_td);
if (EnteredDepot()) return true; if (EnteredDepot()) return true;
if (!CanExitOldTile()) return false; if (!CanExitOldTile()) return false;
@ -114,7 +114,7 @@ protected:
if (IsRailTT() && GetTileType(m_new_tile) == MP_RAILWAY && IsPlainRailTile(m_new_tile)) { if (IsRailTT() && GetTileType(m_new_tile) == MP_RAILWAY && IsPlainRailTile(m_new_tile)) {
m_new_td_bits = (TrackdirBits)(GetTrackBits(m_new_tile) * 0x101); m_new_td_bits = (TrackdirBits)(GetTrackBits(m_new_tile) * 0x101);
} else { } else {
uint32 ts = GetTileTrackStatus(m_new_tile, TT()); uint32 ts = GetTileTrackStatus(m_new_tile, TT(), m_veh->u.road.compatible_roadtypes);
m_new_td_bits = (TrackdirBits)(ts & TRACKDIR_BIT_MASK); m_new_td_bits = (TrackdirBits)(ts & TRACKDIR_BIT_MASK);
} }
return (m_new_td_bits != TRACKDIR_BIT_NONE); return (m_new_td_bits != TRACKDIR_BIT_NONE);

View File

@ -113,7 +113,7 @@ public:
default: default:
m_destTile = v->dest_tile; m_destTile = v->dest_tile;
m_dest_station_id = INVALID_STATION; m_dest_station_id = INVALID_STATION;
m_destTrackdirs = (TrackdirBits)(GetTileTrackStatus(v->dest_tile, TRANSPORT_RAIL) & TRACKDIR_BIT_MASK); m_destTrackdirs = (TrackdirBits)(GetTileTrackStatus(v->dest_tile, TRANSPORT_RAIL, 0) & TRACKDIR_BIT_MASK);
break; break;
} }
CYapfDestinationRailBase::SetDestination(v); CYapfDestinationRailBase::SetDestination(v);

View File

@ -268,14 +268,14 @@ public:
// our source tile will be the next vehicle tile (should be the given one) // our source tile will be the next vehicle tile (should be the given one)
TileIndex src_tile = tile; TileIndex src_tile = tile;
// get available trackdirs on the start tile // get available trackdirs on the start tile
uint ts = GetTileTrackStatus(tile, TRANSPORT_ROAD); uint ts = GetTileTrackStatus(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes);
TrackdirBits src_trackdirs = (TrackdirBits)(ts & TRACKDIR_BIT_MASK); TrackdirBits src_trackdirs = (TrackdirBits)(ts & TRACKDIR_BIT_MASK);
// select reachable trackdirs only // select reachable trackdirs only
src_trackdirs &= DiagdirReachesTrackdirs(enterdir); src_trackdirs &= DiagdirReachesTrackdirs(enterdir);
// get available trackdirs on the destination tile // get available trackdirs on the destination tile
TileIndex dest_tile = v->dest_tile; TileIndex dest_tile = v->dest_tile;
uint dest_ts = GetTileTrackStatus(dest_tile, TRANSPORT_ROAD); uint dest_ts = GetTileTrackStatus(dest_tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes);
TrackdirBits dest_trackdirs = (TrackdirBits)(dest_ts & TRACKDIR_BIT_MASK); TrackdirBits dest_trackdirs = (TrackdirBits)(dest_ts & TRACKDIR_BIT_MASK);
// set origin and destination nodes // set origin and destination nodes
@ -320,7 +320,7 @@ public:
// set destination tile, trackdir // set destination tile, trackdir
// get available trackdirs on the destination tile // get available trackdirs on the destination tile
uint dest_ts = GetTileTrackStatus(dst_tile, TRANSPORT_ROAD); uint dest_ts = GetTileTrackStatus(dst_tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes);
TrackdirBits dst_td_bits = (TrackdirBits)(dest_ts & TRACKDIR_BIT_MASK); TrackdirBits dst_td_bits = (TrackdirBits)(dest_ts & TRACKDIR_BIT_MASK);
Yapf().SetDestination(dst_tile, dst_td_bits); Yapf().SetDestination(dst_tile, dst_td_bits);
@ -345,7 +345,7 @@ public:
// set origin (tile, trackdir) // set origin (tile, trackdir)
TileIndex src_tile = v->tile; TileIndex src_tile = v->tile;
Trackdir src_td = GetVehicleTrackdir(v); Trackdir src_td = GetVehicleTrackdir(v);
if ((GetTileTrackStatus(src_tile, TRANSPORT_ROAD) & TrackdirToTrackdirBits(src_td)) == 0) { if ((GetTileTrackStatus(src_tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes) & TrackdirToTrackdirBits(src_td)) == 0) {
// sometimes the roadveh is not on the road (it resides on non-existing track) // sometimes the roadveh is not on the road (it resides on non-existing track)
// how should we handle that situation? // how should we handle that situation?
return false; return false;
@ -438,7 +438,7 @@ Depot* YapfFindNearestRoadDepot(const Vehicle *v)
{ {
TileIndex tile = v->tile; TileIndex tile = v->tile;
Trackdir trackdir = GetVehicleTrackdir(v); Trackdir trackdir = GetVehicleTrackdir(v);
if ((GetTileTrackStatus(tile, TRANSPORT_ROAD) & TrackdirToTrackdirBits(trackdir)) == 0) if ((GetTileTrackStatus(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes) & TrackdirToTrackdirBits(trackdir)) == 0)
return NULL; return NULL;
// handle the case when our vehicle is already in the depot tile // handle the case when our vehicle is already in the depot tile

View File

@ -53,7 +53,7 @@ public:
// convert origin trackdir to TrackdirBits // convert origin trackdir to TrackdirBits
TrackdirBits trackdirs = TrackdirToTrackdirBits(trackdir); TrackdirBits trackdirs = TrackdirToTrackdirBits(trackdir);
// get available trackdirs on the destination tile // get available trackdirs on the destination tile
TrackdirBits dest_trackdirs = (TrackdirBits)(GetTileTrackStatus(v->dest_tile, TRANSPORT_WATER) & TRACKDIR_BIT_MASK); TrackdirBits dest_trackdirs = (TrackdirBits)(GetTileTrackStatus(v->dest_tile, TRANSPORT_WATER, 0) & TRACKDIR_BIT_MASK);
// create pathfinder instance // create pathfinder instance
Tpf pf; Tpf pf;