--- a/npf.c Tue May 16 22:11:15 2006 +0000
+++ b/npf.c Sat May 20 15:54:46 2006 +0000
@@ -576,7 +576,7 @@
/* check correct rail type (mono, maglev, etc) */
if (type == TRANSPORT_RAIL) {
RailType dst_type = GetTileRailType(dst_tile, src_trackdir);
- if (!IsCompatibleRail(aystar->user_data[NPF_RAILTYPE], dst_type))
+ if (!HASBIT(aystar->user_data[NPF_RAILTYPES], dst_type))
return;
}
@@ -649,7 +649,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, RailType railtype, uint reverse_penalty)
+static NPFFoundTargetData NPFRouteInternal(AyStarNode* start1, AyStarNode* start2, NPFFindStationOrTileData* target, AyStar_EndNodeCheck target_proc, AyStar_CalculateH heuristic_proc, TransportType type, Owner owner, byte railtypes, uint reverse_penalty)
{
int r;
NPFFoundTargetData result;
@@ -691,7 +691,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;
+ _npf_aystar.user_data[NPF_RAILTYPES] = railtypes;
/* GO! */
r = AyStarMain_Main(&_npf_aystar);
@@ -709,7 +709,7 @@
return result;
}
-NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailType railtype)
+NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, NPFFindStationOrTileData* target, TransportType type, Owner owner, byte railtypes)
{
AyStarNode start1;
AyStarNode start2;
@@ -723,15 +723,15 @@
start2.direction = trackdir2;
start2.user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR;
- return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, type, owner, railtype, 0);
+ return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, type, owner, railtypes, 0);
}
-NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, RailType railtype)
+NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, byte railtypes)
{
- return NPFRouteToStationOrTileTwoWay(tile, trackdir, INVALID_TILE, 0, target, type, owner, railtype);
+ return NPFRouteToStationOrTileTwoWay(tile, trackdir, INVALID_TILE, 0, target, type, owner, railtypes);
}
-NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, Owner owner, RailType railtype, uint reverse_penalty)
+NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, Owner owner, byte railtypes, uint reverse_penalty)
{
AyStarNode start1;
AyStarNode start2;
@@ -747,15 +747,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, railtype, reverse_penalty);
+ return NPFRouteInternal(&start1, (IsValidTile(tile2) ? &start2 : NULL), NULL, NPFFindDepot, NPFCalcZero, type, owner, railtypes, reverse_penalty);
}
-NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailType railtype)
+NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, byte railtypes)
{
- return NPFRouteToDepotBreadthFirstTwoWay(tile, trackdir, INVALID_TILE, 0, type, owner, railtype, 0);
+ return NPFRouteToDepotBreadthFirstTwoWay(tile, trackdir, INVALID_TILE, 0, type, owner, railtypes, 0);
}
-NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, RailType railtype)
+NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, byte railtypes)
{
/* 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 Tue May 16 22:11:15 2006 +0000
+++ b/npf.h Sat May 20 15:54:46 2006 +0000
@@ -37,7 +37,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. */
+ NPF_RAILTYPES, /* Contains a bitmask the compatible RailTypes of the engine when NPF_TYPE == TRANSPORT_RAIL. Unused otherwise. */
};
enum { /* Indices into AyStarNode.userdata[] */
@@ -63,27 +63,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, RailType railtype);
+NPFFoundTargetData NPFRouteToStationOrTile(TileIndex tile, Trackdir trackdir, NPFFindStationOrTileData* target, TransportType type, Owner owner, byte railtypes);
/* 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, RailType railtype);
+NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, NPFFindStationOrTileData* target, TransportType type, Owner owner, byte railtypes);
/* 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, RailType railtype);
+NPFFoundTargetData NPFRouteToDepotBreadthFirst(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, byte railtypes);
/* 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, RailType railtype, uint reverse_penalty);
+NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Trackdir trackdir1, TileIndex tile2, Trackdir trackdir2, TransportType type, Owner owner, byte railtypes, 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, RailType railtype);
+NPFFoundTargetData NPFRouteToDepotTrialError(TileIndex tile, Trackdir trackdir, TransportType type, Owner owner, byte railtypes);
void NPFFillWithOrderData(NPFFindStationOrTileData* fstd, Vehicle* v);
--- a/pathfind.c Tue May 16 22:11:15 2006 +0000
+++ b/pathfind.c Sat May 20 15:54:46 2006 +0000
@@ -5,8 +5,8 @@
#include "functions.h"
#include "map.h"
#include "tile.h"
+#include "rail.h"
#include "pathfind.h"
-#include "rail.h"
#include "debug.h"
#include "variables.h"
#include "depot.h"
@@ -442,7 +442,8 @@
void *userdata;
TileIndex dest;
- byte tracktype;
+ TransportType tracktype;
+ byte railtypes;
uint maxlength;
HashLink *new_link;
@@ -728,6 +729,11 @@
/* We are not driving into the tunnel, or it
* is an invalid tunnel */
continue;
+
+ if (!HASBIT(tpf->railtypes, GetRailType(tile))) {
+ bits = 0;
+ break;
+ }
flotr = FindLengthOfTunnel(tile, direction);
si.cur_length += flotr.length * DIAG_FACTOR;
tile = flotr.tile;
@@ -760,6 +766,12 @@
// Check that the tile contains exactly one track
if (bits == 0 || KILL_FIRST_BIT(bits) != 0) break;
+ if ((IsTileType(tile, MP_STREET) && !HASBIT(tpf->railtypes, GB(_m[tile].m4, 0, 4))) ||
+ !HASBIT(tpf->railtypes, GetRailType(tile))) {
+ bits = 0;
+ break;
+ }
+
///////////////////
// If we reach here, the tile has exactly one track.
// tile - index to a tile that is not rail tile, but still straight (with optional signals)
@@ -781,6 +793,11 @@
* bits, not just reachable ones, to prevent infinite loops. */
if (bits == 0 || TracksOverlap(allbits)) break;
+ if (!HASBIT(tpf->railtypes, GetRailType(tile))) {
+ bits = 0;
+ break;
+ }
+
/* If we reach here, the tile has exactly one track, and this
track is reachable => Rail segment continues */
@@ -916,14 +933,15 @@
// new pathfinder for trains. better and faster.
-void NewTrainPathfind(TileIndex tile, TileIndex dest, byte direction, NTPEnumProc *enum_proc, void *data)
+void NewTrainPathfind(TileIndex tile, TileIndex dest, byte railtypes, byte direction, NTPEnumProc *enum_proc, void *data)
{
NewTrackPathFinder tpf;
tpf.dest = dest;
tpf.userdata = data;
tpf.enum_proc = enum_proc;
- tpf.tracktype = 0;
+ tpf.tracktype = TRANSPORT_RAIL;
+ tpf.railtypes = railtypes;
tpf.maxlength = min(_patches.pf_maxlength * 3, 10000);
tpf.nstack = 0;
tpf.new_link = tpf.links;
--- a/pathfind.h Tue May 16 22:11:15 2006 +0000
+++ b/pathfind.h Sat May 20 15:54:46 2006 +0000
@@ -66,6 +66,6 @@
} FindLengthOfTunnelResult;
FindLengthOfTunnelResult FindLengthOfTunnel(TileIndex tile, uint direction);
-void NewTrainPathfind(TileIndex tile, TileIndex dest, byte direction, NTPEnumProc *enum_proc, void *data);
+void NewTrainPathfind(TileIndex tile, TileIndex dest, byte railtypes, byte direction, NTPEnumProc *enum_proc, void *data);
#endif /* PATHFIND_H */
--- a/train_cmd.c Tue May 16 22:11:15 2006 +0000
+++ b/train_cmd.c Sat May 20 15:54:46 2006 +0000
@@ -88,6 +88,7 @@
rvi_v = RailVehInfo(v->engine_type);
first_engine = IsFrontEngine(v) ? v->engine_type : INVALID_VEHICLE;
v->u.rail.cached_total_length = 0;
+ v->u.rail.compatible_railtypes = 0;
for (u = v; u != NULL; u = u->next) {
const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type);
@@ -98,6 +99,7 @@
// update the 'first engine'
u->u.rail.first_engine = (v == u) ? INVALID_VEHICLE : first_engine;
+ u->u.rail.railtype = GetEngine(u->engine_type)->railtype;
if (rvi_u->visual_effect != 0) {
u->u.rail.cached_vis_effect = rvi_u->visual_effect;
@@ -135,6 +137,11 @@
}
}
+ /* Do not count powered wagons for the compatible railtypes, as
+ * wagons always have railtype normal */
+ if (rvi_u->power > 0)
+ v->u.rail.compatible_railtypes |= GetRailTypeInfo(u->u.rail.railtype)->compatible_railtypes;
+
// max speed is the minimum of the speed limits of all vehicles in the consist
if (!(rvi_u->flags & RVI_WAGON) || _patches.wagon_speed_limits)
if (rvi_u->max_speed != 0 && !UsesWagonOverride(u))
@@ -1793,7 +1800,7 @@
Trackdir trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last));
assert (trackdir != INVALID_TRACKDIR);
- ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, last->tile, trackdir_rev, TRANSPORT_RAIL, v->owner, v->u.rail.railtype, NPF_INFINITE_PENALTY);
+ ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, last->tile, trackdir_rev, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes, NPF_INFINITE_PENALTY);
if (ftd.best_bird_dist == 0) {
/* Found target */
tfdd.tile = ftd.node.tile;
@@ -1809,13 +1816,13 @@
// search in the forward direction first.
i = v->direction >> 1;
if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) i = (i - 1) & 3;
- NewTrainPathfind(tile, 0, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
+ NewTrainPathfind(tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
if (tfdd.best_length == (uint)-1){
tfdd.reverse = true;
// search in backwards direction
i = (v->direction^4) >> 1;
if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) i = (i - 1) & 3;
- NewTrainPathfind(tile, 0, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
+ NewTrainPathfind(tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
}
}
@@ -2137,7 +2144,7 @@
trackdir = GetVehicleTrackdir(v);
assert(trackdir != 0xff);
- ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype);
+ ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes);
if (ftd.best_trackdir == 0xff) {
/* We are already at our target. Just do something */
@@ -2161,7 +2168,7 @@
fd.best_track = 0xFF;
NewTrainPathfind(tile - TileOffsByDir(enterdir), v->dest_tile,
- enterdir, (NTPEnumProc*)NtpCallbFindStation, &fd);
+ v->u.rail.compatible_railtypes, enterdir, (NTPEnumProc*)NtpCallbFindStation, &fd);
if (fd.best_track == 0xff) {
// blaha
@@ -2217,7 +2224,7 @@
assert(trackdir != 0xff);
assert(trackdir_rev != 0xff);
- ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, last->tile, trackdir_rev, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype);
+ ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, last->tile, trackdir_rev, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes);
if (ftd.best_bird_dist != 0) {
/* We didn't find anything, just keep on going straight ahead */
reverse_best = false;
@@ -2232,7 +2239,7 @@
fd.best_bird_dist = (uint)-1;
fd.best_track_dist = (uint)-1;
- NewTrainPathfind(v->tile, v->dest_tile, reverse ^ i, (NTPEnumProc*)NtpCallbFindStation, &fd);
+ NewTrainPathfind(v->tile, v->dest_tile, v->u.rail.compatible_railtypes, reverse ^ i, (NTPEnumProc*)NtpCallbFindStation, &fd);
if (best_track != -1) {
if (best_bird_dist != 0) {
@@ -2601,7 +2608,7 @@
return
IsTileOwner(tile, v->owner) && (
!IsFrontEngine(v) ||
- IsCompatibleRail(v->u.rail.railtype, GetRailType(tile))
+ HASBIT(v->u.rail.compatible_railtypes, GetRailType(tile))
);
}
--- a/vehicle.h Tue May 16 22:11:15 2006 +0000
+++ b/vehicle.h Sat May 20 15:54:46 2006 +0000
@@ -71,6 +71,7 @@
byte track;
byte force_proceed;
byte railtype;
+ byte compatible_railtypes;
byte flags;