src/yapf/yapf_rail.cpp
branchnoai
changeset 9732 f8eb3e208514
parent 9723 eee46cb39750
child 10455 22c441f5adf9
equal deleted inserted replaced
9731:9b1552d0fd9b 9732:f8eb3e208514
   179 			next_trackdir = best_next_node.GetTrackdir();
   179 			next_trackdir = best_next_node.GetTrackdir();
   180 		}
   180 		}
   181 		return next_trackdir;
   181 		return next_trackdir;
   182 	}
   182 	}
   183 
   183 
   184 	static bool stCheckReverseTrain(Vehicle* v, TileIndex t1, Trackdir td1, TileIndex t2, Trackdir td2)
   184 	static bool stCheckReverseTrain(Vehicle* v, TileIndex t1, Trackdir td1, TileIndex t2, Trackdir td2, int reverse_penalty)
   185 	{
   185 	{
   186 		Tpf pf1;
   186 		Tpf pf1;
   187 		bool result1 = pf1.CheckReverseTrain(v, t1, td1, t2, td2);
   187 		bool result1 = pf1.CheckReverseTrain(v, t1, td1, t2, td2, reverse_penalty);
   188 
   188 
   189 #if DEBUG_YAPF_CACHE
   189 #if DEBUG_YAPF_CACHE
   190 		Tpf pf2;
   190 		Tpf pf2;
   191 		pf2.DisableCache(true);
   191 		pf2.DisableCache(true);
   192 		bool result2 = pf2.CheckReverseTrain(v, t1, td1, t2, td2);
   192 		bool result2 = pf2.CheckReverseTrain(v, t1, td1, t2, td2, reverse_penalty);
   193 		if (result1 != result2) {
   193 		if (result1 != result2) {
   194 			DEBUG(yapf, 0, "CACHE ERROR: CheckReverseTrain() = [%s, %s]", result1 ? "T" : "F", result2 ? "T" : "F");
   194 			DEBUG(yapf, 0, "CACHE ERROR: CheckReverseTrain() = [%s, %s]", result1 ? "T" : "F", result2 ? "T" : "F");
   195 		}
   195 		}
   196 #endif
   196 #endif
   197 
   197 
   198 		return result1;
   198 		return result1;
   199 	}
   199 	}
   200 
   200 
   201 	FORCEINLINE bool CheckReverseTrain(Vehicle* v, TileIndex t1, Trackdir td1, TileIndex t2, Trackdir td2)
   201 	FORCEINLINE bool CheckReverseTrain(Vehicle* v, TileIndex t1, Trackdir td1, TileIndex t2, Trackdir td2, int reverse_penalty)
   202 	{
   202 	{
   203 		// create pathfinder instance
   203 		// create pathfinder instance
   204 		// set origin and destination nodes
   204 		// set origin and destination nodes
   205 		Yapf().SetOrigin(t1, td1, t2, td2, 1, false);
   205 		Yapf().SetOrigin(t1, td1, t2, td2, reverse_penalty, false);
   206 		Yapf().SetDestination(v);
   206 		Yapf().SetDestination(v);
   207 
   207 
   208 		// find the best path
   208 		// find the best path
   209 		bool bFound = Yapf().FindPath(v);
   209 		bool bFound = Yapf().FindPath(v);
   210 
   210 
   263 	return td_ret;
   263 	return td_ret;
   264 }
   264 }
   265 
   265 
   266 bool YapfCheckReverseTrain(Vehicle* v)
   266 bool YapfCheckReverseTrain(Vehicle* v)
   267 {
   267 {
   268 	// tile where the engine is
   268 	/* last wagon */
   269 	TileIndex tile = v->tile;
       
   270 	// tile where we have last wagon
       
   271 	Vehicle* last_veh = GetLastVehicleInChain(v);
   269 	Vehicle* last_veh = GetLastVehicleInChain(v);
   272 	// if we are in tunnel then give up
   270 
   273 	if (v->u.rail.track == 0x40 || last_veh->u.rail.track == 0x40) return false;
       
   274 	// get trackdirs of both ends
   271 	// get trackdirs of both ends
   275 	Trackdir td = GetVehicleTrackdir(v);
   272 	Trackdir td = GetVehicleTrackdir(v);
   276 	Trackdir td_rev = ReverseTrackdir(GetVehicleTrackdir(last_veh));
   273 	Trackdir td_rev = ReverseTrackdir(GetVehicleTrackdir(last_veh));
   277 
   274 
   278 
   275 	/* tiles where front and back are */
   279 	typedef bool (*PfnCheckReverseTrain)(Vehicle*, TileIndex, Trackdir, TileIndex, Trackdir);
   276 	TileIndex tile = v->tile;
       
   277 	TileIndex tile_rev = last_veh->tile;
       
   278 
       
   279 	int reverse_penalty = 0;
       
   280 
       
   281 	if (v->u.rail.track == TRACK_BIT_WORMHOLE) {
       
   282 		/* front in tunnel / on bridge */
       
   283 		DiagDirection dir_into_wormhole = GetTunnelBridgeDirection(tile);
       
   284 
       
   285 		if (TrackdirToExitdir(td) == dir_into_wormhole) tile = GetOtherTunnelBridgeEnd(tile);
       
   286 		/* Now 'tile' is the tunnel entry/bridge ramp the train will reach when driving forward */
       
   287 
       
   288 		/* Current position of the train in the wormhole */
       
   289 		TileIndex cur_tile = TileVirtXY(v->x_pos, v->y_pos);
       
   290 
       
   291 		/* Add distance to drive in the wormhole as penalty for the forward path, i.e. bonus for the reverse path
       
   292 		 * Note: Negative penalties are ok for the start tile. */
       
   293 		reverse_penalty -= DistanceManhattan(cur_tile, tile) * YAPF_TILE_LENGTH;
       
   294 	}
       
   295 
       
   296 	if (last_veh->u.rail.track == TRACK_BIT_WORMHOLE) {
       
   297 		/* back in tunnel / on bridge */
       
   298 		DiagDirection dir_into_wormhole = GetTunnelBridgeDirection(tile_rev);
       
   299 
       
   300 		if (TrackdirToExitdir(td_rev) == dir_into_wormhole) tile_rev = GetOtherTunnelBridgeEnd(tile_rev);
       
   301 		/* Now 'tile_rev' is the tunnel entry/bridge ramp the train will reach when reversing */
       
   302 
       
   303 		/* Current position of the last wagon in the wormhole */
       
   304 		TileIndex cur_tile = TileVirtXY(last_veh->x_pos, last_veh->y_pos);
       
   305 
       
   306 		/* Add distance to drive in the wormhole as penalty for the revere path. */
       
   307 		reverse_penalty += DistanceManhattan(cur_tile, tile_rev) * YAPF_TILE_LENGTH;
       
   308 	}
       
   309 
       
   310 	typedef bool (*PfnCheckReverseTrain)(Vehicle*, TileIndex, Trackdir, TileIndex, Trackdir, int);
   280 	PfnCheckReverseTrain pfnCheckReverseTrain = CYapfRail1::stCheckReverseTrain;
   311 	PfnCheckReverseTrain pfnCheckReverseTrain = CYapfRail1::stCheckReverseTrain;
   281 
   312 
   282 	// check if non-default YAPF type needed
   313 	// check if non-default YAPF type needed
   283 	if (_patches.forbid_90_deg) {
   314 	if (_patches.forbid_90_deg) {
   284 		pfnCheckReverseTrain = &CYapfRail2::stCheckReverseTrain; // Trackdir, forbid 90-deg
   315 		pfnCheckReverseTrain = &CYapfRail2::stCheckReverseTrain; // Trackdir, forbid 90-deg
   285 	}
   316 	}
   286 
   317 
   287 	bool reverse = pfnCheckReverseTrain(v, tile, td, last_veh->tile, td_rev);
   318 	/* slightly hackish: If the pathfinders finds a path, the cost of the first node is tested to distinguish between forward- and reverse-path. */
       
   319 	if (reverse_penalty == 0) reverse_penalty = 1;
       
   320 
       
   321 	bool reverse = pfnCheckReverseTrain(v, tile, td, tile_rev, td_rev, reverse_penalty);
   288 
   322 
   289 	return reverse;
   323 	return reverse;
   290 }
   324 }
   291 
   325 
   292 bool YapfFindNearestRailDepotTwoWay(Vehicle *v, int max_distance, int reverse_penalty, TileIndex* depot_tile, bool* reversed)
   326 bool YapfFindNearestRailDepotTwoWay(Vehicle *v, int max_distance, int reverse_penalty, TileIndex* depot_tile, bool* reversed)