From 1bf688e5b5a4d9cb509d06d0d2946cdca819f294 Mon Sep 17 00:00:00 2001 From: rubidium Date: Mon, 5 Feb 2007 14:00:32 +0000 Subject: (svn r8593) -Fix (FS#564): bridges do not get destroyed when the bridge head gets flooded and there is a vehicle on the bridge. Original patch by KeeperofTheSoul. --- src/water_cmd.cpp | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) (limited to 'src/water_cmd.cpp') diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 048d6d45e..e7425df58 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -40,6 +40,7 @@ static const SpriteID _water_shore_sprites[] = { }; +static Vehicle *FindFloodableVehicleOnTile(TileIndex tile); static void FloodVehicle(Vehicle *v); /** Build a ship depot. @@ -564,10 +565,9 @@ static void TileLoopWaterHelper(TileIndex tile, const TileIndexDiffC *offs) } } else { _current_player = OWNER_WATER; - { - Vehicle *v = FindVehicleOnTileZ(target, 0); - if (v != NULL) FloodVehicle(v); - } + + Vehicle *v = FindFloodableVehicleOnTile(target); + if (v != NULL) FloodVehicle(v); if (!CmdFailed(DoCommand(target, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR))) { MakeWater(target); @@ -576,6 +576,33 @@ static void TileLoopWaterHelper(TileIndex tile, const TileIndexDiffC *offs) } } +/** + * 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) +{ + if (!IsBridgeTile(tile)) return FindVehicleOnTileZ(tile, 0); + + TileIndex end = GetOtherBridgeEnd(tile); + byte z = GetBridgeHeight(tile); + Vehicle *v; + + /* 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)) { @@ -600,6 +627,7 @@ static void FloodVehicle(Vehicle *v) 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; -- cgit v1.2.3-54-g00ecf