OpenTTD Source 20260911-master-gee2b2ac12a
station.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10#include "stdafx.h"
11#include "core/flatset_type.hpp"
12#include "company_func.h"
13#include "company_base.h"
14#include "roadveh.h"
15#include "viewport_func.h"
16#include "viewport_kdtree.h"
17#include "command_func.h"
18#include "news_func.h"
19#include "aircraft.h"
20#include "vehiclelist.h"
21#include "core/pool_func.hpp"
22#include "station_base.h"
23#include "station_kdtree.h"
24#include "roadstop_base.h"
25#include "industry.h"
26#include "town.h"
27#include "core/random_func.hpp"
28#include "linkgraph/linkgraph.h"
30
31#include "table/strings.h"
32
33#include "safeguards.h"
34
36StationPool _station_pool("Station");
38
39
40StationKdtree _station_kdtree{};
41
42void RebuildStationKdtree()
43{
44 std::vector<StationID> stids;
45 for (const Station *st : Station::Iterate()) {
46 stids.push_back(st->index);
47 }
48 _station_kdtree.Build(stids.begin(), stids.end());
49}
50
51
53{
54 if (CleaningPool()) return;
55
56 CloseWindowById(WindowClass::TrainList, VehicleListIdentifier(VehicleListType::Station, VehicleType::Train, this->owner, this->index).ToWindowNumber());
57 CloseWindowById(WindowClass::RoadVehicleList, VehicleListIdentifier(VehicleListType::Station, VehicleType::Road, this->owner, this->index).ToWindowNumber());
58 CloseWindowById(WindowClass::ShipList, VehicleListIdentifier(VehicleListType::Station, VehicleType::Ship, this->owner, this->index).ToWindowNumber());
59 CloseWindowById(WindowClass::AircraftList, VehicleListIdentifier(VehicleListType::Station, VehicleType::Aircraft, this->owner, this->index).ToWindowNumber());
60
61 this->sign.MarkDirty();
62}
63
64Station::Station(StationID index, TileIndex tile) :
65 SpecializedStation<Station, false>(index, tile),
66 bus_station(INVALID_TILE, 0, 0),
67 truck_station(INVALID_TILE, 0, 0),
68 ship_station(INVALID_TILE, 0, 0),
69 indtype(IT_INVALID),
70 time_since_load(255),
71 time_since_unload(255),
72 last_vehicle_type(VehicleType::Invalid)
73{
74 /* this->random_bits is set in Station::AddFacility() */
75}
76
85{
86 if (CleaningPool()) {
87 for (GoodsEntry &ge : this->goods) {
88 if (!ge.HasData()) continue;
89 ge.GetData().cargo.OnCleanPool();
90 }
91 return;
92 }
93
94 while (!this->loading_vehicles.empty()) {
95 this->loading_vehicles.front()->LeaveStation();
96 }
97
98 for (Aircraft *a : Aircraft::Iterate()) {
99 if (!a->IsNormalAircraft()) continue;
100 if (a->targetairport == this->index) a->targetairport = StationID::Invalid();
101 }
102
103 for (CargoType cargo : EnumRange(NUM_CARGO)) {
104 LinkGraph *lg = LinkGraph::GetIfValid(this->goods[cargo].link_graph);
105 if (lg == nullptr) continue;
106
107 for (NodeID node = 0; node < lg->Size(); ++node) {
108 Station *st = Station::Get((*lg)[node].station);
109 if (!st->goods[cargo].HasData()) continue;
110 st->goods[cargo].GetData().flows.erase(this->index);
111 if ((*lg)[node].HasEdgeTo(this->goods[cargo].node) && (*lg)[node][this->goods[cargo].node].LastUpdate() != EconomyTime::INVALID_DATE) {
112 st->goods[cargo].GetData().flows.DeleteFlows(this->index);
113 RerouteCargo(st, cargo, this->index, st->index);
114 }
115 }
116 lg->RemoveNode(this->goods[cargo].node);
117 if (lg->Size() == 0) {
118 LinkGraphSchedule::instance.Dequeue(lg);
119 delete lg;
120 }
121 }
122
123 for (Vehicle *v : Vehicle::Iterate()) {
124 /* Forget about this station if this station is removed */
125 if (v->last_station_visited == this->index) {
126 v->last_station_visited = StationID::Invalid();
127 }
128 if (v->last_loading_station == this->index) {
129 v->last_loading_station = StationID::Invalid();
130 }
131 }
132
133 /* Remove station from industries and towns that reference it. */
135
136 /* Clear the persistent storage. */
137 delete this->airport.psa;
138
139 if (this->owner == OWNER_NONE) {
140 /* Invalidate all in case of oil rigs. */
141 InvalidateWindowClassesData(WindowClass::StationList, 0);
142 } else {
143 InvalidateWindowData(WindowClass::StationList, this->owner, 0);
144 }
145
146 CloseWindowById(WindowClass::StationView, index);
147
148 /* Now delete all orders that go to the station */
149 RemoveOrderFromAllVehicles(OT_GOTO_STATION, this->index);
150
151 /* Remove all news items */
153
154 for (GoodsEntry &ge : this->goods) {
155 if (!ge.HasData()) continue;
156 ge.GetData().cargo.Truncate();
157 }
158
160
161 _station_kdtree.Remove(this->index);
162 if (this->sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeStation(this->index));
163}
164
165
171void BaseStation::PostDestructor([[maybe_unused]] size_t index)
172{
173 InvalidateWindowData(WindowClass::JoinStation, 0, 0);
174}
175
176bool BaseStation::SetRoadStopTileData(TileIndex tile, uint8_t data, bool animation)
177{
178 for (RoadStopTileData &tile_data : this->custom_roadstop_tile_data) {
179 if (tile_data.tile == tile) {
180 uint8_t &v = animation ? tile_data.animation_frame : tile_data.random_bits;
181 if (v == data) return false;
182 v = data;
183 return true;
184 }
185 }
186 RoadStopTileData tile_data;
187 tile_data.tile = tile;
188 tile_data.animation_frame = animation ? data : 0;
189 tile_data.random_bits = animation ? 0 : data;
190 this->custom_roadstop_tile_data.push_back(tile_data);
191 return data != 0;
192}
193
194void BaseStation::RemoveRoadStopTileData(TileIndex tile)
195{
196 for (RoadStopTileData &tile_data : this->custom_roadstop_tile_data) {
197 if (tile_data.tile == tile) {
198 tile_data = this->custom_roadstop_tile_data.back();
199 this->custom_roadstop_tile_data.pop_back();
200 return;
201 }
202 }
203}
204
210RoadStop *Station::GetPrimaryRoadStop(const RoadVehicle *v) const
211{
212 RoadStop *rs = this->GetPrimaryRoadStop(v->IsBus() ? RoadStopType::Bus : RoadStopType::Truck);
213
214 for (; rs != nullptr; rs = rs->next) {
215 /* The vehicle cannot go to this roadstop (different roadtype) */
216 if (!HasTileAnyRoadType(rs->xy, v->compatible_roadtypes)) continue;
217 /* The vehicle is articulated and can therefore not go to a standard road stop. */
218 if (IsBayRoadStopTile(rs->xy) && v->HasArticulatedPart()) continue;
219
220 /* The vehicle can actually go to this road stop. So, return it! */
221 break;
222 }
223
224 return rs;
225}
226
233void Station::AddFacility(StationFacility new_facility_bit, TileIndex facil_xy)
234{
235 if (this->facilities.None()) {
236 this->MoveSign(facil_xy);
237 this->random_bits = Random();
238 }
239 this->facilities.Set(new_facility_bit);
240 this->owner = _current_company;
242 SetWindowClassesDirty(WindowClass::VehicleOrders);
243}
244
250void Station::MarkTilesDirty(bool cargo_change) const
251{
252 if (this->train_station.IsEmpty()) return;
253
254 /* cargo_change is set if we're refreshing the tiles due to cargo moving
255 * around. */
256 if (cargo_change) {
257 /* Don't waste time updating if there are no custom station graphics
258 * that might change. Even if there are custom graphics, they might
259 * not change. Unfortunately we have no way of telling. */
260 if (this->speclist.empty()) return;
261 }
262
263 for (TileIndex tile : this->train_station) {
264 if (this->TileBelongsToRailStation(tile)) {
266 }
267 }
268}
269
270/* virtual */ uint Station::GetPlatformLength(TileIndex tile) const
271{
272 assert(this->TileBelongsToRailStation(tile));
273
275
276 TileIndex t = tile;
277 uint len = 0;
278 do {
279 t -= delta;
280 len++;
281 } while (IsCompatibleTrainStationTile(t, tile));
282
283 t = tile;
284 do {
285 t += delta;
286 len++;
287 } while (IsCompatibleTrainStationTile(t, tile));
288
289 return len - 1;
290}
291
292/* virtual */ uint Station::GetPlatformLength(TileIndex tile, DiagDirection dir) const
293{
294 TileIndex start_tile = tile;
295 uint length = 0;
296 assert(IsRailStationTile(tile));
297 assert(dir < DiagDirection::End);
298
299 do {
300 length++;
301 tile += TileOffsByDiagDir(dir);
302 } while (IsCompatibleTrainStationTile(tile, start_tile));
303
304 return length;
305}
306
314static uint GetTileCatchmentRadius(TileIndex tile, const Station *st)
315{
316 assert(IsTileType(tile, TileType::Station));
317
318 if (_settings_game.station.modified_catchment) {
319 switch (GetStationType(tile)) {
320 case StationType::Rail: return CA_TRAIN;
322 case StationType::Airport: return st->airport.GetSpec()->catchment;
323 case StationType::Truck: return CA_TRUCK;
324 case StationType::Bus: return CA_BUS;
325 case StationType::Dock: return CA_DOCK;
326
327 default: NOT_REACHED();
331 }
332 } else {
333 switch (GetStationType(tile)) {
334 default: return CA_UNMODIFIED;
338 }
339 }
340}
341
347{
348 uint ret = CA_NONE;
349
350 if (_settings_game.station.modified_catchment) {
351 if (this->bus_stops != nullptr) ret = std::max<uint>(ret, CA_BUS);
352 if (this->truck_stops != nullptr) ret = std::max<uint>(ret, CA_TRUCK);
353 if (!this->train_station.IsEmpty()) ret = std::max<uint>(ret, CA_TRAIN);
354 if (!this->ship_station.IsEmpty()) ret = std::max<uint>(ret, CA_DOCK);
355 if (!this->airport.IsEmpty()) ret = std::max<uint>(ret, this->airport.GetSpec()->catchment);
356 } else {
357 if (this->bus_stops != nullptr || this->truck_stops != nullptr || !this->train_station.IsEmpty() || !this->ship_station.IsEmpty() || !this->airport.IsEmpty()) {
358 ret = CA_UNMODIFIED;
359 }
360 }
361
362 return ret;
363}
364
372{
373 /* Using DistanceMax to get about the same order as with previously used SpiralTileSequence. */
374 uint distance = DistanceMax(this->xy, tile);
375
376 /* Don't check further if this industry is already in the list but update the distance if it's closer */
377 auto pos = std::ranges::find(this->industries_near, ind, &IndustryListEntry::industry);
378 if (pos != this->industries_near.end()) {
379 if (pos->distance > distance) {
380 auto node = this->industries_near.extract(pos);
381 node.value().distance = distance;
382 this->industries_near.insert(std::move(node));
383 }
384 return;
385 }
386
387 /* Include only industries that can accept cargo */
388 if (!ind->IsCargoAccepted()) return;
389
390 this->industries_near.insert(IndustryListEntry{distance, ind});
391}
392
398{
399 auto pos = std::ranges::find(this->industries_near, ind, &IndustryListEntry::industry);
400 if (pos != this->industries_near.end()) {
401 this->industries_near.erase(pos);
402 }
403}
404
405
410{
411 FlatSet<TownID> towns;
412 FlatSet<IndustryID> industries;
413
414 for (const auto &tile : this->catchment_tiles) {
415 TileType type = GetTileType(tile);
416 if (type == TileType::House) {
417 towns.insert(GetTownIndex(tile));
418 } else if (type == TileType::Industry) {
419 industries.insert(GetIndustryIndex(tile));
420 }
421 }
422
423 for (const TownID &townid : towns) { Town::Get(townid)->stations_near.erase(this); }
424 for (const IndustryID &industryid : industries) { Industry::Get(industryid)->stations_near.erase(this); }
425}
426
435{
437 for (TileIndex tile = it; tile != INVALID_TILE; tile = ++it) {
438 if (IsTileType(tile, TileType::House) && GetTownIndex(tile) == t) return true;
439 }
440 return false;
441}
442
448void Station::RecomputeCatchment(bool no_clear_nearby_lists)
449{
450 this->industries_near.clear();
451 if (!no_clear_nearby_lists) this->RemoveFromAllNearbyLists();
452
453 if (this->spread.IsEmpty()) {
454 this->catchment_tiles.Reset();
455 return;
456 }
457
458 if (!_settings_game.station.serve_neutral_industries && this->industry != nullptr) {
459 /* Station is associated with an industry, so we only need to deliver to that industry. */
460 this->catchment_tiles.Initialize(this->industry->location);
461 for (TileIndex tile : this->industry->location) {
462 if (IsTileType(tile, TileType::Industry) && GetIndustryIndex(tile) == this->industry->index) {
463 this->catchment_tiles.SetTile(tile);
464 }
465 }
466 /* The industry's stations_near may have been computed before its neutral station was built so clear and re-add here. */
467 for (Station *st : this->industry->stations_near) {
469 }
470 this->industry->stations_near.clear();
471 this->industry->stations_near.insert(this);
472 this->industries_near.insert(IndustryListEntry{0, this->industry});
473 return;
474 }
475
476 this->catchment_tiles.Initialize(TileArea{this->spread}.Expand(this->GetCatchmentRadius()));
477
478 /* Loop finding all station tiles */
479 for (TileIndex tile : this->spread) {
480 if (!IsTileType(tile, TileType::Station) || GetStationIndex(tile) != this->index) continue;
481
482 uint r = GetTileCatchmentRadius(tile, this);
483 if (r == CA_NONE) continue;
484
485 /* This tile sub-loop doesn't need to test any tiles, they are simply added to the catchment set. */
486 TileArea ta2 = TileArea(tile, 1, 1).Expand(r);
487 for (TileIndex tile2 : ta2) this->catchment_tiles.SetTile(tile2);
488 }
489
490 /* Search catchment tiles for towns and industries */
492 for (TileIndex tile = it; tile != INVALID_TILE; tile = ++it) {
493 if (IsTileType(tile, TileType::House)) {
494 Town *t = Town::GetByTile(tile);
495 t->stations_near.insert(this);
496 }
497 if (IsTileType(tile, TileType::Industry)) {
498 Industry *i = Industry::GetByTile(tile);
499
500 /* Ignore industry if it has a neutral station. It already can't be this station. */
501 if (!_settings_game.station.serve_neutral_industries && i->neutral_station != nullptr) continue;
502
503 i->stations_near.insert(this);
504
505 /* Add if we can deliver to this industry as well */
506 this->AddIndustryToDeliver(i, tile);
507 }
508 }
509}
510
516{
517 for (Town *t : Town::Iterate()) { t->stations_near.clear(); }
518 for (Industry *i : Industry::Iterate()) { i->stations_near.clear(); }
519 for (Station *st : Station::Iterate()) { st->RecomputeCatchment(true); }
520}
521
529{
530 /* Check for incorrect width / length. */
531 if (new_area.w == 0 || new_area.h == 0) return CMD_ERROR;
532
533 /* Check if the first and last tile are valid. */
534 if (!IsValidTile(new_area.tile) || TileAddWrap(new_area.tile, new_area.w - 1, new_area.h - 1) == INVALID_TILE) return CMD_ERROR;
535
536 area.Add(new_area);
537
538 if (area.w > _settings_game.station.station_spread || area.h > _settings_game.station.station_spread) {
539 return CommandCost(STR_ERROR_STATION_TOO_SPREAD_OUT);
540 }
541
542 return CommandCost();
543}
544
550Money AirportMaintenanceCost(Owner owner)
551{
552 Money total_cost = 0;
553
554 for (const Station *st : Station::Iterate()) {
555 if (st->owner == owner && st->facilities.Test(StationFacility::Airport)) {
556 total_cost += _price[Price::InfrastructureAirport] * st->airport.GetSpec()->maintenance_cost;
557 }
558 }
559 /* 3 bits fraction for the maintenance cost factor. */
560 return total_cost >> 3;
561}
562
563bool StationCompare::operator() (const Station *lhs, const Station *rhs) const
564{
565 return lhs->index < rhs->index;
566}
Base for aircraft.
static constexpr CargoType NUM_CARGO
Maximum number of cargo types in a game.
Definition cargo_type.h:75
CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:22
Iterator to iterate over all tiles belonging to a bitmaptilearea.
Definition bitmap_type.h:94
Common return value for all commands.
Iterate a range of enum values.
Flat set implementation that uses a sorted vector for storage.
std::pair< const_iterator, bool > insert(const Tkey &key)
Insert a key into the set, if it does not already exist.
static LinkGraphSchedule instance
Static instance of LinkGraphSchedule.
A connected component of a link graph.
Definition linkgraph.h:37
NodeID Size() const
Get the current size of the component.
Definition linkgraph.h:234
void RemoveNode(NodeID id)
Remove a node from the link graph by overwriting it with the last node.
static Date date
Current date in days (day counter).
static constexpr TimerGame< struct Economy >::Date INVALID_DATE
Functions related to commands.
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
Definition of stuff that is very close to a company, like the company struct itself.
CompanyID _current_company
Company currently doing an action.
Functions related to companies.
static constexpr Owner OWNER_NONE
The tile has no ownership.
DiagDirection
Enumeration for diagonal directions.
@ End
Used for iterations.
Prices _price
Prices and also the fractional part.
Definition economy.cpp:107
@ InfrastructureAirport
Airports maintenance cost.
Flat set container implementation.
void MarkTilesDirty(bool cargo_change) const
Marks the tiles of the station as dirty.
Definition station.cpp:250
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
Base of all industries.
IndustryID GetIndustryIndex(Tile t)
Get the industry ID of the given tile.
Declaration of link graph classes used for cargo distribution.
Declaration of link graph schedule used for cargo distribution.
uint DistanceMax(TileIndex t0, TileIndex t1)
Gets the biggest distance component (x or y) between the two given tiles.
Definition map.cpp:201
TileIndex TileAddWrap(TileIndex tile, int addx, int addy)
This function checks if we add addx/addy to tile, if we do wrap around the edges.
Definition map.cpp:120
TileIndexDiff TileOffsByAxis(Axis axis)
Convert an Axis to a TileIndexDiff.
Definition map_func.h:559
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:574
int32_t TileIndexDiff
An offset value between two tiles.
Definition map_type.h:23
Functions related to news.
void DeleteStationNews(StationID sid)
Remove news regarding given station so there are no 'unknown station now accepts Mail' or 'First trai...
void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination, bool hangar)
Removes an order from all vehicles.
Some methods of Pool are placed here in order to reduce compilation time and binary size.
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don't get linker errors.
Pseudo random number generator.
bool HasTileAnyRoadType(Tile t, RoadTypes rts)
Check if a tile has one of the specified road types.
Definition road_map.h:232
Base class for roadstops.
Road vehicle states.
A number of safeguards to prevent using unsafe methods.
@ Invalid
broken savegame (used internally)
Definition saveload.h:435
@ RoadStopTileData
Saveload version: 340, GitHub pull request: 12883 Move storage of road stop tile data,...
Definition saveload.h:391
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
CommandCost CheckStationSpread(TileArea area, const TileArea &new_area)
Check if adding a new area to a station will exceed the maximum station spread.
Definition station.cpp:528
StationPool _station_pool("Station")
The pool of stations.
Money AirportMaintenanceCost(Owner owner)
Calculates the maintenance cost of all airports of a company.
Definition station.cpp:550
static uint GetTileCatchmentRadius(TileIndex tile, const Station *st)
Get the catchment size of an individual station tile.
Definition station.cpp:314
Base classes/functions for stations.
void RerouteCargo(Station *st, CargoType cargo, StationID avoid, StationID avoid2)
Reroute cargo of type c at station st or in any vehicles unloading there.
Declarations for accessing the k-d tree of stations.
StationType GetStationType(Tile t)
Get the station type of this tile.
Definition station_map.h:44
bool IsBayRoadStopTile(Tile t)
Is tile t a bay (non-drive through) road stop station?
bool IsCompatibleTrainStationTile(Tile test_tile, Tile station_tile)
Check if a tile is a valid continuation to a railstation tile.
bool IsRailStationTile(Tile t)
Is this tile a station tile and a rail station?
StationID GetStationIndex(Tile t)
Get StationID from a tile.
Definition station_map.h:28
Axis GetRailStationAxis(Tile t)
Get the rail direction of a rail station.
static constexpr uint CA_TRAIN
Catchment for train stations with "modified catchment" enabled.
@ Bus
A standard stop for buses.
@ Truck
A standard stop for trucks.
StationFacility
The facilities a station might be having.
@ Airport
Station with an airport.
static constexpr uint CA_NONE
Catchment when the station has no facilities.
@ Dock
Ship port.
@ Rail
Railways/train station.
@ Bus
Road stop for busses.
@ Truck
Road stop for trucks.
@ RailWaypoint
Waypoint for trains.
@ Buoy
Waypoint for ships.
@ RoadWaypoint
Waypoint for trucks and busses.
@ Oilrig
Heliport on an oil rig.
@ Airport
Airports and heliports, excluding the ones on oil rigs.
static constexpr uint CA_DOCK
Catchment for docks with "modified catchment" enabled.
static constexpr uint CA_BUS
Catchment for bus stops with "modified catchment" enabled.
static constexpr uint CA_UNMODIFIED
Catchment for all stations with "modified catchment" disabled.
static constexpr uint CA_TRUCK
Catchment for truck stops with "modified catchment" enabled.
Definition of base types and functions in a cross-platform compatible way.
Aircraft, helicopters, rotors and their shadows belong to this class.
Definition aircraft.h:75
uint8_t catchment
catchment area of this airport
const AirportSpec * GetSpec() const
Get the AirportSpec that from the airport type of this airport.
TileIndex xy
Base tile of the station.
std::vector< SpecMapping< StationSpec > > speclist
List of rail station specs of this station.
StationFacilities facilities
The facilities that this station has.
virtual ~BaseStation()
Ensure the destructor of the sub classes are called as well.
Definition station.cpp:52
TileArea train_station
Tile area the train 'station' part covers.
Owner owner
The owner of this station.
static void PostDestructor(size_t index)
Invalidating of the JoinStation window has to be done after removing item from the pool.
Definition station.cpp:171
uint16_t random_bits
Random bits assigned to this station.
TrackedViewportSign sign
NOSAVE: Dimensions of sign.
std::vector< RoadStopTileData > custom_roadstop_tile_data
List of custom road stop tile data.
TimerGameCalendar::Date build_date
Date of construction.
TileArea spread
NOSAVE: Station spread tile area.
static void InvalidateAllFrom(Source src)
Invalidates (sets source_id to INVALID_SOURCE) all cargo packets from given source.
Stores station stats for a single cargo.
Defines the internal data of a functional industry.
Definition industry.h:64
bool IsCargoAccepted() const
Test if this industry accepts any cargo.
Definition industry.h:225
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition industry.h:253
Station * neutral_station
Associated neutral station.
Definition industry.h:110
StationList stations_near
NOSAVE: List of nearby stations.
Definition industry.h:125
uint16_t w
The width of the area.
void Add(TileIndex to_add)
Add a single tile to a tile area; enlarge if needed.
Definition tilearea.cpp:43
TileIndex tile
The base tile of the area.
uint16_t h
The height of the area.
OrthogonalTileArea & Expand(int rad)
Expand a tile area by rad tiles in each direction, keeping within map bounds.
Definition tilearea.cpp:123
static Pool::IterateWrapper< Vehicle > Iterate(size_t from=0)
static Town * Get(auto index)
static LinkGraph * GetIfValid(auto index)
A Stop for a Road Vehicle.
RoadStop * next
Next stop of the given type at this station.
TileIndex xy
Position on the map.
Buses, trucks and trams belong to this class.
Definition roadveh.h:105
RoadTypes compatible_roadtypes
NOSAVE: Roadtypes this consist is powered on.
Definition roadveh.h:117
bool IsBus() const
Check whether a roadvehicle is a bus.
Class defining several overloaded accessors so we don't have to cast base stations that often.
static Pool::IterateWrapper< Station > Iterate(size_t from=0)
static Station * Get(auto index)
Station data structure.
uint GetPlatformLength(TileIndex tile, DiagDirection dir) const override
Determines the REMAINING length of a platform, starting at (and including) the given tile.
Definition station.cpp:292
~Station() override
Clean up a station by clearing vehicle orders, invalidating windows and removing link stats.
Definition station.cpp:84
RoadStop * bus_stops
All the road stops.
bool CatchmentCoversTown(TownID t) const
Test if the given town ID is covered by our catchment area.
Definition station.cpp:434
TileArea ship_station
Tile area the ship 'station' part covers.
IndustryList industries_near
Cached list of industries near the station that can accept cargo,.
Industry * industry
NOSAVE: Associated industry for neutral stations. (Rebuilt on load from Industry->st).
void MoveSign(TileIndex new_xy) override
Move the station main coordinate somewhere else.
static void RecomputeCatchmentForAll()
Recomputes catchment of all stations.
Definition station.cpp:515
std::array< GoodsEntry, NUM_CARGO > goods
Goods at this station.
void RemoveFromAllNearbyLists()
Remove this station from the nearby stations lists of nearby towns and industries.
Definition station.cpp:409
bool TileBelongsToRailStation(TileIndex tile) const override
Check whether a specific tile belongs to this station.
BitmapTileArea catchment_tiles
NOSAVE: Set of individual tiles covered by catchment area.
void RecomputeCatchment(bool no_clear_nearby_lists=false)
Recompute tiles covered in our catchment area.
Definition station.cpp:448
uint GetCatchmentRadius() const
Determines the catchment radius of the station.
Definition station.cpp:346
Airport airport
Tile area the airport covers.
void AddIndustryToDeliver(Industry *ind, TileIndex tile)
Add nearby industry to station's industries_near list if it accepts cargo.
Definition station.cpp:371
void RemoveIndustryToDeliver(Industry *ind)
Remove nearby industry from station's industries_near list.
Definition station.cpp:397
RoadStop * truck_stops
All the truck stops.
void AddFacility(StationFacility new_facility_bit, TileIndex facil_xy)
Called when new facility is built on the station.
Definition station.cpp:233
Town data structure.
Definition town.h:64
StationList stations_near
NOSAVE: List of nearby stations.
Definition town.h:189
The information about a vehicle list.
Definition vehiclelist.h:32
Vehicle data structure.
bool HasArticulatedPart() const
Check if an engine has an articulated part.
static bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
bool IsValidTile(Tile tile)
Checks if a tile is valid.
Definition tile_map.h:161
static TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition tile_map.h:96
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > > TileIndex
The index/ID of a Tile.
Definition tile_type.h:92
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:100
TileType
The different types of tiles.
Definition tile_type.h:48
@ Station
A tile of a station or airport.
Definition tile_type.h:54
@ Industry
Part of an industry.
Definition tile_type.h:57
@ House
A house by a town.
Definition tile_type.h:52
OrthogonalTileArea TileArea
Shorthand for the much more common orthogonal tile area.
Base of the town class.
TownID GetTownIndex(Tile t)
Get the index of which town this house/street is attached to.
Definition town_map.h:23
VehicleType
Available vehicle types.
@ Ship
Ship vehicle type.
@ Aircraft
Aircraft vehicle type.
@ Road
Road vehicle type.
@ Train
Train vehicle type.
Functions and type for generating vehicle lists.
@ Station
Index is the station.
Definition vehiclelist.h:25
Functions related to (drawing on) viewports.
Declarations for accessing the k-d tree of viewports.
void CloseWindowById(WindowClass cls, WindowNumber number, bool force, int data)
Close a window by its class and window number (if it is open).
Definition window.cpp:1204
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting).
Definition window.cpp:3242
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
Definition window.cpp:3334
void InvalidateWindowClassesData(WindowClass cls, int data, bool gui_scope)
Mark window data of all windows of a given class as invalid (in need of re-computing) Note that by de...
Definition window.cpp:3352