Fix #10831: Level crossing parts left barred after crossing tile removal (#10874)

This commit is contained in:
Jonathan G Rennison 2023-06-03 22:04:24 +01:00 committed by GitHub
parent cd751a598a
commit a2c0e6aa18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 3 deletions

View File

@ -651,7 +651,7 @@ CommandCost CmdRemoveSingleRail(DoCommandFlag flags, TileIndex tile, Track track
cost.AddCost(RailClearCost(GetRailType(tile)));
if (flags & DC_EXEC) {
MarkDirtyAdjacentLevelCrossingTiles(tile, GetCrossingRoadAxis(tile));
UpdateAdjacentLevelCrossingTilesOnLevelCrossingRemoval(tile, GetCrossingRoadAxis(tile));
if (HasReservedTracks(tile, trackbit)) {
v = GetTrainForReservation(tile, track);

View File

@ -504,7 +504,7 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec
}
if (flags & DC_EXEC) {
MarkDirtyAdjacentLevelCrossingTiles(tile, GetCrossingRoadAxis(tile));
UpdateAdjacentLevelCrossingTilesOnLevelCrossingRemoval(tile, GetCrossingRoadAxis(tile));
/* A full diagonal road tile has two road bits. */
UpdateCompanyRoadInfrastructure(existing_rt, GetRoadOwner(tile, rtt), -2);

View File

@ -155,6 +155,7 @@ RoadTypes AddDateIntroducedRoadTypes(RoadTypes current, TimerGameCalendar::Date
void UpdateLevelCrossing(TileIndex tile, bool sound = true, bool force_bar = false);
void MarkDirtyAdjacentLevelCrossingTiles(TileIndex tile, Axis road_axis);
void UpdateAdjacentLevelCrossingTilesOnLevelCrossingRemoval(TileIndex tile, Axis road_axis);
void UpdateCompanyRoadInfrastructure(RoadType rt, Owner o, int count);
struct TileInfo;

View File

@ -1790,7 +1790,8 @@ void UpdateLevelCrossing(TileIndex tile, bool sound, bool force_bar)
/**
* Find adjacent level crossing tiles in this multi-track crossing and mark them dirty.
* @param The tile which causes the update.
* @param tile The tile which causes the update.
* @param road_axis The road axis.
*/
void MarkDirtyAdjacentLevelCrossingTiles(TileIndex tile, Axis road_axis)
{
@ -1804,6 +1805,44 @@ void MarkDirtyAdjacentLevelCrossingTiles(TileIndex tile, Axis road_axis)
}
}
/**
* Update adjacent level crossing tiles in this multi-track crossing, due to removal of a level crossing tile.
* @param tile The crossing tile which has been or is about to be removed, and which caused the update.
* @param road_axis The road axis.
*/
void UpdateAdjacentLevelCrossingTilesOnLevelCrossingRemoval(TileIndex tile, Axis road_axis)
{
const DiagDirection dir1 = AxisToDiagDir(road_axis);
const DiagDirection dir2 = ReverseDiagDir(dir1);
for (DiagDirection dir : { dir1, dir2 }) {
const TileIndexDiff diff = TileOffsByDiagDir(dir);
bool occupied = false;
for (TileIndex t = tile + diff; t < Map::Size() && IsLevelCrossingTile(t) && GetCrossingRoadAxis(t) == road_axis; t += diff) {
occupied |= CheckLevelCrossing(t);
}
if (occupied) {
/* Mark the immediately adjacent tile dirty */
const TileIndex t = tile + diff;
if (t < Map::Size() && IsLevelCrossingTile(t) && GetCrossingRoadAxis(t) == road_axis) {
MarkTileDirtyByTile(t);
}
} else {
/* Unbar the crossing tiles in this direction as necessary */
for (TileIndex t = tile + diff; t < Map::Size() && IsLevelCrossingTile(t) && GetCrossingRoadAxis(t) == road_axis; t += diff) {
if (IsCrossingBarred(t)) {
/* The crossing tile is barred, unbar it and continue to check the next tile */
SetCrossingBarred(t, false);
MarkTileDirtyByTile(t);
} else {
/* The crossing tile is already unbarred, mark the tile dirty and stop checking */
MarkTileDirtyByTile(t);
break;
}
}
}
}
}
/**
* Bars crossing and plays ding-ding sound if not barred already
* @param tile tile with crossing