OpenTTD Source  1.10.0-RC1
newgrf_airport.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
10 #include "stdafx.h"
11 #include "debug.h"
12 #include "date_func.h"
13 #include "newgrf_spritegroup.h"
14 #include "newgrf_text.h"
15 #include "station_base.h"
16 #include "newgrf_class_func.h"
17 
18 #include "safeguards.h"
19 
22  struct Station *st;
23  byte airport_id;
24  byte layout;
26 
35  AirportScopeResolver(ResolverObject &ro, TileIndex tile, Station *st, byte airport_id, byte layout)
36  : ScopeResolver(ro), st(st), airport_id(airport_id), layout(layout), tile(tile)
37  {
38  }
39 
40  uint32 GetRandomBits() const override;
41  uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override;
42  void StorePSA(uint pos, int32 value) override;
43 };
44 
47  AirportScopeResolver airport_scope;
48 
50  CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0);
51 
52  ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override
53  {
54  switch (scope) {
55  case VSG_SCOPE_SELF: return &this->airport_scope;
56  default: return ResolverObject::GetScope(scope, relative);
57  }
58  }
59 
60  const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const override;
61 
62  GrfSpecFeature GetFeature() const override;
63  uint32 GetDebugID() const override;
64 };
65 
71 template <typename Tspec, typename Tid, Tid Tmax>
73 {
74  AirportClass::Get(AirportClass::Allocate('SMAL'))->name = STR_AIRPORT_CLASS_SMALL;
75  AirportClass::Get(AirportClass::Allocate('LARG'))->name = STR_AIRPORT_CLASS_LARGE;
76  AirportClass::Get(AirportClass::Allocate('HUB_'))->name = STR_AIRPORT_CLASS_HUB;
77  AirportClass::Get(AirportClass::Allocate('HELI'))->name = STR_AIRPORT_CLASS_HELIPORTS;
78 }
79 
80 template <typename Tspec, typename Tid, Tid Tmax>
82 {
83  return true;
84 }
85 
87 
88 
90 
92 
99 /* static */ const AirportSpec *AirportSpec::Get(byte type)
100 {
101  assert(type < lengthof(AirportSpec::specs));
102  const AirportSpec *as = &AirportSpec::specs[type];
103  if (type >= NEW_AIRPORT_OFFSET && !as->enabled) {
104  if (_airport_mngr.GetGRFID(type) == 0) return as;
105  byte subst_id = _airport_mngr.GetSubstituteID(type);
106  if (subst_id == AT_INVALID) return as;
107  as = &AirportSpec::specs[subst_id];
108  }
109  if (as->grf_prop.override != AT_INVALID) return &AirportSpec::specs[as->grf_prop.override];
110  return as;
111 }
112 
120 {
121  assert(type < lengthof(AirportSpec::specs));
122  return &AirportSpec::specs[type];
123 }
124 
127 {
128  if (!this->enabled) return false;
129  if (_cur_year < this->min_year) return false;
131  return _cur_year <= this->max_year;
132 }
133 
141 {
142  if (table >= this->num_table) return false;
143 
144  byte w = this->size_x;
145  byte h = this->size_y;
146  if (this->rotation[table] == DIR_E || this->rotation[table] == DIR_W) Swap(w, h);
147 
148  return TileX(tile) + w < MapSizeX() &&
149  TileY(tile) + h < MapSizeY();
150 }
151 
156 {
157  extern const AirportSpec _origin_airport_specs[];
158  memset(&AirportSpec::specs, 0, sizeof(AirportSpec::specs));
159  memcpy(&AirportSpec::specs, &_origin_airport_specs, sizeof(AirportSpec) * NEW_AIRPORT_OFFSET);
160 
161  _airport_mngr.ResetOverride();
162 }
163 
168 {
169  for (int i = 0; i < NUM_AIRPORTS; i++) {
171  if (as->enabled) AirportClass::Assign(as);
172  }
173 }
174 
175 
176 void AirportOverrideManager::SetEntitySpec(AirportSpec *as)
177 {
178  byte airport_id = this->AddEntityID(as->grf_prop.local_id, as->grf_prop.grffile->grfid, as->grf_prop.subst_id);
179 
180  if (airport_id == invalid_ID) {
181  grfmsg(1, "Airport.SetEntitySpec: Too many airports allocated. Ignoring.");
182  return;
183  }
184 
185  memcpy(AirportSpec::GetWithoutOverride(airport_id), as, sizeof(*as));
186 
187  /* Now add the overrides. */
188  for (int i = 0; i < max_offset; i++) {
189  AirportSpec *overridden_as = AirportSpec::GetWithoutOverride(i);
190 
191  if (entity_overrides[i] != as->grf_prop.local_id || grfid_overrides[i] != as->grf_prop.grffile->grfid) continue;
192 
193  overridden_as->grf_prop.override = airport_id;
194  overridden_as->enabled = false;
195  entity_overrides[i] = invalid_ID;
196  grfid_overrides[i] = 0;
197  }
198 }
199 
200 /* virtual */ uint32 AirportScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
201 {
202  switch (variable) {
203  case 0x40: return this->layout;
204  }
205 
206  if (this->st == nullptr) {
207  *available = false;
208  return UINT_MAX;
209  }
210 
211  switch (variable) {
212  /* Get a variable from the persistent storage */
213  case 0x7C: return (this->st->airport.psa != nullptr) ? this->st->airport.psa->GetValue(parameter) : 0;
214 
215  case 0xF0: return this->st->facilities;
216  case 0xFA: return Clamp(this->st->build_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535);
217  }
218 
219  return this->st->GetNewGRFVariable(this->ro, variable, parameter, available);
220 }
221 
222 /* virtual */ const SpriteGroup *AirportResolverObject::ResolveReal(const RealSpriteGroup *group) const
223 {
224  /* Airport action 2s should always have only 1 "loaded" state, but some
225  * times things don't follow the spec... */
226  if (group->num_loaded > 0) return group->loaded[0];
227  if (group->num_loading > 0) return group->loading[0];
228 
229  return nullptr;
230 }
231 
233 {
234  return GSF_AIRPORTS;
235 }
236 
238 {
239  return AirportSpec::Get(this->airport_scope.airport_id)->grf_prop.local_id;
240 }
241 
242 /* virtual */ uint32 AirportScopeResolver::GetRandomBits() const
243 {
244  return this->st == nullptr ? 0 : this->st->random_bits;
245 }
246 
252 /* virtual */ void AirportScopeResolver::StorePSA(uint pos, int32 value)
253 {
254  if (this->st == nullptr) return;
255 
256  if (this->st->airport.psa == nullptr) {
257  /* There is no need to create a storage if the value is zero. */
258  if (value == 0) return;
259 
260  /* Create storage on first modification. */
261  uint32 grfid = (this->ro.grffile != nullptr) ? this->ro.grffile->grfid : 0;
263  this->st->airport.psa = new PersistentStorage(grfid, GSF_AIRPORTS, this->st->airport.tile);
264  }
265  this->st->airport.psa->StoreValue(pos, value);
266 }
267 
279  CallbackID callback, uint32 param1, uint32 param2)
280  : ResolverObject(AirportSpec::Get(airport_id)->grf_prop.grffile, callback, param1, param2), airport_scope(*this, tile, st, airport_id, layout)
281 {
282  this->root_spritegroup = AirportSpec::Get(airport_id)->grf_prop.spritegroup[0];
283 }
284 
285 SpriteID GetCustomAirportSprite(const AirportSpec *as, byte layout)
286 {
287  AirportResolverObject object(INVALID_TILE, nullptr, as->GetIndex(), layout);
288  const SpriteGroup *group = object.Resolve();
289  if (group == nullptr) return as->preview_sprite;
290 
291  return group->GetResult();
292 }
293 
294 uint16 GetAirportCallback(CallbackID callback, uint32 param1, uint32 param2, Station *st, TileIndex tile)
295 {
296  AirportResolverObject object(tile, st, st->airport.type, st->airport.layout, callback, param1, param2);
297  return object.ResolveCallback();
298 }
299 
307 StringID GetAirportTextCallback(const AirportSpec *as, byte layout, uint16 callback)
308 {
309  AirportResolverObject object(INVALID_TILE, nullptr, as->GetIndex(), layout, (CallbackID)callback);
310  uint16 cb_res = object.ResolveCallback();
311  if (cb_res == CALLBACK_FAILED || cb_res == 0x400) return STR_UNDEFINED;
312  if (cb_res > 0x400) {
313  ErrorUnknownCallbackResult(as->grf_prop.grffile->grfid, callback, cb_res);
314  return STR_UNDEFINED;
315  }
316 
317  return GetGRFStringID(as->grf_prop.grffile->grfid, 0xD000 + cb_res);
318 }
Implementation of the NewGRF class&#39; functions.
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
Interface to query and set values specific to a single VarSpriteGroupScope (action 2 scope)...
TileIndex tile
Tile for the callback, only valid for airporttile callbacks.
StationFacility facilities
The facilities that this station has.
static uint MapSizeX()
Get the size of the map along the X.
Definition: map_func.h:72
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:80
void StorePSA(uint pos, int32 value) override
Store a value into the object&#39;s persistent storage.
bool IsAvailable() const
Check whether this airport is available to build.
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
static uint MapSizeY()
Get the size of the map along the Y.
Definition: map_func.h:82
AirportClassID
List of default airport classes.
static AirportSpec * GetWithoutOverride(byte type)
Retrieve airport spec for the given airport.
ResolverObject & ro
Surrounding resolver object.
#define DAYS_TILL_ORIGINAL_BASE_YEAR
The offset in days from the &#39;_date == 0&#39; till &#39;ConvertYMDToDate(ORIGINAL_BASE_YEAR, 0, 1)&#39;.
Definition: date_type.h:80
VarSpriteGroupScope
Functions related to dates.
West.
Functions related to debugging.
Interface for SpriteGroup-s to access the gamestate.
uint32 GetGRFID(uint16 entity_id) const
Gives the GRFID of the file the entity belongs to.
byte GetIndex() const
Get the index of this spec.
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:205
bool never_expire_airports
never expire airports
Set when using the callback resolve system, but not to resolve a callback.
AirportResolverObject(TileIndex tile, Station *st, byte airport_id, byte layout, CallbackID callback=CBID_NO_CALLBACK, uint32 callback_param1=0, uint32 callback_param2=0)
Constructor of the airport resolver.
#define INSTANTIATE_NEWGRF_CLASS_METHODS(name, Tspec, Tid, Tmax)
Force instantiation of the methods so we don&#39;t get linker errors.
AirportScopeResolver(ResolverObject &ro, TileIndex tile, Station *st, byte airport_id, byte layout)
Constructor of the scope resolver for an airport.
virtual ScopeResolver * GetScope(VarSpriteGroupScope scope=VSG_SCOPE_SELF, byte relative=0)
Get a resolver for the scope.
StringID GetGRFStringID(uint32 grfid, StringID stringid)
Returns the index for this stringid associated with its grfID.
byte num_loaded
Number of loaded groups.
uint32 GetRandomBits() const override
Get a few random bits.
bool IsUIAvailable(uint index) const
Check whether the spec will be available to the user at some point in time.
Year _cur_year
Current year, starting at 0.
Definition: date.cpp:25
StationSettings station
settings related to station management
const SpriteGroup * root_spritegroup
Root SpriteGroup to use for resolving.
Invalid airport.
Definition: airport.h:42
Header of Action 04 "universal holder" structure and functions.
Maximal number of airports in total.
Definition: airport.h:41
Struct containing information relating to NewGRF classes for stations and airports.
Definition: newgrf_class.h:19
GrfSpecFeature
Definition: newgrf.h:66
virtual const SpriteGroup * Resolve(ResolverObject &object) const
Base sprite group resolver.
Action 2 handling.
TYPE GetValue(uint pos) const
Gets the value from a given position.
const SpriteGroup ** loaded
List of loaded groups (can be SpriteIDs or Callback results)
uint32 GetDebugID() const override
Get an identifier for the item being resolved.
Number of the first newgrf airport.
Definition: airport.h:39
void StoreValue(uint pos, int32 value)
Stores some value at a given position.
uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override
Get a variable value.
East.
maximum number of airport classes
static void ResetAirports()
This function initializes the airportspec array.
byte layout
Airport layout number.
Definition: station_base.h:310
Definition of base types and functions in a cross-platform compatible way.
A number of safeguards to prevent using unsafe methods.
Class for pooled persistent storage of data.
GrfSpecFeature GetFeature() const override
Get the feature number being resolved for.
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
const SpriteGroup ** loading
List of loading groups (can be SpriteIDs or Callback results)
Resolver for the airport scope.
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:40
static AirportSpec specs[NUM_AIRPORTS]
Specs of the airports.
Resolved object itself.
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:16
const struct SpriteGroup * spritegroup[Tcnt]
pointer to the different sprites of the entity
struct Station * st
Station of the airport for which the callback is run, or nullptr for build gui.
byte layout
Layout of the airport to build.
static T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:137
uint16 override
id of the entity been replaced by
TileIndex tile
The base tile of the area.
Definition: tilearea_type.h:17
void BindAirportSpecs()
Tie all airportspecs to their class.
byte num_loading
Number of loading groups.
const GRFFile * grffile
GRFFile the resolved SpriteGroup belongs to.
void ErrorUnknownCallbackResult(uint32 grfid, uint16 cbid, uint16 cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:17
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:78
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:215
bool IsWithinMapBounds(byte table, TileIndex index) const
Check if the airport would be within the map bounds at the given tile.
void CDECL grfmsg(int severity, const char *str,...)
DEBUG() function dedicated to newGRF debugging messages Function is essentially the same as DEBUG(grf...
Definition: newgrf.cpp:380
CallbackID callback
Callback being resolved.
static NewGRFClass * Get(Tid cls_id)
Get a particular class.
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function() ...
Definition: pool_type.hpp:299
byte airport_id
Type of airport for which the callback is run.
uint16 local_id
id defined by the grf file for this entity
Resolver object for airports.
static void InsertDefaults()
Initialise the defaults.
ScopeResolver * GetScope(VarSpriteGroupScope scope=VSG_SCOPE_SELF, byte relative=0) override
Get a resolver for the scope.
uint16 random_bits
Random bits assigned to this station.
Airport airport
Tile area the airport covers.
Definition: station_base.h:464
void ResetOverride()
Resets the override, which is used while initializing game.
const struct GRFFile * grffile
grf file that introduced this entity
bool enabled
Entity still available (by default true). Newgrf can disable it, though.
CallbackID
List of implemented NewGRF callbacks.
SpriteID preview_sprite
preview sprite for this airport
static const TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:83
Defines the data structure for an airport.
Base classes/functions for stations.
StringID GetAirportTextCallback(const AirportSpec *as, byte layout, uint16 callback)
Get a custom text for the airport.
static const NIFeature * GetFeature(uint window_number)
Get the NIFeature related to the window number.
Station data structure.
Definition: station_base.h:450
struct GRFFileProps grf_prop
Properties related to the grf file.
const SpriteGroup * ResolveReal(const RealSpriteGroup *group) const override
Get the real sprites of the grf.
Date build_date
Date of construction.
uint16 GetSubstituteID(uint16 entity_id) const
Gives the substitute of the entity, as specified by the grf file.
StringID name
Name of this class.
Definition: newgrf_class.h:39