OpenTTD
station.cpp
Go to the documentation of this file.
1 /* $Id$ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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/>.
8  */
9 
12 #include "stdafx.h"
13 #include "company_func.h"
14 #include "company_base.h"
15 #include "roadveh.h"
16 #include "viewport_func.h"
17 #include "viewport_kdtree.h"
18 #include "date_func.h"
19 #include "command_func.h"
20 #include "news_func.h"
21 #include "aircraft.h"
22 #include "vehiclelist.h"
23 #include "core/pool_func.hpp"
24 #include "station_base.h"
25 #include "station_kdtree.h"
26 #include "roadstop_base.h"
27 #include "industry.h"
28 #include "town.h"
29 #include "core/random_func.hpp"
30 #include "linkgraph/linkgraph.h"
32 
33 #include "table/strings.h"
34 
35 #include "safeguards.h"
36 
38 StationPool _station_pool("Station");
40 
41 
42 StationKdtree _station_kdtree(Kdtree_StationXYFunc);
43 
44 void RebuildStationKdtree()
45 {
46  std::vector<StationID> stids;
47  BaseStation *st;
48  FOR_ALL_STATIONS(st) {
49  stids.push_back(st->index);
50  }
51  _station_kdtree.Build(stids.begin(), stids.end());
52 }
53 
54 
55 BaseStation::~BaseStation()
56 {
57  free(this->name);
58  free(this->speclist);
59 
60  if (CleaningPool()) return;
61 
62  DeleteWindowById(WC_TRAINS_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_TRAIN, this->owner, this->index).Pack());
63  DeleteWindowById(WC_ROADVEH_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_ROAD, this->owner, this->index).Pack());
64  DeleteWindowById(WC_SHIPS_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_SHIP, this->owner, this->index).Pack());
65  DeleteWindowById(WC_AIRCRAFT_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_AIRCRAFT, this->owner, this->index).Pack());
66 
67  this->sign.MarkDirty();
68 }
69 
70 Station::Station(TileIndex tile) :
71  SpecializedStation<Station, false>(tile),
72  bus_station(INVALID_TILE, 0, 0),
73  truck_station(INVALID_TILE, 0, 0),
74  ship_station(INVALID_TILE, 0, 0),
75  indtype(IT_INVALID),
76  time_since_load(255),
77  time_since_unload(255),
78  last_vehicle_type(VEH_INVALID)
79 {
80  /* this->random_bits is set in Station::AddFacility() */
81 }
82 
91 {
92  if (CleaningPool()) {
93  for (CargoID c = 0; c < NUM_CARGO; c++) {
94  this->goods[c].cargo.OnCleanPool();
95  }
96  return;
97  }
98 
99  while (!this->loading_vehicles.empty()) {
100  this->loading_vehicles.front()->LeaveStation();
101  }
102 
103  Aircraft *a;
104  FOR_ALL_AIRCRAFT(a) {
105  if (!a->IsNormalAircraft()) continue;
106  if (a->targetairport == this->index) a->targetairport = INVALID_STATION;
107  }
108 
109  for (CargoID c = 0; c < NUM_CARGO; ++c) {
110  LinkGraph *lg = LinkGraph::GetIfValid(this->goods[c].link_graph);
111  if (lg == nullptr) continue;
112 
113  for (NodeID node = 0; node < lg->Size(); ++node) {
114  Station *st = Station::Get((*lg)[node].Station());
115  st->goods[c].flows.erase(this->index);
116  if ((*lg)[node][this->goods[c].node].LastUpdate() != INVALID_DATE) {
117  st->goods[c].flows.DeleteFlows(this->index);
118  RerouteCargo(st, c, this->index, st->index);
119  }
120  }
121  lg->RemoveNode(this->goods[c].node);
122  if (lg->Size() == 0) {
124  delete lg;
125  }
126  }
127 
128  Vehicle *v;
129  FOR_ALL_VEHICLES(v) {
130  /* Forget about this station if this station is removed */
131  if (v->last_station_visited == this->index) {
132  v->last_station_visited = INVALID_STATION;
133  }
134  if (v->last_loading_station == this->index) {
135  v->last_loading_station = INVALID_STATION;
136  }
137  }
138 
139  /* Remove station from industries and towns that reference it. */
140  this->RemoveFromAllNearbyLists();
141 
142  /* Clear the persistent storage. */
143  delete this->airport.psa;
144 
145  if (this->owner == OWNER_NONE) {
146  /* Invalidate all in case of oil rigs. */
148  } else {
149  InvalidateWindowData(WC_STATION_LIST, this->owner, 0);
150  }
151 
153 
154  /* Now delete all orders that go to the station */
155  RemoveOrderFromAllVehicles(OT_GOTO_STATION, this->index);
156 
157  /* Remove all news items */
158  DeleteStationNews(this->index);
159 
160  for (CargoID c = 0; c < NUM_CARGO; c++) {
161  this->goods[c].cargo.Truncate();
162  }
163 
164  CargoPacket::InvalidateAllFrom(this->index);
165 
166  _station_kdtree.Remove(this->index);
167  _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeStation(this->index));
168 }
169 
170 
176 void BaseStation::PostDestructor(size_t index)
177 {
179 }
180 
186 RoadStop *Station::GetPrimaryRoadStop(const RoadVehicle *v) const
187 {
188  RoadStop *rs = this->GetPrimaryRoadStop(v->IsBus() ? ROADSTOP_BUS : ROADSTOP_TRUCK);
189 
190  for (; rs != nullptr; rs = rs->next) {
191  /* The vehicle cannot go to this roadstop (different roadtype) */
192  if (!HasTileAnyRoadType(rs->xy, v->compatible_roadtypes)) continue;
193  /* The vehicle is articulated and can therefore not go to a standard road stop. */
194  if (IsStandardRoadStopTile(rs->xy) && v->HasArticulatedPart()) continue;
195 
196  /* The vehicle can actually go to this road stop. So, return it! */
197  break;
198  }
199 
200  return rs;
201 }
202 
207 void Station::AddFacility(StationFacility new_facility_bit, TileIndex facil_xy)
208 {
209  if (this->facilities == FACIL_NONE) {
210  this->MoveSign(facil_xy);
211  this->random_bits = Random();
212  }
213  this->facilities |= new_facility_bit;
214  this->owner = _current_company;
215  this->build_date = _date;
216 }
217 
223 void Station::MarkTilesDirty(bool cargo_change) const
224 {
225  TileIndex tile = this->train_station.tile;
226  int w, h;
227 
228  if (tile == INVALID_TILE) return;
229 
230  /* cargo_change is set if we're refreshing the tiles due to cargo moving
231  * around. */
232  if (cargo_change) {
233  /* Don't waste time updating if there are no custom station graphics
234  * that might change. Even if there are custom graphics, they might
235  * not change. Unfortunately we have no way of telling. */
236  if (this->num_specs == 0) return;
237  }
238 
239  for (h = 0; h < train_station.h; h++) {
240  for (w = 0; w < train_station.w; w++) {
241  if (this->TileBelongsToRailStation(tile)) {
242  MarkTileDirtyByTile(tile);
243  }
244  tile += TileDiffXY(1, 0);
245  }
246  tile += TileDiffXY(-w, 1);
247  }
248 }
249 
250 /* virtual */ uint Station::GetPlatformLength(TileIndex tile) const
251 {
252  assert(this->TileBelongsToRailStation(tile));
253 
254  TileIndexDiff delta = (GetRailStationAxis(tile) == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
255 
256  TileIndex t = tile;
257  uint len = 0;
258  do {
259  t -= delta;
260  len++;
261  } while (IsCompatibleTrainStationTile(t, tile));
262 
263  t = tile;
264  do {
265  t += delta;
266  len++;
267  } while (IsCompatibleTrainStationTile(t, tile));
268 
269  return len - 1;
270 }
271 
272 /* virtual */ uint Station::GetPlatformLength(TileIndex tile, DiagDirection dir) const
273 {
274  TileIndex start_tile = tile;
275  uint length = 0;
276  assert(IsRailStationTile(tile));
277  assert(dir < DIAGDIR_END);
278 
279  do {
280  length++;
281  tile += TileOffsByDiagDir(dir);
282  } while (IsCompatibleTrainStationTile(tile, start_tile));
283 
284  return length;
285 }
286 
294 static uint GetTileCatchmentRadius(TileIndex tile, const Station *st)
295 {
296  assert(IsTileType(tile, MP_STATION));
297 
299  switch (GetStationType(tile)) {
300  case STATION_RAIL: return CA_TRAIN;
301  case STATION_OILRIG: return CA_UNMODIFIED;
302  case STATION_AIRPORT: return st->airport.GetSpec()->catchment;
303  case STATION_TRUCK: return CA_TRUCK;
304  case STATION_BUS: return CA_BUS;
305  case STATION_DOCK: return CA_DOCK;
306 
307  default: NOT_REACHED();
308  case STATION_BUOY:
309  case STATION_WAYPOINT: return CA_NONE;
310  }
311  } else {
312  switch (GetStationType(tile)) {
313  default: return CA_UNMODIFIED;
314  case STATION_BUOY:
315  case STATION_WAYPOINT: return CA_NONE;
316  }
317  }
318 }
319 
325 {
326  uint ret = CA_NONE;
327 
329  if (this->bus_stops != nullptr) ret = max<uint>(ret, CA_BUS);
330  if (this->truck_stops != nullptr) ret = max<uint>(ret, CA_TRUCK);
331  if (this->train_station.tile != INVALID_TILE) ret = max<uint>(ret, CA_TRAIN);
332  if (this->ship_station.tile != INVALID_TILE) ret = max<uint>(ret, CA_DOCK);
333  if (this->airport.tile != INVALID_TILE) ret = max<uint>(ret, this->airport.GetSpec()->catchment);
334  } else {
335  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) {
336  ret = CA_UNMODIFIED;
337  }
338  }
339 
340  return ret;
341 }
342 
348 {
349  assert(!this->rect.IsEmpty());
350 
351  /* Compute acceptance rectangle */
352  int catchment_radius = this->GetCatchmentRadius();
353 
354  Rect ret = {
355  max<int>(this->rect.left - catchment_radius, 0),
356  max<int>(this->rect.top - catchment_radius, 0),
357  min<int>(this->rect.right + catchment_radius, MapMaxX()),
358  min<int>(this->rect.bottom + catchment_radius, MapMaxY())
359  };
360 
361  return ret;
362 }
363 
369 static void AddIndustryToDeliver(Industry *ind, Station *st)
370 {
371  /* Don't check further if this industry is already in the list */
372  if (st->industries_near.find(ind) != st->industries_near.end()) return;
373 
374  /* Include only industries that can accept cargo */
375  uint cargo_index;
376  for (cargo_index = 0; cargo_index < lengthof(ind->accepts_cargo); cargo_index++) {
377  if (ind->accepts_cargo[cargo_index] != CT_INVALID) break;
378  }
379  if (cargo_index >= lengthof(ind->accepts_cargo)) return;
380 
381  st->industries_near.insert(ind);
382 }
383 
388 {
389  Town *t;
390  FOR_ALL_TOWNS(t) { t->stations_near.erase(this); }
391  Industry *i;
392  FOR_ALL_INDUSTRIES(i) { i->stations_near.erase(this); }
393 }
394 
402 bool Station::CatchmentCoversTown(TownID t) const
403 {
404  BitmapTileIterator it(this->catchment_tiles);
405  for (TileIndex tile = it; tile != INVALID_TILE; tile = ++it) {
406  if (IsTileType(tile, MP_HOUSE) && GetTownIndex(tile) == t) return true;
407  }
408  return false;
409 }
410 
416 {
417  this->industries_near.clear();
418  this->RemoveFromAllNearbyLists();
419 
420  if (this->rect.IsEmpty()) {
421  this->catchment_tiles.Reset();
422  return;
423  }
424 
425  if (!_settings_game.station.serve_neutral_industries && this->industry != nullptr) {
426  /* Station is associated with an industry, so we only need to deliver to that industry. */
427  this->catchment_tiles.Initialize(this->industry->location);
428  TILE_AREA_LOOP(tile, this->industry->location) {
429  if (IsTileType(tile, MP_INDUSTRY) && GetIndustryIndex(tile) == this->industry->index) {
430  this->catchment_tiles.SetTile(tile);
431  }
432  }
433  /* The industry's stations_near may have been computed before its neutral station was built so clear and re-add here. */
434  for (Station *st : this->industry->stations_near) {
435  st->industries_near.erase(this->industry);
436  }
437  this->industry->stations_near.clear();
438  this->industry->stations_near.insert(this);
439  this->industries_near.insert(this->industry);
440  return;
441  }
442 
443  this->catchment_tiles.Initialize(GetCatchmentRect());
444 
445  /* Loop finding all station tiles */
446  TileArea ta(TileXY(this->rect.left, this->rect.top), TileXY(this->rect.right, this->rect.bottom));
447  TILE_AREA_LOOP(tile, ta) {
448  if (!IsTileType(tile, MP_STATION) || GetStationIndex(tile) != this->index) continue;
449 
450  uint r = GetTileCatchmentRadius(tile, this);
451  if (r == CA_NONE) continue;
452 
453  /* This tile sub-loop doesn't need to test any tiles, they are simply added to the catchment set. */
454  TileArea ta2 = TileArea(tile, 1, 1).Expand(r);
455  TILE_AREA_LOOP(tile2, ta2) this->catchment_tiles.SetTile(tile2);
456  }
457 
458  /* Search catchment tiles for towns and industries */
459  BitmapTileIterator it(this->catchment_tiles);
460  for (TileIndex tile = it; tile != INVALID_TILE; tile = ++it) {
461  if (IsTileType(tile, MP_HOUSE)) {
462  Town *t = Town::GetByTile(tile);
463  t->stations_near.insert(this);
464  }
465  if (IsTileType(tile, MP_INDUSTRY)) {
466  Industry *i = Industry::GetByTile(tile);
467 
468  /* Ignore industry if it has a neutral station. It already can't be this station. */
469  if (!_settings_game.station.serve_neutral_industries && i->neutral_station != nullptr) continue;
470 
471  i->stations_near.insert(this);
472 
473  /* Add if we can deliver to this industry as well */
474  AddIndustryToDeliver(i, this);
475  }
476  }
477 }
478 
484 {
485  Station *st;
486  FOR_ALL_STATIONS(st) { st->RecomputeCatchment(); }
487 }
488 
489 /************************************************************************/
490 /* StationRect implementation */
491 /************************************************************************/
492 
493 StationRect::StationRect()
494 {
495  this->MakeEmpty();
496 }
497 
498 void StationRect::MakeEmpty()
499 {
500  this->left = this->top = this->right = this->bottom = 0;
501 }
502 
512 bool StationRect::PtInExtendedRect(int x, int y, int distance) const
513 {
514  return this->left - distance <= x && x <= this->right + distance &&
515  this->top - distance <= y && y <= this->bottom + distance;
516 }
517 
518 bool StationRect::IsEmpty() const
519 {
520  return this->left == 0 || this->left > this->right || this->top > this->bottom;
521 }
522 
523 CommandCost StationRect::BeforeAddTile(TileIndex tile, StationRectMode mode)
524 {
525  int x = TileX(tile);
526  int y = TileY(tile);
527  if (this->IsEmpty()) {
528  /* we are adding the first station tile */
529  if (mode != ADD_TEST) {
530  this->left = this->right = x;
531  this->top = this->bottom = y;
532  }
533  } else if (!this->PtInExtendedRect(x, y)) {
534  /* current rect is not empty and new point is outside this rect
535  * make new spread-out rectangle */
536  Rect new_rect = {min(x, this->left), min(y, this->top), max(x, this->right), max(y, this->bottom)};
537 
538  /* check new rect dimensions against preset max */
539  int w = new_rect.right - new_rect.left + 1;
540  int h = new_rect.bottom - new_rect.top + 1;
541  if (mode != ADD_FORCE && (w > _settings_game.station.station_spread || h > _settings_game.station.station_spread)) {
542  assert(mode != ADD_TRY);
543  return_cmd_error(STR_ERROR_STATION_TOO_SPREAD_OUT);
544  }
545 
546  /* spread-out ok, return true */
547  if (mode != ADD_TEST) {
548  /* we should update the station rect */
549  *this = new_rect;
550  }
551  } else {
552  ; // new point is inside the rect, we don't need to do anything
553  }
554  return CommandCost();
555 }
556 
557 CommandCost StationRect::BeforeAddRect(TileIndex tile, int w, int h, StationRectMode mode)
558 {
559  if (mode == ADD_FORCE || (w <= _settings_game.station.station_spread && h <= _settings_game.station.station_spread)) {
560  /* Important when the old rect is completely inside the new rect, resp. the old one was empty. */
561  CommandCost ret = this->BeforeAddTile(tile, mode);
562  if (ret.Succeeded()) ret = this->BeforeAddTile(TILE_ADDXY(tile, w - 1, h - 1), mode);
563  return ret;
564  }
565  return CommandCost();
566 }
567 
577 /* static */ bool StationRect::ScanForStationTiles(StationID st_id, int left_a, int top_a, int right_a, int bottom_a)
578 {
579  TileArea ta(TileXY(left_a, top_a), TileXY(right_a, bottom_a));
580  TILE_AREA_LOOP(tile, ta) {
581  if (IsTileType(tile, MP_STATION) && GetStationIndex(tile) == st_id) return true;
582  }
583 
584  return false;
585 }
586 
587 bool StationRect::AfterRemoveTile(BaseStation *st, TileIndex tile)
588 {
589  int x = TileX(tile);
590  int y = TileY(tile);
591 
592  /* look if removed tile was on the bounding rect edge
593  * and try to reduce the rect by this edge
594  * do it until we have empty rect or nothing to do */
595  for (;;) {
596  /* check if removed tile is on rect edge */
597  bool left_edge = (x == this->left);
598  bool right_edge = (x == this->right);
599  bool top_edge = (y == this->top);
600  bool bottom_edge = (y == this->bottom);
601 
602  /* can we reduce the rect in either direction? */
603  bool reduce_x = ((left_edge || right_edge) && !ScanForStationTiles(st->index, x, this->top, x, this->bottom));
604  bool reduce_y = ((top_edge || bottom_edge) && !ScanForStationTiles(st->index, this->left, y, this->right, y));
605  if (!(reduce_x || reduce_y)) break; // nothing to do (can't reduce)
606 
607  if (reduce_x) {
608  /* reduce horizontally */
609  if (left_edge) {
610  /* move left edge right */
611  this->left = x = x + 1;
612  } else {
613  /* move right edge left */
614  this->right = x = x - 1;
615  }
616  }
617  if (reduce_y) {
618  /* reduce vertically */
619  if (top_edge) {
620  /* move top edge down */
621  this->top = y = y + 1;
622  } else {
623  /* move bottom edge up */
624  this->bottom = y = y - 1;
625  }
626  }
627 
628  if (left > right || top > bottom) {
629  /* can't continue, if the remaining rectangle is empty */
630  this->MakeEmpty();
631  return true; // empty remaining rect
632  }
633  }
634  return false; // non-empty remaining rect
635 }
636 
637 bool StationRect::AfterRemoveRect(BaseStation *st, TileArea ta)
638 {
639  assert(this->PtInExtendedRect(TileX(ta.tile), TileY(ta.tile)));
640  assert(this->PtInExtendedRect(TileX(ta.tile) + ta.w - 1, TileY(ta.tile) + ta.h - 1));
641 
642  bool empty = this->AfterRemoveTile(st, ta.tile);
643  if (ta.w != 1 || ta.h != 1) empty = empty || this->AfterRemoveTile(st, TILE_ADDXY(ta.tile, ta.w - 1, ta.h - 1));
644  return empty;
645 }
646 
647 StationRect& StationRect::operator = (const Rect &src)
648 {
649  this->left = src.left;
650  this->top = src.top;
651  this->right = src.right;
652  this->bottom = src.bottom;
653  return *this;
654 }
655 
662 {
663  Money total_cost = 0;
664 
665  const Station *st;
666  FOR_ALL_STATIONS(st) {
667  if (st->owner == owner && (st->facilities & FACIL_AIRPORT)) {
668  total_cost += _price[PR_INFRASTRUCTURE_AIRPORT] * st->airport.GetSpec()->maintenance_cost;
669  }
670  }
671  /* 3 bits fraction for the maintenance cost factor. */
672  return total_cost >> 3;
673 }
674 
675 bool StationCompare::operator() (const Station *lhs, const Station *rhs) const
676 {
677  return lhs->index < rhs->index;
678 }
Owner
Enum for all companies/owners.
Definition: company_type.h:20
Road vehicle states.
Iterator to iterate over all tiles belonging to a bitmaptilearea.
Definition: bitmap_type.h:109
static bool HasTileAnyRoadType(TileIndex t, RoadTypes rts)
Check if a tile has one of the specified road types.
Definition: road_map.h:223
StationFacility facilities
The facilities that this station has.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:81
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:257
Select station (when joining stations); Window numbers:
Definition: window_type.h:237
A standard stop for trucks.
Definition: station_type.h:48
Rect GetCatchmentRect() const
Determines catchment rectangle of this station.
Definition: station.cpp:347
The information about a vehicle list.
Definition: vehiclelist.h:31
Non-existing type of vehicle.
Definition: vehicle_type.h:37
const AirportSpec * GetSpec() const
Get the AirportSpec that from the airport type of this airport.
Definition: station_base.h:322
StationID targetairport
Airport to go to next.
Definition: aircraft.h:80
Base class for roadstops.
Part of an industry.
Definition: tile_type.h:51
Functions and type for generating vehicle lists.
int32 TileIndexDiff
An offset value between to tiles.
Definition: map_func.h:156
Train vehicle type.
Definition: vehicle_type.h:26
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:28
Maximal number of cargo types in a game.
Definition: cargo_type.h:66
TileIndex xy
Position on the map.
Definition: roadstop_base.h:69
StationID last_loading_station
Last station the vehicle has stopped at and could possibly leave from with any cargo loaded...
Definition: vehicle_base.h:303
bool CatchmentCoversTown(TownID t) const
Test if the given town ID is covered by our catchment area.
Definition: station.cpp:402
OrthogonalTileArea & Expand(int rad)
Expand a tile area by rad tiles in each direction, keeping within map bounds.
Definition: tilearea.cpp:125
Aircraft, helicopters, rotors and their shadows belong to this class.
Definition: aircraft.h:76
The station has no facilities at all.
Definition: station_type.h:53
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:207
A standard stop for buses.
Definition: station_type.h:47
Vehicle data structure.
Definition: vehicle_base.h:212
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:42
Tindex index
Index of this pool item.
Definition: pool_type.hpp:147
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:869
void RecomputeCatchment()
Recompute tiles covered in our catchment area.
Definition: station.cpp:415
Base for aircraft.
StationID last_station_visited
The last station we stopped at.
Definition: vehicle_base.h:302
void MarkTilesDirty(bool cargo_change) const
Marks the tiles of the station as dirty.
Definition: station.cpp:223
Common return value for all commands.
Definition: command_type.h:25
static bool IsStandardRoadStopTile(TileIndex t)
Is tile t a standard (non-drive through) road stop station?
Definition: station_map.h:225
Catchment for bus stops with "modified catchment" enabled.
Definition: station_type.h:79
static T max(const T a, const T b)
Returns the maximum of two values.
Definition: math_func.hpp:26
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:20
bool IsNormalAircraft() const
Check if the aircraft type is a normal flying device; eg not a rotor or a shadow. ...
Definition: aircraft.h:123
static StationType GetStationType(TileIndex t)
Get the station type of this tile.
Definition: station_map.h:46
StationSettings station
settings related to station management
GoodsEntry goods[NUM_CARGO]
Goods at this station.
Definition: station_base.h:481
void MarkDirty(ZoomLevel maxzoom=ZOOM_LVL_MAX) const
Mark the sign dirty in all viewports.
Definition: viewport.cpp:1471
uint16 maintenance_cost
maintenance cost multiplier
StationList stations_near
NOSAVE: List of nearby stations.
Definition: industry.h:66
Functions related to (drawing on) viewports.
Pseudo random number generator.
A connected component of a link graph.
Definition: linkgraph.h:40
Invalid cargo type.
Definition: cargo_type.h:70
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:3318
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:380
Buses, trucks and trams belong to this class.
Definition: roadveh.h:109
ViewportSign sign
NOSAVE: Dimensions of sign.
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:499
The tile has no ownership.
Definition: company_type.h:27
static TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition: map_func.h:343
OrthogonalTileArea TileArea
Shorthand for the much more common orthogonal tile area.
Definition: tilearea_type.h:98
static bool IsTileType(TileIndex tile, TileType type)
Checks if a tile is a given tiletype.
Definition: tile_map.h:152
static void AddIndustryToDeliver(Industry *ind, Station *st)
Add nearby industry to station&#39;s industries_near list if it accepts cargo.
Definition: station.cpp:369
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:104
IndustryList industries_near
Cached list of industries near the station that can accept cargo,.
Definition: station_base.h:484
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:24
Money AirportMaintenanceCost(Owner owner)
Calculates the maintenance cost of all airports of a company.
Definition: station.cpp:661
bool Succeeded() const
Did this command succeed?
Definition: command_type.h:152
~Station()
Clean up a station by clearing vehicle orders, invalidating windows and removing link stats...
Definition: station.cpp:90
#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:110
#define TILE_ADDXY(tile, x, y)
Adds a given offset to a tile.
Definition: map_func.h:260
A number of safeguards to prevent using unsafe methods.
StationList stations_near
NOSAVE: List of nearby stations.
Definition: town.h:91
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:339
struct RoadStop * next
Next stop of the given type at this station.
Definition: roadstop_base.h:71
uint GetCatchmentRadius() const
Determines the catchment radius of the station.
Definition: station.cpp:324
Represents the covered area of e.g.
Definition: tilearea_type.h:18
static uint GetTileCatchmentRadius(TileIndex tile, const Station *st)
Get the catchment size of an individual station tile.
Definition: station.cpp:294
Road vehicle list; Window numbers:
Definition: window_type.h:309
StationSpecList * speclist
List of station specs of this station.
bool HasArticulatedPart() const
Check if an engine has an articulated part.
Definition: vehicle_base.h:901
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:1940
Station view; Window numbers:
Definition: window_type.h:340
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:51
Catchment for truck stops with "modified catchment" enabled.
Definition: station_type.h:80
Catchment for all stations with "modified catchment" disabled.
Definition: station_type.h:84
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:42
static T min(const T a, const T b)
Returns the minimum of two values.
Definition: math_func.hpp:42
static void RecomputeCatchmentForAll()
Recomputes catchment of all stations.
Definition: station.cpp:483
void RemoveNode(NodeID id)
Remove a node from the link graph by overwriting it with the last node.
Definition: linkgraph.cpp:121
#define return_cmd_error(errcode)
Returns from a function with a specific StringID as error.
Definition: command_func.h:35
Base class for all pools.
Definition: pool_type.hpp:83
Station list; Window numbers:
Definition: window_type.h:297
FlowStatMap flows
Planned flows through this station.
Definition: station_base.h:261
TileIndex tile
The base tile of the area.
Definition: tilearea_type.h:19
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don&#39;t get linker errors.
Definition: pool_func.hpp:226
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:1146
Station with an airport.
Definition: station_type.h:57
static bool CleaningPool()
Returns current state of pool cleaning - yes or no.
Definition: pool_type.hpp:225
Catchment for docks with "modified catchment" enabled.
Definition: station_type.h:82
Functions related to companies.
Catchment when the station has no facilities.
Definition: station_type.h:78
static StationID GetStationIndex(TileIndex t)
Get StationID from a tile.
Definition: station_map.h:30
bool IsBus() const
Check whether a roadvehicle is a bus.
Definition: roadveh_cmd.cpp:81
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:512
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:52
Ships list; Window numbers:
Definition: window_type.h:315
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:80
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:65
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:217
Catchment for train stations with "modified catchment" enabled.
Definition: station_type.h:81
Trains list; Window numbers:
Definition: window_type.h:303
A tile of a station.
Definition: tile_type.h:48
static uint MapMaxY()
Gets the maximum Y coordinate within the map, including MP_VOID.
Definition: map_func.h:113
Town data structure.
Definition: town.h:55
Aircraft list; Window numbers:
Definition: window_type.h:321
Station * neutral_station
Associated neutral station.
Definition: industry.h:45
RoadTypes compatible_roadtypes
Roadtypes this consist is powered on.
Definition: roadveh.h:120
Functions related to commands.
A Stop for a Road Vehicle.
Definition: roadstop_base.h:24
CompanyID _current_company
Company currently doing an action.
Definition: company_cmd.cpp:47
void AddFacility(StationFacility new_facility_bit, TileIndex facil_xy)
Called when new facility is built on the station.
Definition: station.cpp:207
Owner owner
The owner of this station.
#define FOR_ALL_AIRCRAFT(var)
Macro for iterating over all aircraft.
Definition: aircraft.h:144
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:577
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:181
Base of all industries.
K-dimensional tree, specialised for 2-dimensional space.
Definition: kdtree.hpp:38
Aircraft vehicle type.
Definition: vehicle_type.h:29
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: depend.cpp:131
Airport airport
Tile area the airport covers.
Definition: station_base.h:466
static void PostDestructor(size_t index)
Invalidating of the JoinStation window has to be done after removing item from the pool...
Definition: station.cpp:176
DiagDirection
Enumeration for diagonal directions.
#define FOR_ALL_VEHICLES(var)
Iterate over all vehicles.
Definition: vehicle_base.h:987
static const TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:85
Base of the town class.
void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination, bool hangar)
Removes an order from all vehicles.
Definition: order_cmd.cpp:1803
Specification of a rectangle with absolute coordinates of all edges.
A house by a town.
Definition: tile_type.h:46
byte CargoID
Cargo slots to indicate a cargo type within a game.
Definition: cargo_type.h:22
static uint MapMaxX()
Gets the maximum X coordinate within the map, including MP_VOID.
Definition: map_func.h:104
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition: industry.h:115
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:28
char * name
Custom name.
uint16 h
The height of the area.
Definition: tilearea_type.h:21
void RemoveFromAllNearbyLists()
Remove this station from the nearby stations lists of all towns and industries.
Definition: station.cpp:387
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:272
Base class for all station-ish types.
Station data structure.
Definition: station_base.h:452
Road vehicle type.
Definition: vehicle_type.h:27
static TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
Definition: map_func.h:165
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:3300