Use separate tile hash for each vehicle type

This commit is contained in:
Jonathan G Rennison
2020-02-28 22:21:10 +00:00
parent 4020719227
commit 4108672cf6
14 changed files with 227 additions and 221 deletions

View File

@@ -330,7 +330,7 @@ static Vehicle *FindTrainOnTrackEnum(Vehicle *v, void *data)
{
FindTrainOnTrackInfo *info = (FindTrainOnTrackInfo *)data;
if (v->type != VEH_TRAIN || (v->vehstatus & VS_CRASHED)) return nullptr;
if ((v->vehstatus & VS_CRASHED)) return nullptr;
Train *t = Train::From(v);
if (t->track & TRACK_BIT_WORMHOLE) {
@@ -372,7 +372,7 @@ PBSTileInfo FollowTrainReservation(const Train *v, Vehicle **train_on_res)
ftoti.res = FollowReservation(v->owner, GetRailTypeInfo(v->railtype)->compatible_railtypes, tile, trackdir);
ftoti.res.okay = IsSafeWaitingPosition(v, ftoti.res.tile, ftoti.res.trackdir, true, _settings_game.pf.forbid_90_deg);
if (train_on_res != nullptr) {
FindVehicleOnPos(ftoti.res.tile, &ftoti, FindTrainOnTrackEnum);
FindVehicleOnPos(ftoti.res.tile, VEH_TRAIN, &ftoti, FindTrainOnTrackEnum);
if (ftoti.best != nullptr) *train_on_res = ftoti.best->First();
if (*train_on_res == nullptr && IsRailStationTile(ftoti.res.tile)) {
/* The target tile is a rail station. The track follower
@@ -381,13 +381,13 @@ PBSTileInfo FollowTrainReservation(const Train *v, Vehicle **train_on_res)
* for a possible train. */
TileIndexDiff diff = TileOffsByDiagDir(TrackdirToExitdir(ReverseTrackdir(ftoti.res.trackdir)));
for (TileIndex st_tile = ftoti.res.tile + diff; *train_on_res == nullptr && IsCompatibleTrainStationTile(st_tile, ftoti.res.tile); st_tile += diff) {
FindVehicleOnPos(st_tile, &ftoti, FindTrainOnTrackEnum);
FindVehicleOnPos(st_tile, VEH_TRAIN, &ftoti, FindTrainOnTrackEnum);
if (ftoti.best != nullptr) *train_on_res = ftoti.best->First();
}
}
if (*train_on_res == nullptr && IsTileType(ftoti.res.tile, MP_TUNNELBRIDGE) && IsTrackAcrossTunnelBridge(ftoti.res.tile, TrackdirToTrack(ftoti.res.trackdir)) && !IsTunnelBridgeWithSignalSimulation(ftoti.res.tile)) {
/* The target tile is a bridge/tunnel, also check the other end tile. */
FindVehicleOnPos(GetOtherTunnelBridgeEnd(ftoti.res.tile), &ftoti, FindTrainOnTrackEnum);
FindVehicleOnPos(GetOtherTunnelBridgeEnd(ftoti.res.tile), VEH_TRAIN, &ftoti, FindTrainOnTrackEnum);
if (ftoti.best != nullptr) *train_on_res = ftoti.best->First();
}
}
@@ -419,21 +419,21 @@ Train *GetTrainForReservation(TileIndex tile, Track track)
FindTrainOnTrackInfo ftoti;
ftoti.res = FollowReservation(GetTileOwner(tile), rts, tile, trackdir, true);
FindVehicleOnPos(ftoti.res.tile, &ftoti, FindTrainOnTrackEnum);
FindVehicleOnPos(ftoti.res.tile, VEH_TRAIN, &ftoti, FindTrainOnTrackEnum);
if (ftoti.best != nullptr) return ftoti.best;
/* Special case for stations: check the whole platform for a vehicle. */
if (IsRailStationTile(ftoti.res.tile)) {
TileIndexDiff diff = TileOffsByDiagDir(TrackdirToExitdir(ReverseTrackdir(ftoti.res.trackdir)));
for (TileIndex st_tile = ftoti.res.tile + diff; IsCompatibleTrainStationTile(st_tile, ftoti.res.tile); st_tile += diff) {
FindVehicleOnPos(st_tile, &ftoti, FindTrainOnTrackEnum);
FindVehicleOnPos(st_tile, VEH_TRAIN, &ftoti, FindTrainOnTrackEnum);
if (ftoti.best != nullptr) return ftoti.best;
}
}
/* Special case for bridges/tunnels: check the other end as well. */
if (IsTileType(ftoti.res.tile, MP_TUNNELBRIDGE) && IsTrackAcrossTunnelBridge(ftoti.res.tile, TrackdirToTrack(ftoti.res.trackdir))) {
FindVehicleOnPos(GetOtherTunnelBridgeEnd(ftoti.res.tile), &ftoti, FindTrainOnTrackEnum);
FindVehicleOnPos(GetOtherTunnelBridgeEnd(ftoti.res.tile), VEH_TRAIN, &ftoti, FindTrainOnTrackEnum);
if (ftoti.best != nullptr) return ftoti.best;
}
}
@@ -608,8 +608,7 @@ bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bo
TileIndex other_end = GetOtherTunnelBridgeEnd(tile);
if (HasAcrossTunnelBridgeReservation(other_end) && GetTunnelBridgeExitSignalState(other_end) == SIGNAL_STATE_RED) return false;
Direction dir = DiagDirToDir(GetTunnelBridgeDirection(other_end));
if (HasVehicleOnPos(other_end, &dir, [](Vehicle *v, void *data) -> Vehicle * {
if (v->type != VEH_TRAIN) return nullptr;
if (HasVehicleOnPos(other_end, VEH_TRAIN, &dir, [](Vehicle *v, void *data) -> Vehicle * {
DirDiff diff = DirDifference(v->direction, *((Direction *) data));
if (diff == DIRDIFF_SAME) return v;
if (diff == DIRDIFF_45RIGHT || diff == DIRDIFF_45LEFT) {