summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryexo <yexo@openttd.org>2009-05-06 21:38:59 +0000
committeryexo <yexo@openttd.org>2009-05-06 21:38:59 +0000
commitca435fcece2b98d2d4e6f80df6eb1eaeb2e060dc (patch)
treebdd412bfda6223a9eaf306426d30ec52dd9d9d67
parent2664f2a2d95dbc2122ff1f9b96e8569ae401892f (diff)
downloadopenttd-ca435fcece2b98d2d4e6f80df6eb1eaeb2e060dc.tar.xz
(svn r16243) -Fix [FS#2875]: CmdBuildTunnel could be called with invalid parameters from the api code, causing crashes later
-rw-r--r--src/ai/api/ai_tunnel.cpp17
-rw-r--r--src/ai/api/ai_tunnel.hpp6
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);