OpenTTD
station_base.h
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 #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 "bitmap_type.h"
23 #include <map>
24 #include <set>
25 
28 
29 static const byte INITIAL_STATION_RATING = 175;
30 
38 class FlowStat {
39 public:
40  typedef std::map<uint32, StationID> SharesMap;
41 
42  static const SharesMap empty_sharesmap;
43 
49  inline FlowStat() {NOT_REACHED();}
50 
57  inline FlowStat(StationID st, uint flow, bool restricted = false)
58  {
59  assert(flow > 0);
60  this->shares[flow] = st;
61  this->unrestricted = restricted ? 0 : flow;
62  }
63 
72  inline void AppendShare(StationID st, uint flow, bool restricted = false)
73  {
74  assert(flow > 0);
75  this->shares[(--this->shares.end())->first + flow] = st;
76  if (!restricted) this->unrestricted += flow;
77  }
78 
79  uint GetShare(StationID st) const;
80 
81  void ChangeShare(StationID st, int flow);
82 
83  void RestrictShare(StationID st);
84 
85  void ReleaseShare(StationID st);
86 
87  void ScaleToMonthly(uint runtime);
88 
94  inline const SharesMap *GetShares() const { return &this->shares; }
95 
100  inline uint GetUnrestricted() const { return this->unrestricted; }
101 
107  inline void SwapShares(FlowStat &other)
108  {
109  this->shares.swap(other.shares);
110  Swap(this->unrestricted, other.unrestricted);
111  }
112 
121  inline StationID GetViaWithRestricted(bool &is_restricted) const
122  {
123  assert(!this->shares.empty());
124  uint rand = RandomRange((--this->shares.end())->first);
125  is_restricted = rand >= this->unrestricted;
126  return this->shares.upper_bound(rand)->second;
127  }
128 
136  inline StationID GetVia() const
137  {
138  assert(!this->shares.empty());
139  return this->unrestricted > 0 ?
140  this->shares.upper_bound(RandomRange(this->unrestricted))->second :
141  INVALID_STATION;
142  }
143 
144  StationID GetVia(StationID excluded, StationID excluded2 = INVALID_STATION) const;
145 
146  void Invalidate();
147 
148 private:
149  SharesMap shares;
151 };
152 
154 class FlowStatMap : public std::map<StationID, FlowStat> {
155 public:
156  uint GetFlow() const;
157  uint GetFlowVia(StationID via) const;
158  uint GetFlowFrom(StationID from) const;
159  uint GetFlowFromVia(StationID from, StationID via) const;
160 
161  void AddFlow(StationID origin, StationID via, uint amount);
162  void PassOnFlow(StationID origin, StationID via, uint amount);
163  StationIDStack DeleteFlows(StationID via);
164  void RestrictFlows(StationID via);
165  void ReleaseFlows(StationID via);
166  void FinalizeLocalConsumption(StationID self);
167 };
168 
172 struct GoodsEntry {
180 
190 
196 
202 
208 
214  };
215 
216  GoodsEntry() :
217  status(0),
218  time_since_pickup(255),
219  rating(INITIAL_STATION_RATING),
220  last_speed(0),
221  last_age(255),
222  amount_fract(0),
223  link_graph(INVALID_LINK_GRAPH),
224  node(INVALID_NODE),
225  max_waiting_cargo(0)
226  {}
227 
228  byte status;
229 
236 
237  byte rating;
238 
249 
254  byte last_age;
255 
258 
259  LinkGraphID link_graph;
260  NodeID node;
263 
269  bool HasVehicleEverTriedLoading() const { return this->last_speed != 0; }
270 
275  inline bool HasRating() const
276  {
277  return HasBit(this->status, GES_RATING);
278  }
279 
285  inline StationID GetVia(StationID source) const
286  {
287  FlowStatMap::const_iterator flow_it(this->flows.find(source));
288  return flow_it != this->flows.end() ? flow_it->second.GetVia() : INVALID_STATION;
289  }
290 
299  inline StationID GetVia(StationID source, StationID excluded, StationID excluded2 = INVALID_STATION) const
300  {
301  FlowStatMap::const_iterator flow_it(this->flows.find(source));
302  return flow_it != this->flows.end() ? flow_it->second.GetVia(excluded, excluded2) : INVALID_STATION;
303  }
304 };
305 
307 struct Airport : public TileArea {
308  Airport() : TileArea(INVALID_TILE, 0, 0) {}
309 
310  uint64 flags;
311  byte type;
312  byte layout;
314 
316 
322  const AirportSpec *GetSpec() const
323  {
324  if (this->tile == INVALID_TILE) return &AirportSpec::dummy;
325  return AirportSpec::Get(this->type);
326  }
327 
334  const AirportFTAClass *GetFTA() const
335  {
336  return this->GetSpec()->fsm;
337  }
338 
340  inline bool HasHangar() const
341  {
342  return this->GetSpec()->nof_depots > 0;
343  }
344 
354  {
355  const AirportSpec *as = this->GetSpec();
356  switch (this->rotation) {
357  case DIR_N: return this->tile + ToTileIndexDiff(tidc);
358 
359  case DIR_E: return this->tile + TileDiffXY(tidc.y, as->size_x - 1 - tidc.x);
360 
361  case DIR_S: return this->tile + TileDiffXY(as->size_x - 1 - tidc.x, as->size_y - 1 - tidc.y);
362 
363  case DIR_W: return this->tile + TileDiffXY(as->size_y - 1 - tidc.y, tidc.x);
364 
365  default: NOT_REACHED();
366  }
367  }
368 
375  inline TileIndex GetHangarTile(uint hangar_num) const
376  {
377  const AirportSpec *as = this->GetSpec();
378  for (uint i = 0; i < as->nof_depots; i++) {
379  if (as->depot_table[i].hangar_num == hangar_num) {
380  return this->GetRotatedTileFromOffset(as->depot_table[i].ti);
381  }
382  }
383  NOT_REACHED();
384  }
385 
393  {
394  const AirportSpec *as = this->GetSpec();
395  const HangarTileTable *htt = GetHangarDataByTile(tile);
396  return ChangeDir(htt->dir, DirDifference(this->rotation, as->rotation[0]));
397  }
398 
405  inline uint GetHangarNum(TileIndex tile) const
406  {
407  const HangarTileTable *htt = GetHangarDataByTile(tile);
408  return htt->hangar_num;
409  }
410 
412  inline uint GetNumHangars() const
413  {
414  uint num = 0;
415  uint counted = 0;
416  const AirportSpec *as = this->GetSpec();
417  for (uint i = 0; i < as->nof_depots; i++) {
418  if (!HasBit(counted, as->depot_table[i].hangar_num)) {
419  num++;
420  SetBit(counted, as->depot_table[i].hangar_num);
421  }
422  }
423  return num;
424  }
425 
426 private:
434  {
435  const AirportSpec *as = this->GetSpec();
436  for (uint i = 0; i < as->nof_depots; i++) {
437  if (this->GetRotatedTileFromOffset(as->depot_table[i].ti) == tile) {
438  return as->depot_table + i;
439  }
440  }
441  NOT_REACHED();
442  }
443 };
444 
446  bool operator() (const Industry *lhs, const Industry *rhs) const;
447 };
448 
449 typedef std::set<Industry *, IndustryCompare> IndustryList;
450 
452 struct Station FINAL : SpecializedStation<Station, false> {
453 public:
454  RoadStop *GetPrimaryRoadStop(RoadStopType type) const
455  {
456  return type == ROADSTOP_BUS ? bus_stops : truck_stops;
457  }
458 
459  RoadStop *GetPrimaryRoadStop(const struct RoadVehicle *v) const;
460 
465 
469 
470  IndustryType indtype;
471 
473 
474  StationHadVehicleOfType had_vehicle_of_type;
475 
476  byte time_since_load;
477  byte time_since_unload;
478 
479  byte last_vehicle_type;
480  std::list<Vehicle *> loading_vehicles;
482  CargoTypes always_accepted;
483 
484  IndustryList industries_near;
486 
488  ~Station();
489 
490  void AddFacility(StationFacility new_facility_bit, TileIndex facil_xy);
491 
492  void MarkTilesDirty(bool cargo_change) const;
493 
494  void UpdateVirtCoord() override;
495 
496  void MoveSign(TileIndex new_xy) override;
497 
498  void AfterStationTileSetChange(bool adding, StationType type);
499 
500  uint GetPlatformLength(TileIndex tile, DiagDirection dir) const override;
501  uint GetPlatformLength(TileIndex tile) const override;
502  void RecomputeCatchment();
503  static void RecomputeCatchmentForAll();
504 
505  uint GetCatchmentRadius() const;
506  Rect GetCatchmentRect() const;
507  bool CatchmentCoversTown(TownID t) const;
508  void RemoveFromAllNearbyLists();
509 
510  inline bool TileIsInCatchment(TileIndex tile) const
511  {
512  return this->catchment_tiles.HasTile(tile);
513  }
514 
515  inline bool TileBelongsToRailStation(TileIndex tile) const override
516  {
517  return IsRailStationTile(tile) && GetStationIndex(tile) == this->index;
518  }
519 
520  inline bool TileBelongsToAirport(TileIndex tile) const
521  {
522  return IsAirportTile(tile) && GetStationIndex(tile) == this->index;
523  }
524 
525  uint32 GetNewGRFVariable(const ResolverObject &object, byte variable, byte parameter, bool *available) const override;
526 
527  void GetTileArea(TileArea *ta, StationType type) const override;
528 };
529 
530 #define FOR_ALL_STATIONS(var) FOR_ALL_BASE_STATIONS_OF_TYPE(Station, var)
531 
534 private:
535  const Station *st;
536 
537 public:
542  AirportTileIterator(const Station *st) : OrthogonalTileIterator(st->airport), st(st)
543  {
544  if (!st->TileBelongsToAirport(this->tile)) ++(*this);
545  }
546 
547  inline TileIterator& operator ++()
548  {
549  (*this).OrthogonalTileIterator::operator++();
550  while (this->tile != INVALID_TILE && !st->TileBelongsToAirport(this->tile)) {
551  (*this).OrthogonalTileIterator::operator++();
552  }
553  return *this;
554  }
555 
556  virtual TileIterator *Clone() const
557  {
558  return new AirportTileIterator(*this);
559  }
560 };
561 
562 void RebuildStationKdtree();
563 
564 #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:311
const HangarTileTable * GetHangarDataByTile(TileIndex tile) const
Retrieve hangar information of a hangar at a given tile.
Definition: station_base.h:433
Finite sTate mAchine (FTA) of an airport.
Definition: airport.h:145
Types related to the industry.
const AirportSpec * GetSpec() const
Get the AirportSpec that from the airport type of this airport.
Definition: station_base.h:322
TileArea bus_station
Tile area the bus &#39;station&#39; part covers.
Definition: station_base.h:462
Direction rotation
How this airport is rotated.
Definition: station_base.h:313
Minimal stack that uses a pool to avoid pointers.
const Station * st
The station the airport is a part of.
Definition: station_base.h:535
TileArea ship_station
Tile area the ship &#39;station&#39; part covers.
Definition: station_base.h:467
Direction GetHangarExitDirection(TileIndex tile) const
Get the exit direction of the hangar at a specific tile.
Definition: station_base.h:392
byte size_y
size of airport in y direction
Iterator to iterate over all tiles belonging to an airport.
Definition: station_base.h:533
SharesMap shares
Shares of flow to be sent via specified station (or consumed locally).
Definition: station_base.h:149
bool HasVehicleEverTriedLoading() const
Reports whether a vehicle has ever tried to load the cargo at this station.
Definition: station_base.h:269
static bool IsAirportTile(TileIndex t)
Is this tile a station tile and an airport tile?
Definition: station_map.h:169
uint GetNumHangars() const
Get the number of hangars on this airport.
Definition: station_base.h:412
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:340
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:334
West.
void SwapShares(FlowStat &other)
Swap the shares maps, and thus the content of this FlowStat with the other one.
Definition: station_base.h:107
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:66
Set when cargo was delivered for final delivery during the current STATION_ACCEPTANCE_TICKS interval...
Definition: station_base.h:213
Set when cargo was delivered for final delivery this month.
Definition: station_base.h:207
const HangarTileTable * depot_table
gives the position of the depots on the airports
A standard stop for buses.
Definition: station_type.h:47
Defines the internal data of a functional industry.
Definition: industry.h:42
Stores station stats for a single cargo.
Definition: station_base.h:172
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:556
StationPool _station_pool
The pool of stations.
StationCargoList cargo
The cargo packets of cargo waiting in this station.
Definition: station_base.h:257
bool HasRating() const
Does this cargo have a rating at this station?
Definition: station_base.h:275
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:46
North.
NewGRF handling of airports.
Pseudo random number generator.
int16 y
The y value of the coordinate.
Definition: map_type.h:61
Set when cargo was delivered for final delivery last month.
Definition: station_base.h:201
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:468
Buses, trucks and trams belong to this class.
Definition: roadveh.h:109
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:515
byte amount_fract
Fractional part of the amount in the cargo list.
Definition: station_base.h:256
byte rating
Station rating for this cargo.
Definition: station_base.h:237
OrthogonalTileArea TileArea
Shorthand for the much more common orthogonal tile area.
Definition: tilearea_type.h:98
RoadStop * truck_stops
All the truck stops.
Definition: station_base.h:463
This indicates whether a cargo has a rating at the station.
Definition: station_base.h:189
StationID GetVia(StationID source) const
Get the best next hop for a cargo packet from station source.
Definition: station_base.h:285
LinkGraphID link_graph
Link graph this station belongs to.
Definition: station_base.h:259
uint unrestricted
Limit for unrestricted shares.
Definition: station_base.h:150
GoodsEntryStatus
Status of this cargo for the station.
Definition: station_base.h:174
FlowStat()
Invalid constructor.
Definition: station_base.h:49
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
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:136
TileArea truck_station
Tile area the truck &#39;station&#39; part covers.
Definition: station_base.h:464
byte status
Status of this cargo, see GoodsEntryStatus.
Definition: station_base.h:228
byte layout
Airport layout number.
Definition: station_base.h:312
FlowStat(StationID st, uint flow, bool restricted=false)
Create a FlowStat with an initial entry.
Definition: station_base.h:57
int16 x
The x value of the coordinate.
Definition: map_type.h:60
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:299
NodeID node
ID of node in link graph referring to this goods entry.
Definition: station_base.h:260
Represents the covered area of e.g.
Definition: tilearea_type.h:18
Class for pooled persistent storage of data.
Represents a tile area containing containing individually set tiles.
Definition: bitmap_type.h:21
South.
Base class for tile iterators.
static const AirportSpec * Get(byte type)
Retrieve airport spec for the given airport.
PersistentStorage * psa
Persistent storage for NewGRF airports.
Definition: station_base.h:315
All airport-related information.
Definition: station_base.h:307
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:310
static const SharesMap empty_sharesmap
Static instance of FlowStat::SharesMap.
Definition: station_base.h:42
byte last_speed
Maximum speed (up to 255) of the last vehicle that tried to load this cargo.
Definition: station_base.h:248
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:102
byte last_age
Age in years (up to 255) of the last vehicle that tried to load this cargo.
Definition: station_base.h:254
TileIndex GetHangarTile(uint hangar_num) const
Get the first tile of the given hangar.
Definition: station_base.h:375
TileIndexDiffC ti
Tile offset from the top-most airport tile.
RoadStop * bus_stops
All the road stops.
Definition: station_base.h:461
Base class for all pools.
Definition: pool_type.hpp:83
FlowStatMap flows
Planned flows through this station.
Definition: station_base.h:261
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:121
A pair-construct of a TileIndexDiff.
Definition: map_type.h:59
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:100
Set when a vehicle ever delivered cargo to the station for final delivery.
Definition: station_base.h:195
uint GetHangarNum(TileIndex tile) const
Get the hangar number of the hangar at a specific tile.
Definition: station_base.h:405
static StationID GetStationIndex(TileIndex t)
Get StationID from a tile.
Definition: station_map.h:30
StationType
Station types.
Definition: station_type.h:34
Direction dir
Direction of the exit.
uint max_waiting_cargo
Max cargo from this station waiting at any station.
Definition: station_base.h:262
StationFacility
The facilities a station might be having.
Definition: station_type.h:52
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:94
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:72
BitmapTileArea catchment_tiles
NOSAVE: Set of individual tiles covered by catchment area.
Definition: station_base.h:472
Flow statistics telling how much flow should be sent along a link.
Definition: station_base.h:38
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:154
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:466
TileIndex GetRotatedTileFromOffset(TileIndexDiffC tidc) const
Add the tileoffset to the base tile of this airport but rotate it first.
Definition: station_base.h:353
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:85
Specification of a rectangle with absolute coordinates of all edges.
IndustryType indtype
Industry type to get the name from.
Definition: station_base.h:470
byte time_since_pickup
Number of rating-intervals (up to 255) since the last vehicle tried to load this cargo.
Definition: station_base.h:235
Defines the data structure for an airport.
StationHadVehicleOfType
The vehicles that may have visited a station.
Definition: station_type.h:64
Industry * industry
NOSAVE: Associated industry for neutral stations. (Rebuilt on load from Industry->st) ...
Definition: station_base.h:485
Station data structure.
Definition: station_base.h:452
Set when the station accepts the cargo currently for final deliveries.
Definition: station_base.h:179
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:542
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:482