train_cmd.c
changeset 5385 3868f2e6db9b
parent 5380 8ea58542b6e0
child 5400 bba42ad3223b
--- a/train_cmd.c	Wed Dec 27 12:22:25 2006 +0000
+++ b/train_cmd.c	Wed Dec 27 12:38:02 2006 +0000
@@ -25,6 +25,7 @@
 #include "waypoint.h"
 #include "vehicle_gui.h"
 #include "train.h"
+#include "bridge.h"
 #include "newgrf_callbacks.h"
 #include "newgrf_engine.h"
 #include "newgrf_sound.h"
@@ -105,10 +106,7 @@
 		/* Power is not added for articulated parts */
 		if (IsArticulatedPart(u)) continue;
 
-		if (IsBridgeTile(u->tile) && IsBridgeMiddle(u->tile) && DiagDirToAxis(DirToDiagDir(u->direction)) == GetBridgeAxis(u->tile)) {
-			if (!HasPowerOnRail(u->u.rail.railtype, GetRailTypeOnBridge(u->tile))) engine_has_power = false;
-			if (!HasPowerOnRail(v->u.rail.railtype, GetRailTypeOnBridge(u->tile))) wagon_has_power = false;
-		} else if (IsLevelCrossingTile(u->tile)) {
+		if (IsLevelCrossingTile(u->tile)) {
 			if (!HasPowerOnRail(u->u.rail.railtype, GetRailTypeCrossing(u->tile))) engine_has_power = false;
 			if (!HasPowerOnRail(v->u.rail.railtype, GetRailTypeCrossing(u->tile))) wagon_has_power = false;
 		} else {
@@ -1601,13 +1599,14 @@
 		UpdateVarsAfterSwap(a);
 		UpdateVarsAfterSwap(b);
 
-		VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos);
-		VehicleEnterTile(b, b->tile, b->x_pos, b->y_pos);
+		/* call the proper EnterTile function unless we are in a wormhole */
+		if (!(a->u.rail.track & 0x40)) VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos);
+		if (!(b->u.rail.track & 0x40)) VehicleEnterTile(b, b->tile, b->x_pos, b->y_pos);
 	} else {
 		if (!(a->u.rail.track & 0x80)) a->direction = ReverseDir(a->direction);
 		UpdateVarsAfterSwap(a);
 
-		VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos);
+		if (!(a->u.rail.track & 0x40)) VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos);
 	}
 
 	/* Update train's power incase tiles were different rail type */
@@ -1940,8 +1939,6 @@
 		return tfdd;
 	}
 
-	if (v->u.rail.track == 0x40) tile = GetVehicleOutOfTunnelTile(v);
-
 	if (_patches.yapf.rail_use_yapf) {
 		bool found = YapfFindNearestRailDepotTwoWay(v, max_distance, NPF_INFINITE_PENALTY, &tfdd.tile, &tfdd.reverse);
 		tfdd.best_length = found ? max_distance / 2 : -1; // some fake distance or NOT_FOUND
@@ -2733,9 +2730,7 @@
 	byte new_z, old_z;
 
 	// need this hint so it returns the right z coordinate on bridges.
-	_get_z_hint = v->z_pos;
 	new_z = GetSlopeZ(v->x_pos, v->y_pos);
-	_get_z_hint = 0;
 
 	old_z = v->z_pos;
 	v->z_pos = new_z;
@@ -2811,13 +2806,6 @@
 			// normal tracks, jump to owner check
 			break;
 
-		case MP_TUNNELBRIDGE:
-			if (IsBridge(tile) && IsBridgeMiddle(tile)) {
-				// is train going over the bridge?
-				if (v->z_pos > GetTileMaxZ(tile)) return true;
-			}
-			break;
-
 		case MP_STREET:
 			// tracks over roads, do owner check of tracks
 			return
@@ -3158,15 +3146,16 @@
 				v->direction = chosen_dir;
 			}
 		} else {
-			/* in tunnel */
+			/* in tunnel on on a bridge */
 			GetNewVehiclePos(v, &gp);
 
-			// Check if to exit the tunnel...
-			if (!IsTunnelTile(gp.new_tile) ||
-					!(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y)&0x4) ) {
+			SetSpeedLimitOnBridge(v);
+
+			if (!(IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) || !(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y) & 0x4)) {
 				v->x_pos = gp.x;
 				v->y_pos = gp.y;
 				VehiclePositionChanged(v);
+				if (!(v->vehstatus & VS_HIDDEN)) EndVehicleMove(v);
 				continue;
 			}
 		}
@@ -3263,7 +3252,7 @@
 	 * others are on it */
 	DisableTrainCrossing(v->tile);
 
-	if (v->u.rail.track == 0x40) { // inside a tunnel
+	if ( (v->u.rail.track == 0x40 && v->vehstatus & VS_HIDDEN) ) { // inside a tunnel
 		TileIndex endtile = CheckTunnelBusy(v->tile, NULL);
 
 		if (endtile == INVALID_TILE) return; // tunnel is busy (error returned)
@@ -3294,15 +3283,16 @@
 	};
 
 	do {
-		//I need to buffer the train direction
-		if (!(v->u.rail.track & 0x40)) {
+		/* We don't need to twist around vehicles if they're not visible */
+		if (!(v->vehstatus & VS_HIDDEN)) {
 			v->direction = ChangeDir(v->direction, delta[GB(Random(), 0, 2)]);
-		}
-		if (!(v->vehstatus & VS_HIDDEN)) {
 			BeginVehicleMove(v);
 			UpdateTrainDeltaXY(v, v->direction);
 			v->cur_image = GetTrainImage(v, v->direction);
-			AfterSetTrainPos(v, false);
+			/* Refrain from updating the z position of the vehicle when on
+			   a bridge, because AfterSetTrainPos will put the vehicle under
+			   the bridge in that case */
+			if (!(v->u.rail.track & 0x40)) AfterSetTrainPos(v, false);
 		}
 	} while ((v = v->next) != NULL);
 }
@@ -3313,7 +3303,7 @@
 	uint32 r;
 	Vehicle *u;
 
-	if (state == 4 && v->u.rail.track != 0x40) {
+	if (state == 4 && !(v->u.rail.track & VS_HIDDEN)) {
 		CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE);
 	}
 
@@ -3402,10 +3392,11 @@
 
 	tile = v->tile;
 
-	// tunnel entrance?
-	if (IsTunnelTile(tile) &&
-			DiagDirToDir(GetTunnelDirection(tile)) == v->direction) {
-		return true;
+	if (IsTileType(tile, MP_TUNNELBRIDGE)) {
+		DiagDirection dir;
+
+		dir = IsTunnel(tile) ? GetTunnelDirection(tile) : GetBridgeRampDirection(tile);
+		if (DiagDirToDir(dir) == v->direction) return true;
 	}
 
 	// depot?