Changeset - r1967:32488abc8e36
[Not reviewed]
master
0 4 0
matthijs - 19 years ago 2005-06-22 22:38:18
matthijs@openttd.org
(svn r2473) - Add: VehicleMayEnterTile(), which checks if the tile owner of a tile is correct for a vehicle to enter it. Based upon glx's code.
- Fix: [ 1203769 ] [NPF] NPF tries to plan over bridges, through tunnels, over level crossings of other players. (glx)
- Codechange: Renamed TRANSPORT_MAX to TRANSPORT_END and added INVALID_TRANSPORT.
- Codechange: Moved IsLevelCrossing() from tile.h to rail.h
- Add: GetCrossingTransportType(), which returns the transport type (road, rail) of both tracks on a level crossing.
- Removed old TODO that was fulfilled already.
4 files changed with 88 insertions and 17 deletions:
npf.c
57
10
rail.h
29
tile.h
6
0 comments (0 inline, 0 general)
npf.c
Show inline comments
 
@@ -399,6 +399,60 @@ void NPFSaveTargetData(AyStar* as, OpenL
 
	ftd->node = current->path.node;
 
}
 

	
 
/**
 
 * Finds out if a given player's vehicles are allowed to enter a given tile.
 
 * @param owner    The owner of the vehicle.
 
 * @param tile     The tile that is about to be entered.
 
 * @param enterdir The direction from which the vehicle wants to enter the tile.
 
 * @return         true if the vehicle can enter the tile.
 
 * @todo           This function should be used in other places than just NPF,
 
 *                 maybe moved to another file too.
 
 */
 
bool VehicleMayEnterTile(Owner owner, TileIndex tile, DiagDirection enterdir)
 
{
 
	if (
 
		IsTileType(tile, MP_RAILWAY) /* Rail tile (also rail depot) */
 
		|| IsTrainStationTile(tile) /* Rail station tile */
 
		|| IsTileDepotType(tile, TRANSPORT_ROAD) /* Road depot tile */
 
		|| IsRoadStationTile(tile) /* Road station tile */
 
		|| IsTileDepotType(tile, TRANSPORT_WATER) /* Water depot tile */
 
		)
 
		return IsTileOwner(tile, owner); /* You need to own these tiles entirely to use them */
 

	
 
	switch (GetTileType(tile)) {
 
		case MP_STREET:
 
			/* rail-road crossing : are we looking at the railway part? */
 
			if (IsLevelCrossing(tile) && GetCrossingTransportType(tile, TrackdirToTrack(DiagdirToDiagTrackdir(enterdir))) == TRANSPORT_RAIL)
 
				return IsTileOwner(tile, owner); /* Railway needs owner check, while the street is public */
 
			break;
 
		case MP_TUNNELBRIDGE:
 
#if 0
 
/* OPTIMISATION: If we are on the middle of a bridge, we will not do the cpu
 
 * intensive owner check, instead we will just assume that if the vehicle
 
 * managed to get on the bridge, it is probably allowed to :-)
 
 */
 
			if ((_map5[tile] & 0xC6) == 0xC0 && (unsigned)(_map5[tile] & 0x1) == (enterdir & 0x1)) {
 
				/* on the middle part of a railway bridge: find bridge ending */
 
				while (IsTileType(tile, MP_TUNNELBRIDGE) && !((_map5[tile] & 0xC6) == 0x80)) {
 
					tile += TileOffsByDir(_map5[tile] & 0x1);
 
				}
 
			}
 
			/* if we were on a railway middle part, we are now at a railway bridge ending */
 
#endif
 
			if (
 
				(_map5[tile] & 0xFC) == 0 /* railway tunnel */
 
				|| (_map5[tile] & 0xC6) == 0x80 /* railway bridge ending */
 
				|| ((_map5[tile] & 0xF8) == 0xE0 && ((unsigned)_map5[tile] & 0x1) != (enterdir & 0x1)) /* railway under bridge */
 
				)
 
				return IsTileOwner(tile, owner);
 
			break;
 
		default:
 
			break;
 
	}
 

	
 
	return true; /* no need to check */
 
}
 

	
 
/* Will just follow the results of GetTileTrackStatus concerning where we can
 
 * go and where not. Uses AyStar.user_data[NPF_TYPE] as the transport type and
 
 * an argument to GetTileTrackStatus. Will skip tunnels, meaning that the
 
@@ -480,16 +534,9 @@ void NPFFollowTrack(AyStar* aystar, Open
 
	}
 

	
 
	/* Check the owner of the tile */
 
	if (
 
		IsTileType(dst_tile, MP_RAILWAY) /* Rail tile (also rail depot) */
 
		|| IsTrainStationTile(dst_tile) /* Rail station tile */
 
		|| IsTileDepotType(dst_tile, TRANSPORT_ROAD) /* Road depot tile */
 
		|| IsRoadStationTile(dst_tile) /* Road station tile */
 
		|| IsTileDepotType(dst_tile, TRANSPORT_WATER) /* Water depot tile */
 
	) /* TODO: Crossings, tunnels and bridges are "public" now */
 
		/* The above cases are "private" tiles, we need to check the owner */
 
		if (!IsTileOwner(dst_tile, aystar->user_data[NPF_OWNER]))
 
			return;
 
	if (!VehicleMayEnterTile(aystar->user_data[NPF_OWNER], dst_tile, TrackdirToExitdir(src_trackdir))) {
 
		return;
 
	}
 

	
 
	/* Determine available tracks */
 
	if (type != TRANSPORT_WATER && (IsRoadStationTile(dst_tile) || IsTileDepotType(dst_tile, type))){
openttd.h
Show inline comments
 
@@ -106,7 +106,8 @@ typedef enum TransportTypes {
 
  TRANSPORT_RAIL = 0,
 
	TRANSPORT_ROAD = 1,
 
	TRANSPORT_WATER,	// = 2
 
	TRANSPORT_MAX			// = 3
 
	TRANSPORT_END,
 
	INVALID_TRANSPORT = 0xff,
 
} TransportType;
 

	
 
typedef struct TileInfo {
rail.h
Show inline comments
 
@@ -443,4 +443,33 @@ static inline bool HasSemaphores(TileInd
 
 */
 
RailType GetTileRailType(TileIndex tile, byte trackdir);
 

	
 
/**
 
 * Returns whether the given tile is a level crossing.
 
 */
 
static inline bool IsLevelCrossing(TileIndex tile)
 
{
 
	return (_map5[tile] & 0xF0) == 0x10;
 
}
 

	
 
/**
 
 * Gets the transport type of the given track on the given crossing tile.
 
 * @return  The transport type of the given track, either TRANSPORT_ROAD,
 
 * TRANSPORT_RAIL.
 
 */
 
static inline TransportType GetCrossingTransportType(TileIndex tile, Track track)
 
{
 
	/* XXX: Nicer way to write this? */
 
	switch(track)
 
	{
 
		/* When map5 bit 3 is set, the road runs in the y direction (DIAG2) */
 
		case TRACK_DIAG1:
 
			return (HASBIT(_map5[tile], 3) ? TRANSPORT_RAIL : TRANSPORT_ROAD);
 
		case TRACK_DIAG2:
 
			return (HASBIT(_map5[tile], 3) ? TRANSPORT_ROAD : TRANSPORT_RAIL);
 
		default:
 
			assert(0);
 
	}
 
	return INVALID_TRANSPORT;
 
}
 

	
 
#endif // RAIL_H
tile.h
Show inline comments
 
@@ -18,7 +18,6 @@ typedef enum TileTypes {
 
	MP_UNMOVABLE
 
} TileType;
 

	
 
/* TODO: Find out values */
 
/* Direction as commonly used in v->direction, 8 way. */
 
typedef enum Directions {
 
	DIR_N   = 0,
 
@@ -116,9 +115,4 @@ static inline bool IsTileOwner(TileIndex
 
	return GetTileOwner(tile) == owner;
 
}
 

	
 
static inline bool IsLevelCrossing(TileIndex tile)
 
{
 
	return (_map5[tile] & 0xF0) == 0x10;
 
}
 

	
 
#endif
0 comments (0 inline, 0 general)