diff options
author | matthijs <matthijs@openttd.org> | 2005-06-22 22:38:18 +0000 |
---|---|---|
committer | matthijs <matthijs@openttd.org> | 2005-06-22 22:38:18 +0000 |
commit | 7549cb52714014a10f62c6d04fd8bcad21e09a33 (patch) | |
tree | a7c77399d349a4859cb2ea13be5ad9abd8fef001 | |
parent | 3192b4becd50a0b138f431f439dcb5178edbb27b (diff) | |
download | openttd-7549cb52714014a10f62c6d04fd8bcad21e09a33.tar.xz |
(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.
-rw-r--r-- | npf.c | 67 | ||||
-rw-r--r-- | openttd.h | 3 | ||||
-rw-r--r-- | rail.h | 29 | ||||
-rw-r--r-- | tile.h | 6 |
4 files changed, 88 insertions, 17 deletions
@@ -399,6 +399,60 @@ void NPFSaveTargetData(AyStar* as, OpenListNode* current) { 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, OpenListNode* current) { } /* 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))){ @@ -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 { @@ -443,4 +443,33 @@ static inline bool HasSemaphores(TileIndex tile, Track track) */ 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 @@ -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 tile, Owner owner) return GetTileOwner(tile) == owner; } -static inline bool IsLevelCrossing(TileIndex tile) -{ - return (_map5[tile] & 0xF0) == 0x10; -} - #endif |