Mercurial > hg > openttd
changeset 5940:8518d27e667f draft
(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.
author | rubidium <rubidium@openttd.org> |
---|---|
date | Mon, 05 Feb 2007 14:00:32 +0000 |
parents | 1347bd144518 |
children | d0e1f93e603a |
files | src/vehicle.cpp src/vehicle.h src/water_cmd.cpp |
diffstat | 3 files changed, 35 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -167,7 +167,7 @@ return (Vehicle*)VehicleFromPos(tile, &ti, EnsureNoVehicleProcZ); } -Vehicle *FindVehicleBetween(TileIndex from, TileIndex to, byte z) +Vehicle *FindVehicleBetween(TileIndex from, TileIndex to, byte z, bool without_crashed) { int x1 = TileX(from); int y1 = TileY(from); @@ -181,6 +181,7 @@ intswap(y1,y2); } FOR_ALL_VEHICLES(veh) { + if (without_crashed && (veh->vehstatus & VS_CRASHED) != 0) continue; if ((veh->type == VEH_Train || veh->type == VEH_Road) && (z==0xFF || veh->z_pos == z)) { if ((veh->x_pos>>4) >= x1 && (veh->x_pos>>4) <= x2 && (veh->y_pos>>4) >= y1 && (veh->y_pos>>4) <= y2) {
--- a/src/vehicle.h +++ b/src/vehicle.h @@ -306,7 +306,7 @@ uint32 VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y); StringID VehicleInTheWayErrMsg(const Vehicle* v); -Vehicle *FindVehicleBetween(TileIndex from, TileIndex to, byte z); +Vehicle *FindVehicleBetween(TileIndex from, TileIndex to, byte z, bool without_crashed = false); bool UpdateSignalsOnSegment(TileIndex tile, DiagDirection direction); void SetSignalsOnBothDir(TileIndex tile, byte track);
--- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -40,6 +40,7 @@ }; +static Vehicle *FindFloodableVehicleOnTile(TileIndex tile); static void FloodVehicle(Vehicle *v); /** Build a ship depot. @@ -564,10 +565,9 @@ } } 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 @@ } } +/** + * 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 @@ 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;