OpenTTD
station_base.h
Go to the documentation of this file.
1 /* $Id: station_base.h 27178 2015-03-07 18:27:01Z frosch $ */
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 #ifndef STATION_BASE_H
13 #define STATION_BASE_H
14 
15 #include "core/random_func.hpp"
16 #include "base_station_base.h"
17 #include "newgrf_airport.h"
18 #include "cargopacket.h"
19 #include "industry_type.h"
21 #include "newgrf_storage.h"
22 #include <map>
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 
446 struct Station FINAL : SpecializedStation<Station, false> {
447 public:
448  RoadStop *GetPrimaryRoadStop(RoadStopType type) const
449  {
450  return type == ROADSTOP_BUS ? bus_stops : truck_stops;
451  }
452 
453  RoadStop *GetPrimaryRoadStop(const struct RoadVehicle *v) const;
454 
459 
462 
463  IndustryType indtype;
464 
465  StationHadVehicleOfTypeByte had_vehicle_of_type;
466 
467  byte time_since_load;
468  byte time_since_unload;
469 
470  byte last_vehicle_type;
471  std::list<Vehicle *> loading_vehicles;
474 
476 
478  ~Station();
479 
480  void AddFacility(StationFacility new_facility_bit, TileIndex facil_xy);
481 
482  void MarkTilesDirty(bool cargo_change) const;
483 
484  void UpdateVirtCoord();
485 
486  /* virtual */ uint GetPlatformLength(TileIndex tile, DiagDirection dir) const;
487  /* virtual */ uint GetPlatformLength(TileIndex tile) const;
488  void RecomputeIndustriesNear();
489  static void RecomputeIndustriesNearForAll();
490 
491  uint GetCatchmentRadius() const;
492  Rect GetCatchmentRect() const;
493 
494  /* virtual */ inline bool TileBelongsToRailStation(TileIndex tile) const
495  {
496  return IsRailStationTile(tile) && GetStationIndex(tile) == this->index;
497  }
498 
499  inline bool TileBelongsToAirport(TileIndex tile) const
500  {
501  return IsAirportTile(tile) && GetStationIndex(tile) == this->index;
502  }
503 
504  /* virtual */ uint32 GetNewGRFVariable(const ResolverObject &object, byte variable, byte parameter, bool *available) const;
505 
506  /* virtual */ void GetTileArea(TileArea *ta, StationType type) const;
507 };
508 
509 #define FOR_ALL_STATIONS(var) FOR_ALL_BASE_STATIONS_OF_TYPE(Station, var)
510 
513 private:
514  const Station *st;
515 
516 public:
521  AirportTileIterator(const Station *st) : OrthogonalTileIterator(st->airport), st(st)
522  {
523  if (!st->TileBelongsToAirport(this->tile)) ++(*this);
524  }
525 
526  inline TileIterator& operator ++()
527  {
528  (*this).OrthogonalTileIterator::operator++();
529  while (this->tile != INVALID_TILE && !st->TileBelongsToAirport(this->tile)) {
530  (*this).OrthogonalTileIterator::operator++();
531  }
532  return *this;
533  }
534 
535  virtual TileIterator *Clone() const
536  {
537  return new AirportTileIterator(*this);
538  }
539 };
540 
541 #endif /* STATION_BASE_H */
static void Swap(T &a, T &b)
Type safe swap operation.
Definition: math_func.hpp:277
byte type
Type of this airport,.
Definition: station_base.h:309
IndustryVector industries_near
Cached list of industries near the station that can accept cargo,.
Definition: station_base.h:475
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:144
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:456
Minimal stack that uses a pool to avoid pointers.
const Station * st
The station the airport is a part of.
Definition: station_base.h:514
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:512
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:168
East.
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:463
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
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.
Set when cargo was delivered for final delivery during the current STATION_ACCEPTANCE_TICKS interval...
Definition: station_base.h:211
TileIndex dock_tile
The location of the dock.
Definition: station_base.h:461
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:48
Stores station stats for a single cargo.
Definition: station_base.h:170
StationFacility
The facilities a station might be having.
Definition: station_type.h:53
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:535
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:83
RoadStopType
Types of RoadStops.
Definition: station_type.h:47
Direction
Defines the 8 directions on the map.
NewGRF handling of airports.
Pseudo random number generator.
uint32 always_accepted
Bitmask of always accepted cargo types (by houses, HQs, industry tiles when industry doesn&#39;t accept c...
Definition: station_base.h:473
int16 y
The y value of the coordinate.
Definition: map_type.h:60
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.
Buses, trucks and trams belong to this class.
Definition: roadveh.h:88
uint GetShare(StationID st) const
Get flow for a station.
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:457
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
West.
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:103
const Direction * rotation
the rotation of each tiletable
North.
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:458
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:59
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:18
Class for pooled persistent storage of data.
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
DiagDirection
Enumeration for diagonal directions.
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.
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.
DirectionByte rotation
How this airport is rotated.
Definition: station_base.h:311
RoadStop * bus_stops
All the road stops.
Definition: station_base.h:455
Base class for all pools.
Definition: pool_type.hpp:83
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
Maximal number of cargo types in a game.
Definition: cargo_type.h:66
A pair-construct of a TileIndexDiff.
Definition: map_type.h:58
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:232
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:29
StationType
Station types.
Definition: station_type.h:35
Direction dir
Direction of the exit.
uint max_waiting_cargo
Max cargo from this station waiting at any station.
Definition: station_base.h:260
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:80
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
bool TileBelongsToRailStation(TileIndex tile) const
Check whether a specific tile belongs to this station.
Definition: station_base.h:494
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:24
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:181
Airport airport
Tile area the airport covers.
Definition: station_base.h:460
South.
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.
static const TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:85
Specification of a rectangle with absolute coordinates of all edges.
IndustryType indtype
Industry type to get the name from.
Definition: station_base.h:463
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.
Station data structure.
Definition: station_base.h:446
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:521