diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/vehicle.cpp | 3 | ||||
-rw-r--r-- | src/vehicle.h | 2 | ||||
-rw-r--r-- | src/water_cmd.cpp | 36 |
3 files changed, 35 insertions, 6 deletions
diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 8ee5d62b2..94fe2660a 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -167,7 +167,7 @@ Vehicle *FindVehicleOnTileZ(TileIndex tile, byte z) 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 @@ Vehicle *FindVehicleBetween(TileIndex from, TileIndex to, byte z) 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) { diff --git a/src/vehicle.h b/src/vehicle.h index a23133188..780663725 100644 --- a/src/vehicle.h +++ b/src/vehicle.h @@ -306,7 +306,7 @@ Vehicle *CreateEffectVehicleRel(const Vehicle *v, int x, int y, int z, EffectVeh 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); 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; |