mirror of https://github.com/OpenTTD/OpenTTD
(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.release/0.4.5
parent
3192b4becd
commit
7549cb5271
67
npf.c
67
npf.c
|
@ -399,6 +399,60 @@ void NPFSaveTargetData(AyStar* as, OpenListNode* current) {
|
||||||
ftd->node = current->path.node;
|
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
|
/* 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
|
* 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
|
* an argument to GetTileTrackStatus. Will skip tunnels, meaning that the
|
||||||
|
@ -480,16 +534,9 @@ void NPFFollowTrack(AyStar* aystar, OpenListNode* current) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the owner of the tile */
|
/* Check the owner of the tile */
|
||||||
if (
|
if (!VehicleMayEnterTile(aystar->user_data[NPF_OWNER], dst_tile, TrackdirToExitdir(src_trackdir))) {
|
||||||
IsTileType(dst_tile, MP_RAILWAY) /* Rail tile (also rail depot) */
|
return;
|
||||||
|| 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;
|
|
||||||
|
|
||||||
/* Determine available tracks */
|
/* Determine available tracks */
|
||||||
if (type != TRANSPORT_WATER && (IsRoadStationTile(dst_tile) || IsTileDepotType(dst_tile, type))){
|
if (type != TRANSPORT_WATER && (IsRoadStationTile(dst_tile) || IsTileDepotType(dst_tile, type))){
|
||||||
|
|
|
@ -106,7 +106,8 @@ typedef enum TransportTypes {
|
||||||
TRANSPORT_RAIL = 0,
|
TRANSPORT_RAIL = 0,
|
||||||
TRANSPORT_ROAD = 1,
|
TRANSPORT_ROAD = 1,
|
||||||
TRANSPORT_WATER, // = 2
|
TRANSPORT_WATER, // = 2
|
||||||
TRANSPORT_MAX // = 3
|
TRANSPORT_END,
|
||||||
|
INVALID_TRANSPORT = 0xff,
|
||||||
} TransportType;
|
} TransportType;
|
||||||
|
|
||||||
typedef struct TileInfo {
|
typedef struct TileInfo {
|
||||||
|
|
29
rail.h
29
rail.h
|
@ -443,4 +443,33 @@ static inline bool HasSemaphores(TileIndex tile, Track track)
|
||||||
*/
|
*/
|
||||||
RailType GetTileRailType(TileIndex tile, byte trackdir);
|
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
|
#endif // RAIL_H
|
||||||
|
|
6
tile.h
6
tile.h
|
@ -18,7 +18,6 @@ typedef enum TileTypes {
|
||||||
MP_UNMOVABLE
|
MP_UNMOVABLE
|
||||||
} TileType;
|
} TileType;
|
||||||
|
|
||||||
/* TODO: Find out values */
|
|
||||||
/* Direction as commonly used in v->direction, 8 way. */
|
/* Direction as commonly used in v->direction, 8 way. */
|
||||||
typedef enum Directions {
|
typedef enum Directions {
|
||||||
DIR_N = 0,
|
DIR_N = 0,
|
||||||
|
@ -116,9 +115,4 @@ static inline bool IsTileOwner(TileIndex tile, Owner owner)
|
||||||
return GetTileOwner(tile) == owner;
|
return GetTileOwner(tile) == owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool IsLevelCrossing(TileIndex tile)
|
|
||||||
{
|
|
||||||
return (_map5[tile] & 0xF0) == 0x10;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue