(svn r15792) -Codechange: Use a different algorithm for train vehicles to follow the vehicle in front of them.

This commit is contained in:
frosch 2009-03-21 22:25:38 +00:00
parent 2a422e3e95
commit 12dbe1dd0f

View File

@ -3356,34 +3356,6 @@ static byte AfterSetTrainPos(Vehicle *v, bool new_tile)
return old_z; return old_z;
} }
static const Direction _new_vehicle_direction_table[11] = {
DIR_N , DIR_NW, DIR_W , INVALID_DIR,
DIR_NE, DIR_N , DIR_SW, INVALID_DIR,
DIR_E , DIR_SE, DIR_S
};
static inline int GetDirectionToVehicle(const Vehicle *v, int x, int y)
{
byte offs;
x -= v->x_pos;
if (x >= 0) {
offs = (x > 2) ? 0 : 1;
} else {
offs = (x < -2) ? 2 : 1;
}
y -= v->y_pos;
if (y >= 0) {
offs += ((y > 2) ? 0 : 1) * 4;
} else {
offs += ((y < -2) ? 2 : 1) * 4;
}
assert(offs < 11);
return _new_vehicle_direction_table[offs];
}
/* Check if the vehicle is compatible with the specified tile */ /* Check if the vehicle is compatible with the specified tile */
static inline bool CheckCompatibleRail(const Vehicle *v, TileIndex tile) static inline bool CheckCompatibleRail(const Vehicle *v, TileIndex tile)
{ {
@ -3726,15 +3698,30 @@ static void TrainController(Vehicle *v, Vehicle *nomove)
TryReserveRailTrack(gp.new_tile, TrackBitsToTrack(chosen_track)); TryReserveRailTrack(gp.new_tile, TrackBitsToTrack(chosen_track));
} }
} else { } else {
static const TrackBits _matching_tracks[8] = {
TRACK_BIT_LEFT | TRACK_BIT_RIGHT, TRACK_BIT_X,
TRACK_BIT_UPPER | TRACK_BIT_LOWER, TRACK_BIT_Y,
TRACK_BIT_LEFT | TRACK_BIT_RIGHT, TRACK_BIT_X,
TRACK_BIT_UPPER | TRACK_BIT_LOWER, TRACK_BIT_Y
};
/* The wagon is active, simply follow the prev vehicle. */ /* The wagon is active, simply follow the prev vehicle. */
chosen_track = (TrackBits)(byte)(_matching_tracks[GetDirectionToVehicle(prev, gp.x, gp.y)] & bits); if (prev->tile == gp.new_tile) {
/* Choose the same track as prev */
if (prev->u.rail.track == TRACK_BIT_WORMHOLE) {
/* Vehicles entering tunnels enter the wormhole earlier than for bridges.
* However, just choose the track into the wormhole. */
assert(IsTunnel(prev->tile));
chosen_track = bits;
} else {
chosen_track = prev->u.rail.track;
}
} else {
/* Choose the track that leads to the tile where prev is. */
static const TrackBits _connecting_track[DIAGDIR_END][DIAGDIR_END] = {
{TRACK_BIT_Y, TRACK_BIT_LOWER, TRACK_BIT_NONE, TRACK_BIT_LEFT },
{TRACK_BIT_UPPER, TRACK_BIT_X, TRACK_BIT_LEFT, TRACK_BIT_NONE },
{TRACK_BIT_NONE, TRACK_BIT_RIGHT, TRACK_BIT_Y, TRACK_BIT_UPPER},
{TRACK_BIT_RIGHT, TRACK_BIT_NONE, TRACK_BIT_LOWER, TRACK_BIT_X }
};
DiagDirection exitdir = DiagdirBetweenTiles(gp.new_tile, prev->tile);
assert(IsValidDiagDirection(exitdir));
chosen_track = _connecting_track[enterdir][exitdir];
}
chosen_track &= bits;
} }
/* Make sure chosen track is a valid track */ /* Make sure chosen track is a valid track */