train_cmd.c
branchcustombridgeheads
changeset 5611 11da6bafbfb9
parent 5605 3864438e7cb2
child 5612 5e103bb5236d
--- 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?