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