yapf/follow_track.hpp
changeset 3933 a5f08e17f4a0
parent 3931 ca6abd14504a
child 3976 b52d2c1acc5c
equal deleted inserted replaced
3932:882af4997b60 3933:a5f08e17f4a0
    25 		m_pPerf = pPerf;
    25 		m_pPerf = pPerf;
    26 		// don't worry, all is inlined so compiler should remove unnecessary initializations
    26 		// don't worry, all is inlined so compiler should remove unnecessary initializations
    27 		m_new_tile = INVALID_TILE;
    27 		m_new_tile = INVALID_TILE;
    28 		m_new_td_bits = TRACKDIR_BIT_NONE;
    28 		m_new_td_bits = TRACKDIR_BIT_NONE;
    29 		m_exitdir = INVALID_DIAGDIR;
    29 		m_exitdir = INVALID_DIAGDIR;
    30 		m_is_station = m_is_tunnel = false;
    30 		m_is_station = m_is_bridge = m_is_tunnel = false;
    31 		m_tiles_skipped = 0;
    31 		m_tiles_skipped = 0;
    32 	}
    32 	}
    33 
    33 
    34 	FORCEINLINE static TransportType TT() {return Ttr_type_;}
    34 	FORCEINLINE static TransportType TT() {return Ttr_type_;}
    35 	FORCEINLINE static bool IsWaterTT() {return TT() == TRANSPORT_WATER;}
    35 	FORCEINLINE static bool IsWaterTT() {return TT() == TRANSPORT_WATER;}
    58 
    58 
    59 protected:
    59 protected:
    60 	/** Follow the m_exitdir from m_old_tile and fill m_new_tile and m_tiles_skipped */
    60 	/** Follow the m_exitdir from m_old_tile and fill m_new_tile and m_tiles_skipped */
    61 	FORCEINLINE void FollowTileExit()
    61 	FORCEINLINE void FollowTileExit()
    62 	{
    62 	{
       
    63 		m_is_station = m_is_bridge = m_is_tunnel = false;
       
    64 		m_tiles_skipped = 0;
       
    65 
    63 		// extra handling for tunnels in our direction
    66 		// extra handling for tunnels in our direction
    64 		if (IsTunnelTile(m_old_tile)) {
    67 		if (IsTunnelTile(m_old_tile)) {
    65 			DiagDirection tunnel_enterdir = GetTunnelDirection(m_old_tile);
    68 			DiagDirection tunnel_enterdir = GetTunnelDirection(m_old_tile);
    66 			if (tunnel_enterdir == m_exitdir) {
    69 			if (tunnel_enterdir == m_exitdir) {
    67 				// we are entering the tunnel
    70 				// we are entering the tunnel
    71 				m_tiles_skipped = flotr.length - 1;
    74 				m_tiles_skipped = flotr.length - 1;
    72 				return;
    75 				return;
    73 			}
    76 			}
    74 			assert(ReverseDiagDir(tunnel_enterdir) == m_exitdir);
    77 			assert(ReverseDiagDir(tunnel_enterdir) == m_exitdir);
    75 		}
    78 		}
    76 		// not a tunnel or station
    79 
    77 		m_is_tunnel = false;
    80 		// extra handling for bridge ramp in our direction
    78 		m_tiles_skipped = 0;
    81 		if (IsBridgeTile(m_old_tile)) {
    79 
    82 			DiagDirection bridge_enterdir = GetBridgeRampDirection(m_old_tile);
    80 		// normal or station tile
    83 			if (bridge_enterdir == m_exitdir) {
       
    84 				// we are entering the bridge ramp
       
    85 				m_new_tile = GetOtherBridgeEnd(m_old_tile);
       
    86 				uint32 bridge_length = GetBridgeLength(m_old_tile, m_new_tile);
       
    87 				m_tiles_skipped = bridge_length;
       
    88 				m_is_bridge = true;
       
    89 				return;
       
    90 			}
       
    91 			assert(ReverseDiagDir(bridge_enterdir) == m_exitdir);
       
    92 		}
       
    93 
       
    94 		// normal or station tile, do one step
    81 		TileIndexDiff diff = TileOffsByDir(m_exitdir);
    95 		TileIndexDiff diff = TileOffsByDir(m_exitdir);
    82 		m_new_tile = TILE_ADD(m_old_tile, diff);
    96 		m_new_tile = TILE_ADD(m_old_tile, diff);
    83 
    97 
    84 		// special handling for stations
    98 		// special handling for stations
    85 		if (IsRailTT() && IsRailwayStationTile(m_new_tile)) {
    99 		if (IsRailTT() && IsRailwayStationTile(m_new_tile)) {
   146 		}
   160 		}
   147 
   161 
   148 		// rail transport is possible only on tiles with the same owner as vehicle
   162 		// rail transport is possible only on tiles with the same owner as vehicle
   149 		if (IsRailTT() && GetTileOwner(m_new_tile) != m_veh->owner) {
   163 		if (IsRailTT() && GetTileOwner(m_new_tile) != m_veh->owner) {
   150 			// different owner
   164 			// different owner
   151 			if (IsBridgeTile(m_new_tile)) {
   165 			return false;
   152 				if (IsBridgeMiddle(m_new_tile)) {
       
   153 						// bridge middle has no owner - tile is owned by the owner of the under-bridge track
       
   154 					if (GetBridgeAxis(m_new_tile) != DiagDirToAxis(m_exitdir)) {
       
   155 						// so it must be under bridge track (and wrong owner)
       
   156 						return false;
       
   157 					}
       
   158 					// in the middle of the bridge - when we came here, it should be ok
       
   159 				} else {
       
   160 					// different owner, on the bridge ramp
       
   161 					return false;
       
   162 				}
       
   163 			} else {
       
   164 				// different owner, not a bridge
       
   165 				return false;
       
   166 			}
       
   167 		}
   166 		}
   168 
   167 
   169 		// rail transport is possible only on compatible rail types
   168 		// rail transport is possible only on compatible rail types
   170 		if (IsRailTT()) {
   169 		if (IsRailTT()) {
   171 			RailType rail_type = GetTileRailType(m_new_tile, DiagdirToDiagTrackdir(m_exitdir));
   170 			RailType rail_type = GetTileRailType(m_new_tile, DiagdirToDiagTrackdir(m_exitdir));
   222 	{
   221 	{
   223 		int min_speed = 0;
   222 		int min_speed = 0;
   224 		int max_speed = INT_MAX; // no limit
   223 		int max_speed = INT_MAX; // no limit
   225 
   224 
   226 		// for now we handle only on-bridge speed limit
   225 		// for now we handle only on-bridge speed limit
   227 		if (IsBridgeTile(m_old_tile) && !IsWaterTT() && IsDiagonalTrackdir(m_old_td)) {
   226 		if (!IsWaterTT() && IsBridgeTile(m_old_tile)) {
   228 			bool is_on_bridge = true;
   227 			int spd = _bridge[GetBridgeType(m_old_tile)].speed;
   229 			if (IsBridgeMiddle(m_old_tile)) {
   228 			if (IsRoadTT()) spd *= 2;
   230 				// get track axis
   229 			if (max_speed > spd) max_speed = spd;
   231 				Axis track_axis = DiagDirToAxis(TrackdirToExitdir(m_old_td));
       
   232 				// get under-bridge axis
       
   233 				Axis bridge_axis =  GetBridgeAxis(m_old_tile);
       
   234 				if (track_axis != bridge_axis) is_on_bridge = false;
       
   235 			}
       
   236 			if (is_on_bridge) {
       
   237 				int spd = _bridge[GetBridgeType(m_old_tile)].speed;
       
   238 				if (IsRoadTT()) spd *= 2;
       
   239 				if (max_speed > spd) max_speed = spd;
       
   240 			}
       
   241 		}
   230 		}
   242 
   231 
   243 		// if min speed was requested, return it
   232 		// if min speed was requested, return it
   244 		if (pmin_speed) *pmin_speed = min_speed;
   233 		if (pmin_speed) *pmin_speed = min_speed;
   245 		return max_speed;
   234 		return max_speed;