MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / RecomputeCatchment

Method RecomputeCatchment

src/station.cpp:466–528  ·  view source on GitHub ↗

* 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. */

Source from the content-addressed store, hash-verified

464 * @param no_clear_nearby_lists If Station::RemoveFromAllNearbyLists does not need to be called.
465 */
466void 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

Callers 5

CmdRemoveFromRailStationFunction · 0.80
RemoveRailStationFunction · 0.80
BuildOilRigFunction · 0.80

Calls 15

AddIndustryToDeliverMethod · 0.95
IsTileTypeFunction · 0.85
GetIndustryIndexFunction · 0.85
TileXYFunction · 0.85
GetStationIndexFunction · 0.85
GetTileCatchmentRadiusFunction · 0.85
SetTileMethod · 0.80
ExpandMethod · 0.80
clearMethod · 0.45
IsEmptyMethod · 0.45

Tested by

no test coverage detected