From 12dbe1dd0f6f01164099e35172de172a49549768 Mon Sep 17 00:00:00 2001 From: frosch Date: Sat, 21 Mar 2009 22:25:38 +0000 Subject: [PATCH] (svn r15792) -Codechange: Use a different algorithm for train vehicles to follow the vehicle in front of them. --- src/train_cmd.cpp | 59 ++++++++++++++++++----------------------------- 1 file changed, 23 insertions(+), 36 deletions(-) diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index e5df3b9c44..e52a04eb02 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -3356,34 +3356,6 @@ static byte AfterSetTrainPos(Vehicle *v, bool new_tile) 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 */ 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)); } } 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. */ - 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 */