water_cmd.c
branch0.5
changeset 5427 63ce73145566
parent 5210 dc52acfad05c
child 5439 7af52897085a
--- a/water_cmd.c	Wed Jan 31 22:08:23 2007 +0000
+++ b/water_cmd.c	Thu Feb 08 10:00:22 2007 +0000
@@ -40,6 +40,7 @@
 };
 
 
+static Vehicle *FindFloodableVehicleOnTile(TileIndex tile);
 static void FloodVehicle(Vehicle *v);
 
 /** Build a ship depot.
@@ -593,7 +594,7 @@
 
 		_current_player = OWNER_WATER;
 		{
-			Vehicle *v = FindVehicleOnTileZ(target, 0);
+			Vehicle *v = FindFloodableVehicleOnTile(target);
 			if (v != NULL) FloodVehicle(v);
 		}
 
@@ -604,6 +605,36 @@
 	}
 }
 
+/**
+ * Finds a vehicle to flood.
+ * It does not find vehicles that are already crashed on bridges, i.e. flooded.
+ * @param tile the tile where to find a vehicle to flood
+ * @return a vehicle too flood or NULL when there is no vehicle too flood.
+ */
+static Vehicle *FindFloodableVehicleOnTile(TileIndex tile)
+{
+	TileIndex end;
+	byte z;
+	Vehicle *v;
+
+	if (!IsBridgeTile(tile)) return FindVehicleOnTileZ(tile, 0);
+
+	end = GetOtherBridgeEnd(tile);
+	z = GetBridgeHeight(tile);
+
+	/* check the start tile first since as this is closest to the water */
+	v = FindVehicleOnTileZ(tile, z);
+	if (v != NULL && (v->vehstatus & VS_CRASHED) == 0) return v;
+
+	/* check a vehicle in between both bridge heads */
+	v = FindVehicleBetween(tile, end, z, true);
+	if (v != NULL) return v;
+
+	/* check the end tile last to give fleeing vehicles a chance to escape */
+	v = FindVehicleOnTileZ(end, z);
+	return (v != NULL && (v->vehstatus & VS_CRASHED) == 0) ? v : NULL;
+}
+
 static void FloodVehicle(Vehicle *v)
 {
 	if (!(v->vehstatus & VS_CRASHED)) {
@@ -628,6 +659,7 @@
 			BEGIN_ENUM_WAGONS(v)
 				if (v->cargo_type == CT_PASSENGERS) pass += v->cargo_count;
 				v->vehstatus |= VS_CRASHED;
+				MarkAllViewportsDirty(v->left_coord, v->top_coord, v->right_coord + 1, v->bottom_coord + 1);
 			END_ENUM_WAGONS(v)
 
 			v = u;
@@ -661,9 +693,8 @@
 		{{ 0, -1}, {0, 0}, {1, 0}, { 0, -1}, { 1, -1}}
 	};
 
-	/* Ensure sea-level canals do not flood */
-	if ((IsTileType(tile, MP_WATER) || IsTileType(tile, MP_TUNNELBRIDGE)) &&
-			!IsTileOwner(tile, OWNER_WATER)) return;
+	/* Ensure sea-level canals and buoys on canal borders do not flood */
+	if ((IsTileType(tile, MP_WATER) || IsTileType(tile, MP_TUNNELBRIDGE) || IsBuoyTile(tile)) && !IsTileOwner(tile, OWNER_WATER)) return;
 
 	if (IS_INT_INSIDE(TileX(tile), 1, MapSizeX() - 3 + 1) &&
 			IS_INT_INSIDE(TileY(tile), 1, MapSizeY() - 3 + 1)) {