* Prepare for removal of this stop; update other neighbouring stops * if needed. Also update the length etc. */
| 120 | * if needed. Also update the length etc. |
| 121 | */ |
| 122 | void RoadStop::ClearDriveThrough() |
| 123 | { |
| 124 | assert(this->entries != nullptr); |
| 125 | |
| 126 | RoadStopType rst = GetRoadStopType(this->xy); |
| 127 | Axis axis = GetDriveThroughStopAxis(this->xy); |
| 128 | TileIndexDiff offset = TileOffsByAxis(axis); |
| 129 | |
| 130 | /* Information about the tile north of us */ |
| 131 | TileIndex north_tile = this->xy - offset; |
| 132 | bool north = IsDriveThroughRoadStopContinuation(this->xy, north_tile); |
| 133 | RoadStop *rs_north = north ? RoadStop::GetByTile(north_tile, rst) : nullptr; |
| 134 | |
| 135 | /* Information about the tile south of us */ |
| 136 | TileIndex south_tile = this->xy + offset; |
| 137 | bool south = IsDriveThroughRoadStopContinuation(this->xy, south_tile); |
| 138 | RoadStop *rs_south = south ? RoadStop::GetByTile(south_tile, rst) : nullptr; |
| 139 | |
| 140 | /* Must only be cleared after we determined which neighbours are |
| 141 | * part of our little entry 'queue' */ |
| 142 | DoClearSquare(this->xy); |
| 143 | |
| 144 | if (north) { |
| 145 | /* There is a tile to the north, so we can't clear ourselves. */ |
| 146 | if (south) { |
| 147 | /* There are more southern tiles too, they must be split; |
| 148 | * first make the new southern 'base' */ |
| 149 | rs_south->status.Set(RoadStopStatusFlag::BaseEntry); |
| 150 | rs_south->entries = new Entries(); |
| 151 | |
| 152 | /* Keep track of the base because we need it later on */ |
| 153 | RoadStop *rs_south_base = rs_south; |
| 154 | TileIndex base_tile = south_tile; |
| 155 | |
| 156 | /* Make all (even more) southern stops part of the new entry queue */ |
| 157 | for (south_tile += offset; IsDriveThroughRoadStopContinuation(base_tile, south_tile); south_tile += offset) { |
| 158 | rs_south = RoadStop::GetByTile(south_tile, rst); |
| 159 | rs_south->entries = rs_south_base->entries; |
| 160 | } |
| 161 | |
| 162 | /* Find the other end; the northern most tile */ |
| 163 | for (; IsDriveThroughRoadStopContinuation(base_tile, north_tile); north_tile -= offset) { |
| 164 | rs_north = RoadStop::GetByTile(north_tile, rst); |
| 165 | } |
| 166 | |
| 167 | /* We have to rebuild the entries because we cannot easily determine |
| 168 | * how full each part is. So instead of keeping and maintaining a list |
| 169 | * of vehicles and using that to 'rebuild' the occupied state we just |
| 170 | * rebuild it from scratch as that removes lots of maintenance code |
| 171 | * for the vehicle list and it's faster in real games as long as you |
| 172 | * do not keep split and merge road stop every tick by the millions. */ |
| 173 | rs_south_base->entries->east.Rebuild(rs_south_base); |
| 174 | rs_south_base->entries->west.Rebuild(rs_south_base); |
| 175 | |
| 176 | assert(rs_north->status.Test(RoadStopStatusFlag::BaseEntry)); |
| 177 | rs_north->entries->east.Rebuild(rs_north); |
| 178 | rs_north->entries->west.Rebuild(rs_north); |
| 179 | } else { |
no test coverage detected