OpenTTD
newgrf_airporttiles.cpp
Go to the documentation of this file.
1 /* $Id: newgrf_airporttiles.cpp 27984 2018-03-11 13:19:41Z 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 #include "stdafx.h"
13 #include "debug.h"
14 #include "newgrf_airporttiles.h"
15 #include "newgrf_spritegroup.h"
16 #include "newgrf_sound.h"
17 #include "station_base.h"
18 #include "water.h"
19 #include "landscape.h"
20 #include "company_base.h"
21 #include "town.h"
22 #include "table/strings.h"
23 #include "table/airporttiles.h"
24 #include "newgrf_animation_base.h"
25 
26 #include "safeguards.h"
27 
28 
29 AirportTileSpec AirportTileSpec::tiles[NUM_AIRPORTTILES];
30 
32 
39 {
40  /* should be assert(gfx < lengthof(tiles)), but that gives compiler warnings
41  * since it's always true if the following holds: */
42  assert_compile(MAX_UVALUE(StationGfx) + 1 == lengthof(tiles));
43  return &AirportTileSpec::tiles[gfx];
44 }
45 
52 {
53  return AirportTileSpec::Get(GetAirportGfx(tile));
54 }
55 
60 {
61  memset(&AirportTileSpec::tiles, 0, sizeof(AirportTileSpec::tiles));
62  memcpy(&AirportTileSpec::tiles, &_origin_airporttile_specs, sizeof(_origin_airporttile_specs));
63 
64  /* Reset any overrides that have been set. */
65  _airporttile_mngr.ResetOverride();
66 }
67 
68 void AirportTileOverrideManager::SetEntitySpec(const AirportTileSpec *airpts)
69 {
70  StationGfx airpt_id = this->AddEntityID(airpts->grf_prop.local_id, airpts->grf_prop.grffile->grfid, airpts->grf_prop.subst_id);
71 
72  if (airpt_id == invalid_ID) {
73  grfmsg(1, "AirportTile.SetEntitySpec: Too many airport tiles allocated. Ignoring.");
74  return;
75  }
76 
77  memcpy(&AirportTileSpec::tiles[airpt_id], airpts, sizeof(*airpts));
78 
79  /* Now add the overrides. */
80  for (int i = 0; i < max_offset; i++) {
81  AirportTileSpec *overridden_airpts = &AirportTileSpec::tiles[i];
82 
83  if (entity_overrides[i] != airpts->grf_prop.local_id || grfid_overrides[i] != airpts->grf_prop.grffile->grfid) continue;
84 
85  overridden_airpts->grf_prop.override = airpt_id;
86  overridden_airpts->enabled = false;
87  entity_overrides[i] = invalid_ID;
88  grfid_overrides[i] = 0;
89  }
90 }
91 
98 {
99  const AirportTileSpec *it = AirportTileSpec::Get(gfx);
100  return it->grf_prop.override == INVALID_AIRPORTTILE ? gfx : it->grf_prop.override;
101 }
102 
111 static uint32 GetNearbyAirportTileInformation(byte parameter, TileIndex tile, StationID index, bool grf_version8)
112 {
113  if (parameter != 0) tile = GetNearbyTile(parameter, tile); // only perform if it is required
114  bool is_same_airport = (IsTileType(tile, MP_STATION) && IsAirport(tile) && GetStationIndex(tile) == index);
115 
116  return GetNearbyTileInformation(tile, grf_version8) | (is_same_airport ? 1 : 0) << 8;
117 }
118 
119 
128 static uint32 GetAirportTileIDAtOffset(TileIndex tile, const Station *st, uint32 cur_grfid)
129 {
130  if (!st->TileBelongsToAirport(tile)) {
131  return 0xFFFF;
132  }
133 
134  StationGfx gfx = GetAirportGfx(tile);
135  const AirportTileSpec *ats = AirportTileSpec::Get(gfx);
136 
137  if (gfx < NEW_AIRPORTTILE_OFFSET) { // Does it belongs to an old type?
138  /* It is an old tile. We have to see if it's been overridden */
139  if (ats->grf_prop.override == INVALID_AIRPORTTILE) { // has it been overridden?
140  return 0xFF << 8 | gfx; // no. Tag FF + the gfx id of that tile
141  }
142  /* Overridden */
143  const AirportTileSpec *tile_ovr = AirportTileSpec::Get(ats->grf_prop.override);
144 
145  if (tile_ovr->grf_prop.grffile->grfid == cur_grfid) {
146  return tile_ovr->grf_prop.local_id; // same grf file
147  } else {
148  return 0xFFFE; // not the same grf file
149  }
150  }
151  /* Not an 'old type' tile */
152  if (ats->grf_prop.spritegroup[0] != NULL) { // tile has a spritegroup ?
153  if (ats->grf_prop.grffile->grfid == cur_grfid) { // same airport, same grf ?
154  return ats->grf_prop.local_id;
155  } else {
156  return 0xFFFE; // Defined in another grf file
157  }
158  }
159  /* The tile has no spritegroup */
160  return 0xFF << 8 | ats->grf_prop.subst_id; // so just give him the substitute
161 }
162 
163 /* virtual */ uint32 AirportTileScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
164 {
165  assert(this->st != NULL);
166 
167  extern uint32 GetRelativePosition(TileIndex tile, TileIndex ind_tile);
168 
169  switch (variable) {
170  /* Terrain type */
171  case 0x41: return GetTerrainType(this->tile);
172 
173  /* Current town zone of the tile in the nearest town */
174  case 0x42: return GetTownRadiusGroup(ClosestTownFromTile(this->tile, UINT_MAX), this->tile);
175 
176  /* Position relative to most northern airport tile. */
177  case 0x43: return GetRelativePosition(this->tile, this->st->airport.tile);
178 
179  /* Animation frame of tile */
180  case 0x44: return GetAnimationFrame(this->tile);
181 
182  /* Land info of nearby tiles */
183  case 0x60: return GetNearbyAirportTileInformation(parameter, this->tile, this->st->index, this->ro.grffile->grf_version >= 8);
184 
185  /* Animation stage of nearby tiles */
186  case 0x61: {
187  TileIndex tile = GetNearbyTile(parameter, this->tile);
188  if (this->st->TileBelongsToAirport(tile)) {
189  return GetAnimationFrame(tile);
190  }
191  return UINT_MAX;
192  }
193 
194  /* Get airport tile ID at offset */
195  case 0x62: return GetAirportTileIDAtOffset(GetNearbyTile(parameter, this->tile), this->st, this->ro.grffile->grfid);
196  }
197 
198  DEBUG(grf, 1, "Unhandled airport tile variable 0x%X", variable);
199 
200  *available = false;
201  return UINT_MAX;
202 }
203 
204 /* virtual */ uint32 AirportTileScopeResolver::GetRandomBits() const
205 {
206  return (this->st == NULL ? 0 : this->st->random_bits) | (this->tile == INVALID_TILE ? 0 : GetStationTileRandomBits(this->tile) << 16);
207 }
208 
219  CallbackID callback, uint32 callback_param1, uint32 callback_param2)
220  : ResolverObject(ats->grf_prop.grffile, callback, callback_param1, callback_param2), tiles_scope(*this, ats, tile, st)
221 {
222  this->root_spritegroup = ats->grf_prop.spritegroup[0];
223 }
224 
225 uint16 GetAirportTileCallback(CallbackID callback, uint32 param1, uint32 param2, const AirportTileSpec *ats, Station *st, TileIndex tile, int extra_data = 0)
226 {
227  AirportTileResolverObject object(ats, tile, st, callback, param1, param2);
228  return object.ResolveCallback();
229 }
230 
231 static void AirportDrawTileLayout(const TileInfo *ti, const TileLayoutSpriteGroup *group, byte colour, StationGfx gfx)
232 {
233  const DrawTileSprites *dts = group->ProcessRegisters(NULL);
234 
235  SpriteID image = dts->ground.sprite;
236  SpriteID pal = dts->ground.pal;
237 
238  if (GB(image, 0, SPRITE_WIDTH) != 0) {
239  if (image == SPR_FLAT_WATER_TILE && IsTileOnWater(ti->tile)) {
240  DrawWaterClassGround(ti);
241  } else {
242  DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, GENERAL_SPRITE_COLOUR(colour)));
243  }
244  }
245 
246  DrawNewGRFTileSeq(ti, dts, TO_BUILDINGS, 0, GENERAL_SPRITE_COLOUR(colour));
247 }
248 
249 bool DrawNewAirportTile(TileInfo *ti, Station *st, StationGfx gfx, const AirportTileSpec *airts)
250 {
251  if (ti->tileh != SLOPE_FLAT) {
252  bool draw_old_one = true;
254  /* Called to determine the type (if any) of foundation to draw */
255  uint32 callback_res = GetAirportTileCallback(CBID_AIRPTILE_DRAW_FOUNDATIONS, 0, 0, airts, st, ti->tile);
256  if (callback_res != CALLBACK_FAILED) draw_old_one = ConvertBooleanCallback(airts->grf_prop.grffile, CBID_AIRPTILE_DRAW_FOUNDATIONS, callback_res);
257  }
258 
259  if (draw_old_one) DrawFoundation(ti, FOUNDATION_LEVELED);
260  }
261 
262  AirportTileResolverObject object(airts, ti->tile, st);
263  const SpriteGroup *group = object.Resolve();
264  if (group == NULL || group->type != SGT_TILELAYOUT) {
265  return false;
266  }
267 
268  const TileLayoutSpriteGroup *tlgroup = (const TileLayoutSpriteGroup *)group;
269  AirportDrawTileLayout(ti, tlgroup, Company::Get(st->owner)->colour, gfx);
270  return true;
271 }
272 
274 struct AirportTileAnimationBase : public AnimationBase<AirportTileAnimationBase, AirportTileSpec, Station, int, GetAirportTileCallback> {
275  static const CallbackID cb_animation_speed = CBID_AIRPTILE_ANIMATION_SPEED;
276  static const CallbackID cb_animation_next_frame = CBID_AIRPTILE_ANIM_NEXT_FRAME;
277 
278  static const AirportTileCallbackMask cbm_animation_speed = CBM_AIRT_ANIM_SPEED;
279  static const AirportTileCallbackMask cbm_animation_next_frame = CBM_AIRT_ANIM_NEXT_FRAME;
280 };
281 
282 void AnimateAirportTile(TileIndex tile)
283 {
284  const AirportTileSpec *ats = AirportTileSpec::GetByTile(tile);
285  if (ats == NULL) return;
286 
288 }
289 
290 void AirportTileAnimationTrigger(Station *st, TileIndex tile, AirpAnimationTrigger trigger, CargoID cargo_type)
291 {
292  const AirportTileSpec *ats = AirportTileSpec::GetByTile(tile);
293  if (!HasBit(ats->animation.triggers, trigger)) return;
294 
295  AirportTileAnimationBase::ChangeAnimationFrame(CBID_AIRPTILE_ANIM_START_STOP, ats, st, tile, Random(), (uint8)trigger | (cargo_type << 8));
296 }
297 
298 void AirportAnimationTrigger(Station *st, AirpAnimationTrigger trigger, CargoID cargo_type)
299 {
300  if (st->airport.tile == INVALID_TILE) return;
301 
302  TILE_AREA_LOOP(tile, st->airport) {
303  if (st->TileBelongsToAirport(tile)) AirportTileAnimationTrigger(st, tile, trigger, cargo_type);
304  }
305 }
306 
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:44
company buildings - depots, stations, HQ, ...
Definition: transparency.h:29
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:246
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:243
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:126
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:47
static const uint INVALID_AIRPORTTILE
id for an invalid airport tile
Definition: airport.h:27
static StationGfx GetAirportGfx(TileIndex t)
Get the station graphics of this airport tile.
Definition: station_map.h:245
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:51
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:390
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:3239
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 give tiletype.
Definition: tile_map.h:143
const DrawTileSprites * ProcessRegisters(uint8 *stage) const
Process registers and the construction stage into the sprite layout.
TileIndex tile
Tile index.
Definition: tile_cmd.h:48
decides if default foundations need to be drawn
The tile is leveled up to a flat slope.
Definition: slope_type.h:97
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:60
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:170
static const uint NUM_AIRPORTTILES
Total number of airport tiles.
Definition: airport.h:25
static bool IsAirport(TileIndex t)
Is this station tile an airport?
Definition: station_map.h:158
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:42
#define MAX_UVALUE(type)
The largest value that can be entered in a variable.
Definition: stdafx.h:515
number of bits for the sprite number
Definition: sprites.h:1494
HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile)
Returns the bit corresponding to the town zone of the specified tile.
Definition: town_cmd.cpp:1998
const struct SpriteGroup * spritegroup[Tcnt]
pointer to the different sprites of the entity
Helper class for animation control.
NewGRF handling of airport tiles.
uint32 GetVariable(byte variable, uint32 parameter, bool *available) const
Get a variable value.
uint32 GetRandomBits() const
Get a few random bits.
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:39
uint16 override
id of the entity been replaced by
TileIndex tile
The base tile of the area.
Definition: tilearea_type.h:19
OwnerByte owner
The owner of this station.
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:29
PalSpriteID ground
Palette and sprite for the ground.
Definition: sprite.h:61
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:19
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:80
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:24
A tile of a station.
Definition: tile_type.h:48
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:604
uint8 callback_mask
Bitmask telling which grf callback is set.
uint16 local_id
id defined by the grf file for this entity
Airport airport
Tile area the airport covers.
Definition: station_base.h:460
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:85
Base of the town class.
static const uint NEW_AIRPORTTILE_OFFSET
offset of first newgrf airport tile
Definition: airport.h:26
byte CargoID
Cargo slots to indicate a cargo type within a game.
Definition: cargo_type.h:22
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:25
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:518
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:446
AirpAnimationTrigger
Animation triggers for airport tiles.
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition: gfx_type.h:26