mirror of https://github.com/OpenTTD/OpenTTD
(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.
parent
cf5f19520c
commit
1bf688e5b5
|
@ -167,7 +167,7 @@ Vehicle *FindVehicleOnTileZ(TileIndex tile, byte z)
|
||||||
return (Vehicle*)VehicleFromPos(tile, &ti, EnsureNoVehicleProcZ);
|
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 x1 = TileX(from);
|
||||||
int y1 = TileY(from);
|
int y1 = TileY(from);
|
||||||
|
@ -181,6 +181,7 @@ Vehicle *FindVehicleBetween(TileIndex from, TileIndex to, byte z)
|
||||||
intswap(y1,y2);
|
intswap(y1,y2);
|
||||||
}
|
}
|
||||||
FOR_ALL_VEHICLES(veh) {
|
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->type == VEH_Train || veh->type == VEH_Road) && (z==0xFF || veh->z_pos == z)) {
|
||||||
if ((veh->x_pos>>4) >= x1 && (veh->x_pos>>4) <= x2 &&
|
if ((veh->x_pos>>4) >= x1 && (veh->x_pos>>4) <= x2 &&
|
||||||
(veh->y_pos>>4) >= y1 && (veh->y_pos>>4) <= y2) {
|
(veh->y_pos>>4) >= y1 && (veh->y_pos>>4) <= y2) {
|
||||||
|
|
|
@ -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);
|
uint32 VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y);
|
||||||
|
|
||||||
StringID VehicleInTheWayErrMsg(const Vehicle* v);
|
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);
|
bool UpdateSignalsOnSegment(TileIndex tile, DiagDirection direction);
|
||||||
void SetSignalsOnBothDir(TileIndex tile, byte track);
|
void SetSignalsOnBothDir(TileIndex tile, byte track);
|
||||||
|
|
|
@ -40,6 +40,7 @@ static const SpriteID _water_shore_sprites[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static Vehicle *FindFloodableVehicleOnTile(TileIndex tile);
|
||||||
static void FloodVehicle(Vehicle *v);
|
static void FloodVehicle(Vehicle *v);
|
||||||
|
|
||||||
/** Build a ship depot.
|
/** Build a ship depot.
|
||||||
|
@ -564,10 +565,9 @@ static void TileLoopWaterHelper(TileIndex tile, const TileIndexDiffC *offs)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_current_player = OWNER_WATER;
|
_current_player = OWNER_WATER;
|
||||||
{
|
|
||||||
Vehicle *v = FindVehicleOnTileZ(target, 0);
|
Vehicle *v = FindFloodableVehicleOnTile(target);
|
||||||
if (v != NULL) FloodVehicle(v);
|
if (v != NULL) FloodVehicle(v);
|
||||||
}
|
|
||||||
|
|
||||||
if (!CmdFailed(DoCommand(target, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR))) {
|
if (!CmdFailed(DoCommand(target, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR))) {
|
||||||
MakeWater(target);
|
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)
|
static void FloodVehicle(Vehicle *v)
|
||||||
{
|
{
|
||||||
if (!(v->vehstatus & VS_CRASHED)) {
|
if (!(v->vehstatus & VS_CRASHED)) {
|
||||||
|
@ -600,6 +627,7 @@ static void FloodVehicle(Vehicle *v)
|
||||||
BEGIN_ENUM_WAGONS(v)
|
BEGIN_ENUM_WAGONS(v)
|
||||||
if (v->cargo_type == CT_PASSENGERS) pass += v->cargo_count;
|
if (v->cargo_type == CT_PASSENGERS) pass += v->cargo_count;
|
||||||
v->vehstatus |= VS_CRASHED;
|
v->vehstatus |= VS_CRASHED;
|
||||||
|
MarkAllViewportsDirty(v->left_coord, v->top_coord, v->right_coord + 1, v->bottom_coord + 1);
|
||||||
END_ENUM_WAGONS(v)
|
END_ENUM_WAGONS(v)
|
||||||
|
|
||||||
v = u;
|
v = u;
|
||||||
|
|
Loading…
Reference in New Issue