--- a/train_cmd.c Sat Dec 30 18:36:42 2006 +0000
+++ b/train_cmd.c Sun Dec 31 02:53:23 2006 +0000
@@ -2740,24 +2740,26 @@
static byte AfterSetTrainPos(Vehicle *v, bool new_tile)
{
- byte new_z, old_z;
-
- // need this hint so it returns the right z coordinate on bridges.
- new_z = GetSlopeZ(v->x_pos, v->y_pos);
-
- old_z = v->z_pos;
- v->z_pos = new_z;
-
- if (new_tile) {
- CLRBIT(v->u.rail.flags, VRF_GOINGUP);
- CLRBIT(v->u.rail.flags, VRF_GOINGDOWN);
-
- if (new_z != old_z) {
- TileIndex tile = TileVirtXY(v->x_pos, v->y_pos);
-
- // XXX workaround, whole UP/DOWN detection needs overhaul
- if (!IsTunnelTile(tile)) {
- SETBIT(v->u.rail.flags, (new_z > old_z) ? VRF_GOINGUP : VRF_GOINGDOWN);
+ byte new_z;
+ byte old_z = v->z_pos;
+
+ if (v->type != VEH_Train || v->u.rail.track != 0x40) {
+ // need this hint so it returns the right z coordinate on bridges.
+ new_z = GetSlopeZ(v->x_pos, v->y_pos);
+
+ v->z_pos = new_z;
+
+ if (new_tile) {
+ CLRBIT(v->u.rail.flags, VRF_GOINGUP);
+ CLRBIT(v->u.rail.flags, VRF_GOINGDOWN);
+
+ if (new_z != old_z) {
+ TileIndex tile = TileVirtXY(v->x_pos, v->y_pos);
+
+ // XXX workaround, whole UP/DOWN detection needs overhaul
+ if (!IsTunnelTile(tile)) {
+ SETBIT(v->u.rail.flags, (new_z > old_z) ? VRF_GOINGUP : VRF_GOINGDOWN);
+ }
}
}
}
@@ -2783,9 +2785,12 @@
static Direction GetNewVehicleDirection(const Vehicle *v, int x, int y)
{
- uint offs = (y - v->y_pos + 1) * 4 + (x - v->x_pos + 1);
- assert(offs < 11);
- return _new_vehicle_direction_table[offs];
+ if (v->type != VEH_Train || v->u.rail.track != 0x40 || !IsBridgeTile(v->tile)) {
+ uint offs = (y - v->y_pos + 1) * 4 + (x - v->x_pos + 1);
+ assert(offs < 11);
+ return _new_vehicle_direction_table[offs];
+ }
+ return DiagDirToDir(GetBridgeRampDirection(v->tile));
}
static int GetDirectionToVehicle(const Vehicle *v, int x, int y)
@@ -3042,7 +3047,10 @@
} else {
/* is not inside depot */
- if (!TrainCheckIfLineEnds(v)) return;
+ if (!TrainCheckIfLineEnds(v)) {
+ /* reversing */
+ return;
+ }
r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
if (r & 0x8) {
@@ -3064,11 +3072,20 @@
/* A new tile is about to be entered. */
byte bits;
+
/* Determine what direction we're entering the new tile from */
dir = GetNewVehicleDirectionByTile(gp.new_tile, gp.old_tile);
enterdir = DirToDiagDir(dir);
assert(enterdir==0 || enterdir==1 || enterdir==2 || enterdir==3);
+ /* We should not let the train that is leaving custom bridge head to enter the tile that is under bridge */
+ if (IsBridgeTile(gp.old_tile) && GetBridgeRampDirection(gp.old_tile) == enterdir) {
+ /* train entering the bridge body */
+ extern uint32 VehicleEnter_Railway_Bridge(Vehicle *v, TileIndex tile, int x, int y);
+ VehicleEnter_Railway_Bridge(v, gp.new_tile, gp.x, gp.y);
+ goto move_done;
+ }
+
/* Get the status of the tracks in the new tile and mask
* away the bits that aren't reachable. */
ts = GetTileTrackStatus(gp.new_tile, TRANSPORT_RAIL) & _reachable_tracks[enterdir];
@@ -3173,6 +3190,7 @@
}
}
+move_done:
/* update image of train, as well as delta XY */
newdir = GetNewVehicleDirection(v, gp.x, gp.y);
UpdateTrainDeltaXY(v, newdir);
@@ -3405,11 +3423,11 @@
tile = v->tile;
- if (IsTileType(tile, MP_TUNNEL) || IsTileType(tile, MP_RAILWAY_BRIDGE)) {
- DiagDirection dir;
-
- dir = IsTunnelTile(tile) ? GetTunnelDirection(tile) : GetBridgeRampDirection(tile);
- if (DiagDirToDir(dir) == v->direction) return true;
+ if (IsTunnelTile(tile)) {
+ DiagDirection dir = GetTunnelDirection(tile);
+ if (v->direction == DiagDirToDir(dir)) return true;
+ } else if (IsBridgeTile(tile)) {
+ if (TrackdirToExitdir(GetVehicleTrackdir(v)) == GetBridgeRampDirection(tile)) return true;
}
// depot?