OpenTTD
station_base.h
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 #ifndef STATION_BASE_H
11 #define STATION_BASE_H
12 
13 #include "core/random_func.hpp"
14 #include "base_station_base.h"
15 #include "newgrf_airport.h"
16 #include "cargopacket.h"
17 #include "industry_type.h"
19 #include "newgrf_storage.h"
20 #include "bitmap_type.h"
21 #include <map>
22 #include <set>
23 
26 
27 static const byte INITIAL_STATION_RATING = 175;
28 
36 class FlowStat {
37 public:
38  typedef std::map<uint32, StationID> SharesMap;
39 
40  static const SharesMap empty_sharesmap;
41 
47  inline FlowStat() {NOT_REACHED();}
48 
55  inline FlowStat(StationID st, uint flow, bool restricted = false)
56  {
57  assert(flow > 0);
58  this->shares[flow] = st;
59  this->unrestricted = restricted ? 0 : flow;
60  }
61 
70  inline void AppendShare(StationID st, uint flow, bool restricted = false)
71  {
72  assert(flow > 0);
73  this->shares[(--this->shares.end())->first + flow] = st;
74  if (!restricted) this->unrestricted += flow;
75  }
76 
77  uint GetShare(StationID st) const;
78 
79  void ChangeShare(StationID st, int flow);
80 
81  void RestrictShare(StationID st);
82 
83  void ReleaseShare(StationID st);
84 
85  void ScaleToMonthly(uint runtime);
86 
92  inline const SharesMap *GetShares() const { return &this->shares; }
93 
98  inline uint GetUnrestricted() const { return this->unrestricted; }
99 
105  inline void SwapShares(FlowStat &other)
106  {
107  this->shares.swap(other.shares);
108  Swap(this->unrestricted, other.unrestricted);
109  }
110 
119  inline StationID GetViaWithRestricted(bool &is_restricted) const
120  {
121  assert(!this->shares.empty());
122  uint rand = RandomRange((--this->shares.end())->first);
123  is_restricted = rand >= this->unrestricted;
124  return this->shares.upper_bound(rand)->second;
125  }
126 
134  inline StationID GetVia() const
135  {
136  assert(!this->shares.empty());
137  return this->unrestricted > 0 ?
138  this->shares.upper_bound(RandomRange(this->unrestricted))->second :
139  INVALID_STATION;
140  }
141 
142  StationID GetVia(StationID excluded, StationID excluded2 = INVALID_STATION) const;
143 
144  void Invalidate();
145 
146 private:
147  SharesMap shares;
149 };
150 
152 class FlowStatMap : public std::map<StationID, FlowStat> {
153 public:
154  uint GetFlow() const;
155  uint GetFlowVia(StationID via) const;
156  uint GetFlowFrom(StationID from) const;
157  uint GetFlowFromVia(StationID from, StationID via) const;
158 
159  void AddFlow(StationID origin, StationID via, uint amount);
160  void PassOnFlow(StationID origin, StationID via, uint amount);
161  StationIDStack DeleteFlows(StationID via);
162  void RestrictFlows(StationID via);
163  void ReleaseFlows(StationID via);
164  void FinalizeLocalConsumption(StationID self);
165 };
166 
170 struct GoodsEntry {
178 
188 
194 
200 
206 
212  };
213 
214  GoodsEntry() :
215  status(0),
216  time_since_pickup(255),
217  rating(INITIAL_STATION_RATING),
218  last_speed(0),
219  last_age(255),
220  amount_fract(0),
221  link_graph(INVALID_LINK_GRAPH),
222  node(INVALID_NODE),
223  max_waiting_cargo(0)
224  {}
225 
226  byte status;
227 
234 
235  byte rating;
236 
247 
252  byte last_age;
253 
256 
257  LinkGraphID link_graph;
258  NodeID node;
261 
267  bool HasVehicleEverTriedLoading() const { return this->last_speed != 0; }
268 
273  inline bool HasRating() const
274  {
275  return HasBit(this->status, GES_RATING);
276  }
277 
283  inline StationID GetVia(StationID source) const
284  {
285  FlowStatMap::const_iterator flow_it(this->flows.find(source));
286  return flow_it != this->flows.end() ? flow_it->second.GetVia() : INVALID_STATION;
287  }
288 
297  inline StationID GetVia(StationID source, StationID excluded, StationID excluded2 = INVALID_STATION) const
298  {
299  FlowStatMap::const_iterator flow_it(this->flows.find(source));
300  return flow_it != this->flows.end() ? flow_it->second.GetVia(excluded, excluded2) : INVALID_STATION;
301  }
302 };
303 
305 struct Airport : public TileArea {
306  Airport() : TileArea(INVALID_TILE, 0, 0) {}
307 
308  uint64 flags;
309  byte type;
310  byte layout;
312 
314 
320  const AirportSpec *GetSpec() const
321  {
322  if (this->tile == INVALID_TILE) return &AirportSpec::dummy;
323  return AirportSpec::Get(this->type);
324  }
325 
332  const AirportFTAClass *GetFTA() const
333  {
334  return this->GetSpec()->fsm;
335  }
336 
338  inline bool HasHangar() const
339  {
340  return this->GetSpec()->nof_depots > 0;
341  }
342 
352  {
353  const AirportSpec *as = this->GetSpec();
354  switch (this->rotation) {
355  case DIR_N: return this->tile + ToTileIndexDiff(tidc);
356 
357  case DIR_E: return this->tile + TileDiffXY(tidc.y, as->size_x - 1 - tidc.x);
358 
359  case DIR_S: return this->tile + TileDiffXY(as->size_x - 1 - tidc.x, as->size_y - 1 - tidc.y);
360 
361  case DIR_W: return this->tile + TileDiffXY(as->size_y - 1 - tidc.y, tidc.x);
362 
363  default: NOT_REACHED();
364  }
365  }
366 
373  inline TileIndex GetHangarTile(uint hangar_num) const
374  {
375  const AirportSpec *as = this->GetSpec();
376  for (uint i = 0; i < as->nof_depots; i++) {
377  if (as->depot_table[i].hangar_num == hangar_num) {
378  return this->GetRotatedTileFromOffset(as->depot_table[i].ti);
379  }
380  }
381  NOT_REACHED();
382  }
383 
391  {
392  const AirportSpec *as = this->GetSpec();
393  const HangarTileTable *htt = GetHangarDataByTile(tile);
394  return ChangeDir(htt->dir, DirDifference(this->rotation, as->rotation[0]));
395  }
396 
403  inline uint GetHangarNum(TileIndex tile) const
404  {
405  const HangarTileTable *htt = GetHangarDataByTile(tile);
406  return htt->hangar_num;
407  }
408 
410  inline uint GetNumHangars() const
411  {
412  uint num = 0;
413  uint counted = 0;
414  const AirportSpec *as = this->GetSpec();
415  for (uint i = 0; i < as->nof_depots; i++) {
416  if (!HasBit(counted, as->depot_table[i].hangar_num)) {
417  num++;
418  SetBit(counted, as->depot_table[i].hangar_num);
419  }
420  }
421  return num;
422  }
423 
424 private:
432  {
433  const AirportSpec *as = this->GetSpec();
434  for (uint i = 0; i < as->nof_depots; i++) {
435  if (this->GetRotatedTileFromOffset(as->depot_table[i].ti) == tile) {
436  return as->depot_table + i;
437  }
438  }
439  NOT_REACHED();
440  }
441 };
442 
444  bool operator() (const Industry *lhs, const Industry *rhs) const;
445 };
446 
447 typedef std::set<Industry *, IndustryCompare> IndustryList;
448 
450 struct Station FINAL : SpecializedStation<Station, false> {
451 public:
452  RoadStop *GetPrimaryRoadStop(RoadStopType type) const
453  {
454  return type == ROADSTOP_BUS ? bus_stops : truck_stops;
455  }
456 
457  RoadStop *GetPrimaryRoadStop(const struct RoadVehicle *v) const;
458 
463 
467 
468  IndustryType indtype;
469 
471 
472  StationHadVehicleOfType had_vehicle_of_type;
473 
474  byte time_since_load;
475  byte time_since_unload;
476 
477  byte last_vehicle_type;
478  std::list<Vehicle *> loading_vehicles;
480  CargoTypes always_accepted;
481 
482  IndustryList industries_near;
484 
486  ~Station();
487 
488  void AddFacility(StationFacility new_facility_bit, TileIndex facil_xy);
489 
490  void MarkTilesDirty(bool cargo_change) const;
491 
492  void UpdateVirtCoord() override;
493 
494  void MoveSign(TileIndex new_xy) override;
495 
496  void AfterStationTileSetChange(bool adding, StationType type);
497 
498  uint GetPlatformLength(TileIndex tile, DiagDirection dir) const override;
499  uint GetPlatformLength(TileIndex tile) const override;
500  void RecomputeCatchment();
501  static void RecomputeCatchmentForAll();
502 
503  uint GetCatchmentRadius() const;
504  Rect GetCatchmentRect() const;
505  bool CatchmentCoversTown(TownID t) const;
506  void RemoveFromAllNearbyLists();
507 
508  inline bool TileIsInCatchment(TileIndex tile) const
509  {
510  return this->catchment_tiles.HasTile(tile);
511  }
512 
513  inline bool TileBelongsToRailStation(TileIndex tile) const override
514  {
515  return IsRailStationTile(tile) && GetStationIndex(tile) == this->index;
516  }
517 
518  inline bool TileBelongsToAirport(TileIndex tile) const
519  {
520  return IsAirportTile(tile) && GetStationIndex(tile) == this->index;
521  }
522 
523  uint32 GetNewGRFVariable(const ResolverObject &object, byte variable, byte parameter, bool *available) const override;
524 
525  void GetTileArea(TileArea *ta, StationType type) const override;
526 };
527 
530 private:
531  const Station *st;
532 
533 public:
538  AirportTileIterator(const Station *st) : OrthogonalTileIterator(st->airport), st(st)
539  {
540  if (!st->TileBelongsToAirport(this->tile)) ++(*this);
541  }
542 
543  inline TileIterator& operator ++()
544  {
545  (*this).OrthogonalTileIterator::operator++();
546  while (this->tile != INVALID_TILE && !st->TileBelongsToAirport(this->tile)) {
547  (*this).OrthogonalTileIterator::operator++();
548  }
549  return *this;
550  }
551 
552  virtual TileIterator *Clone() const
553  {
554  return new AirportTileIterator(*this);
555  }
556 };
557 
558 void RebuildStationKdtree();
559 
560 #endif /* STATION_BASE_H */
static void Swap(T &a, T &b)
Type safe swap operation.
Definition: math_func.hpp:275
byte type
Type of this airport,.
Definition: station_base.h:309
const HangarTileTable * GetHangarDataByTile(TileIndex tile) const
Retrieve hangar information of a hangar at a given tile.
Definition: station_base.h:431
Finite sTate mAchine (FTA) of an airport.
Definition: airport.h:143
Types related to the industry.
const AirportSpec * GetSpec() const
Get the AirportSpec that from the airport type of this airport.
Definition: station_base.h:320
TileArea bus_station
Tile area the bus &#39;station&#39; part covers.
Definition: station_base.h:460
Direction rotation
How this airport is rotated.
Definition: station_base.h:311
Minimal stack that uses a pool to avoid pointers.
const Station * st
The station the airport is a part of.
Definition: station_base.h:531
TileArea ship_station
Tile area the ship &#39;station&#39; part covers.
Definition: station_base.h:465
Direction GetHangarExitDirection(TileIndex tile) const
Get the exit direction of the hangar at a specific tile.
Definition: station_base.h:390
byte size_y
size of airport in y direction
Iterator to iterate over all tiles belonging to an airport.
Definition: station_base.h:529
SharesMap shares
Shares of flow to be sent via specified station (or consumed locally).
Definition: station_base.h:147
bool HasVehicleEverTriedLoading() const
Reports whether a vehicle has ever tried to load the cargo at this station.
Definition: station_base.h:267
static bool IsAirportTile(TileIndex t)
Is this tile a station tile and an airport tile?
Definition: station_map.h:167
uint GetNumHangars() const
Get the number of hangars on this airport.
Definition: station_base.h:410
byte hangar_num
The hangar to which this tile belongs.
bool HasHangar() const
Check if this airport has at least one hangar.
Definition: station_base.h:338
CargoList that is used for stations.
Definition: cargopacket.h:448
const AirportFTAClass * GetFTA() const
Get the finite-state machine for this airport or the finite-state machine for the dummy airport in ca...
Definition: station_base.h:332
West.
void SwapShares(FlowStat &other)
Swap the shares maps, and thus the content of this FlowStat with the other one.
Definition: station_base.h:105
Functionality related to the temporary and persistent storage arrays for NewGRFs. ...
static T SetBit(T &x, const uint8 y)
Set a bit in a variable.
Interface for SpriteGroup-s to access the gamestate.
Maximal number of cargo types in a game.
Definition: cargo_type.h:64
Set when cargo was delivered for final delivery during the current STATION_ACCEPTANCE_TICKS interval...
Definition: station_base.h:211
Set when cargo was delivered for final delivery this month.
Definition: station_base.h:205
const HangarTileTable * depot_table
gives the position of the depots on the airports
A standard stop for buses.
Definition: station_type.h:45
Defines the internal data of a functional industry.
Definition: industry.h:40
Stores station stats for a single cargo.
Definition: station_base.h:170
static const AirportSpec dummy
The dummy airport.
A list of all hangar tiles in an airport.
virtual TileIterator * Clone() const
Allocate a new iterator that is a copy of this one.
Definition: station_base.h:552
StationPool _station_pool
The pool of stations.
StationCargoList cargo
The cargo packets of cargo waiting in this station.
Definition: station_base.h:255
bool HasRating() const
Does this cargo have a rating at this station?
Definition: station_base.h:273
byte nof_depots
the number of hangar tiles in this airport
static uint32 RandomRange(uint32 limit)
Pick a random number between 0 and limit - 1, inclusive.
Definition: random_func.hpp:81
RoadStopType
Types of RoadStops.
Definition: station_type.h:44
North.
NewGRF handling of airports.
Pseudo random number generator.
int16 y
The y value of the coordinate.
Definition: map_type.h:59
Set when cargo was delivered for final delivery last month.
Definition: station_base.h:199
Base class for cargo packets.
void ScaleToMonthly(uint runtime)
Scale all shares from link graph&#39;s runtime to monthly values.
TileArea docking_station
Tile area the docking tiles cover.
Definition: station_base.h:466
Buses, trucks and trams belong to this class.
Definition: roadveh.h:107
uint GetShare(StationID st) const
Get flow for a station.
bool TileBelongsToRailStation(TileIndex tile) const override
Check whether a specific tile belongs to this station.
Definition: station_base.h:513
byte amount_fract
Fractional part of the amount in the cargo list.
Definition: station_base.h:254
byte rating
Station rating for this cargo.
Definition: station_base.h:235
OrthogonalTileArea TileArea
Shorthand for the much more common orthogonal tile area.
Definition: tilearea_type.h:96
RoadStop * truck_stops
All the truck stops.
Definition: station_base.h:461
This indicates whether a cargo has a rating at the station.
Definition: station_base.h:187
StationID GetVia(StationID source) const
Get the best next hop for a cargo packet from station source.
Definition: station_base.h:283
LinkGraphID link_graph
Link graph this station belongs to.
Definition: station_base.h:257
uint unrestricted
Limit for unrestricted shares.
Definition: station_base.h:148
GoodsEntryStatus
Status of this cargo for the station.
Definition: station_base.h:172
FlowStat()
Invalid constructor.
Definition: station_base.h:47
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
East.
const Direction * rotation
the rotation of each tiletable
StationID GetVia() const
Get a station a package can be routed to.
Definition: station_base.h:134
TileArea truck_station
Tile area the truck &#39;station&#39; part covers.
Definition: station_base.h:462
byte status
Status of this cargo, see GoodsEntryStatus.
Definition: station_base.h:226
byte layout
Airport layout number.
Definition: station_base.h:310
FlowStat(StationID st, uint flow, bool restricted=false)
Create a FlowStat with an initial entry.
Definition: station_base.h:55
int16 x
The x value of the coordinate.
Definition: map_type.h:58
Direction
Defines the 8 directions on the map.
StationID GetVia(StationID source, StationID excluded, StationID excluded2=INVALID_STATION) const
Get the best next hop for a cargo packet from station source, optionally excluding one or two station...
Definition: station_base.h:297
NodeID node
ID of node in link graph referring to this goods entry.
Definition: station_base.h:258
Represents the covered area of e.g.
Definition: tilearea_type.h:16
Class for pooled persistent storage of data.
Represents a tile area containing containing individually set tiles.
Definition: bitmap_type.h:19
South.
Base class for tile iterators.
Definition: tilearea_type.h:99
static const AirportSpec * Get(byte type)
Retrieve airport spec for the given airport.
PersistentStorage * psa
Persistent storage for NewGRF airports.
Definition: station_base.h:313
All airport-related information.
Definition: station_base.h:305
static DirDiff DirDifference(Direction d0, Direction d1)
Calculate the difference between two directions.
static Direction ChangeDir(Direction d, DirDiff delta)
Change a direction by a given difference.
void RestrictShare(StationID st)
Restrict a flow by moving it to the end of the map and decreasing the amount of unrestricted flow...
uint64 flags
stores which blocks on the airport are taken. was 16 bit earlier on, then 32
Definition: station_base.h:308
static const SharesMap empty_sharesmap
Static instance of FlowStat::SharesMap.
Definition: station_base.h:40
byte last_speed
Maximum speed (up to 255) of the last vehicle that tried to load this cargo.
Definition: station_base.h:246
Declaration of link graph types used for cargo distribution.
bool HasTile(TileIndex tile) const
Test if a tile is part of the tile area.
Definition: bitmap_type.h:100
byte last_age
Age in years (up to 255) of the last vehicle that tried to load this cargo.
Definition: station_base.h:252
TileIndex GetHangarTile(uint hangar_num) const
Get the first tile of the given hangar.
Definition: station_base.h:373
TileIndexDiffC ti
Tile offset from the top-most airport tile.
RoadStop * bus_stops
All the road stops.
Definition: station_base.h:459
Base class for all pools.
Definition: pool_type.hpp:82
FlowStatMap flows
Planned flows through this station.
Definition: station_base.h:259
void ChangeShare(StationID st, int flow)
Change share for specified station.
StationID GetViaWithRestricted(bool &is_restricted) const
Get a station a package can be routed to.
Definition: station_base.h:119
A pair-construct of a TileIndexDiff.
Definition: map_type.h:57
void ReleaseShare(StationID st)
Release ("unrestrict") a flow by moving it to the begin of the map and increasing the amount of unres...
static TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
Return the offset between to tiles from a TileIndexDiffC struct.
Definition: map_func.h:230
uint GetUnrestricted() const
Return total amount of unrestricted shares.
Definition: station_base.h:98
Set when a vehicle ever delivered cargo to the station for final delivery.
Definition: station_base.h:193
uint GetHangarNum(TileIndex tile) const
Get the hangar number of the hangar at a specific tile.
Definition: station_base.h:403
static StationID GetStationIndex(TileIndex t)
Get StationID from a tile.
Definition: station_map.h:28
StationType
Station types.
Definition: station_type.h:32
Direction dir
Direction of the exit.
uint max_waiting_cargo
Max cargo from this station waiting at any station.
Definition: station_base.h:260
StationFacility
The facilities a station might be having.
Definition: station_type.h:50
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:78
void Invalidate()
Reduce all flows to minimum capacity so that they don&#39;t get in the way of link usage statistics too m...
const SharesMap * GetShares() const
Get the actual shares as a const pointer so that they can be iterated over.
Definition: station_base.h:92
byte size_x
size of airport in x direction
void AppendShare(StationID st, uint flow, bool restricted=false)
Add some flow to the end of the shares map.
Definition: station_base.h:70
BitmapTileArea catchment_tiles
NOSAVE: Set of individual tiles covered by catchment area.
Definition: station_base.h:470
Flow statistics telling how much flow should be sent along a link.
Definition: station_base.h:36
A Stop for a Road Vehicle.
Definition: roadstop_base.h:22
Iterator to iterate over a tile area (rectangle) of the map.
Base classes/functions for base stations.
Flow descriptions by origin stations.
Definition: station_base.h:152
static TileIndexDiff TileDiffXY(int x, int y)
Calculates an offset for the given coordinate(-offset).
Definition: map_func.h:179
Airport airport
Tile area the airport covers.
Definition: station_base.h:464
TileIndex GetRotatedTileFromOffset(TileIndexDiffC tidc) const
Add the tileoffset to the base tile of this airport but rotate it first.
Definition: station_base.h:351
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
DiagDirection
Enumeration for diagonal directions.
static const TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:83
Specification of a rectangle with absolute coordinates of all edges.
IndustryType indtype
Industry type to get the name from.
Definition: station_base.h:468
byte time_since_pickup
Number of rating-intervals (up to 255) since the last vehicle tried to load this cargo.
Definition: station_base.h:233
Defines the data structure for an airport.
StationHadVehicleOfType
The vehicles that may have visited a station.
Definition: station_type.h:62
Industry * industry
NOSAVE: Associated industry for neutral stations. (Rebuilt on load from Industry->st) ...
Definition: station_base.h:483
Station data structure.
Definition: station_base.h:450
Set when the station accepts the cargo currently for final deliveries.
Definition: station_base.h:177
Class defining several overloaded accessors so we don&#39;t have to cast base stations that often...
AirportTileIterator(const Station *st)
Construct the iterator.
Definition: station_base.h:538
CargoTypes always_accepted
Bitmask of always accepted cargo types (by houses, HQs, industry tiles when industry doesn&#39;t accept c...
Definition: station_base.h:480