diff options
author | yexo <yexo@openttd.org> | 2009-05-06 21:38:59 +0000 |
---|---|---|
committer | yexo <yexo@openttd.org> | 2009-05-06 21:38:59 +0000 |
commit | ca435fcece2b98d2d4e6f80df6eb1eaeb2e060dc (patch) | |
tree | bdd412bfda6223a9eaf306426d30ec52dd9d9d67 /src | |
parent | 2664f2a2d95dbc2122ff1f9b96e8569ae401892f (diff) | |
download | openttd-ca435fcece2b98d2d4e6f80df6eb1eaeb2e060dc.tar.xz |
(svn r16243) -Fix [FS#2875]: CmdBuildTunnel could be called with invalid parameters from the api code, causing crashes later
Diffstat (limited to 'src')
-rw-r--r-- | src/ai/api/ai_tunnel.cpp | 17 | ||||
-rw-r--r-- | src/ai/api/ai_tunnel.hpp | 6 |
2 files changed, 20 insertions, 3 deletions
diff --git a/src/ai/api/ai_tunnel.cpp b/src/ai/api/ai_tunnel.cpp index cc7d95606..ea103ce4e 100644 --- a/src/ai/api/ai_tunnel.cpp +++ b/src/ai/api/ai_tunnel.cpp @@ -23,8 +23,21 @@ /* If it's a tunnel alread, take the easy way out! */ if (IsTunnelTile(tile)) return ::GetOtherTunnelEnd(tile); - ::DoCommand(tile, 0, 0, DC_AUTO, CMD_BUILD_TUNNEL); - return _build_tunnel_endtile == 0 ? INVALID_TILE : _build_tunnel_endtile; + uint start_z; + Slope start_tileh = ::GetTileSlope(tile, &start_z); + DiagDirection direction = ::GetInclinedSlopeDirection(start_tileh); + if (direction == INVALID_DIAGDIR) return INVALID_TILE; + + TileIndexDiff delta = ::TileOffsByDiagDir(direction); + uint end_z; + do { + tile += delta; + if (!::IsValidTile(tile)) return INVALID_TILE; + + ::GetTileSlope(tile, &end_z); + } while (start_z != end_z); + + return tile; } static void _DoCommandReturnBuildTunnel2(class AIInstance *instance) diff --git a/src/ai/api/ai_tunnel.hpp b/src/ai/api/ai_tunnel.hpp index 3e554b68c..de0a7635c 100644 --- a/src/ai/api/ai_tunnel.hpp +++ b/src/ai/api/ai_tunnel.hpp @@ -46,11 +46,15 @@ public: /** * Get the tile that exits on the other end of a (would be) tunnel starting - * at tile. + * at tile. If there is no 'simple' inclined slope at the start tile, + * this function will return AIMap::TILE_INVALID. * @param tile The tile that is an entrance to a tunnel or the tile where you may want to build a tunnel. * @pre AIMap::IsValidTile(tile). * @return The TileIndex that is the other end of the (would be) tunnel, or * AIMap::TILE_INVALID if no other end was found (can't build tunnel). + * @note Even if this function returns a valid tile, that is no guarantee + * that building a tunnel will succeed. Use BuildTunnel in AITestMode to + * check whether a tunnel can actually be build. */ static TileIndex GetOtherTunnelEnd(TileIndex tile); |