(svn r10922) -Codechange: Allow building and removing tracks and signals when there is a
authormaedhros
Thu, 16 Aug 2007 13:13:07 +0000
changeset 7944 65c7c2e1bcb9
parent 7943 5bd1fbc094c6
child 7945 ff24db9275cd
(svn r10922) -Codechange: Allow building and removing tracks and signals when there is a
train on a parallel diagonal track that doesn't interact with this one. (frosch)
src/rail_cmd.cpp
--- a/src/rail_cmd.cpp	Thu Aug 16 10:10:59 2007 +0000
+++ b/src/rail_cmd.cpp	Thu Aug 16 13:13:07 2007 +0000
@@ -78,6 +78,44 @@
  *               11uuuudd => rail depot
  */
 
+/** Struct used in EnsureNoTrainOnTrack() */
+struct TrainOnTrackData {
+	TileIndex tile;       ///< tile to check
+	uint z;               ///< tile max Z
+	TrackBits rail_bits;  ///< trackbits of interest
+};
+
+static void *EnsureNoTrainOnTrackProc(Vehicle *v, void *data)
+{
+	const TrainOnTrackData *info = (const TrainOnTrackData *)data;
+
+	if (v->tile != info->tile || v->type != VEH_TRAIN) return NULL;
+	if (v->z_pos > info->z) return NULL;
+
+	if ((v->u.rail.track != info->rail_bits) && !TracksOverlap(v->u.rail.track | info->rail_bits)) return NULL;
+
+	_error_message = VehicleInTheWayErrMsg(v);
+	return v;
+}
+
+/**
+ * Tests if a vehicle interacts with the specified track.
+ * All track bits interact except parallel TRACK_BIT_HORZ or TRACK_BIT_VERT.
+ *
+ * @param tile The tile.
+ * @param track The track.
+ */
+static bool EnsureNoTrainOnTrack(TileIndex tile, Track track)
+{
+	TrainOnTrackData info;
+
+	info.tile = tile;
+	info.z = GetTileMaxZ(tile);
+	info.rail_bits = TrackToTrackBits(track);
+
+	return VehicleFromPos(tile, &info, EnsureNoTrainOnTrackProc) == NULL;
+}
+
 static bool CheckTrackCombination(TileIndex tile, TrackBits to_build, uint flags)
 {
 	TrackBits current; // The current track layout
@@ -239,7 +277,7 @@
 	switch (GetTileType(tile)) {
 		case MP_RAILWAY:
 			if (!CheckTrackCombination(tile, trackbit, flags) ||
-					!EnsureNoVehicleOnGround(tile)) {
+					!EnsureNoTrainOnTrack(tile, track)) {
 				return CMD_ERROR;
 			}
 			if (!IsTileOwner(tile, _current_player) ||
@@ -374,7 +412,7 @@
 
 			if (!IsPlainRailTile(tile) ||
 					(_current_player != OWNER_WATER && !CheckTileOwnership(tile)) ||
-					!EnsureNoVehicleOnGround(tile)) {
+					!EnsureNoTrainOnTrack(tile, track)) {
 				return CMD_ERROR;
 			}
 
@@ -647,7 +685,7 @@
 	SignalVariant sigvar = (pre_signal ^ HASBIT(p1, 4)) ? SIG_SEMAPHORE : SIG_ELECTRIC;
 	CommandCost cost;
 
-	if (!ValParamTrackOrientation(track) || !IsTileType(tile, MP_RAILWAY) || !EnsureNoVehicleOnGround(tile))
+	if (!ValParamTrackOrientation(track) || !IsTileType(tile, MP_RAILWAY) || !EnsureNoTrainOnTrack(tile, track))
 		return CMD_ERROR;
 
 	/* Protect against invalid signal copying */
@@ -935,7 +973,7 @@
 
 	if (!ValParamTrackOrientation(track) ||
 			!IsTileType(tile, MP_RAILWAY) ||
-			!EnsureNoVehicleOnGround(tile) ||
+			!EnsureNoTrainOnTrack(tile, track) ||
 			!HasSignalOnTrack(tile, track)) {
 		return CMD_ERROR;
 	}