glx@10294: /* $Id$ */ glx@10294: rubidium@10455: /** @file effectvehicle.cpp Implementation of everything generic to vehicles. */ glx@10294: glx@10294: #include "stdafx.h" glx@10294: #include "openttd.h" glx@10294: #include "road_map.h" glx@10294: #include "roadveh.h" glx@10294: #include "ship.h" glx@10294: #include "spritecache.h" glx@10294: #include "tile_cmd.h" glx@10294: #include "landscape.h" glx@10294: #include "timetable.h" glx@10294: #include "viewport_func.h" glx@10294: #include "gfx_func.h" glx@10294: #include "news_func.h" glx@10294: #include "command_func.h" glx@10294: #include "saveload.h" glx@10294: #include "player_func.h" glx@10294: #include "debug.h" glx@10294: #include "vehicle_gui.h" glx@10294: #include "rail_type.h" glx@10294: #include "train.h" glx@10294: #include "aircraft.h" glx@10294: #include "industry_map.h" glx@10294: #include "station_map.h" glx@10294: #include "water_map.h" glx@10294: #include "yapf/yapf.h" glx@10294: #include "newgrf_callbacks.h" glx@10294: #include "newgrf_engine.h" glx@10294: #include "newgrf_sound.h" glx@10294: #include "group.h" glx@10294: #include "order_func.h" glx@10294: #include "strings_func.h" glx@10294: #include "zoom_func.h" glx@10294: #include "functions.h" glx@10294: #include "date_func.h" glx@10294: #include "window_func.h" glx@10294: #include "vehicle_func.h" glx@10294: #include "signal_func.h" glx@10294: #include "sound_func.h" glx@10294: #include "variables.h" glx@10294: #include "autoreplace_func.h" glx@10294: #include "autoreplace_gui.h" glx@10294: #include "string_func.h" glx@10294: #include "settings_type.h" glx@10294: #include "oldpool_func.h" glx@10294: #include "depot_map.h" glx@10294: #include "animated_tile_func.h" glx@10294: #include "effectvehicle_base.h" glx@10294: #include "effectvehicle_func.h" glx@10294: glx@10294: #include "table/sprites.h" glx@10294: #include "table/strings.h" glx@10294: glx@10294: static void ChimneySmokeInit(Vehicle *v) glx@10294: { glx@10294: uint32 r = Random(); glx@10294: v->cur_image = SPR_CHIMNEY_SMOKE_0 + GB(r, 0, 3); glx@10294: v->progress = GB(r, 16, 3); glx@10294: } glx@10294: glx@10294: static void ChimneySmokeTick(Vehicle *v) glx@10294: { glx@10294: if (v->progress > 0) { glx@10294: v->progress--; glx@10294: } else { glx@10294: BeginVehicleMove(v); glx@10294: glx@10294: TileIndex tile = TileVirtXY(v->x_pos, v->y_pos); glx@10294: if (!IsTileType(tile, MP_INDUSTRY)) { glx@10294: EndVehicleMove(v); glx@10294: delete v; glx@10294: return; glx@10294: } glx@10294: glx@10294: if (v->cur_image != SPR_CHIMNEY_SMOKE_7) { glx@10294: v->cur_image++; glx@10294: } else { glx@10294: v->cur_image = SPR_CHIMNEY_SMOKE_0; glx@10294: } glx@10294: v->progress = 7; glx@10294: VehiclePositionChanged(v); glx@10294: EndVehicleMove(v); glx@10294: } glx@10294: } glx@10294: glx@10294: static void SteamSmokeInit(Vehicle *v) glx@10294: { glx@10294: v->cur_image = SPR_STEAM_SMOKE_0; glx@10294: v->progress = 12; glx@10294: } glx@10294: glx@10294: static void SteamSmokeTick(Vehicle *v) glx@10294: { glx@10294: bool moved = false; glx@10294: glx@10294: BeginVehicleMove(v); glx@10294: glx@10294: v->progress++; glx@10294: glx@10294: if ((v->progress & 7) == 0) { glx@10294: v->z_pos++; glx@10294: moved = true; glx@10294: } glx@10294: glx@10294: if ((v->progress & 0xF) == 4) { glx@10294: if (v->cur_image != SPR_STEAM_SMOKE_4) { glx@10294: v->cur_image++; glx@10294: } else { glx@10294: EndVehicleMove(v); glx@10294: delete v; glx@10294: return; glx@10294: } glx@10294: moved = true; glx@10294: } glx@10294: glx@10294: if (moved) { glx@10294: VehiclePositionChanged(v); glx@10294: EndVehicleMove(v); glx@10294: } glx@10294: } glx@10294: glx@10294: static void DieselSmokeInit(Vehicle *v) glx@10294: { glx@10294: v->cur_image = SPR_DIESEL_SMOKE_0; glx@10294: v->progress = 0; glx@10294: } glx@10294: glx@10294: static void DieselSmokeTick(Vehicle *v) glx@10294: { glx@10294: v->progress++; glx@10294: glx@10294: if ((v->progress & 3) == 0) { glx@10294: BeginVehicleMove(v); glx@10294: v->z_pos++; glx@10294: VehiclePositionChanged(v); glx@10294: EndVehicleMove(v); glx@10294: } else if ((v->progress & 7) == 1) { glx@10294: BeginVehicleMove(v); glx@10294: if (v->cur_image != SPR_DIESEL_SMOKE_5) { glx@10294: v->cur_image++; glx@10294: VehiclePositionChanged(v); glx@10294: EndVehicleMove(v); glx@10294: } else { glx@10294: EndVehicleMove(v); glx@10294: delete v; glx@10294: } glx@10294: } glx@10294: } glx@10294: glx@10294: static void ElectricSparkInit(Vehicle *v) glx@10294: { glx@10294: v->cur_image = SPR_ELECTRIC_SPARK_0; glx@10294: v->progress = 1; glx@10294: } glx@10294: glx@10294: static void ElectricSparkTick(Vehicle *v) glx@10294: { glx@10294: if (v->progress < 2) { glx@10294: v->progress++; glx@10294: } else { glx@10294: v->progress = 0; glx@10294: BeginVehicleMove(v); glx@10294: if (v->cur_image != SPR_ELECTRIC_SPARK_5) { glx@10294: v->cur_image++; glx@10294: VehiclePositionChanged(v); glx@10294: EndVehicleMove(v); glx@10294: } else { glx@10294: EndVehicleMove(v); glx@10294: delete v; glx@10294: } glx@10294: } glx@10294: } glx@10294: glx@10294: static void SmokeInit(Vehicle *v) glx@10294: { glx@10294: v->cur_image = SPR_SMOKE_0; glx@10294: v->progress = 12; glx@10294: } glx@10294: glx@10294: static void SmokeTick(Vehicle *v) glx@10294: { glx@10294: bool moved = false; glx@10294: glx@10294: BeginVehicleMove(v); glx@10294: glx@10294: v->progress++; glx@10294: glx@10294: if ((v->progress & 3) == 0) { glx@10294: v->z_pos++; glx@10294: moved = true; glx@10294: } glx@10294: glx@10294: if ((v->progress & 0xF) == 4) { glx@10294: if (v->cur_image != SPR_SMOKE_4) { glx@10294: v->cur_image++; glx@10294: } else { glx@10294: EndVehicleMove(v); glx@10294: delete v; glx@10294: return; glx@10294: } glx@10294: moved = true; glx@10294: } glx@10294: glx@10294: if (moved) { glx@10294: VehiclePositionChanged(v); glx@10294: EndVehicleMove(v); glx@10294: } glx@10294: } glx@10294: glx@10294: static void ExplosionLargeInit(Vehicle *v) glx@10294: { glx@10294: v->cur_image = SPR_EXPLOSION_LARGE_0; glx@10294: v->progress = 0; glx@10294: } glx@10294: glx@10294: static void ExplosionLargeTick(Vehicle *v) glx@10294: { glx@10294: v->progress++; glx@10294: if ((v->progress & 3) == 0) { glx@10294: BeginVehicleMove(v); glx@10294: if (v->cur_image != SPR_EXPLOSION_LARGE_F) { glx@10294: v->cur_image++; glx@10294: VehiclePositionChanged(v); glx@10294: EndVehicleMove(v); glx@10294: } else { glx@10294: EndVehicleMove(v); glx@10294: delete v; glx@10294: } glx@10294: } glx@10294: } glx@10294: glx@10294: static void BreakdownSmokeInit(Vehicle *v) glx@10294: { glx@10294: v->cur_image = SPR_BREAKDOWN_SMOKE_0; glx@10294: v->progress = 0; glx@10294: } glx@10294: glx@10294: static void BreakdownSmokeTick(Vehicle *v) glx@10294: { glx@10294: v->progress++; glx@10294: if ((v->progress & 7) == 0) { glx@10294: BeginVehicleMove(v); glx@10294: if (v->cur_image != SPR_BREAKDOWN_SMOKE_3) { glx@10294: v->cur_image++; glx@10294: } else { glx@10294: v->cur_image = SPR_BREAKDOWN_SMOKE_0; glx@10294: } glx@10294: VehiclePositionChanged(v); glx@10294: EndVehicleMove(v); glx@10294: } glx@10294: glx@10294: v->u.effect.animation_state--; glx@10294: if (v->u.effect.animation_state == 0) { glx@10294: BeginVehicleMove(v); glx@10294: EndVehicleMove(v); glx@10294: delete v; glx@10294: } glx@10294: } glx@10294: glx@10294: static void ExplosionSmallInit(Vehicle *v) glx@10294: { glx@10294: v->cur_image = SPR_EXPLOSION_SMALL_0; glx@10294: v->progress = 0; glx@10294: } glx@10294: glx@10294: static void ExplosionSmallTick(Vehicle *v) glx@10294: { glx@10294: v->progress++; glx@10294: if ((v->progress & 3) == 0) { glx@10294: BeginVehicleMove(v); glx@10294: if (v->cur_image != SPR_EXPLOSION_SMALL_B) { glx@10294: v->cur_image++; glx@10294: VehiclePositionChanged(v); glx@10294: EndVehicleMove(v); glx@10294: } else { glx@10294: EndVehicleMove(v); glx@10294: delete v; glx@10294: } glx@10294: } glx@10294: } glx@10294: glx@10294: static void BulldozerInit(Vehicle *v) glx@10294: { glx@10294: v->cur_image = SPR_BULLDOZER_NE; glx@10294: v->progress = 0; glx@10294: v->u.effect.animation_state = 0; glx@10294: v->u.effect.animation_substate = 0; glx@10294: } glx@10294: glx@10294: struct BulldozerMovement { glx@10294: byte direction:2; glx@10294: byte image:2; glx@10294: byte duration:3; glx@10294: }; glx@10294: glx@10294: static const BulldozerMovement _bulldozer_movement[] = { glx@10294: { 0, 0, 4 }, glx@10294: { 3, 3, 4 }, glx@10294: { 2, 2, 7 }, glx@10294: { 0, 2, 7 }, glx@10294: { 1, 1, 3 }, glx@10294: { 2, 2, 7 }, glx@10294: { 0, 2, 7 }, glx@10294: { 1, 1, 3 }, glx@10294: { 2, 2, 7 }, glx@10294: { 0, 2, 7 }, glx@10294: { 3, 3, 6 }, glx@10294: { 2, 2, 6 }, glx@10294: { 1, 1, 7 }, glx@10294: { 3, 1, 7 }, glx@10294: { 0, 0, 3 }, glx@10294: { 1, 1, 7 }, glx@10294: { 3, 1, 7 }, glx@10294: { 0, 0, 3 }, glx@10294: { 1, 1, 7 }, glx@10294: { 3, 1, 7 } glx@10294: }; glx@10294: glx@10294: static const struct { glx@10294: int8 x; glx@10294: int8 y; glx@10294: } _inc_by_dir[] = { glx@10294: { -1, 0 }, glx@10294: { 0, 1 }, glx@10294: { 1, 0 }, glx@10294: { 0, -1 } glx@10294: }; glx@10294: glx@10294: static void BulldozerTick(Vehicle *v) glx@10294: { glx@10294: v->progress++; glx@10294: if ((v->progress & 7) == 0) { glx@10294: const BulldozerMovement* b = &_bulldozer_movement[v->u.effect.animation_state]; glx@10294: glx@10294: BeginVehicleMove(v); glx@10294: glx@10294: v->cur_image = SPR_BULLDOZER_NE + b->image; glx@10294: glx@10294: v->x_pos += _inc_by_dir[b->direction].x; glx@10294: v->y_pos += _inc_by_dir[b->direction].y; glx@10294: glx@10294: v->u.effect.animation_substate++; glx@10294: if (v->u.effect.animation_substate >= b->duration) { glx@10294: v->u.effect.animation_substate = 0; glx@10294: v->u.effect.animation_state++; glx@10294: if (v->u.effect.animation_state == lengthof(_bulldozer_movement)) { glx@10294: EndVehicleMove(v); glx@10294: delete v; glx@10294: return; glx@10294: } glx@10294: } glx@10294: VehiclePositionChanged(v); glx@10294: EndVehicleMove(v); glx@10294: } glx@10294: } glx@10294: glx@10294: static void BubbleInit(Vehicle *v) glx@10294: { glx@10294: v->cur_image = SPR_BUBBLE_GENERATE_0; glx@10294: v->spritenum = 0; glx@10294: v->progress = 0; glx@10294: } glx@10294: glx@10294: struct BubbleMovement { glx@10294: int8 x:4; glx@10294: int8 y:4; glx@10294: int8 z:4; glx@10294: byte image:4; glx@10294: }; glx@10294: glx@10294: #define MK(x, y, z, i) { x, y, z, i } glx@10294: #define ME(i) { i, 4, 0, 0 } glx@10294: glx@10294: static const BubbleMovement _bubble_float_sw[] = { glx@10294: MK(0, 0, 1, 0), glx@10294: MK(1, 0, 1, 1), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(1, 0, 1, 2), glx@10294: ME(1) glx@10294: }; glx@10294: glx@10294: glx@10294: static const BubbleMovement _bubble_float_ne[] = { glx@10294: MK( 0, 0, 1, 0), glx@10294: MK(-1, 0, 1, 1), glx@10294: MK( 0, 0, 1, 0), glx@10294: MK(-1, 0, 1, 2), glx@10294: ME(1) glx@10294: }; glx@10294: glx@10294: static const BubbleMovement _bubble_float_se[] = { glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 1, 1, 1), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 1, 1, 2), glx@10294: ME(1) glx@10294: }; glx@10294: glx@10294: static const BubbleMovement _bubble_float_nw[] = { glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, -1, 1, 1), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, -1, 1, 2), glx@10294: ME(1) glx@10294: }; glx@10294: glx@10294: static const BubbleMovement _bubble_burst[] = { glx@10294: MK(0, 0, 1, 2), glx@10294: MK(0, 0, 1, 7), glx@10294: MK(0, 0, 1, 8), glx@10294: MK(0, 0, 1, 9), glx@10294: ME(0) glx@10294: }; glx@10294: glx@10294: static const BubbleMovement _bubble_absorb[] = { glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 1), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 2), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 1), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 2), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 1), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 2), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 1), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 2), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 1), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 2), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 1), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 2), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 1), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 2), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 1), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 2), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 1), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 2), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 1), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 2), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 1), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 2), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 1), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 2), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 1), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 2), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 1), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 2), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 1), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 2), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(0, 0, 1, 1), glx@10294: MK(2, 1, 3, 0), glx@10294: MK(1, 1, 3, 1), glx@10294: MK(2, 1, 3, 0), glx@10294: MK(1, 1, 3, 2), glx@10294: MK(2, 1, 3, 0), glx@10294: MK(1, 1, 3, 1), glx@10294: MK(2, 1, 3, 0), glx@10294: MK(1, 0, 1, 2), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(1, 0, 1, 1), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(1, 0, 1, 2), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(1, 0, 1, 1), glx@10294: MK(0, 0, 1, 0), glx@10294: MK(1, 0, 1, 2), glx@10294: ME(2), glx@10294: MK(0, 0, 0, 0xA), glx@10294: MK(0, 0, 0, 0xB), glx@10294: MK(0, 0, 0, 0xC), glx@10294: MK(0, 0, 0, 0xD), glx@10294: MK(0, 0, 0, 0xE), glx@10294: ME(0) glx@10294: }; glx@10294: #undef ME glx@10294: #undef MK glx@10294: glx@10294: static const BubbleMovement * const _bubble_movement[] = { glx@10294: _bubble_float_sw, glx@10294: _bubble_float_ne, glx@10294: _bubble_float_se, glx@10294: _bubble_float_nw, glx@10294: _bubble_burst, glx@10294: _bubble_absorb, glx@10294: }; glx@10294: glx@10294: static void BubbleTick(Vehicle *v) glx@10294: { glx@10294: /* glx@10294: * Warning: those effects can NOT use Random(), and have to use glx@10294: * InteractiveRandom(), because somehow someone forgot to save glx@10294: * spritenum to the savegame, and so it will cause desyncs in glx@10294: * multiplayer!! (that is: in ToyLand) glx@10294: */ glx@10294: uint et; glx@10294: glx@10294: v->progress++; glx@10294: if ((v->progress & 3) != 0) return; glx@10294: glx@10294: BeginVehicleMove(v); glx@10294: glx@10294: if (v->spritenum == 0) { glx@10294: v->cur_image++; glx@10294: if (v->cur_image < SPR_BUBBLE_GENERATE_3) { glx@10294: VehiclePositionChanged(v); glx@10294: EndVehicleMove(v); glx@10294: return; glx@10294: } glx@10294: if (v->u.effect.animation_substate != 0) { glx@10294: v->spritenum = GB(InteractiveRandom(), 0, 2) + 1; glx@10294: } else { glx@10294: v->spritenum = 6; glx@10294: } glx@10294: et = 0; glx@10294: } else { glx@10294: et = v->engine_type + 1; glx@10294: } glx@10294: glx@10294: const BubbleMovement *b = &_bubble_movement[v->spritenum - 1][et]; glx@10294: glx@10294: if (b->y == 4 && b->x == 0) { glx@10294: EndVehicleMove(v); glx@10294: delete v; glx@10294: return; glx@10294: } glx@10294: glx@10294: if (b->y == 4 && b->x == 1) { glx@10294: if (v->z_pos > 180 || Chance16I(1, 96, InteractiveRandom())) { glx@10294: v->spritenum = 5; glx@10294: SndPlayVehicleFx(SND_2F_POP, v); glx@10294: } glx@10294: et = 0; glx@10294: } glx@10294: glx@10294: if (b->y == 4 && b->x == 2) { glx@10294: TileIndex tile; glx@10294: glx@10294: et++; glx@10294: SndPlayVehicleFx(SND_31_EXTRACT, v); glx@10294: glx@10294: tile = TileVirtXY(v->x_pos, v->y_pos); glx@10294: if (IsTileType(tile, MP_INDUSTRY) && GetIndustryGfx(tile) == GFX_BUBBLE_CATCHER) AddAnimatedTile(tile); glx@10294: } glx@10294: glx@10294: v->engine_type = et; glx@10294: b = &_bubble_movement[v->spritenum - 1][et]; glx@10294: glx@10294: v->x_pos += b->x; glx@10294: v->y_pos += b->y; glx@10294: v->z_pos += b->z; glx@10294: v->cur_image = SPR_BUBBLE_0 + b->image; glx@10294: glx@10294: VehiclePositionChanged(v); glx@10294: EndVehicleMove(v); glx@10294: } glx@10294: glx@10294: glx@10294: typedef void EffectInitProc(Vehicle *v); glx@10294: typedef void EffectTickProc(Vehicle *v); glx@10294: glx@10294: static EffectInitProc * const _effect_init_procs[] = { glx@10294: ChimneySmokeInit, glx@10294: SteamSmokeInit, glx@10294: DieselSmokeInit, glx@10294: ElectricSparkInit, glx@10294: SmokeInit, glx@10294: ExplosionLargeInit, glx@10294: BreakdownSmokeInit, glx@10294: ExplosionSmallInit, glx@10294: BulldozerInit, glx@10294: BubbleInit, glx@10294: }; glx@10294: glx@10294: static EffectTickProc * const _effect_tick_procs[] = { glx@10294: ChimneySmokeTick, glx@10294: SteamSmokeTick, glx@10294: DieselSmokeTick, glx@10294: ElectricSparkTick, glx@10294: SmokeTick, glx@10294: ExplosionLargeTick, glx@10294: BreakdownSmokeTick, glx@10294: ExplosionSmallTick, glx@10294: BulldozerTick, glx@10294: BubbleTick, glx@10294: }; glx@10294: glx@10294: glx@10294: Vehicle *CreateEffectVehicle(int x, int y, int z, EffectVehicleType type) glx@10294: { glx@10294: Vehicle *v = new EffectVehicle(); glx@10294: if (v != NULL) { glx@10294: v->subtype = type; glx@10294: v->x_pos = x; glx@10294: v->y_pos = y; glx@10294: v->z_pos = z; glx@10294: v->tile = 0; glx@10294: v->UpdateDeltaXY(INVALID_DIR); glx@10294: v->vehstatus = VS_UNCLICKABLE; glx@10294: glx@10294: _effect_init_procs[type](v); glx@10294: glx@10294: VehiclePositionChanged(v); glx@10294: BeginVehicleMove(v); glx@10294: EndVehicleMove(v); glx@10294: } glx@10294: return v; glx@10294: } glx@10294: glx@10294: Vehicle *CreateEffectVehicleAbove(int x, int y, int z, EffectVehicleType type) glx@10294: { glx@10294: int safe_x = Clamp(x, 0, MapMaxX() * TILE_SIZE); glx@10294: int safe_y = Clamp(y, 0, MapMaxY() * TILE_SIZE); glx@10294: return CreateEffectVehicle(x, y, GetSlopeZ(safe_x, safe_y) + z, type); glx@10294: } glx@10294: glx@10294: Vehicle *CreateEffectVehicleRel(const Vehicle *v, int x, int y, int z, EffectVehicleType type) glx@10294: { glx@10294: return CreateEffectVehicle(v->x_pos + x, v->y_pos + y, v->z_pos + z, type); glx@10294: } glx@10294: glx@10294: void EffectVehicle::Tick() glx@10294: { glx@10294: _effect_tick_procs[this->subtype](this); glx@10294: } glx@10294: glx@10294: void EffectVehicle::UpdateDeltaXY(Direction direction) glx@10294: { glx@10294: this->x_offs = 0; glx@10294: this->y_offs = 0; glx@10294: this->x_extent = 1; glx@10294: this->y_extent = 1; glx@10294: this->z_extent = 1; glx@10294: }