OpenTTD
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 <http://www.gnu.org/licenses/>.
6  */
7 
10 #include "stdafx.h"
11 #include "company_func.h"
12 #include "company_base.h"
13 #include "roadveh.h"
14 #include "viewport_func.h"
15 #include "viewport_kdtree.h"
16 #include "date_func.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 
36 StationPool _station_pool("Station");
38 
39 
40 StationKdtree _station_kdtree(Kdtree_StationXYFunc);
41 
42 void 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 
52 BaseStation::~BaseStation()
53 {
54  free(this->name);
55  free(this->speclist);
56 
57  if (CleaningPool()) return;
58 
59  DeleteWindowById(WC_TRAINS_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_TRAIN, this->owner, this->index).Pack());
60  DeleteWindowById(WC_ROADVEH_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_ROAD, this->owner, this->index).Pack());
61  DeleteWindowById(WC_SHIPS_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_SHIP, this->owner, this->index).Pack());
62  DeleteWindowById(WC_AIRCRAFT_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_AIRCRAFT, this->owner, this->index).Pack());
63 
64  this->sign.MarkDirty();
65 }
66 
67 Station::Station(TileIndex tile) :
68  SpecializedStation<Station, false>(tile),
69  bus_station(INVALID_TILE, 0, 0),
70  truck_station(INVALID_TILE, 0, 0),
71  ship_station(INVALID_TILE, 0, 0),
72  indtype(IT_INVALID),
73  time_since_load(255),
74  time_since_unload(255),
75  last_vehicle_type(VEH_INVALID)
76 {
77  /* this->random_bits is set in Station::AddFacility() */
78 }
79 
88 {
89  if (CleaningPool()) {
90  for (CargoID c = 0; c < NUM_CARGO; c++) {
91  this->goods[c].cargo.OnCleanPool();
92  }
93  return;
94  }
95 
96  while (!this->loading_vehicles.empty()) {
97  this->loading_vehicles.front()->LeaveStation();
98  }
99 
100  for (Aircraft *a : Aircraft::Iterate()) {
101  if (!a->IsNormalAircraft()) continue;
102  if (a->targetairport == this->index) a->targetairport = INVALID_STATION;
103  }
104 
105  for (CargoID c = 0; c < NUM_CARGO; ++c) {
106  LinkGraph *lg = LinkGraph::GetIfValid(this->goods[c].link_graph);
107  if (lg == nullptr) continue;
108 
109  for (NodeID node = 0; node < lg->Size(); ++node) {
110  Station *st = Station::Get((*lg)[node].Station());
111  st->goods[c].flows.erase(this->index);
112  if ((*lg)[node][this->goods[c].node].LastUpdate() != INVALID_DATE) {
113  st->goods[c].flows.DeleteFlows(this->index);
114  RerouteCargo(st, c, this->index, st->index);
115  }
116  }
117  lg->RemoveNode(this->goods[c].node);
118  if (lg->Size() == 0) {
120  delete lg;
121  }
122  }
123 
124  for (Vehicle *v : Vehicle::Iterate()) {
125  /* Forget about this station if this station is removed */
126  if (v->last_station_visited == this->index) {
127  v->last_station_visited = INVALID_STATION;
128  }
129  if (v->last_loading_station == this->index) {
130  v->last_loading_station = INVALID_STATION;
131  }
132  }
133 
134  /* Remove station from industries and towns that reference it. */
135  this->RemoveFromAllNearbyLists();
136 
137  /* Clear the persistent storage. */
138  delete this->airport.psa;
139 
140  if (this->owner == OWNER_NONE) {
141  /* Invalidate all in case of oil rigs. */
143  } else {
144  InvalidateWindowData(WC_STATION_LIST, this->owner, 0);
145  }
146 
148 
149  /* Now delete all orders that go to the station */
150  RemoveOrderFromAllVehicles(OT_GOTO_STATION, this->index);
151 
152  /* Remove all news items */
153  DeleteStationNews(this->index);
154 
155  for (CargoID c = 0; c < NUM_CARGO; c++) {
156  this->goods[c].cargo.Truncate();
157  }
158 
159  CargoPacket::InvalidateAllFrom(this->index);
160 
161  _station_kdtree.Remove(this->index);
162  if (this->sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeStation(this->index));
163 }
164 
165 
171 void BaseStation::PostDestructor(size_t index)
172 {
174 }
175 
181 RoadStop *Station::GetPrimaryRoadStop(const RoadVehicle *v) const
182 {
183  RoadStop *rs = this->GetPrimaryRoadStop(v->IsBus() ? ROADSTOP_BUS : ROADSTOP_TRUCK);
184 
185  for (; rs != nullptr; rs = rs->next) {
186  /* The vehicle cannot go to this roadstop (different roadtype) */
187  if (!HasTileAnyRoadType(rs->xy, v->compatible_roadtypes)) continue;
188  /* The vehicle is articulated and can therefore not go to a standard road stop. */
189  if (IsStandardRoadStopTile(rs->xy) && v->HasArticulatedPart()) continue;
190 
191  /* The vehicle can actually go to this road stop. So, return it! */
192  break;
193  }
194 
195  return rs;
196 }
197 
202 void Station::AddFacility(StationFacility new_facility_bit, TileIndex facil_xy)
203 {
204  if (this->facilities == FACIL_NONE) {
205  this->MoveSign(facil_xy);
206  this->random_bits = Random();
207  }
208  this->facilities |= new_facility_bit;
209  this->owner = _current_company;
210  this->build_date = _date;
211 }
212 
218 void Station::MarkTilesDirty(bool cargo_change) const
219 {
220  TileIndex tile = this->train_station.tile;
221  int w, h;
222 
223  if (tile == INVALID_TILE) return;
224 
225  /* cargo_change is set if we're refreshing the tiles due to cargo moving
226  * around. */
227  if (cargo_change) {
228  /* Don't waste time updating if there are no custom station graphics
229  * that might change. Even if there are custom graphics, they might
230  * not change. Unfortunately we have no way of telling. */
231  if (this->num_specs == 0) return;
232  }
233 
234  for (h = 0; h < train_station.h; h++) {
235  for (w = 0; w < train_station.w; w++) {
236  if (this->TileBelongsToRailStation(tile)) {
237  MarkTileDirtyByTile(tile);
238  }
239  tile += TileDiffXY(1, 0);
240  }
241  tile += TileDiffXY(-w, 1);
242  }
243 }
244 
245 /* virtual */ uint Station::GetPlatformLength(TileIndex tile) const
246 {
247  assert(this->TileBelongsToRailStation(tile));
248 
249  TileIndexDiff delta = (GetRailStationAxis(tile) == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
250 
251  TileIndex t = tile;
252  uint len = 0;
253  do {
254  t -= delta;
255  len++;
256  } while (IsCompatibleTrainStationTile(t, tile));
257 
258  t = tile;
259  do {
260  t += delta;
261  len++;
262  } while (IsCompatibleTrainStationTile(t, tile));
263 
264  return len - 1;
265 }
266 
267 /* virtual */ uint Station::GetPlatformLength(TileIndex tile, DiagDirection dir) const
268 {
269  TileIndex start_tile = tile;
270  uint length = 0;
271  assert(IsRailStationTile(tile));
272  assert(dir < DIAGDIR_END);
273 
274  do {
275  length++;
276  tile += TileOffsByDiagDir(dir);
277  } while (IsCompatibleTrainStationTile(tile, start_tile));
278 
279  return length;
280 }
281 
289 static uint GetTileCatchmentRadius(TileIndex tile, const Station *st)
290 {
291  assert(IsTileType(tile, MP_STATION));
292 
294  switch (GetStationType(tile)) {
295  case STATION_RAIL: return CA_TRAIN;
296  case STATION_OILRIG: return CA_UNMODIFIED;
297  case STATION_AIRPORT: return st->airport.GetSpec()->catchment;
298  case STATION_TRUCK: return CA_TRUCK;
299  case STATION_BUS: return CA_BUS;
300  case STATION_DOCK: return CA_DOCK;
301 
302  default: NOT_REACHED();
303  case STATION_BUOY:
304  case STATION_WAYPOINT: return CA_NONE;
305  }
306  } else {
307  switch (GetStationType(tile)) {
308  default: return CA_UNMODIFIED;
309  case STATION_BUOY:
310  case STATION_WAYPOINT: return CA_NONE;
311  }
312  }
313 }
314 
320 {
321  uint ret = CA_NONE;
322 
324  if (this->bus_stops != nullptr) ret = max<uint>(ret, CA_BUS);
325  if (this->truck_stops != nullptr) ret = max<uint>(ret, CA_TRUCK);
326  if (this->train_station.tile != INVALID_TILE) ret = max<uint>(ret, CA_TRAIN);
327  if (this->ship_station.tile != INVALID_TILE) ret = max<uint>(ret, CA_DOCK);
328  if (this->airport.tile != INVALID_TILE) ret = max<uint>(ret, this->airport.GetSpec()->catchment);
329  } else {
330  if (this->bus_stops != nullptr || this->truck_stops != nullptr || this->train_station.tile != INVALID_TILE || this->ship_station.tile != INVALID_TILE || this->airport.tile != INVALID_TILE) {
331  ret = CA_UNMODIFIED;
332  }
333  }
334 
335  return ret;
336 }
337 
343 {
344  assert(!this->rect.IsEmpty());
345 
346  /* Compute acceptance rectangle */
347  int catchment_radius = this->GetCatchmentRadius();
348 
349  Rect ret = {
350  max<int>(this->rect.left - catchment_radius, 0),
351  max<int>(this->rect.top - catchment_radius, 0),
352  min<int>(this->rect.right + catchment_radius, MapMaxX()),
353  min<int>(this->rect.bottom + catchment_radius, MapMaxY())
354  };
355 
356  return ret;
357 }
358 
364 static void AddIndustryToDeliver(Industry *ind, Station *st)
365 {
366  /* Don't check further if this industry is already in the list */
367  if (st->industries_near.find(ind) != st->industries_near.end()) return;
368 
369  /* Include only industries that can accept cargo */
370  uint cargo_index;
371  for (cargo_index = 0; cargo_index < lengthof(ind->accepts_cargo); cargo_index++) {
372  if (ind->accepts_cargo[cargo_index] != CT_INVALID) break;
373  }
374  if (cargo_index >= lengthof(ind->accepts_cargo)) return;
375 
376  st->industries_near.insert(ind);
377 }
378 
383 {
384  for (Town *t : Town::Iterate()) { t->stations_near.erase(this); }
385  for (Industry *i : Industry::Iterate()) { i->stations_near.erase(this); }
386 }
387 
395 bool Station::CatchmentCoversTown(TownID t) const
396 {
397  BitmapTileIterator it(this->catchment_tiles);
398  for (TileIndex tile = it; tile != INVALID_TILE; tile = ++it) {
399  if (IsTileType(tile, MP_HOUSE) && GetTownIndex(tile) == t) return true;
400  }
401  return false;
402 }
403 
409 {
410  this->industries_near.clear();
411  this->RemoveFromAllNearbyLists();
412 
413  if (this->rect.IsEmpty()) {
414  this->catchment_tiles.Reset();
415  return;
416  }
417 
418  if (!_settings_game.station.serve_neutral_industries && this->industry != nullptr) {
419  /* Station is associated with an industry, so we only need to deliver to that industry. */
420  this->catchment_tiles.Initialize(this->industry->location);
421  TILE_AREA_LOOP(tile, this->industry->location) {
422  if (IsTileType(tile, MP_INDUSTRY) && GetIndustryIndex(tile) == this->industry->index) {
423  this->catchment_tiles.SetTile(tile);
424  }
425  }
426  /* The industry's stations_near may have been computed before its neutral station was built so clear and re-add here. */
427  for (Station *st : this->industry->stations_near) {
428  st->industries_near.erase(this->industry);
429  }
430  this->industry->stations_near.clear();
431  this->industry->stations_near.insert(this);
432  this->industries_near.insert(this->industry);
433  return;
434  }
435 
436  this->catchment_tiles.Initialize(GetCatchmentRect());
437 
438  /* Loop finding all station tiles */
439  TileArea ta(TileXY(this->rect.left, this->rect.top), TileXY(this->rect.right, this->rect.bottom));
440  TILE_AREA_LOOP(tile, ta) {
441  if (!IsTileType(tile, MP_STATION) || GetStationIndex(tile) != this->index) continue;
442 
443  uint r = GetTileCatchmentRadius(tile, this);
444  if (r == CA_NONE) continue;
445 
446  /* This tile sub-loop doesn't need to test any tiles, they are simply added to the catchment set. */
447  TileArea ta2 = TileArea(tile, 1, 1).Expand(r);
448  TILE_AREA_LOOP(tile2, ta2) this->catchment_tiles.SetTile(tile2);
449  }
450 
451  /* Search catchment tiles for towns and industries */
452  BitmapTileIterator it(this->catchment_tiles);
453  for (TileIndex tile = it; tile != INVALID_TILE; tile = ++it) {
454  if (IsTileType(tile, MP_HOUSE)) {
455  Town *t = Town::GetByTile(tile);
456  t->stations_near.insert(this);
457  }
458  if (IsTileType(tile, MP_INDUSTRY)) {
459  Industry *i = Industry::GetByTile(tile);
460 
461  /* Ignore industry if it has a neutral station. It already can't be this station. */
462  if (!_settings_game.station.serve_neutral_industries && i->neutral_station != nullptr) continue;
463 
464  i->stations_near.insert(this);
465 
466  /* Add if we can deliver to this industry as well */
467  AddIndustryToDeliver(i, this);
468  }
469  }
470 }
471 
477 {
478  for (Station *st : Station::Iterate()) { st->RecomputeCatchment(); }
479 }
480 
481 /************************************************************************/
482 /* StationRect implementation */
483 /************************************************************************/
484 
485 StationRect::StationRect()
486 {
487  this->MakeEmpty();
488 }
489 
490 void StationRect::MakeEmpty()
491 {
492  this->left = this->top = this->right = this->bottom = 0;
493 }
494 
504 bool StationRect::PtInExtendedRect(int x, int y, int distance) const
505 {
506  return this->left - distance <= x && x <= this->right + distance &&
507  this->top - distance <= y && y <= this->bottom + distance;
508 }
509 
510 bool StationRect::IsEmpty() const
511 {
512  return this->left == 0 || this->left > this->right || this->top > this->bottom;
513 }
514 
515 CommandCost StationRect::BeforeAddTile(TileIndex tile, StationRectMode mode)
516 {
517  int x = TileX(tile);
518  int y = TileY(tile);
519  if (this->IsEmpty()) {
520  /* we are adding the first station tile */
521  if (mode != ADD_TEST) {
522  this->left = this->right = x;
523  this->top = this->bottom = y;
524  }
525  } else if (!this->PtInExtendedRect(x, y)) {
526  /* current rect is not empty and new point is outside this rect
527  * make new spread-out rectangle */
528  Rect new_rect = {min(x, this->left), min(y, this->top), max(x, this->right), max(y, this->bottom)};
529 
530  /* check new rect dimensions against preset max */
531  int w = new_rect.right - new_rect.left + 1;
532  int h = new_rect.bottom - new_rect.top + 1;
533  if (mode != ADD_FORCE && (w > _settings_game.station.station_spread || h > _settings_game.station.station_spread)) {
534  assert(mode != ADD_TRY);
535  return_cmd_error(STR_ERROR_STATION_TOO_SPREAD_OUT);
536  }
537 
538  /* spread-out ok, return true */
539  if (mode != ADD_TEST) {
540  /* we should update the station rect */
541  *this = new_rect;
542  }
543  } else {
544  ; // new point is inside the rect, we don't need to do anything
545  }
546  return CommandCost();
547 }
548 
549 CommandCost StationRect::BeforeAddRect(TileIndex tile, int w, int h, StationRectMode mode)
550 {
551  if (mode == ADD_FORCE || (w <= _settings_game.station.station_spread && h <= _settings_game.station.station_spread)) {
552  /* Important when the old rect is completely inside the new rect, resp. the old one was empty. */
553  CommandCost ret = this->BeforeAddTile(tile, mode);
554  if (ret.Succeeded()) ret = this->BeforeAddTile(TILE_ADDXY(tile, w - 1, h - 1), mode);
555  return ret;
556  }
557  return CommandCost();
558 }
559 
569 /* static */ bool StationRect::ScanForStationTiles(StationID st_id, int left_a, int top_a, int right_a, int bottom_a)
570 {
571  TileArea ta(TileXY(left_a, top_a), TileXY(right_a, bottom_a));
572  TILE_AREA_LOOP(tile, ta) {
573  if (IsTileType(tile, MP_STATION) && GetStationIndex(tile) == st_id) return true;
574  }
575 
576  return false;
577 }
578 
579 bool StationRect::AfterRemoveTile(BaseStation *st, TileIndex tile)
580 {
581  int x = TileX(tile);
582  int y = TileY(tile);
583 
584  /* look if removed tile was on the bounding rect edge
585  * and try to reduce the rect by this edge
586  * do it until we have empty rect or nothing to do */
587  for (;;) {
588  /* check if removed tile is on rect edge */
589  bool left_edge = (x == this->left);
590  bool right_edge = (x == this->right);
591  bool top_edge = (y == this->top);
592  bool bottom_edge = (y == this->bottom);
593 
594  /* can we reduce the rect in either direction? */
595  bool reduce_x = ((left_edge || right_edge) && !ScanForStationTiles(st->index, x, this->top, x, this->bottom));
596  bool reduce_y = ((top_edge || bottom_edge) && !ScanForStationTiles(st->index, this->left, y, this->right, y));
597  if (!(reduce_x || reduce_y)) break; // nothing to do (can't reduce)
598 
599  if (reduce_x) {
600  /* reduce horizontally */
601  if (left_edge) {
602  /* move left edge right */
603  this->left = x = x + 1;
604  } else {
605  /* move right edge left */
606  this->right = x = x - 1;
607  }
608  }
609  if (reduce_y) {
610  /* reduce vertically */
611  if (top_edge) {
612  /* move top edge down */
613  this->top = y = y + 1;
614  } else {
615  /* move bottom edge up */
616  this->bottom = y = y - 1;
617  }
618  }
619 
620  if (left > right || top > bottom) {
621  /* can't continue, if the remaining rectangle is empty */
622  this->MakeEmpty();
623  return true; // empty remaining rect
624  }
625  }
626  return false; // non-empty remaining rect
627 }
628 
629 bool StationRect::AfterRemoveRect(BaseStation *st, TileArea ta)
630 {
631  assert(this->PtInExtendedRect(TileX(ta.tile), TileY(ta.tile)));
632  assert(this->PtInExtendedRect(TileX(ta.tile) + ta.w - 1, TileY(ta.tile) + ta.h - 1));
633 
634  bool empty = this->AfterRemoveTile(st, ta.tile);
635  if (ta.w != 1 || ta.h != 1) empty = empty || this->AfterRemoveTile(st, TILE_ADDXY(ta.tile, ta.w - 1, ta.h - 1));
636  return empty;
637 }
638 
639 StationRect& StationRect::operator = (const Rect &src)
640 {
641  this->left = src.left;
642  this->top = src.top;
643  this->right = src.right;
644  this->bottom = src.bottom;
645  return *this;
646 }
647 
654 {
655  Money total_cost = 0;
656 
657  for (const Station *st : Station::Iterate()) {
658  if (st->owner == owner && (st->facilities & FACIL_AIRPORT)) {
659  total_cost += _price[PR_INFRASTRUCTURE_AIRPORT] * st->airport.GetSpec()->maintenance_cost;
660  }
661  }
662  /* 3 bits fraction for the maintenance cost factor. */
663  return total_cost >> 3;
664 }
665 
666 bool StationCompare::operator() (const Station *lhs, const Station *rhs) const
667 {
668  return lhs->index < rhs->index;
669 }
Owner
Enum for all companies/owners.
Definition: company_type.h:18
Road vehicle states.
Iterator to iterate over all tiles belonging to a bitmaptilearea.
Definition: bitmap_type.h:107
static bool HasTileAnyRoadType(TileIndex t, RoadTypes rts)
Check if a tile has one of the specified road types.
Definition: road_map.h:221
StationFacility facilities
The facilities that this station has.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:79
Definition of stuff that is very close to a company, like the company struct itself.
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:302
Select station (when joining stations); Window numbers:
Definition: window_type.h:235
A standard stop for trucks.
Definition: station_type.h:46
Rect GetCatchmentRect() const
Determines catchment rectangle of this station.
Definition: station.cpp:342
The information about a vehicle list.
Definition: vehiclelist.h:29
Non-existing type of vehicle.
Definition: vehicle_type.h:35
const AirportSpec * GetSpec() const
Get the AirportSpec that from the airport type of this airport.
Definition: station_base.h:320
Base class for roadstops.
Part of an industry.
Definition: tile_type.h:49
Functions and type for generating vehicle lists.
int32 TileIndexDiff
An offset value between to tiles.
Definition: map_func.h:154
Train vehicle type.
Definition: vehicle_type.h:24
void Unqueue(LinkGraph *lg)
Remove a link graph from the execution queue.
Functions related to dates.
Used for iterations.
Ship vehicle type.
Definition: vehicle_type.h:26
Maximal number of cargo types in a game.
Definition: cargo_type.h:64
TileIndex xy
Position on the map.
Definition: roadstop_base.h:67
bool CatchmentCoversTown(TownID t) const
Test if the given town ID is covered by our catchment area.
Definition: station.cpp:395
OrthogonalTileArea & Expand(int rad)
Expand a tile area by rad tiles in each direction, keeping within map bounds.
Definition: tilearea.cpp:123
Aircraft, helicopters, rotors and their shadows belong to this class.
Definition: aircraft.h:74
The station has no facilities at all.
Definition: station_type.h:51
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:205
A standard stop for buses.
Definition: station_type.h:45
Vehicle data structure.
Definition: vehicle_base.h:210
byte station_spread
amount a station may spread
StationIDStack DeleteFlows(StationID via)
Delete all flows at a station for specific cargo and destination.
Defines the internal data of a functional industry.
Definition: industry.h:40
Tindex index
Index of this pool item.
Definition: pool_type.hpp:189
Declarations for accessing the k-d tree of stations.
void DeleteStationNews(StationID sid)
Remove news regarding given station so there are no &#39;unknown station now accepts Mail&#39; or &#39;First trai...
Definition: news_gui.cpp:916
void RecomputeCatchment()
Recompute tiles covered in our catchment area.
Definition: station.cpp:408
Base for aircraft.
void MarkTilesDirty(bool cargo_change) const
Marks the tiles of the station as dirty.
Definition: station.cpp:218
static Pool::IterateWrapper< Station > Iterate(size_t from=0)
Returns an iterable ensemble of all valid stations of type T.
Common return value for all commands.
Definition: command_type.h:23
static bool IsStandardRoadStopTile(TileIndex t)
Is tile t a standard (non-drive through) road stop station?
Definition: station_map.h:223
Catchment for bus stops with "modified catchment" enabled.
Definition: station_type.h:77
static T max(const T a, const T b)
Returns the maximum of two values.
Definition: math_func.hpp:24
static void InvalidateAllFrom(SourceType src_type, SourceID src)
Invalidates (sets source_id to INVALID_SOURCE) all cargo packets from given source.
uint16 w
The width of the area.
Definition: tilearea_type.h:18
static StationType GetStationType(TileIndex t)
Get the station type of this tile.
Definition: station_map.h:44
StationSettings station
settings related to station management
GoodsEntry goods[NUM_CARGO]
Goods at this station.
Definition: station_base.h:479
void MarkDirty(ZoomLevel maxzoom=ZOOM_LVL_MAX) const
Mark the sign dirty in all viewports.
Definition: viewport.cpp:1469
StationList stations_near
NOSAVE: List of nearby stations.
Definition: industry.h:64
Functions related to (drawing on) viewports.
Pseudo random number generator.
A connected component of a link graph.
Definition: linkgraph.h:38
Invalid cargo type.
Definition: cargo_type.h:68
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:3334
static bool IsCompatibleTrainStationTile(TileIndex test_tile, TileIndex station_tile)
Check if a tile is a valid continuation to a railstation tile.
Definition: station_map.h:378
Buses, trucks and trams belong to this class.
Definition: roadveh.h:107
byte catchment
catchment area of this airport
Some methods of Pool are placed here in order to reduce compilation time and binary size...
uint Size() const
Get the current size of the component.
Definition: linkgraph.h:497
The tile has no ownership.
Definition: company_type.h:25
static TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition: map_func.h:341
OrthogonalTileArea TileArea
Shorthand for the much more common orthogonal tile area.
Definition: tilearea_type.h:96
static bool IsTileType(TileIndex tile, TileType type)
Checks if a tile is a given tiletype.
Definition: tile_map.h:150
static void AddIndustryToDeliver(Industry *ind, Station *st)
Add nearby industry to station&#39;s industries_near list if it accepts cargo.
Definition: station.cpp:364
bool serve_neutral_industries
company stations can serve industries with attached neutral stations
static bool IsRailStationTile(TileIndex t)
Is this tile a station tile and a rail station?
Definition: station_map.h:102
IndustryList industries_near
Cached list of industries near the station that can accept cargo,.
Definition: station_base.h:482
static LinkGraphSchedule instance
Static instance of LinkGraphSchedule.
static TownID GetTownIndex(TileIndex t)
Get the index of which town this house/street is attached to.
Definition: town_map.h:22
Money AirportMaintenanceCost(Owner owner)
Calculates the maintenance cost of all airports of a company.
Definition: station.cpp:653
bool Succeeded() const
Did this command succeed?
Definition: command_type.h:150
~Station()
Clean up a station by clearing vehicle orders, invalidating windows and removing link stats...
Definition: station.cpp:87
#define TILE_AREA_LOOP(var, ta)
A loop which iterates over the tiles of a TileArea.
Definition of base types and functions in a cross-platform compatible way.
static const Date INVALID_DATE
Representation of an invalid date.
Definition: date_type.h:108
#define TILE_ADDXY(tile, x, y)
Adds a given offset to a tile.
Definition: map_func.h:258
A number of safeguards to prevent using unsafe methods.
StationList stations_near
NOSAVE: List of nearby stations.
Definition: town.h:89
Declaration of link graph schedule used for cargo distribution.
static Axis GetRailStationAxis(TileIndex t)
Get the rail direction of a rail station.
Definition: station_map.h:337
struct RoadStop * next
Next stop of the given type at this station.
Definition: roadstop_base.h:69
uint GetCatchmentRadius() const
Determines the catchment radius of the station.
Definition: station.cpp:319
Represents the covered area of e.g.
Definition: tilearea_type.h:16
static uint GetTileCatchmentRadius(TileIndex tile, const Station *st)
Get the catchment size of an individual station tile.
Definition: station.cpp:289
Road vehicle list; Window numbers:
Definition: window_type.h:307
StationSpecList * speclist
List of station specs of this station.
bool HasArticulatedPart() const
Check if an engine has an articulated part.
Definition: vehicle_base.h:899
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
Definition: viewport.cpp:1938
Station view; Window numbers:
Definition: window_type.h:338
StationRect - used to track station spread out rectangle - cheaper than scanning whole map...
CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]
16 input cargo slots
Definition: industry.h:49
Catchment for truck stops with "modified catchment" enabled.
Definition: station_type.h:78
Catchment for all stations with "modified catchment" disabled.
Definition: station_type.h:82
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:40
static T min(const T a, const T b)
Returns the minimum of two values.
Definition: math_func.hpp:40
static void RecomputeCatchmentForAll()
Recomputes catchment of all stations.
Definition: station.cpp:476
void RemoveNode(NodeID id)
Remove a node from the link graph by overwriting it with the last node.
Definition: linkgraph.cpp:119
#define return_cmd_error(errcode)
Returns from a function with a specific StringID as error.
Definition: command_func.h:33
Base class for all pools.
Definition: pool_type.hpp:82
Station list; Window numbers:
Definition: window_type.h:295
FlowStatMap flows
Planned flows through this station.
Definition: station_base.h:259
TileIndex tile
The base tile of the area.
Definition: tilearea_type.h:17
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don&#39;t get linker errors.
Definition: pool_func.hpp:224
The X axis.
void DeleteWindowById(WindowClass cls, WindowNumber number, bool force)
Delete a window by its class and window number (if it is open).
Definition: window.cpp:1162
Station with an airport.
Definition: station_type.h:55
static bool CleaningPool()
Returns current state of pool cleaning - yes or no.
Definition: pool_type.hpp:270
Catchment for docks with "modified catchment" enabled.
Definition: station_type.h:80
Functions related to companies.
Catchment when the station has no facilities.
Definition: station_type.h:76
static StationID GetStationIndex(TileIndex t)
Get StationID from a tile.
Definition: station_map.h:28
bool IsBus() const
Check whether a roadvehicle is a bus.
Definition: roadveh_cmd.cpp:79
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition: pool_type.hpp:340
bool PtInExtendedRect(int x, int y, int distance=0) const
Determines whether a given point (x, y) is within a certain distance of the station rectangle...
Definition: station.cpp:504
void Build(It begin, It end)
Clear and rebuild the tree from a new sequence of elements,.
Definition: kdtree.hpp:365
StationFacility
The facilities a station might be having.
Definition: station_type.h:50
Ships list; Window numbers:
Definition: window_type.h:313
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:78
void RerouteCargo(Station *st, CargoID c, StationID avoid, StationID avoid2)
Reroute cargo of type c at station st or in any vehicles unloading there.
bool modified_catchment
different-size catchment areas
void Remove(const T &element)
Remove a single element from the tree, if it exists.
Definition: kdtree.hpp:420
static IndustryID GetIndustryIndex(TileIndex t)
Get the industry ID of the given tile.
Definition: industry_map.h:63
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:215
Catchment for train stations with "modified catchment" enabled.
Definition: station_type.h:79
Trains list; Window numbers:
Definition: window_type.h:301
A tile of a station.
Definition: tile_type.h:46
static uint MapMaxY()
Gets the maximum Y coordinate within the map, including MP_VOID.
Definition: map_func.h:111
Town data structure.
Definition: town.h:53
Aircraft list; Window numbers:
Definition: window_type.h:319
Station * neutral_station
Associated neutral station.
Definition: industry.h:43
RoadTypes compatible_roadtypes
Roadtypes this consist is powered on.
Definition: roadveh.h:118
Functions related to commands.
A Stop for a Road Vehicle.
Definition: roadstop_base.h:22
CompanyID _current_company
Company currently doing an action.
Definition: company_cmd.cpp:45
void AddFacility(StationFacility new_facility_bit, TileIndex facil_xy)
Called when new facility is built on the station.
Definition: station.cpp:202
Owner owner
The owner of this station.
static bool ScanForStationTiles(StationID st_id, int left_a, int top_a, int right_a, int bottom_a)
Check whether station tiles of the given station id exist in the given rectangle. ...
Definition: station.cpp:569
Declaration of link graph classes used for cargo distribution.
static TileIndexDiff TileDiffXY(int x, int y)
Calculates an offset for the given coordinate(-offset).
Definition: map_func.h:179
Base of all industries.
static Pool::IterateWrapper< Aircraft > Iterate(size_t from=0)
Returns an iterable ensemble of all valid vehicles of type T.
K-dimensional tree, specialised for 2-dimensional space.
Definition: kdtree.hpp:38
Aircraft vehicle type.
Definition: vehicle_type.h:27
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: depend.cpp:129
Airport airport
Tile area the airport covers.
Definition: station_base.h:464
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
DiagDirection
Enumeration for diagonal directions.
static const TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:83
Base of the town class.
void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination, bool hangar)
Removes an order from all vehicles.
Definition: order_cmd.cpp:1801
Specification of a rectangle with absolute coordinates of all edges.
A house by a town.
Definition: tile_type.h:44
byte CargoID
Cargo slots to indicate a cargo type within a game.
Definition: cargo_type.h:20
TrackedViewportSign sign
NOSAVE: Dimensions of sign.
static uint MapMaxX()
Gets the maximum X coordinate within the map, including MP_VOID.
Definition: map_func.h:102
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition: industry.h:113
Functions related to news.
StationPool _station_pool("Station")
The pool of stations.
Base classes/functions for stations.
static Station * Get(size_t index)
Gets station with given index.
Date _date
Current date in days (day counter)
Definition: date.cpp:26
char * name
Custom name.
uint16 h
The height of the area.
Definition: tilearea_type.h:19
void RemoveFromAllNearbyLists()
Remove this station from the nearby stations lists of all towns and industries.
Definition: station.cpp:382
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:267
Base class for all station-ish types.
Station data structure.
Definition: station_base.h:450
Road vehicle type.
Definition: vehicle_type.h:25
static TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
Definition: map_func.h:163
Class defining several overloaded accessors so we don&#39;t have to cast base stations that often...
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:3316