(svn r2514) - Codechange: [NPF] Move the checking of railtype into a funciton IsCompatibleRail().
authormatthijs
Sun, 03 Jul 2005 13:02:54 +0000
changeset 2006 324916f22a8a
parent 2005 8331cf472aea
child 2007 b3bdf698ee26
(svn r2514) - Codechange: [NPF] Move the checking of railtype into a funciton IsCompatibleRail().
- Codechange: [NPF] Check the railtype along a route against the engine type instead of against the previouse tile. This clears the way for electriefied rails.
- Add: [NPF] [ 1209644 ] A penalty for crossings (peter1138)
npf.c
npf.h
pathfind.c
rail.c
rail.h
roadveh_cmd.c
settings.c
ship_cmd.c
train_cmd.c
variables.h
vehicle.c
--- a/npf.c	Sun Jul 03 11:31:03 2005 +0000
+++ b/npf.c	Sun Jul 03 13:02:54 2005 +0000
@@ -234,9 +234,12 @@
 				break;
 			}
 			/* Fall through if above if is false, it is a bridge
-			 * then. We treat that as ordinary rail */
+			 * then. We treat that as ordinary road */
 		case MP_STREET:
 			cost = NPF_TILE_LENGTH;
+			/* Increase the cost for level crossings */
+			if ((_map5[tile] & 0xF0) == 0x10)
+				cost += _patches.npf_crossing_penalty;
 			break;
 		default:
 			break;
@@ -524,16 +527,11 @@
 	if (IsTileType(dst_tile, MP_TUNNELBRIDGE) && (_map5[dst_tile] & 0xF0) == 0 && GetTileZ(dst_tile) < GetTileZ(src_tile))
 		return;
 
-	/* check correct rail type (mono, maglev, etc)
-	 * XXX: This now compares with the previous tile, which should not pose a
-	 * problem, but it might be nicer to compare with the first tile, or even
-	 * the type of the vehicle... Maybe an NPF_RAILTYPE userdata sometime? */
+	/* check correct rail type (mono, maglev, etc) */
 	if (type == TRANSPORT_RAIL) {
-		RailType src_type = GetTileRailType(src_tile, src_trackdir);
-		RailType dst_type = GetTileRailType(dst_tile, TrackdirToExitdir(src_trackdir));
-		if (src_type != dst_type) {
+		RailType dst_type = GetTileRailType(dst_tile, src_trackdir);
+		if (!IsCompatibleRail(aystar->user_data[NPF_RAILTYPE], dst_type))
 			return;
-		}
 	}
 
 	/* Check the owner of the tile */
@@ -604,7 +602,7 @@
  * multiple targets that are spread around, we should perform a breadth first
  * search by specifiying CalcZero as our heuristic.
  */
-static NPFFoundTargetData NPFRouteInternal(AyStarNode* start1, AyStarNode* start2, NPFFindStationOrTileData* target, AyStar_EndNodeCheck target_proc, AyStar_CalculateH heuristic_proc, TransportType type, Owner owner, uint reverse_penalty)
+static NPFFoundTargetData NPFRouteInternal(AyStarNode* start1, AyStarNode* start2, NPFFindStationOrTileData* target, AyStar_EndNodeCheck target_proc, AyStar_CalculateH heuristic_proc, TransportType type, Owner owner, RailType railtype, uint reverse_penalty)
 {
 	int r;
 	NPFFoundTargetData result;
@@ -646,6 +644,7 @@
 	/* Initialize user_data */
 	_npf_aystar.user_data[NPF_TYPE] = type;
 	_npf_aystar.user_data[NPF_OWNER] = owner;
+	_npf_aystar.user_data[NPF_RAILTYPE] = railtype;
 
 	/* GO! */
 	r = AyStarMain_Main(&_npf_aystar);
@@ -663,7 +662,7 @@
 	return result;
 }
 
-NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, NPFFindStationOrTileData* target, TransportType type, Owner owner)
+NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailType railtype)
 {
 	AyStarNode start1;
 	AyStarNode start2;
@@ -677,15 +676,15 @@
 	start2.direction = trackdir2;
 	start2.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR;
 
-	return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, type, owner, 0);
+	return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, type, owner, railtype, 0);
 }
 
-NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner)
+NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailType railtype)
 {
-	return NPFRouteToStationOrTileTwoWay(tile, trackdir, INVALID_TILE, 0, target, type, owner);
+	return NPFRouteToStationOrTileTwoWay(tile, trackdir, INVALID_TILE, 0, target, type, owner, railtype);
 }
 
-NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, Owner owner, uint reverse_penalty)
+NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, Owner owner, RailType railtype, uint reverse_penalty)
 {
 	AyStarNode start1;
 	AyStarNode start2;
@@ -701,15 +700,15 @@
 
 	/* perform a breadth first search. Target is NULL,
 	 * since we are just looking for any depot...*/
-	return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), NULL, NPFFindDepot, NPFCalcZero, type, owner, reverse_penalty);
+	return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), NULL, NPFFindDepot, NPFCalcZero, type, owner, railtype, reverse_penalty);
 }
 
-NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner)
+NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailType railtype)
 {
-	return NPFRouteToDepotBreadthFirstTwoWay(tile, trackdir, INVALID_TILE, 0, type, owner, 0);
+	return NPFRouteToDepotBreadthFirstTwoWay(tile, trackdir, INVALID_TILE, 0, type, owner, railtype, 0);
 }
 
-NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner)
+NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailType railtype)
 {
 	/* Okay, what we're gonna do. First, we look at all depots, calculate
 	 * the manhatten distance to get to each depot. We then sort them by
--- a/npf.h	Sun Jul 03 11:31:03 2005 +0000
+++ b/npf.h	Sun Jul 03 13:02:54 2005 +0000
@@ -35,6 +35,7 @@
 enum { /* Indices into AyStar.userdata[] */
 	NPF_TYPE = 0, /* Contains a TransportTypes value */
 	NPF_OWNER, /* Contains an Owner value */
+	NPF_RAILTYPE, /* Contains the RailType value of the engine when NPF_TYPE == TRANSPORT_RAIL. Unused otherwise. */
 };
 
 enum { /* Indices into AyStarNode.userdata[] */
@@ -59,27 +60,27 @@
 /* Will search from the given tile and direction, for a route to the given
  * station for the given transport type. See the declaration of
  * NPFFoundTargetData above for the meaning of the result. */
-NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner);
+NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailType railtype);
 /* Will search as above, but with two start nodes, the second being the
  * reverse. Look at the NPF_FLAG_REVERSE flag in the result node to see which
  * direction was taken (NPFGetBit(result.node, NPF_FLAG_REVERSE)) */
-NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, NPFFindStationOrTileData* target, TransportType type, Owner owner);
+NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailType railtype);
 
 /* Will search a route to the closest depot. */
 
 /* Search using breadth first. Good for little track choice and inaccurate
  * heuristic, such as railway/road.*/
-NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner);
+NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailType railtype);
 /* Same as above but with two start nodes, the second being the reverse. Call
  * NPFGetBit(result.node, NPF_FLAG_REVERSE) to see from which node the path
  * orginated. All pathfs from the second node will have the given
  * reverse_penalty applied (NPF_TILE_LENGTH is the equivalent of one full
  * tile).
  */
-NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, Owner owner, uint reverse_penalty);
+NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, Owner owner, RailType railtype, uint reverse_penalty);
 /* Search by trying each depot in order of Manhattan Distance. Good for lots
  * of choices and accurate heuristics, such as water. */
-NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner);
+NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailType railtype);
 
 void NPFFillWithOrderData(NPFFindStationOrTileData* fstd, Vehicle* v);
 
--- a/pathfind.c	Sun Jul 03 11:31:03 2005 +0000
+++ b/pathfind.c	Sun Jul 03 13:02:54 2005 +0000
@@ -131,6 +131,7 @@
 	RememberData rd;
 	int owner = -1;
 
+	/* XXX: Mode 2 is currently only used for ships, why is this code here? */
 	if (tpf->tracktype == TRANSPORT_RAIL) {
 		if (IsTileType(tile, MP_RAILWAY) || IsTileType(tile, MP_STATION) || IsTileType(tile, MP_TUNNELBRIDGE)) {
 			owner = GetTileOwner(tile);
@@ -340,6 +341,10 @@
 
 	/* if i can get rid of this, tail end recursion can be used to minimize
 	 * stack space dramatically. */
+
+	/* If we are doing signal setting, we must reverse at evere tile, so we
+	 * iterate all the tracks in a signal block, even when a normal train would
+	 * not reach it (for example, when two lines merge */
 	if (tpf->hasbit_13)
 		return;
 
--- a/rail.c	Sun Jul 03 11:31:03 2005 +0000
+++ b/rail.c	Sun Jul 03 13:02:54 2005 +0000
@@ -97,7 +97,7 @@
 	TRACKDIR_DIAG1_NE, TRACKDIR_DIAG2_SE, TRACKDIR_UPPER_E, TRACKDIR_LOWER_E, TRACKDIR_LEFT_S, TRACKDIR_RIGHT_S
 };
 
-RailType GetTileRailType(TileIndex tile, byte trackdir)
+RailType GetTileRailType(TileIndex tile, Trackdir trackdir)
 {
 	RailType type = INVALID_RAILTYPE;
 	switch (GetTileType(tile)) {
@@ -123,7 +123,7 @@
 			if ((_map5[tile] & 0xC6) == 0xC0 && ((DiagDirection)(_map5[tile] & 0x1)) == (TrackdirToExitdir(trackdir) & 0x1))
 				type = (_map3_lo[tile] >> 4) & RAILTYPE_MASK;
 			/* under bridge (any type) */
-			if ((_map5[tile] & 0xC0) == 0xC0 && (_map5[tile] & 0x1) != (trackdir & 0x1))
+			if ((_map5[tile] & 0xC0) == 0xC0 && ((uint)_map5[tile] & 0x1) != (trackdir & 0x1))
 				type = _map3_lo[tile] & RAILTYPE_MASK;
 			break;
 		default:
--- a/rail.h	Sun Jul 03 11:31:03 2005 +0000
+++ b/rail.h	Sun Jul 03 13:02:54 2005 +0000
@@ -441,7 +441,7 @@
  * The given trackdir is used when there are (could be) multiple rail types on
  * one tile.
  */
-RailType GetTileRailType(TileIndex tile, byte trackdir);
+RailType GetTileRailType(TileIndex tile, Trackdir trackdir);
 
 /**
  * Returns whether the given tile is a level crossing.
@@ -472,4 +472,17 @@
 	return INVALID_TRANSPORT;
 }
 
+/**
+ * Checks if an engine of the given RailType can drive on a tile with a given
+ * RailType. This would normally just be an equality check, but for electric
+ * rails (which also support non-electric engines).
+ * @return Whether the engine can drive on this tile.
+ * @param  enginetype The RailType of the engine we are considering.
+ * @param  tiletype   The RailType of the tile we are considering.
+ */
+static inline bool IsCompatibleRail(RailType enginetype, RailType tiletype)
+{
+	return enginetype == tiletype;
+}
+
 #endif // RAIL_H
--- a/roadveh_cmd.c	Sun Jul 03 11:31:03 2005 +0000
+++ b/roadveh_cmd.c	Sun Jul 03 13:02:54 2005 +0000
@@ -304,7 +304,7 @@
 		/* See where we are now */
 		Trackdir trackdir = GetVehicleTrackdir(v);
 
-		ftd = NPFRouteToDepotBreadthFirst(v->tile, trackdir, TRANSPORT_ROAD, v->owner);
+		ftd = NPFRouteToDepotBreadthFirst(v->tile, trackdir, TRANSPORT_ROAD, v->owner, INVALID_RAILTYPE);
 		if (ftd.best_bird_dist == 0)
 			return GetDepotByTile(ftd.node.tile); /* Target found */
 		else
@@ -1086,7 +1086,7 @@
 		trackdir = DiagdirToDiagTrackdir(enterdir);
 		//debug("Finding path. Enterdir: %d, Trackdir: %d", enterdir, trackdir);
 
-		ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_ROAD, v->owner);
+		ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_ROAD, v->owner, INVALID_RAILTYPE);
 		if (ftd.best_trackdir == 0xff) {
 			/* We are already at our target. Just do something */
 			//TODO: maybe display error?
@@ -1163,7 +1163,7 @@
   fstd.dest_coords = tile;
   fstd.station_index = -1;	// indicates that the destination is a tile, not a station
 
-  return NPFRouteToStationOrTile(v->tile, trackdir, &fstd, TRANSPORT_ROAD, v->owner).best_path_dist;
+  return NPFRouteToStationOrTile(v->tile, trackdir, &fstd, TRANSPORT_ROAD, v->owner, INVALID_RAILTYPE).best_path_dist;
 }
 
 typedef struct RoadDriveEntry {
--- a/settings.c	Sun Jul 03 11:31:03 2005 +0000
+++ b/settings.c	Sun Jul 03 13:02:54 2005 +0000
@@ -977,6 +977,8 @@
 	{"npf_water_curve_penalty",     SDT_UINT32, (void*)(NPF_TILE_LENGTH / 4),   &_patches.npf_water_curve_penalty,      NULL},
 	/* This is the penalty for road, same as for rail. */
 	{"npf_road_curve_penalty",      SDT_UINT32, (void*)(1),                     &_patches.npf_road_curve_penalty,       NULL},
+	/* This is the penalty for level crossings, for both road and rail vehicles */
+ 	{"npf_crossing_penalty",        SDT_UINT32, (void*)(3 * NPF_TILE_LENGTH),   &_patches.npf_crossing_penalty,         NULL},
 
 	{NULL,                          0,          NULL,                           NULL,                                   NULL}
 };
--- a/ship_cmd.c	Sun Jul 03 11:31:03 2005 +0000
+++ b/ship_cmd.c	Sun Jul 03 13:02:54 2005 +0000
@@ -65,7 +65,7 @@
 	if (_patches.new_pathfinding_all) {
 		NPFFoundTargetData ftd;
 		byte trackdir = GetVehicleTrackdir(v);
-		ftd = NPFRouteToDepotTrialError(v->tile, trackdir, TRANSPORT_WATER, v->owner);
+		ftd = NPFRouteToDepotTrialError(v->tile, trackdir, TRANSPORT_WATER, v->owner, INVALID_RAILTYPE);
 		if (ftd.best_bird_dist == 0)
 			best_depot = GetDepotByTile(ftd.node.tile); /* Found target */
 		else
@@ -565,7 +565,7 @@
 
 		NPFFillWithOrderData(&fstd, v);
 
-		ftd = NPFRouteToStationOrTile(src_tile, trackdir, &fstd, TRANSPORT_WATER, v->owner);
+		ftd = NPFRouteToStationOrTile(src_tile, trackdir, &fstd, TRANSPORT_WATER, v->owner, INVALID_RAILTYPE);
 
 		if (ftd.best_trackdir != 0xff)
 			/* If ftd.best_bird_dist is 0, we found our target and ftd.best_trackdir contains
--- a/train_cmd.c	Sun Jul 03 11:31:03 2005 +0000
+++ b/train_cmd.c	Sun Jul 03 13:02:54 2005 +0000
@@ -1543,7 +1543,7 @@
 		Trackdir trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last));
 
 		assert (trackdir != INVALID_TRACKDIR);
-		ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, last->tile, trackdir_rev, TRANSPORT_RAIL, v->owner, NPF_INFINITE_PENALTY);
+		ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, last->tile, trackdir_rev, TRANSPORT_RAIL, v->owner, v->u.rail.railtype, NPF_INFINITE_PENALTY);
 		if (ftd.best_bird_dist == 0) {
 			/* Found target */
 			tfdd.tile = ftd.node.tile;
@@ -1910,7 +1910,7 @@
 		trackdir = GetVehicleTrackdir(v);
 		assert(trackdir != 0xff);
 
-		ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner);
+		ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype);
 
 		if (ftd.best_trackdir == 0xff) {
 			/* We are already at our target. Just do something */
@@ -2048,7 +2048,7 @@
 		assert(trackdir != 0xff);
 		assert(trackdir_rev != 0xff);
 
-		ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, last->tile, trackdir_rev, &fstd, TRANSPORT_RAIL, v->owner);
+		ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, last->tile, trackdir_rev, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype);
 		if (ftd.best_bird_dist != 0) {
 			/* We didn't find anything, just keep on going straight ahead */
 			reverse_best = false;
--- a/variables.h	Sun Jul 03 11:31:03 2005 +0000
+++ b/variables.h	Sun Jul 03 13:02:54 2005 +0000
@@ -216,6 +216,7 @@
 	uint32 npf_buoy_penalty; /* The penalty for going over (through) a buoy */
 	uint32 npf_water_curve_penalty; /* The penalty for curves */
 	uint32 npf_road_curve_penalty; /* The penalty for curves */
+ 	uint32 npf_crossing_penalty; /* The penalty for level crossings */
 
 	bool population_in_label; // Show the population of a town in his label?
 } Patches;
--- a/vehicle.c	Sun Jul 03 11:31:03 2005 +0000
+++ b/vehicle.c	Sun Jul 03 13:02:54 2005 +0000
@@ -368,9 +368,9 @@
 static Vehicle *GetPrevVehicleInChain_bruteforce(const Vehicle *v)
 {
 	Vehicle *u;
-	
+
 	FOR_ALL_VEHICLES(u) if (u->type == VEH_Train && u->next == v) return u;
-	
+
 	return NULL;
 }