OpenTTD
effectvehicle.cpp
Go to the documentation of this file.
1 /* $Id: effectvehicle.cpp 27668 2016-10-16 14:59:44Z 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 "landscape.h"
14 #include "core/random_func.hpp"
15 #include "industry_map.h"
16 #include "vehicle_func.h"
17 #include "sound_func.h"
18 #include "animated_tile_func.h"
19 #include "effectvehicle_func.h"
20 #include "effectvehicle_base.h"
21 
22 #include "safeguards.h"
23 
24 
31 static bool IncrementSprite(EffectVehicle *v, SpriteID last)
32 {
33  if (v->sprite_seq.seq[0].sprite != last) {
34  v->sprite_seq.seq[0].sprite++;
35  return true;
36  } else {
37  return false;
38  }
39 }
40 
41 static void ChimneySmokeInit(EffectVehicle *v)
42 {
43  uint32 r = Random();
44  v->sprite_seq.Set(SPR_CHIMNEY_SMOKE_0 + GB(r, 0, 3));
45  v->progress = GB(r, 16, 3);
46 }
47 
48 static bool ChimneySmokeTick(EffectVehicle *v)
49 {
50  if (v->progress > 0) {
51  v->progress--;
52  } else {
53  TileIndex tile = TileVirtXY(v->x_pos, v->y_pos);
54  if (!IsTileType(tile, MP_INDUSTRY)) {
55  delete v;
56  return false;
57  }
58 
59  if (!IncrementSprite(v, SPR_CHIMNEY_SMOKE_7)) {
60  v->sprite_seq.Set(SPR_CHIMNEY_SMOKE_0);
61  }
62  v->progress = 7;
64  }
65 
66  return true;
67 }
68 
69 static void SteamSmokeInit(EffectVehicle *v)
70 {
71  v->sprite_seq.Set(SPR_STEAM_SMOKE_0);
72  v->progress = 12;
73 }
74 
75 static bool SteamSmokeTick(EffectVehicle *v)
76 {
77  bool moved = false;
78 
79  v->progress++;
80 
81  if ((v->progress & 7) == 0) {
82  v->z_pos++;
83  moved = true;
84  }
85 
86  if ((v->progress & 0xF) == 4) {
87  if (!IncrementSprite(v, SPR_STEAM_SMOKE_4)) {
88  delete v;
89  return false;
90  }
91  moved = true;
92  }
93 
94  if (moved) v->UpdatePositionAndViewport();
95 
96  return true;
97 }
98 
99 static void DieselSmokeInit(EffectVehicle *v)
100 {
101  v->sprite_seq.Set(SPR_DIESEL_SMOKE_0);
102  v->progress = 0;
103 }
104 
105 static bool DieselSmokeTick(EffectVehicle *v)
106 {
107  v->progress++;
108 
109  if ((v->progress & 3) == 0) {
110  v->z_pos++;
112  } else if ((v->progress & 7) == 1) {
113  if (!IncrementSprite(v, SPR_DIESEL_SMOKE_5)) {
114  delete v;
115  return false;
116  }
118  }
119 
120  return true;
121 }
122 
123 static void ElectricSparkInit(EffectVehicle *v)
124 {
125  v->sprite_seq.Set(SPR_ELECTRIC_SPARK_0);
126  v->progress = 1;
127 }
128 
129 static bool ElectricSparkTick(EffectVehicle *v)
130 {
131  if (v->progress < 2) {
132  v->progress++;
133  } else {
134  v->progress = 0;
135 
136  if (!IncrementSprite(v, SPR_ELECTRIC_SPARK_5)) {
137  delete v;
138  return false;
139  }
141  }
142 
143  return true;
144 }
145 
146 static void SmokeInit(EffectVehicle *v)
147 {
148  v->sprite_seq.Set(SPR_SMOKE_0);
149  v->progress = 12;
150 }
151 
152 static bool SmokeTick(EffectVehicle *v)
153 {
154  bool moved = false;
155 
156  v->progress++;
157 
158  if ((v->progress & 3) == 0) {
159  v->z_pos++;
160  moved = true;
161  }
162 
163  if ((v->progress & 0xF) == 4) {
164  if (!IncrementSprite(v, SPR_SMOKE_4)) {
165  delete v;
166  return false;
167  }
168  moved = true;
169  }
170 
171  if (moved) v->UpdatePositionAndViewport();
172 
173  return true;
174 }
175 
176 static void ExplosionLargeInit(EffectVehicle *v)
177 {
178  v->sprite_seq.Set(SPR_EXPLOSION_LARGE_0);
179  v->progress = 0;
180 }
181 
182 static bool ExplosionLargeTick(EffectVehicle *v)
183 {
184  v->progress++;
185  if ((v->progress & 3) == 0) {
186  if (!IncrementSprite(v, SPR_EXPLOSION_LARGE_F)) {
187  delete v;
188  return false;
189  }
191  }
192 
193  return true;
194 }
195 
196 static void BreakdownSmokeInit(EffectVehicle *v)
197 {
198  v->sprite_seq.Set(SPR_BREAKDOWN_SMOKE_0);
199  v->progress = 0;
200 }
201 
202 static bool BreakdownSmokeTick(EffectVehicle *v)
203 {
204  v->progress++;
205  if ((v->progress & 7) == 0) {
206  if (!IncrementSprite(v, SPR_BREAKDOWN_SMOKE_3)) {
207  v->sprite_seq.Set(SPR_BREAKDOWN_SMOKE_0);
208  }
210  }
211 
212  v->animation_state--;
213  if (v->animation_state == 0) {
214  delete v;
215  return false;
216  }
217 
218  return true;
219 }
220 
221 static void ExplosionSmallInit(EffectVehicle *v)
222 {
223  v->sprite_seq.Set(SPR_EXPLOSION_SMALL_0);
224  v->progress = 0;
225 }
226 
227 static bool ExplosionSmallTick(EffectVehicle *v)
228 {
229  v->progress++;
230  if ((v->progress & 3) == 0) {
231  if (!IncrementSprite(v, SPR_EXPLOSION_SMALL_B)) {
232  delete v;
233  return false;
234  }
236  }
237 
238  return true;
239 }
240 
241 static void BulldozerInit(EffectVehicle *v)
242 {
243  v->sprite_seq.Set(SPR_BULLDOZER_NE);
244  v->progress = 0;
245  v->animation_state = 0;
246  v->animation_substate = 0;
247 }
248 
250  byte direction:2;
251  byte image:2;
252  byte duration:3;
253 };
254 
255 static const BulldozerMovement _bulldozer_movement[] = {
256  { 0, 0, 4 },
257  { 3, 3, 4 },
258  { 2, 2, 7 },
259  { 0, 2, 7 },
260  { 1, 1, 3 },
261  { 2, 2, 7 },
262  { 0, 2, 7 },
263  { 1, 1, 3 },
264  { 2, 2, 7 },
265  { 0, 2, 7 },
266  { 3, 3, 6 },
267  { 2, 2, 6 },
268  { 1, 1, 7 },
269  { 3, 1, 7 },
270  { 0, 0, 3 },
271  { 1, 1, 7 },
272  { 3, 1, 7 },
273  { 0, 0, 3 },
274  { 1, 1, 7 },
275  { 3, 1, 7 }
276 };
277 
278 static const struct {
279  int8 x;
280  int8 y;
281 } _inc_by_dir[] = {
282  { -1, 0 },
283  { 0, 1 },
284  { 1, 0 },
285  { 0, -1 }
286 };
287 
288 static bool BulldozerTick(EffectVehicle *v)
289 {
290  v->progress++;
291  if ((v->progress & 7) == 0) {
292  const BulldozerMovement *b = &_bulldozer_movement[v->animation_state];
293 
294  v->sprite_seq.Set(SPR_BULLDOZER_NE + b->image);
295 
296  v->x_pos += _inc_by_dir[b->direction].x;
297  v->y_pos += _inc_by_dir[b->direction].y;
298 
299  v->animation_substate++;
300  if (v->animation_substate >= b->duration) {
301  v->animation_substate = 0;
302  v->animation_state++;
303  if (v->animation_state == lengthof(_bulldozer_movement)) {
304  delete v;
305  return false;
306  }
307  }
309  }
310 
311  return true;
312 }
313 
314 static void BubbleInit(EffectVehicle *v)
315 {
316  v->sprite_seq.Set(SPR_BUBBLE_GENERATE_0);
317  v->spritenum = 0;
318  v->progress = 0;
319 }
320 
322  int8 x:4;
323  int8 y:4;
324  int8 z:4;
325  byte image:4;
326 };
327 
328 #define MK(x, y, z, i) { x, y, z, i }
329 #define ME(i) { i, 4, 0, 0 }
330 
331 static const BubbleMovement _bubble_float_sw[] = {
332  MK(0, 0, 1, 0),
333  MK(1, 0, 1, 1),
334  MK(0, 0, 1, 0),
335  MK(1, 0, 1, 2),
336  ME(1)
337 };
338 
339 
340 static const BubbleMovement _bubble_float_ne[] = {
341  MK( 0, 0, 1, 0),
342  MK(-1, 0, 1, 1),
343  MK( 0, 0, 1, 0),
344  MK(-1, 0, 1, 2),
345  ME(1)
346 };
347 
348 static const BubbleMovement _bubble_float_se[] = {
349  MK(0, 0, 1, 0),
350  MK(0, 1, 1, 1),
351  MK(0, 0, 1, 0),
352  MK(0, 1, 1, 2),
353  ME(1)
354 };
355 
356 static const BubbleMovement _bubble_float_nw[] = {
357  MK(0, 0, 1, 0),
358  MK(0, -1, 1, 1),
359  MK(0, 0, 1, 0),
360  MK(0, -1, 1, 2),
361  ME(1)
362 };
363 
364 static const BubbleMovement _bubble_burst[] = {
365  MK(0, 0, 1, 2),
366  MK(0, 0, 1, 7),
367  MK(0, 0, 1, 8),
368  MK(0, 0, 1, 9),
369  ME(0)
370 };
371 
372 static const BubbleMovement _bubble_absorb[] = {
373  MK(0, 0, 1, 0),
374  MK(0, 0, 1, 1),
375  MK(0, 0, 1, 0),
376  MK(0, 0, 1, 2),
377  MK(0, 0, 1, 0),
378  MK(0, 0, 1, 1),
379  MK(0, 0, 1, 0),
380  MK(0, 0, 1, 2),
381  MK(0, 0, 1, 0),
382  MK(0, 0, 1, 1),
383  MK(0, 0, 1, 0),
384  MK(0, 0, 1, 2),
385  MK(0, 0, 1, 0),
386  MK(0, 0, 1, 1),
387  MK(0, 0, 1, 0),
388  MK(0, 0, 1, 2),
389  MK(0, 0, 1, 0),
390  MK(0, 0, 1, 1),
391  MK(0, 0, 1, 0),
392  MK(0, 0, 1, 2),
393  MK(0, 0, 1, 0),
394  MK(0, 0, 1, 1),
395  MK(0, 0, 1, 0),
396  MK(0, 0, 1, 2),
397  MK(0, 0, 1, 0),
398  MK(0, 0, 1, 1),
399  MK(0, 0, 1, 0),
400  MK(0, 0, 1, 2),
401  MK(0, 0, 1, 0),
402  MK(0, 0, 1, 1),
403  MK(0, 0, 1, 0),
404  MK(0, 0, 1, 2),
405  MK(0, 0, 1, 0),
406  MK(0, 0, 1, 1),
407  MK(0, 0, 1, 0),
408  MK(0, 0, 1, 2),
409  MK(0, 0, 1, 0),
410  MK(0, 0, 1, 1),
411  MK(0, 0, 1, 0),
412  MK(0, 0, 1, 2),
413  MK(0, 0, 1, 0),
414  MK(0, 0, 1, 1),
415  MK(0, 0, 1, 0),
416  MK(0, 0, 1, 2),
417  MK(0, 0, 1, 0),
418  MK(0, 0, 1, 1),
419  MK(0, 0, 1, 0),
420  MK(0, 0, 1, 2),
421  MK(0, 0, 1, 0),
422  MK(0, 0, 1, 1),
423  MK(0, 0, 1, 0),
424  MK(0, 0, 1, 2),
425  MK(0, 0, 1, 0),
426  MK(0, 0, 1, 1),
427  MK(0, 0, 1, 0),
428  MK(0, 0, 1, 2),
429  MK(0, 0, 1, 0),
430  MK(0, 0, 1, 1),
431  MK(0, 0, 1, 0),
432  MK(0, 0, 1, 2),
433  MK(0, 0, 1, 0),
434  MK(0, 0, 1, 1),
435  MK(2, 1, 3, 0),
436  MK(1, 1, 3, 1),
437  MK(2, 1, 3, 0),
438  MK(1, 1, 3, 2),
439  MK(2, 1, 3, 0),
440  MK(1, 1, 3, 1),
441  MK(2, 1, 3, 0),
442  MK(1, 0, 1, 2),
443  MK(0, 0, 1, 0),
444  MK(1, 0, 1, 1),
445  MK(0, 0, 1, 0),
446  MK(1, 0, 1, 2),
447  MK(0, 0, 1, 0),
448  MK(1, 0, 1, 1),
449  MK(0, 0, 1, 0),
450  MK(1, 0, 1, 2),
451  ME(2),
452  MK(0, 0, 0, 0xA),
453  MK(0, 0, 0, 0xB),
454  MK(0, 0, 0, 0xC),
455  MK(0, 0, 0, 0xD),
456  MK(0, 0, 0, 0xE),
457  ME(0)
458 };
459 #undef ME
460 #undef MK
461 
462 static const BubbleMovement * const _bubble_movement[] = {
463  _bubble_float_sw,
464  _bubble_float_ne,
465  _bubble_float_se,
466  _bubble_float_nw,
467  _bubble_burst,
468  _bubble_absorb,
469 };
470 
471 static bool BubbleTick(EffectVehicle *v)
472 {
473  uint anim_state;
474 
475  v->progress++;
476  if ((v->progress & 3) != 0) return true;
477 
478  if (v->spritenum == 0) {
479  v->sprite_seq.seq[0].sprite++;
480  if (v->sprite_seq.seq[0].sprite < SPR_BUBBLE_GENERATE_3) {
482  return true;
483  }
484  if (v->animation_substate != 0) {
485  v->spritenum = GB(Random(), 0, 2) + 1;
486  } else {
487  v->spritenum = 6;
488  }
489  anim_state = 0;
490  } else {
491  anim_state = v->animation_state + 1;
492  }
493 
494  const BubbleMovement *b = &_bubble_movement[v->spritenum - 1][anim_state];
495 
496  if (b->y == 4 && b->x == 0) {
497  delete v;
498  return false;
499  }
500 
501  if (b->y == 4 && b->x == 1) {
502  if (v->z_pos > 180 || Chance16I(1, 96, Random())) {
503  v->spritenum = 5;
504  if (_settings_client.sound.ambient) SndPlayVehicleFx(SND_2F_POP, v);
505  }
506  anim_state = 0;
507  }
508 
509  if (b->y == 4 && b->x == 2) {
510  TileIndex tile;
511 
512  anim_state++;
513  if (_settings_client.sound.ambient) SndPlayVehicleFx(SND_31_EXTRACT, v);
514 
515  tile = TileVirtXY(v->x_pos, v->y_pos);
516  if (IsTileType(tile, MP_INDUSTRY) && GetIndustryGfx(tile) == GFX_BUBBLE_CATCHER) AddAnimatedTile(tile);
517  }
518 
519  v->animation_state = anim_state;
520  b = &_bubble_movement[v->spritenum - 1][anim_state];
521 
522  v->x_pos += b->x;
523  v->y_pos += b->y;
524  v->z_pos += b->z;
525  v->sprite_seq.Set(SPR_BUBBLE_0 + b->image);
526 
528 
529  return true;
530 }
531 
532 
533 typedef void EffectInitProc(EffectVehicle *v);
534 typedef bool EffectTickProc(EffectVehicle *v);
535 
537 static EffectInitProc * const _effect_init_procs[] = {
538  ChimneySmokeInit, // EV_CHIMNEY_SMOKE
539  SteamSmokeInit, // EV_STEAM_SMOKE
540  DieselSmokeInit, // EV_DIESEL_SMOKE
541  ElectricSparkInit, // EV_ELECTRIC_SPARK
542  SmokeInit, // EV_CRASH_SMOKE
543  ExplosionLargeInit, // EV_EXPLOSION_LARGE
544  BreakdownSmokeInit, // EV_BREAKDOWN_SMOKE
545  ExplosionSmallInit, // EV_EXPLOSION_SMALL
546  BulldozerInit, // EV_BULLDOZER
547  BubbleInit, // EV_BUBBLE
548  SmokeInit, // EV_BREAKDOWN_SMOKE_AIRCRAFT
549  SmokeInit, // EV_COPPER_MINE_SMOKE
550 };
551 assert_compile(lengthof(_effect_init_procs) == EV_END);
552 
554 static EffectTickProc * const _effect_tick_procs[] = {
555  ChimneySmokeTick, // EV_CHIMNEY_SMOKE
556  SteamSmokeTick, // EV_STEAM_SMOKE
557  DieselSmokeTick, // EV_DIESEL_SMOKE
558  ElectricSparkTick, // EV_ELECTRIC_SPARK
559  SmokeTick, // EV_CRASH_SMOKE
560  ExplosionLargeTick, // EV_EXPLOSION_LARGE
561  BreakdownSmokeTick, // EV_BREAKDOWN_SMOKE
562  ExplosionSmallTick, // EV_EXPLOSION_SMALL
563  BulldozerTick, // EV_BULLDOZER
564  BubbleTick, // EV_BUBBLE
565  SmokeTick, // EV_BREAKDOWN_SMOKE_AIRCRAFT
566  SmokeTick, // EV_COPPER_MINE_SMOKE
567 };
568 assert_compile(lengthof(_effect_tick_procs) == EV_END);
569 
572  TO_INDUSTRIES, // EV_CHIMNEY_SMOKE
573  TO_INVALID, // EV_STEAM_SMOKE
574  TO_INVALID, // EV_DIESEL_SMOKE
575  TO_INVALID, // EV_ELECTRIC_SPARK
576  TO_INVALID, // EV_CRASH_SMOKE
577  TO_INVALID, // EV_EXPLOSION_LARGE
578  TO_INVALID, // EV_BREAKDOWN_SMOKE
579  TO_INVALID, // EV_EXPLOSION_SMALL
580  TO_INVALID, // EV_BULLDOZER
581  TO_INDUSTRIES, // EV_BUBBLE
582  TO_INVALID, // EV_BREAKDOWN_SMOKE_AIRCRAFT
583  TO_INDUSTRIES, // EV_COPPER_MINE_SMOKE
584 };
585 assert_compile(lengthof(_effect_transparency_options) == EV_END);
586 
587 
597 {
598  if (!Vehicle::CanAllocateItem()) return NULL;
599 
600  EffectVehicle *v = new EffectVehicle();
601  v->subtype = type;
602  v->x_pos = x;
603  v->y_pos = y;
604  v->z_pos = z;
605  v->tile = 0;
608 
609  _effect_init_procs[type](v);
610 
612 
613  return v;
614 }
615 
625 {
626  int safe_x = Clamp(x, 0, MapMaxX() * TILE_SIZE);
627  int safe_y = Clamp(y, 0, MapMaxY() * TILE_SIZE);
628  return CreateEffectVehicle(x, y, GetSlopePixelZ(safe_x, safe_y) + z, type);
629 }
630 
640 EffectVehicle *CreateEffectVehicleRel(const Vehicle *v, int x, int y, int z, EffectVehicleType type)
641 {
642  return CreateEffectVehicle(v->x_pos + x, v->y_pos + y, v->z_pos + z, type);
643 }
644 
646 {
647  return _effect_tick_procs[this->subtype](this);
648 }
649 
651 {
652  this->x_offs = 0;
653  this->y_offs = 0;
654  this->x_extent = 1;
655  this->y_extent = 1;
656  this->z_extent = 1;
657 }
658 
664 {
665  return _effect_transparency_options[this->subtype];
666 }
Flag for an invalid direction.
static bool Chance16I(const uint a, const uint b, const uint32 r)
Checks if a given randomize-number is below a given probability.
void AddAnimatedTile(TileIndex tile)
Add the given tile to the animated tile table (if it does not exist on that table yet)...
Part of an industry.
Definition: tile_type.h:51
static IndustryGfx GetIndustryGfx(TileIndex t)
Get the industry graphics ID for the given industry tile.
Definition: industry_map.h:139
byte spritenum
currently displayed sprite index 0xfd == custom sprite, 0xfe == custom second head sprite 0xff == res...
Definition: vehicle_base.h:279
Functions related to vehicles.
Vehicle data structure.
Definition: vehicle_base.h:212
byte animation_substate
Sub state to time the change of the graphics/behaviour.
void Set(SpriteID sprite)
Assign a single sprite to the sequence.
Definition: vehicle_base.h:163
bool ambient
Play ambient, industry and town sounds.
A special vehicle is one of the following:
static EffectInitProc *const _effect_init_procs[]
Functions to initialise an effect vehicle after construction.
Accessors for industries.
byte vehstatus
Status.
Definition: vehicle_base.h:317
EffectVehicle * CreateEffectVehicleAbove(int x, int y, int z, EffectVehicleType type)
Create an effect vehicle above a particular location.
static const uint TILE_SIZE
Tile size in world coordinates.
Definition: tile_type.h:15
VehicleSpriteSeq sprite_seq
Vehicle appearance.
Definition: vehicle_base.h:280
Direction
Defines the 8 directions on the map.
static bool IncrementSprite(EffectVehicle *v, SpriteID last)
Increment the sprite unless it has reached the end of the animation.
Pseudo random number generator.
byte subtype
subtype (Filled with values from #EffectVehicles/#TrainSubTypes/#AircraftSubTypes) ...
Definition: vehicle_base.h:327
Tile animation!
TransparencyOption GetTransparencyOption() const
Determines the transparency option affecting the effect.
static bool IsTileType(TileIndex tile, TileType type)
Checks if a tile is a give tiletype.
Definition: tile_map.h:143
SoundSettings sound
sound effect settings
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:76
Definition of base types and functions in a cross-platform compatible way.
A number of safeguards to prevent using unsafe methods.
void UpdateDeltaXY(Direction direction)
Updates the x and y offsets and the size of the sprite used for this vehicle.
TileIndex tile
Current tile index.
Definition: vehicle_base.h:230
Base class for all effect vehicles.
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:42
Functions related to sound.
EffectVehicle * CreateEffectVehicleRel(const Vehicle *v, int x, int y, int z, EffectVehicleType type)
Create an effect vehicle above a particular vehicle.
static T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:139
EffectVehicle * CreateEffectVehicle(int x, int y, int z, EffectVehicleType type)
Create an effect vehicle at a particular location.
bool Tick()
Calls the tick handler of the vehicle.
static TileIndex TileVirtXY(uint x, uint y)
Get a tile from the virtual XY-coordinate.
Definition: map_func.h:196
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:19
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:80
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
Invalid transparency option.
Definition: transparency.h:35
static uint MapMaxY()
Gets the maximum Y coordinate within the map, including MP_VOID.
Definition: map_func.h:113
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function() ...
Definition: pool_type.hpp:216
Functions related to OTTD&#39;s landscape.
int32 z_pos
z coordinate.
Definition: vehicle_base.h:270
EffectVehicleType
Effect vehicle types.
int32 x_pos
x coordinate.
Definition: vehicle_base.h:268
byte progress
The percentage (if divided by 256) this vehicle already crossed the tile unit.
Definition: vehicle_base.h:297
int32 y_pos
y coordinate.
Definition: vehicle_base.h:269
static uint MapMaxX()
Gets the maximum X coordinate within the map, including MP_VOID.
Definition: map_func.h:104
SpriteID sprite
The &#39;real&#39; sprite.
Definition: gfx_type.h:25
industries
Definition: transparency.h:28
uint16 animation_state
State primarily used to change the graphics/behaviour.
Functions related to effect vehicles.
void UpdatePositionAndViewport()
Update the position of the vehicle, and update the viewport.
Definition: vehicle.cpp:1589
static EffectTickProc *const _effect_tick_procs[]
Functions for controlling effect vehicles at each tick.
TransparencyOption
Transparency option bits: which position in _transparency_opt stands for which transparency.
Definition: transparency.h:24
Vehicle is not clickable by the user (shadow vehicles).
Definition: vehicle_base.h:34
static const TransparencyOption _effect_transparency_options[]
Transparency options affecting the effects.