train_cmd.c
changeset 2916 8f1aa489701f
parent 2883 e1efe385e89c
child 2928 414b96d4d4fb
equal deleted inserted replaced
2915:c59cbb76b5b2 2916:8f1aa489701f
    17 #include "news.h"
    17 #include "news.h"
    18 #include "engine.h"
    18 #include "engine.h"
    19 #include "player.h"
    19 #include "player.h"
    20 #include "sound.h"
    20 #include "sound.h"
    21 #include "depot.h"
    21 #include "depot.h"
    22 #include "debug.h"
       
    23 #include "waypoint.h"
    22 #include "waypoint.h"
    24 #include "vehicle_gui.h"
    23 #include "vehicle_gui.h"
    25 #include "train.h"
    24 #include "train.h"
    26 
    25 
    27 static bool TrainCheckIfLineEnds(Vehicle *v);
    26 static bool TrainCheckIfLineEnds(Vehicle *v);
  1550 		first = first->next;
  1549 		first = first->next;
  1551 		length -= 2;
  1550 		length -= 2;
  1552 	}
  1551 	}
  1553 }
  1552 }
  1554 
  1553 
  1555 static TileIndex GetVehicleTileOutOfTunnel(const Vehicle* v, bool reverse)
       
  1556 {
       
  1557 	TileIndex tile;
       
  1558 	byte direction = (!reverse) ? DirToDiagdir(v->direction) : ReverseDiagdir(v->direction >> 1);
       
  1559 	TileIndexDiff delta = TileOffsByDir(direction);
       
  1560 
       
  1561 	if (v->u.rail.track != 0x40) return v->tile;
       
  1562 
       
  1563 	for (tile = v->tile;; tile += delta) {
       
  1564 		if (IsTunnelTile(tile) && GB(_m[tile].m5, 0, 2) != direction && GetTileZ(tile) == v->z_pos)
       
  1565  			break;
       
  1566  	}
       
  1567  	return tile;
       
  1568 }
       
  1569 
       
  1570 static void ReverseTrainDirection(Vehicle *v)
  1554 static void ReverseTrainDirection(Vehicle *v)
  1571 {
  1555 {
  1572 	int l = 0, r = -1;
  1556 	int l = 0, r = -1;
  1573 	Vehicle *u;
  1557 	Vehicle *u;
  1574 	TileIndex tile;
       
  1575 	Trackdir trackdir;
       
  1576 	TileIndex pbs_end_tile = v->u.rail.pbs_end_tile; // these may be changed, and we may need
       
  1577 	Trackdir pbs_end_trackdir = v->u.rail.pbs_end_trackdir; // the old values, so cache them
       
  1578 
       
  1579 	u = GetLastVehicleInChain(v);
       
  1580 	tile = GetVehicleTileOutOfTunnel(u, false);
       
  1581 	trackdir = ReverseTrackdir(GetVehicleTrackdir(u));
       
  1582 
       
  1583 	if (PBSTileReserved(tile) & (1 << TrackdirToTrack(trackdir))) {
       
  1584 		NPFFindStationOrTileData fstd;
       
  1585 		NPFFoundTargetData ftd;
       
  1586 
       
  1587 		NPFFillWithOrderData(&fstd, v);
       
  1588 
       
  1589 		tile = GetVehicleTileOutOfTunnel(u, true);
       
  1590 
       
  1591 		DEBUG(pbs, 2) ("pbs: (%i) choose reverse (RV), tile:%x, trackdir:%i",v->unitnumber,  u->tile, trackdir);
       
  1592 		ftd = NPFRouteToStationOrTile(tile, trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype, PBS_MODE_ANY);
       
  1593 
       
  1594 		if (ftd.best_trackdir == 0xFF) {
       
  1595 			DEBUG(pbs, 0) ("pbs: (%i) no nodes encountered (RV)", v->unitnumber);
       
  1596 			CLRBIT(v->u.rail.flags, VRF_REVERSING);
       
  1597 			return;
       
  1598 		}
       
  1599 
       
  1600 		// we found a way out of the pbs block
       
  1601 		if (NPFGetFlag(&ftd.node, NPF_FLAG_PBS_EXIT)) {
       
  1602 			if (NPFGetFlag(&ftd.node, NPF_FLAG_PBS_BLOCKED)) {
       
  1603 				CLRBIT(v->u.rail.flags, VRF_REVERSING);
       
  1604 				return;
       
  1605 			}
       
  1606 		}
       
  1607 
       
  1608 		v->u.rail.pbs_end_tile = ftd.node.tile;
       
  1609 		v->u.rail.pbs_end_trackdir = ftd.node.direction;
       
  1610 	}
       
  1611 
       
  1612 	tile = GetVehicleTileOutOfTunnel(v, false);
       
  1613 	trackdir = GetVehicleTrackdir(v);
       
  1614 
       
  1615 	if (v->u.rail.pbs_status == PBS_STAT_HAS_PATH) {
       
  1616 		TileIndex tile = AddTileIndexDiffCWrap(v->tile, TileIndexDiffCByDir(TrackdirToExitdir(trackdir)));
       
  1617 		uint32 ts;
       
  1618 		assert(tile != INVALID_TILE);
       
  1619 		ts = GetTileTrackStatus(tile, TRANSPORT_RAIL);
       
  1620 		ts &= TrackdirReachesTrackdirs(trackdir);
       
  1621 		assert(ts != 0 && KillFirstBit2x64(ts) == 0);
       
  1622 		trackdir = FindFirstBit2x64(ts);
       
  1623 		PBSClearPath(tile, trackdir, pbs_end_tile, pbs_end_trackdir);
       
  1624 		v->u.rail.pbs_status = PBS_STAT_NONE;
       
  1625 	} else if (PBSTileReserved(tile) & (1 << TrackdirToTrack(trackdir))) {
       
  1626 		PBSClearPath(tile, trackdir, pbs_end_tile, pbs_end_trackdir);
       
  1627 		if (v->u.rail.track != 0x40)
       
  1628 			PBSReserveTrack(tile, trackdir & 7);
       
  1629 	};
       
  1630 
  1558 
  1631 	if (IsTileDepotType(v->tile, TRANSPORT_RAIL))
  1559 	if (IsTileDepotType(v->tile, TRANSPORT_RAIL))
  1632 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
  1560 		InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
  1633 
  1561 
  1634 
  1562 
  2038 	for (u = v; u != NULL; u = u->next) {
  1966 	for (u = v; u != NULL; u = u->next) {
  2039 		if (u->u.rail.track != 0x80 || u->tile != v->tile) return false;
  1967 		if (u->u.rail.track != 0x80 || u->tile != v->tile) return false;
  2040 	}
  1968 	}
  2041 
  1969 
  2042 	if (v->u.rail.force_proceed == 0) {
  1970 	if (v->u.rail.force_proceed == 0) {
  2043 		Trackdir trackdir = GetVehicleTrackdir(v);
       
  2044 
       
  2045 		if (++v->load_unload_time_rem < 37) {
  1971 		if (++v->load_unload_time_rem < 37) {
  2046 			InvalidateWindowClasses(WC_TRAINS_LIST);
  1972 			InvalidateWindowClasses(WC_TRAINS_LIST);
  2047 			return true;
  1973 			return true;
  2048 		}
  1974 		}
  2049 
  1975 
  2050 		v->load_unload_time_rem = 0;
  1976 		v->load_unload_time_rem = 0;
  2051 
  1977 
  2052 		if (PBSIsPbsSegment(v->tile, trackdir)) {
       
  2053 			NPFFindStationOrTileData fstd;
       
  2054 			NPFFoundTargetData ftd;
       
  2055 
       
  2056 			if (PBSTileUnavail(v->tile) & (1 << trackdir)) return true;
       
  2057 
       
  2058 			NPFFillWithOrderData(&fstd, v);
       
  2059 
       
  2060 			DEBUG(pbs, 2) ("pbs: (%i) choose depot (DP), tile:%x, trackdir:%i",v->unitnumber,  v->tile, trackdir);
       
  2061 			ftd = NPFRouteToStationOrTile(v->tile, trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype, PBS_MODE_GREEN);
       
  2062 
       
  2063 			// we found a way out of the pbs block
       
  2064 			if (NPFGetFlag(&ftd.node, NPF_FLAG_PBS_EXIT)) {
       
  2065 				if (NPFGetFlag(&ftd.node, NPF_FLAG_PBS_BLOCKED) || NPFGetFlag(&ftd.node, NPF_FLAG_PBS_RED)) {
       
  2066 					return true;
       
  2067 				} else {
       
  2068 					v->u.rail.pbs_end_tile = ftd.node.tile;
       
  2069 					v->u.rail.pbs_end_trackdir = ftd.node.direction;
       
  2070 					goto green;
       
  2071 				}
       
  2072 			}
       
  2073 		}
       
  2074 
       
  2075 		if (UpdateSignalsOnSegment(v->tile, v->direction)) {
  1978 		if (UpdateSignalsOnSegment(v->tile, v->direction)) {
  2076 			InvalidateWindowClasses(WC_TRAINS_LIST);
  1979 			InvalidateWindowClasses(WC_TRAINS_LIST);
  2077 			return true;
  1980 			return true;
  2078 		}
  1981 		}
  2079 	}
  1982 	}
  2080 green:
  1983 
  2081 	VehicleServiceInDepot(v);
  1984 	VehicleServiceInDepot(v);
  2082 	InvalidateWindowClasses(WC_TRAINS_LIST);
  1985 	InvalidateWindowClasses(WC_TRAINS_LIST);
  2083 	TrainPlayLeaveStationSound(v);
  1986 	TrainPlayLeaveStationSound(v);
  2084 
  1987 
  2085 	v->u.rail.track = 1;
  1988 	v->u.rail.track = 1;
  2213 
  2116 
  2214 	if (_patches.new_pathfinding_all) { /* Use a new pathfinding for everything */
  2117 	if (_patches.new_pathfinding_all) { /* Use a new pathfinding for everything */
  2215 		NPFFindStationOrTileData fstd;
  2118 		NPFFindStationOrTileData fstd;
  2216 		NPFFoundTargetData ftd;
  2119 		NPFFoundTargetData ftd;
  2217 		Trackdir trackdir;
  2120 		Trackdir trackdir;
  2218 		uint16 pbs_tracks;
       
  2219 
  2121 
  2220 		NPFFillWithOrderData(&fstd, v);
  2122 		NPFFillWithOrderData(&fstd, v);
  2221 		/* The enterdir for the new tile, is the exitdir for the old tile */
  2123 		/* The enterdir for the new tile, is the exitdir for the old tile */
  2222 		trackdir = GetVehicleTrackdir(v);
  2124 		trackdir = GetVehicleTrackdir(v);
  2223 		assert(trackdir != 0xff);
  2125 		assert(trackdir != 0xff);
  2224 
  2126 
  2225 		pbs_tracks = PBSTileReserved(tile);
  2127 		ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype);
  2226 		pbs_tracks |= pbs_tracks << 8;
       
  2227 		pbs_tracks &= TrackdirReachesTrackdirs(trackdir);
       
  2228 		if (pbs_tracks || (v->u.rail.pbs_status == PBS_STAT_NEED_PATH)) {
       
  2229 			DEBUG(pbs, 2) ("pbs: (%i) choosefromblock, tile_org:%x tile_dst:%x  trackdir:%i  pbs_tracks:%i",v->unitnumber, tile,tile - TileOffsByDir(enterdir), trackdir, pbs_tracks);
       
  2230 			// clear the currently planned path
       
  2231 			if (v->u.rail.pbs_status != PBS_STAT_NEED_PATH) PBSClearPath(tile, FindFirstBit2x64(pbs_tracks), v->u.rail.pbs_end_tile, v->u.rail.pbs_end_trackdir);
       
  2232 
       
  2233 			// try to find a route to a green exit signal
       
  2234 			ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype, PBS_MODE_ANY);
       
  2235 
       
  2236 			v->u.rail.pbs_end_tile = ftd.node.tile;
       
  2237 			v->u.rail.pbs_end_trackdir = ftd.node.direction;
       
  2238 
       
  2239 		} else
       
  2240 			ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype, PBS_MODE_NONE);
       
  2241 
  2128 
  2242 		if (ftd.best_trackdir == 0xff) {
  2129 		if (ftd.best_trackdir == 0xff) {
  2243 			/* We are already at our target. Just do something */
  2130 			/* We are already at our target. Just do something */
  2244 			//TODO: maybe display error?
  2131 			//TODO: maybe display error?
  2245 			//TODO: go straight ahead if possible?
  2132 			//TODO: go straight ahead if possible?
  2315 		trackdir = GetVehicleTrackdir(v);
  2202 		trackdir = GetVehicleTrackdir(v);
  2316 		trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last));
  2203 		trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last));
  2317 		assert(trackdir != 0xff);
  2204 		assert(trackdir != 0xff);
  2318 		assert(trackdir_rev != 0xff);
  2205 		assert(trackdir_rev != 0xff);
  2319 
  2206 
  2320 		ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, last->tile, trackdir_rev, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype, PBS_MODE_NONE);
  2207 		ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, last->tile, trackdir_rev, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype);
  2321 
       
  2322 		if (ftd.best_bird_dist != 0) {
  2208 		if (ftd.best_bird_dist != 0) {
  2323 			/* We didn't find anything, just keep on going straight ahead */
  2209 			/* We didn't find anything, just keep on going straight ahead */
  2324 			reverse_best = false;
  2210 			reverse_best = false;
  2325 		} else {
  2211 		} else {
  2326 			if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE))
  2212 			if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE))
  2904 					gp.x = v->x_pos;
  2790 					gp.x = v->x_pos;
  2905 					gp.y = v->y_pos;
  2791 					gp.y = v->y_pos;
  2906 				} else {
  2792 				} else {
  2907 					/* is not inside depot */
  2793 					/* is not inside depot */
  2908 
  2794 
  2909 					if ((prev == NULL) && (!TrainCheckIfLineEnds(v)))
  2795 					if (!TrainCheckIfLineEnds(v))
  2910 						return;
  2796 						return;
  2911 
  2797 
  2912 					r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
  2798 					r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
  2913 					if (r & 0x8) {
  2799 					if (r & 0x8) {
  2914 						//debug("%x & 0x8", r);
  2800 						//debug("%x & 0x8", r);
  2959 					//debug("!CheckCompatibleRail(%p, %x)", v, gp.new_tile);
  2845 					//debug("!CheckCompatibleRail(%p, %x)", v, gp.new_tile);
  2960 					goto invalid_rail;
  2846 					goto invalid_rail;
  2961 				}
  2847 				}
  2962 
  2848 
  2963 				if (prev == NULL) {
  2849 				if (prev == NULL) {
  2964 					byte trackdir;
       
  2965 					/* Currently the locomotive is active. Determine which one of the
  2850 					/* Currently the locomotive is active. Determine which one of the
  2966 					 * available tracks to choose */
  2851 					 * available tracks to choose */
  2967 					chosen_track = 1 << ChooseTrainTrack(v, gp.new_tile, enterdir, bits);
  2852 					chosen_track = 1 << ChooseTrainTrack(v, gp.new_tile, enterdir, bits);
  2968 					assert(chosen_track & tracks);
  2853 					assert(chosen_track & tracks);
  2969 
  2854 
  2970 					trackdir = TrackEnterdirToTrackdir(FIND_FIRST_BIT(chosen_track), enterdir);
       
  2971 					assert(trackdir != 0xff);
       
  2972 
       
  2973 					if (PBSIsPbsSignal(gp.new_tile,trackdir) && PBSIsPbsSegment(gp.new_tile,trackdir)) {
       
  2974 						// encountered a pbs signal, and possible a pbs block
       
  2975 						DEBUG(pbs, 3) ("pbs: (%i) arrive AT signal, tile:%x  pbs_stat:%i",v->unitnumber, gp.new_tile, v->u.rail.pbs_status);
       
  2976 
       
  2977 						if (v->u.rail.pbs_status == PBS_STAT_NONE) {
       
  2978 							// we havent planned a path already, so try to find one now
       
  2979 							NPFFindStationOrTileData fstd;
       
  2980 							NPFFoundTargetData ftd;
       
  2981 
       
  2982 							NPFFillWithOrderData(&fstd, v);
       
  2983 
       
  2984 							DEBUG(pbs, 2) ("pbs: (%i) choose signal (TC), tile:%x, trackdir:%i",v->unitnumber,  gp.new_tile, trackdir);
       
  2985 							ftd = NPFRouteToStationOrTile(gp.new_tile, trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype, PBS_MODE_GREEN);
       
  2986 
       
  2987 							if (v->u.rail.force_proceed != 0)
       
  2988 								goto green_light;
       
  2989 
       
  2990 							if (ftd.best_trackdir == 0xFF)
       
  2991 								goto red_light;
       
  2992 
       
  2993 							// we found a way out of the pbs block
       
  2994 							if (NPFGetFlag(&ftd.node, NPF_FLAG_PBS_EXIT)) {
       
  2995 								if (NPFGetFlag(&ftd.node, NPF_FLAG_PBS_BLOCKED) || NPFGetFlag(&ftd.node, NPF_FLAG_PBS_RED))
       
  2996 									goto red_light;
       
  2997 								else {
       
  2998 									v->u.rail.pbs_end_tile = ftd.node.tile;
       
  2999 									v->u.rail.pbs_end_trackdir = ftd.node.direction;
       
  3000 									goto green_light;
       
  3001 								}
       
  3002 
       
  3003 							};
       
  3004 
       
  3005 						} else {
       
  3006 							// we have already planned a path through this pbs block
       
  3007 							// on entering the block, we reset our status
       
  3008 							v->u.rail.pbs_status = PBS_STAT_NONE;
       
  3009 							goto green_light;
       
  3010 						};
       
  3011 						DEBUG(pbs, 3) ("pbs: (%i) no green light found, or was no pbs-block",v->unitnumber);
       
  3012 					};
       
  3013 
       
  3014 					/* Check if it's a red signal and that force proceed is not clicked. */
  2855 					/* Check if it's a red signal and that force proceed is not clicked. */
  3015 					if ( (tracks>>16)&chosen_track && v->u.rail.force_proceed == 0) goto red_light;
  2856 					if ( (tracks>>16)&chosen_track && v->u.rail.force_proceed == 0) goto red_light;
  3016 				} else {
  2857 				} else {
  3017 					static byte _matching_tracks[8] = {0x30, 1, 0xC, 2, 0x30, 1, 0xC, 2};
  2858 					static byte _matching_tracks[8] = {0x30, 1, 0xC, 2, 0x30, 1, 0xC, 2};
  3018 
  2859 
  3019 					/* The wagon is active, simply follow the prev vehicle. */
  2860 					/* The wagon is active, simply follow the prev vehicle. */
  3020 					chosen_track = (byte)(_matching_tracks[GetDirectionToVehicle(prev, gp.x, gp.y)] & bits);
  2861 					chosen_track = (byte)(_matching_tracks[GetDirectionToVehicle(prev, gp.x, gp.y)] & bits);
  3021 				}
  2862 				}
  3022 green_light:
       
  3023 				if (v->next == NULL)
       
  3024 					PBSClearTrack(gp.old_tile, FIND_FIRST_BIT(v->u.rail.track));
       
  3025 
  2863 
  3026 				/* make sure chosen track is a valid track */
  2864 				/* make sure chosen track is a valid track */
  3027 				assert(chosen_track==1 || chosen_track==2 || chosen_track==4 || chosen_track==8 || chosen_track==16 || chosen_track==32);
  2865 				assert(chosen_track==1 || chosen_track==2 || chosen_track==4 || chosen_track==8 || chosen_track==16 || chosen_track==32);
  3028 
  2866 
  3029 				/* Update XY to reflect the entrance to the new tile, and select the direction to use */
  2867 				/* Update XY to reflect the entrance to the new tile, and select the direction to use */
  3048 					v->u.rail.track = chosen_track;
  2886 					v->u.rail.track = chosen_track;
  3049 					assert(v->u.rail.track);
  2887 					assert(v->u.rail.track);
  3050 				}
  2888 				}
  3051 
  2889 
  3052 				if (IsFrontEngine(v))
  2890 				if (IsFrontEngine(v))
  3053 				TrainMovedChangeSignals(gp.new_tile, enterdir);
  2891 					TrainMovedChangeSignals(gp.new_tile, enterdir);
  3054 
  2892 
  3055 				/* Signals can only change when the first
  2893 				/* Signals can only change when the first
  3056 				 * (above) or the last vehicle moves. */
  2894 				 * (above) or the last vehicle moves. */
  3057 				if (v->next == NULL)
  2895 				if (v->next == NULL)
  3058 				TrainMovedChangeSignals(gp.old_tile, (enterdir) ^ 2);
  2896 					TrainMovedChangeSignals(gp.old_tile, (enterdir) ^ 2);
  3059 
  2897 
  3060 				if (prev == NULL) {
  2898 				if (prev == NULL) {
  3061 					AffectSpeedByDirChange(v, chosen_dir);
  2899 					AffectSpeedByDirChange(v, chosen_dir);
  3062 				}
  2900 				}
  3063 
  2901 
  3162 
  3000 
  3163 	BeginVehicleMove(v);
  3001 	BeginVehicleMove(v);
  3164 	EndVehicleMove(v);
  3002 	EndVehicleMove(v);
  3165 	DeleteVehicle(v);
  3003 	DeleteVehicle(v);
  3166 
  3004 
  3167 	// clear up reserved pbs tracks
       
  3168 	if (PBSTileReserved(v->tile) & v->u.rail.track) {
       
  3169 		if (v == u) {
       
  3170 			PBSClearPath(v->tile, FIND_FIRST_BIT(v->u.rail.track), v->u.rail.pbs_end_tile, v->u.rail.pbs_end_trackdir);
       
  3171 			PBSClearPath(v->tile, FIND_FIRST_BIT(v->u.rail.track) + 8, v->u.rail.pbs_end_tile, v->u.rail.pbs_end_trackdir);
       
  3172 		};
       
  3173 		if (v->tile != u->tile) {
       
  3174 			PBSClearTrack(v->tile, FIND_FIRST_BIT(v->u.rail.track));
       
  3175 		};
       
  3176 	}
       
  3177 
       
  3178 	if (!(v->u.rail.track & 0xC0))
  3005 	if (!(v->u.rail.track & 0xC0))
  3179 		SetSignalsOnBothDir(v->tile, FIND_FIRST_BIT(v->u.rail.track));
  3006 		SetSignalsOnBothDir(v->tile, FIND_FIRST_BIT(v->u.rail.track));
  3180 
  3007 
  3181 	/* Check if the wagon was on a road/rail-crossing and disable it if no
  3008 	/* Check if the wagon was on a road/rail-crossing and disable it if no
  3182 	 * others are on it */
  3009 	 * others are on it */
  3300 	TileIndex tile;
  3127 	TileIndex tile;
  3301 	uint x,y;
  3128 	uint x,y;
  3302 	uint16 break_speed;
  3129 	uint16 break_speed;
  3303 	DiagDirection t;
  3130 	DiagDirection t;
  3304 	uint32 ts;
  3131 	uint32 ts;
  3305 	byte trackdir;
       
  3306 
  3132 
  3307 	t = v->breakdown_ctr;
  3133 	t = v->breakdown_ctr;
  3308 	if (t > 1) {
  3134 	if (t > 1) {
  3309 		v->vehstatus |= VS_TRAIN_SLOWING;
  3135 		v->vehstatus |= VS_TRAIN_SLOWING;
  3310 
  3136 
  3336 	}
  3162 	}
  3337 	/* Calculate next tile */
  3163 	/* Calculate next tile */
  3338 	tile += TileOffsByDir(t);
  3164 	tile += TileOffsByDir(t);
  3339 	// determine the track status on the next tile.
  3165 	// determine the track status on the next tile.
  3340 	ts = GetTileTrackStatus(tile, TRANSPORT_RAIL) & _reachable_tracks[t];
  3166 	ts = GetTileTrackStatus(tile, TRANSPORT_RAIL) & _reachable_tracks[t];
  3341 
       
  3342 	// if there are tracks on the new tile, pick one (trackdir will only be used when its a signal tile, in which case only 1 trackdir is accessible for us)
       
  3343 	if (ts & TRACKDIR_BIT_MASK)
       
  3344 		trackdir = FindFirstBit2x64(ts & TRACKDIR_BIT_MASK);
       
  3345 	else
       
  3346 		trackdir = INVALID_TRACKDIR;
       
  3347 
  3167 
  3348 	/* Calc position within the current tile ?? */
  3168 	/* Calc position within the current tile ?? */
  3349 	x = v->x_pos & 0xF;
  3169 	x = v->x_pos & 0xF;
  3350 	y = v->y_pos & 0xF;
  3170 	y = v->y_pos & 0xF;
  3351 
  3171 
  3398 		v->cur_speed = 0;
  3218 		v->cur_speed = 0;
  3399 		ReverseTrainDirection(v);
  3219 		ReverseTrainDirection(v);
  3400 		return false;
  3220 		return false;
  3401 	}
  3221 	}
  3402 
  3222 
  3403 	if  (v->u.rail.pbs_status == PBS_STAT_HAS_PATH)
       
  3404 		return true;
       
  3405 
       
  3406 	if ((trackdir != INVALID_TRACKDIR) && (PBSIsPbsSignal(tile,trackdir) && PBSIsPbsSegment(tile,trackdir)) && !(IsTileType(v->tile, MP_STATION) && (v->current_order.station == _m[v->tile].m2))) {
       
  3407 		NPFFindStationOrTileData fstd;
       
  3408 		NPFFoundTargetData ftd;
       
  3409 
       
  3410 		NPFFillWithOrderData(&fstd, v);
       
  3411 
       
  3412 		DEBUG(pbs, 2) ("pbs: (%i) choose signal (CEOL), tile:%x  trackdir:%i", v->unitnumber, tile, trackdir);
       
  3413 		ftd = NPFRouteToStationOrTile(tile, trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype, PBS_MODE_GREEN);
       
  3414 
       
  3415 		if (ftd.best_trackdir != 0xFF && NPFGetFlag(&ftd.node, NPF_FLAG_PBS_EXIT)) {
       
  3416 			if (!(NPFGetFlag(&ftd.node, NPF_FLAG_PBS_BLOCKED) || NPFGetFlag(&ftd.node, NPF_FLAG_PBS_RED))) {
       
  3417 				v->u.rail.pbs_status = PBS_STAT_HAS_PATH;
       
  3418 				v->u.rail.pbs_end_tile = ftd.node.tile;
       
  3419 				v->u.rail.pbs_end_trackdir = ftd.node.direction;
       
  3420 				return true;
       
  3421 			}
       
  3422 		};
       
  3423 	};
       
  3424 
       
  3425 	// slow down
  3223 	// slow down
  3426 	v->vehstatus |= VS_TRAIN_SLOWING;
  3224 	v->vehstatus |= VS_TRAIN_SLOWING;
  3427 	break_speed = _breakdown_speeds[x & 0xF];
  3225 	break_speed = _breakdown_speeds[x & 0xF];
  3428 	if (!(v->direction&1)) break_speed >>= 1;
  3226 	if (!(v->direction&1)) break_speed >>= 1;
  3429 	if (break_speed < v->cur_speed) v->cur_speed = break_speed;
  3227 	if (break_speed < v->cur_speed) v->cur_speed = break_speed;
  3576 static void CheckIfTrainNeedsService(Vehicle *v)
  3374 static void CheckIfTrainNeedsService(Vehicle *v)
  3577 {
  3375 {
  3578 	const Depot* depot;
  3376 	const Depot* depot;
  3579 	TrainFindDepotData tfdd;
  3377 	TrainFindDepotData tfdd;
  3580 
  3378 
  3581 	if (PBSTileReserved(v->tile) & v->u.rail.track)     return;
       
  3582 	if (v->u.rail.pbs_status == PBS_STAT_HAS_PATH)      return;
       
  3583 	if (_patches.servint_trains == 0)                   return;
  3379 	if (_patches.servint_trains == 0)                   return;
  3584 	if (!VehicleNeedsService(v))                        return;
  3380 	if (!VehicleNeedsService(v))                        return;
  3585 	if (v->vehstatus & VS_STOPPED)                      return;
  3381 	if (v->vehstatus & VS_STOPPED)                      return;
  3586 	if (_patches.gotodepot && VehicleHasDepotOrders(v)) return;
  3382 	if (_patches.gotodepot && VehicleHasDepotOrders(v)) return;
  3587 
  3383