* Recompute tiles covered in our catchment area. * This will additionally recompute nearby towns and industries. * @param no_clear_nearby_lists If Station::RemoveFromAllNearbyLists does not need to be called. */
| 464 | * @param no_clear_nearby_lists If Station::RemoveFromAllNearbyLists does not need to be called. |
| 465 | */ |
| 466 | void Station::RecomputeCatchment(bool no_clear_nearby_lists) |
| 467 | { |
| 468 | this->industries_near.clear(); |
| 469 | if (!no_clear_nearby_lists) this->RemoveFromAllNearbyLists(); |
| 470 | |
| 471 | if (this->rect.IsEmpty()) { |
| 472 | this->catchment_tiles.Reset(); |
| 473 | return; |
| 474 | } |
| 475 | |
| 476 | if (!_settings_game.station.serve_neutral_industries && this->industry != nullptr) { |
| 477 | /* Station is associated with an industry, so we only need to deliver to that industry. */ |
| 478 | this->catchment_tiles.Initialize(this->industry->location); |
| 479 | for (TileIndex tile : this->industry->location) { |
| 480 | if (IsTileType(tile, MP_INDUSTRY) && GetIndustryIndex(tile) == this->industry->index) { |
| 481 | this->catchment_tiles.SetTile(tile); |
| 482 | } |
| 483 | } |
| 484 | /* The industry's stations_near may have been computed before its neutral station was built so clear and re-add here. */ |
| 485 | for (Station *st : this->industry->stations_near) { |
| 486 | st->RemoveIndustryToDeliver(this->industry); |
| 487 | } |
| 488 | this->industry->stations_near.clear(); |
| 489 | this->industry->stations_near.insert(this); |
| 490 | this->industries_near.insert(IndustryListEntry{0, this->industry}); |
| 491 | return; |
| 492 | } |
| 493 | |
| 494 | this->catchment_tiles.Initialize(GetCatchmentRect()); |
| 495 | |
| 496 | /* Loop finding all station tiles */ |
| 497 | TileArea ta(TileXY(this->rect.left, this->rect.top), TileXY(this->rect.right, this->rect.bottom)); |
| 498 | for (TileIndex tile : ta) { |
| 499 | if (!IsTileType(tile, MP_STATION) || GetStationIndex(tile) != this->index) continue; |
| 500 | |
| 501 | uint r = GetTileCatchmentRadius(tile, this); |
| 502 | if (r == CA_NONE) continue; |
| 503 | |
| 504 | /* This tile sub-loop doesn't need to test any tiles, they are simply added to the catchment set. */ |
| 505 | TileArea ta2 = TileArea(tile, 1, 1).Expand(r); |
| 506 | for (TileIndex tile2 : ta2) this->catchment_tiles.SetTile(tile2); |
| 507 | } |
| 508 | |
| 509 | /* Search catchment tiles for towns and industries */ |
| 510 | BitmapTileIterator it(this->catchment_tiles); |
| 511 | for (TileIndex tile = it; tile != INVALID_TILE; tile = ++it) { |
| 512 | if (IsTileType(tile, MP_HOUSE)) { |
| 513 | Town *t = Town::GetByTile(tile); |
| 514 | t->stations_near.insert(this); |
| 515 | } |
| 516 | if (IsTileType(tile, MP_INDUSTRY)) { |
| 517 | Industry *i = Industry::GetByTile(tile); |
| 518 | |
| 519 | /* Ignore industry if it has a neutral station. It already can't be this station. */ |
| 520 | if (!_settings_game.station.serve_neutral_industries && i->neutral_station != nullptr) continue; |
| 521 | |
| 522 | i->stations_near.insert(this); |
| 523 |
no test coverage detected