OpenTTD
newgrf_airporttiles.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 "newgrf_airporttiles.h"
13 #include "newgrf_spritegroup.h"
14 #include "newgrf_sound.h"
15 #include "station_base.h"
16 #include "water.h"
17 #include "landscape.h"
18 #include "company_base.h"
19 #include "town.h"
20 #include "table/strings.h"
21 #include "table/airporttiles.h"
22 #include "newgrf_animation_base.h"
23 
24 #include "safeguards.h"
25 
26 
27 AirportTileSpec AirportTileSpec::tiles[NUM_AIRPORTTILES];
28 
30 
37 {
38  /* should be assert(gfx < lengthof(tiles)), but that gives compiler warnings
39  * since it's always true if the following holds: */
40  assert_compile(MAX_UVALUE(StationGfx) + 1 == lengthof(tiles));
41  return &AirportTileSpec::tiles[gfx];
42 }
43 
50 {
51  return AirportTileSpec::Get(GetAirportGfx(tile));
52 }
53 
58 {
59  memset(&AirportTileSpec::tiles, 0, sizeof(AirportTileSpec::tiles));
60  memcpy(&AirportTileSpec::tiles, &_origin_airporttile_specs, sizeof(_origin_airporttile_specs));
61 
62  /* Reset any overrides that have been set. */
63  _airporttile_mngr.ResetOverride();
64 }
65 
66 void AirportTileOverrideManager::SetEntitySpec(const AirportTileSpec *airpts)
67 {
68  StationGfx airpt_id = this->AddEntityID(airpts->grf_prop.local_id, airpts->grf_prop.grffile->grfid, airpts->grf_prop.subst_id);
69 
70  if (airpt_id == invalid_ID) {
71  grfmsg(1, "AirportTile.SetEntitySpec: Too many airport tiles allocated. Ignoring.");
72  return;
73  }
74 
75  memcpy(&AirportTileSpec::tiles[airpt_id], airpts, sizeof(*airpts));
76 
77  /* Now add the overrides. */
78  for (int i = 0; i < max_offset; i++) {
79  AirportTileSpec *overridden_airpts = &AirportTileSpec::tiles[i];
80 
81  if (entity_overrides[i] != airpts->grf_prop.local_id || grfid_overrides[i] != airpts->grf_prop.grffile->grfid) continue;
82 
83  overridden_airpts->grf_prop.override = airpt_id;
84  overridden_airpts->enabled = false;
85  entity_overrides[i] = invalid_ID;
86  grfid_overrides[i] = 0;
87  }
88 }
89 
96 {
97  const AirportTileSpec *it = AirportTileSpec::Get(gfx);
98  return it->grf_prop.override == INVALID_AIRPORTTILE ? gfx : it->grf_prop.override;
99 }
100 
109 static uint32 GetNearbyAirportTileInformation(byte parameter, TileIndex tile, StationID index, bool grf_version8)
110 {
111  if (parameter != 0) tile = GetNearbyTile(parameter, tile); // only perform if it is required
112  bool is_same_airport = (IsTileType(tile, MP_STATION) && IsAirport(tile) && GetStationIndex(tile) == index);
113 
114  return GetNearbyTileInformation(tile, grf_version8) | (is_same_airport ? 1 : 0) << 8;
115 }
116 
117 
126 static uint32 GetAirportTileIDAtOffset(TileIndex tile, const Station *st, uint32 cur_grfid)
127 {
128  if (!st->TileBelongsToAirport(tile)) {
129  return 0xFFFF;
130  }
131 
132  StationGfx gfx = GetAirportGfx(tile);
133  const AirportTileSpec *ats = AirportTileSpec::Get(gfx);
134 
135  if (gfx < NEW_AIRPORTTILE_OFFSET) { // Does it belongs to an old type?
136  /* It is an old tile. We have to see if it's been overridden */
137  if (ats->grf_prop.override == INVALID_AIRPORTTILE) { // has it been overridden?
138  return 0xFF << 8 | gfx; // no. Tag FF + the gfx id of that tile
139  }
140  /* Overridden */
141  const AirportTileSpec *tile_ovr = AirportTileSpec::Get(ats->grf_prop.override);
142 
143  if (tile_ovr->grf_prop.grffile->grfid == cur_grfid) {
144  return tile_ovr->grf_prop.local_id; // same grf file
145  } else {
146  return 0xFFFE; // not the same grf file
147  }
148  }
149  /* Not an 'old type' tile */
150  if (ats->grf_prop.spritegroup[0] != nullptr) { // tile has a spritegroup ?
151  if (ats->grf_prop.grffile->grfid == cur_grfid) { // same airport, same grf ?
152  return ats->grf_prop.local_id;
153  } else {
154  return 0xFFFE; // Defined in another grf file
155  }
156  }
157  /* The tile has no spritegroup */
158  return 0xFF << 8 | ats->grf_prop.subst_id; // so just give him the substitute
159 }
160 
161 /* virtual */ uint32 AirportTileScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
162 {
163  assert(this->st != nullptr);
164 
165  extern uint32 GetRelativePosition(TileIndex tile, TileIndex ind_tile);
166 
167  switch (variable) {
168  /* Terrain type */
169  case 0x41: return GetTerrainType(this->tile);
170 
171  /* Current town zone of the tile in the nearest town */
172  case 0x42: return GetTownRadiusGroup(ClosestTownFromTile(this->tile, UINT_MAX), this->tile);
173 
174  /* Position relative to most northern airport tile. */
175  case 0x43: return GetRelativePosition(this->tile, this->st->airport.tile);
176 
177  /* Animation frame of tile */
178  case 0x44: return GetAnimationFrame(this->tile);
179 
180  /* Land info of nearby tiles */
181  case 0x60: return GetNearbyAirportTileInformation(parameter, this->tile, this->st->index, this->ro.grffile->grf_version >= 8);
182 
183  /* Animation stage of nearby tiles */
184  case 0x61: {
185  TileIndex tile = GetNearbyTile(parameter, this->tile);
186  if (this->st->TileBelongsToAirport(tile)) {
187  return GetAnimationFrame(tile);
188  }
189  return UINT_MAX;
190  }
191 
192  /* Get airport tile ID at offset */
193  case 0x62: return GetAirportTileIDAtOffset(GetNearbyTile(parameter, this->tile), this->st, this->ro.grffile->grfid);
194  }
195 
196  DEBUG(grf, 1, "Unhandled airport tile variable 0x%X", variable);
197 
198  *available = false;
199  return UINT_MAX;
200 }
201 
202 /* virtual */ uint32 AirportTileScopeResolver::GetRandomBits() const
203 {
204  return (this->st == nullptr ? 0 : this->st->random_bits) | (this->tile == INVALID_TILE ? 0 : GetStationTileRandomBits(this->tile) << 16);
205 }
206 
217  CallbackID callback, uint32 callback_param1, uint32 callback_param2)
218  : ResolverObject(ats->grf_prop.grffile, callback, callback_param1, callback_param2), tiles_scope(*this, ats, tile, st)
219 {
220  this->root_spritegroup = ats->grf_prop.spritegroup[0];
221 }
222 
223 uint16 GetAirportTileCallback(CallbackID callback, uint32 param1, uint32 param2, const AirportTileSpec *ats, Station *st, TileIndex tile, int extra_data = 0)
224 {
225  AirportTileResolverObject object(ats, tile, st, callback, param1, param2);
226  return object.ResolveCallback();
227 }
228 
229 static void AirportDrawTileLayout(const TileInfo *ti, const TileLayoutSpriteGroup *group, byte colour, StationGfx gfx)
230 {
231  const DrawTileSprites *dts = group->ProcessRegisters(nullptr);
232 
233  SpriteID image = dts->ground.sprite;
234  SpriteID pal = dts->ground.pal;
235 
236  if (GB(image, 0, SPRITE_WIDTH) != 0) {
237  if (image == SPR_FLAT_WATER_TILE && IsTileOnWater(ti->tile)) {
238  DrawWaterClassGround(ti);
239  } else {
240  DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, GENERAL_SPRITE_COLOUR(colour)));
241  }
242  }
243 
244  DrawNewGRFTileSeq(ti, dts, TO_BUILDINGS, 0, GENERAL_SPRITE_COLOUR(colour));
245 }
246 
247 bool DrawNewAirportTile(TileInfo *ti, Station *st, StationGfx gfx, const AirportTileSpec *airts)
248 {
249  if (ti->tileh != SLOPE_FLAT) {
250  bool draw_old_one = true;
252  /* Called to determine the type (if any) of foundation to draw */
253  uint32 callback_res = GetAirportTileCallback(CBID_AIRPTILE_DRAW_FOUNDATIONS, 0, 0, airts, st, ti->tile);
254  if (callback_res != CALLBACK_FAILED) draw_old_one = ConvertBooleanCallback(airts->grf_prop.grffile, CBID_AIRPTILE_DRAW_FOUNDATIONS, callback_res);
255  }
256 
257  if (draw_old_one) DrawFoundation(ti, FOUNDATION_LEVELED);
258  }
259 
260  AirportTileResolverObject object(airts, ti->tile, st);
261  const SpriteGroup *group = object.Resolve();
262  if (group == nullptr || group->type != SGT_TILELAYOUT) {
263  return false;
264  }
265 
266  const TileLayoutSpriteGroup *tlgroup = (const TileLayoutSpriteGroup *)group;
267  AirportDrawTileLayout(ti, tlgroup, Company::Get(st->owner)->colour, gfx);
268  return true;
269 }
270 
272 struct AirportTileAnimationBase : public AnimationBase<AirportTileAnimationBase, AirportTileSpec, Station, int, GetAirportTileCallback> {
273  static const CallbackID cb_animation_speed = CBID_AIRPTILE_ANIMATION_SPEED;
274  static const CallbackID cb_animation_next_frame = CBID_AIRPTILE_ANIM_NEXT_FRAME;
275 
276  static const AirportTileCallbackMask cbm_animation_speed = CBM_AIRT_ANIM_SPEED;
277  static const AirportTileCallbackMask cbm_animation_next_frame = CBM_AIRT_ANIM_NEXT_FRAME;
278 };
279 
280 void AnimateAirportTile(TileIndex tile)
281 {
282  const AirportTileSpec *ats = AirportTileSpec::GetByTile(tile);
283  if (ats == nullptr) return;
284 
286 }
287 
288 void AirportTileAnimationTrigger(Station *st, TileIndex tile, AirpAnimationTrigger trigger, CargoID cargo_type)
289 {
290  const AirportTileSpec *ats = AirportTileSpec::GetByTile(tile);
291  if (!HasBit(ats->animation.triggers, trigger)) return;
292 
293  AirportTileAnimationBase::ChangeAnimationFrame(CBID_AIRPTILE_ANIM_START_STOP, ats, st, tile, Random(), (uint8)trigger | (cargo_type << 8));
294 }
295 
296 void AirportAnimationTrigger(Station *st, AirpAnimationTrigger trigger, CargoID cargo_type)
297 {
298  if (st->airport.tile == INVALID_TILE) return;
299 
300  TILE_AREA_LOOP(tile, st->airport) {
301  if (st->TileBelongsToAirport(tile)) AirportTileAnimationTrigger(st, tile, trigger, cargo_type);
302  }
303 }
304 
Definition of stuff that is very close to a company, like the company struct itself.
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
Tile information, used while rendering the tile.
Definition: tile_cmd.h:42
company buildings - depots, stations, HQ, ...
Definition: transparency.h:27
uint32 GetRelativePosition(TileIndex tile, TileIndex ind_tile)
This is the position of the tile relative to the northernmost tile of the industry.
uint16 triggers
The triggers that trigger animation.
Called to determine airport tile next animation frame.
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:291
decides animation speed
static const AirportTileSpec * GetByTile(TileIndex tile)
Retrieve airport tile spec for the given airport tile.
static byte GetAnimationFrame(TileIndex t)
Get the current animation frame.
Definition: tile_map.h:250
Functions related to debugging.
static void DrawNewGRFTileSeq(const struct TileInfo *ti, const DrawTileSprites *dts, TransparencyOption to, uint32 stage, PaletteID default_palette)
Draw NewGRF industrytile or house sprite layout.
Definition: sprite.h:124
Interface for SpriteGroup-s to access the gamestate.
uint32 GetTerrainType(TileIndex tile, TileContext context)
Function used by houses (and soon industries) to get information on type of "terrain" the tile it is ...
Slope tileh
Slope of the tile.
Definition: tile_cmd.h:45
static const uint INVALID_AIRPORTTILE
id for an invalid airport tile
Definition: airport.h:25
static StationGfx GetAirportGfx(TileIndex t)
Get the station graphics of this airport tile.
Definition: station_map.h:244
static void ChangeAnimationFrame(CallbackID cb, const AirportTileSpec *spec, Station *obj, TileIndex tile, uint32 random_bits, uint32 trigger, int extra_data=0)
Check a callback to determine what the next animation step is and execute that step.
a flat tile
Definition: slope_type.h:49
static void AnimateTile(const AirportTileSpec *spec, Station *obj, TileIndex tile, bool random_animation, int extra_data=0)
Animate a single tile.
void DrawFoundation(TileInfo *ti, Foundation f)
Draw foundation f at tile ti.
Definition: landscape.cpp:470
const SpriteGroup * root_spritegroup
Root SpriteGroup to use for resolving.
AirportTileResolverObject(const AirportTileSpec *ats, TileIndex tile, Station *st, CallbackID callback=CBID_NO_CALLBACK, uint32 callback_param1=0, uint32 callback_param2=0)
Constructor of the resolver for airport tiles.
Town * ClosestTownFromTile(TileIndex tile, uint threshold)
Return the town closest (in distance or ownership) to a given tile, within a given threshold...
Definition: town_cmd.cpp:3488
virtual const SpriteGroup * Resolve(ResolverObject &object) const
Base sprite group resolver.
Action 2 handling.
TileIndex GetNearbyTile(byte parameter, TileIndex tile, bool signed_offsets, Axis axis)
Get the tile at the given offset.
static bool IsTileType(TileIndex tile, TileType type)
Checks if a tile is a given tiletype.
Definition: tile_map.h:150
const DrawTileSprites * ProcessRegisters(uint8 *stage) const
Process registers and the construction stage into the sprite layout.
TileIndex tile
Tile index.
Definition: tile_cmd.h:46
decides if default foundations need to be drawn
The tile is leveled up to a flat slope.
Definition: slope_type.h:95
static uint32 GetAirportTileIDAtOffset(TileIndex tile, const Station *st, uint32 cur_grfid)
Make an analysis of a tile and check whether it belongs to the same airport, and/or the same grf file...
Ground palette sprite of a tile, together with its sprite layout.
Definition: sprite.h:58
Resolver for tiles of an airport.
decides next animation frame
bool ConvertBooleanCallback(const GRFFile *grffile, uint16 cbid, uint16 cb_res)
Converts a callback result into a boolean.
#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 void ResetAirportTiles()
This function initializes the tile array of AirportTileSpec.
Function implementations related to NewGRF animation.
bool enabled
entity still available (by default true). newgrf can disable it, though
A number of safeguards to prevent using unsafe methods.
static PaletteID GroundSpritePaletteTransform(SpriteID image, PaletteID pal, PaletteID default_pal)
Applies PALETTE_MODIFIER_COLOUR to a palette entry of a ground sprite.
Definition: sprite.h:168
static const uint NUM_AIRPORTTILES
Total number of airport tiles.
Definition: airport.h:23
static bool IsAirport(TileIndex t)
Is this station tile an airport?
Definition: station_map.h:157
uint8 animation_special_flags
Extra flags to influence the animation.
static const AirportTileSpec * Get(StationGfx gfx)
Retrieve airport tile spec for the given airport tile.
AirportTileCallbackMask
Callback masks for airport tiles.
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:40
#define MAX_UVALUE(type)
The largest value that can be entered in a variable.
Definition: stdafx.h:469
number of bits for the sprite number
Definition: sprites.h:1512
HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile)
Returns the bit corresponding to the town zone of the specified tile.
Definition: town_cmd.cpp:2181
const struct SpriteGroup * spritegroup[Tcnt]
pointer to the different sprites of the entity
Helper class for animation control.
NewGRF handling of airport tiles.
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:35
uint16 override
id of the entity been replaced by
TileIndex tile
The base tile of the area.
Definition: tilearea_type.h:17
byte StationGfx
Copy from station_map.h.
Called to determine the type (if any) of foundation to draw for an airport tile.
static StationID GetStationIndex(TileIndex t)
Get StationID from a tile.
Definition: station_map.h:28
PalSpriteID ground
Palette and sprite for the ground.
Definition: sprite.h:59
uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override
Get a variable value.
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:17
uint32 GetNearbyTileInformation(TileIndex tile, bool grf_version8)
Common part of station var 0x67, house var 0x62, indtile var 0x60, industry var 0x62.
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:78
Helper class for a unified approach to NewGRF animation.
AnimationInfo animation
Information about the animation.
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:375
CallbackID callback
Callback being resolved.
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
static const AirportTileSpec _origin_airporttile_specs[]
All default airport tiles.
Definition: airporttiles.h:22
A tile of a station.
Definition: tile_type.h:46
static Station * GetByTile(TileIndex tile)
Get the station belonging to a specific tile.
Called to indicate how long the current animation frame should last.
Functions related to OTTD&#39;s landscape.
Defines the data structure of each individual tile of an airport.
void DrawGroundSprite(SpriteID image, PaletteID pal, const SubSprite *sub, int extra_offs_x, int extra_offs_y)
Draws a ground sprite for the current tile.
Definition: viewport.cpp:575
Owner owner
The owner of this station.
uint8 callback_mask
Bitmask telling which grf callback is set.
uint16 local_id
id defined by the grf file for this entity
uint32 GetRandomBits() const override
Get a few random bits.
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
CallbackID
List of implemented NewGRF callbacks.
Called for periodically starting or stopping the animation.
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
Functions related to NewGRF provided sounds.
static const TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:83
Base of the town class.
static const uint NEW_AIRPORTTILE_OFFSET
offset of first newgrf airport tile
Definition: airport.h:24
byte CargoID
Cargo slots to indicate a cargo type within a game.
Definition: cargo_type.h:20
Functions related to water (management)
static bool IsTileOnWater(TileIndex t)
Tests if the tile was built on water.
Definition: water_map.h:130
StationGfx GetTranslatedAirportTileID(StationGfx gfx)
Do airporttile gfx ID translation for NewGRFs.
SpriteID sprite
The &#39;real&#39; sprite.
Definition: gfx_type.h:23
Base classes/functions for stations.
Action 2 sprite layout for houses, industry tiles, objects and airport tiles.
GRFFileProps grf_prop
properties related the the grf file
static byte GetStationTileRandomBits(TileIndex t)
Get the random bits of a station tile.
Definition: station_map.h:517
Tables with airporttile defaults.
static uint32 GetNearbyAirportTileInformation(byte parameter, TileIndex tile, StationID index, bool grf_version8)
Based on newhouses/newindustries equivalent, but adapted for airports.
Station data structure.
Definition: station_base.h:450
AirpAnimationTrigger
Animation triggers for airport tiles.
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition: gfx_type.h:24