tron@2186: /* $Id$ */ tron@2186: rubidium@9111: /** @file effectvehicle.cpp Implementation of everything generic to vehicles. */ belugas@6423: truelight@0: #include "stdafx.h" Darkvater@1891: #include "openttd.h" tron@3957: #include "road_map.h" tron@3959: #include "roadveh.h" tron@3961: #include "ship.h" tron@1349: #include "spritecache.h" rubidium@8119: #include "tile_cmd.h" maedhros@6453: #include "landscape.h" maedhros@6980: #include "timetable.h" rubidium@8224: #include "viewport_func.h" rubidium@8224: #include "gfx_func.h" rubidium@8763: #include "news_func.h" rubidium@8116: #include "command_func.h" truelight@0: #include "saveload.h" rubidium@10208: #include "company_func.h" celestar@1601: #include "debug.h" matthijs@1752: #include "vehicle_gui.h" rubidium@8103: #include "rail_type.h" bjarni@2676: #include "train.h" bjarni@4662: #include "aircraft.h" peter1138@3428: #include "industry_map.h" celestar@3404: #include "station_map.h" tron@3957: #include "water_map.h" KUDr@4130: #include "yapf/yapf.h" peter1138@5717: #include "newgrf_callbacks.h" peter1138@4603: #include "newgrf_engine.h" peter1138@4656: #include "newgrf_sound.h" rubidium@6643: #include "group.h" rubidium@8784: #include "order_func.h" rubidium@8114: #include "strings_func.h" rubidium@8123: #include "zoom_func.h" rubidium@8131: #include "functions.h" rubidium@8140: #include "date_func.h" rubidium@8131: #include "window_func.h" rubidium@8144: #include "vehicle_func.h" smatz@8238: #include "signal_func.h" rubidium@8157: #include "sound_func.h" rubidium@8211: #include "variables.h" rubidium@8212: #include "autoreplace_func.h" rubidium@8212: #include "autoreplace_gui.h" rubidium@8214: #include "string_func.h" rubidium@8270: #include "settings_type.h" smatz@8847: #include "oldpool_func.h" rubidium@8962: #include "depot_map.h" rubidium@9005: #include "animated_tile_func.h" rubidium@9009: #include "effectvehicle_base.h" rubidium@9009: #include "effectvehicle_func.h" truelight@0: rubidium@8264: #include "table/sprites.h" rubidium@8264: #include "table/strings.h" rubidium@8264: tron@1371: static void ChimneySmokeInit(Vehicle *v) truelight@0: { truelight@0: uint32 r = Random(); tron@2140: v->cur_image = SPR_CHIMNEY_SMOKE_0 + GB(r, 0, 3); tron@2140: v->progress = GB(r, 16, 3); truelight@0: } truelight@0: tron@1371: static void ChimneySmokeTick(Vehicle *v) truelight@0: { tron@1371: if (v->progress > 0) { tron@1371: v->progress--; tron@1371: } else { truelight@0: BeginVehicleMove(v); truelight@193: rubidium@8980: TileIndex tile = TileVirtXY(v->x_pos, v->y_pos); tron@1035: if (!IsTileType(tile, MP_INDUSTRY)) { truelight@0: EndVehicleMove(v); rubidium@7398: delete v; truelight@0: return; truelight@0: } truelight@0: tron@1371: if (v->cur_image != SPR_CHIMNEY_SMOKE_7) { tron@1371: v->cur_image++; tron@1371: } else { tron@1371: v->cur_image = SPR_CHIMNEY_SMOKE_0; tron@1371: } truelight@0: v->progress = 7; truelight@0: VehiclePositionChanged(v); truelight@0: EndVehicleMove(v); truelight@0: } truelight@0: } truelight@0: tron@1371: static void SteamSmokeInit(Vehicle *v) truelight@0: { tron@1371: v->cur_image = SPR_STEAM_SMOKE_0; truelight@0: v->progress = 12; truelight@0: } truelight@0: tron@1371: static void SteamSmokeTick(Vehicle *v) truelight@0: { tron@1371: bool moved = false; truelight@193: truelight@0: BeginVehicleMove(v); truelight@193: tron@1371: v->progress++; truelight@193: tron@1371: if ((v->progress & 7) == 0) { truelight@0: v->z_pos++; truelight@0: moved = true; truelight@0: } truelight@0: tron@1371: if ((v->progress & 0xF) == 4) { tron@1371: if (v->cur_image != SPR_STEAM_SMOKE_4) { tron@1371: v->cur_image++; tron@1371: } else { truelight@0: EndVehicleMove(v); rubidium@7398: delete v; truelight@0: return; truelight@0: } truelight@0: moved = true; truelight@0: } truelight@0: truelight@0: if (moved) { truelight@0: VehiclePositionChanged(v); truelight@0: EndVehicleMove(v); truelight@0: } truelight@0: } truelight@0: tron@1371: static void DieselSmokeInit(Vehicle *v) truelight@0: { tron@1371: v->cur_image = SPR_DIESEL_SMOKE_0; truelight@0: v->progress = 0; truelight@0: } truelight@0: tron@1371: static void DieselSmokeTick(Vehicle *v) truelight@0: { tron@1371: v->progress++; tron@1371: tron@1371: if ((v->progress & 3) == 0) { truelight@0: BeginVehicleMove(v); truelight@0: v->z_pos++; truelight@0: VehiclePositionChanged(v); truelight@0: EndVehicleMove(v); truelight@0: } else if ((v->progress & 7) == 1) { truelight@0: BeginVehicleMove(v); tron@1371: if (v->cur_image != SPR_DIESEL_SMOKE_5) { tron@1371: v->cur_image++; tron@1371: VehiclePositionChanged(v); tron@1371: EndVehicleMove(v); tron@1371: } else { truelight@0: EndVehicleMove(v); rubidium@7398: delete v; truelight@0: } truelight@0: } truelight@0: } truelight@0: tron@1371: static void ElectricSparkInit(Vehicle *v) truelight@0: { tron@1371: v->cur_image = SPR_ELECTRIC_SPARK_0; truelight@0: v->progress = 1; truelight@0: } truelight@0: tron@1371: static void ElectricSparkTick(Vehicle *v) truelight@0: { tron@1371: if (v->progress < 2) { tron@1371: v->progress++; tron@1371: } else { truelight@0: v->progress = 0; truelight@0: BeginVehicleMove(v); tron@1371: if (v->cur_image != SPR_ELECTRIC_SPARK_5) { tron@1371: v->cur_image++; tron@1371: VehiclePositionChanged(v); tron@1371: EndVehicleMove(v); tron@1371: } else { truelight@0: EndVehicleMove(v); rubidium@7398: delete v; truelight@0: } truelight@0: } truelight@0: } truelight@0: tron@1371: static void SmokeInit(Vehicle *v) truelight@0: { tron@1371: v->cur_image = SPR_SMOKE_0; truelight@0: v->progress = 12; truelight@0: } truelight@0: tron@1371: static void SmokeTick(Vehicle *v) truelight@0: { tron@1371: bool moved = false; truelight@193: truelight@0: BeginVehicleMove(v); truelight@193: tron@1371: v->progress++; truelight@193: tron@1371: if ((v->progress & 3) == 0) { truelight@0: v->z_pos++; truelight@0: moved = true; truelight@0: } truelight@0: tron@1371: if ((v->progress & 0xF) == 4) { tron@1371: if (v->cur_image != SPR_SMOKE_4) { tron@1371: v->cur_image++; tron@1371: } else { truelight@0: EndVehicleMove(v); rubidium@7398: delete v; truelight@0: return; truelight@0: } truelight@0: moved = true; truelight@0: } truelight@0: truelight@0: if (moved) { truelight@0: VehiclePositionChanged(v); truelight@0: EndVehicleMove(v); truelight@0: } truelight@0: } truelight@0: tron@1371: static void ExplosionLargeInit(Vehicle *v) truelight@0: { tron@1371: v->cur_image = SPR_EXPLOSION_LARGE_0; truelight@0: v->progress = 0; truelight@0: } truelight@0: tron@1371: static void ExplosionLargeTick(Vehicle *v) truelight@0: { tron@1371: v->progress++; tron@1371: if ((v->progress & 3) == 0) { truelight@0: BeginVehicleMove(v); tron@1371: if (v->cur_image != SPR_EXPLOSION_LARGE_F) { tron@1371: v->cur_image++; tron@1371: VehiclePositionChanged(v); tron@1371: EndVehicleMove(v); tron@1371: } else { truelight@0: EndVehicleMove(v); rubidium@7398: delete v; truelight@0: } truelight@0: } truelight@0: } truelight@0: tron@1371: static void BreakdownSmokeInit(Vehicle *v) truelight@0: { tron@1371: v->cur_image = SPR_BREAKDOWN_SMOKE_0; truelight@0: v->progress = 0; truelight@0: } truelight@0: tron@1371: static void BreakdownSmokeTick(Vehicle *v) truelight@0: { tron@1371: v->progress++; tron@1371: if ((v->progress & 7) == 0) { truelight@0: BeginVehicleMove(v); tron@1371: if (v->cur_image != SPR_BREAKDOWN_SMOKE_3) { tron@1371: v->cur_image++; tron@1371: } else { tron@1371: v->cur_image = SPR_BREAKDOWN_SMOKE_0; tron@1371: } truelight@0: VehiclePositionChanged(v); truelight@0: EndVehicleMove(v); truelight@0: } truelight@0: rubidium@9008: v->u.effect.animation_state--; rubidium@9008: if (v->u.effect.animation_state == 0) { truelight@0: BeginVehicleMove(v); truelight@0: EndVehicleMove(v); rubidium@7398: delete v; truelight@0: } truelight@0: } truelight@0: tron@1371: static void ExplosionSmallInit(Vehicle *v) truelight@0: { tron@1371: v->cur_image = SPR_EXPLOSION_SMALL_0; truelight@0: v->progress = 0; truelight@0: } truelight@0: tron@1371: static void ExplosionSmallTick(Vehicle *v) truelight@0: { tron@1371: v->progress++; tron@1371: if ((v->progress & 3) == 0) { truelight@0: BeginVehicleMove(v); tron@1371: if (v->cur_image != SPR_EXPLOSION_SMALL_B) { tron@1371: v->cur_image++; tron@1371: VehiclePositionChanged(v); tron@1371: EndVehicleMove(v); tron@1371: } else { truelight@0: EndVehicleMove(v); rubidium@7398: delete v; truelight@0: } truelight@0: } truelight@0: } truelight@0: tron@1364: static void BulldozerInit(Vehicle *v) truelight@0: { tron@1364: v->cur_image = SPR_BULLDOZER_NE; truelight@0: v->progress = 0; rubidium@9008: v->u.effect.animation_state = 0; rubidium@9008: v->u.effect.animation_substate = 0; truelight@0: } truelight@0: rubidium@6248: struct BulldozerMovement { tron@1365: byte direction:2; tron@1364: byte image:2; tron@1364: byte duration:3; rubidium@6248: }; truelight@0: tron@1364: static const BulldozerMovement _bulldozer_movement[] = { tron@1364: { 0, 0, 4 }, tron@1364: { 3, 3, 4 }, tron@1364: { 2, 2, 7 }, tron@1364: { 0, 2, 7 }, tron@1364: { 1, 1, 3 }, tron@1364: { 2, 2, 7 }, tron@1364: { 0, 2, 7 }, tron@1364: { 1, 1, 3 }, tron@1364: { 2, 2, 7 }, tron@1364: { 0, 2, 7 }, tron@1364: { 3, 3, 6 }, tron@1364: { 2, 2, 6 }, tron@1364: { 1, 1, 7 }, tron@1364: { 3, 1, 7 }, tron@1364: { 0, 0, 3 }, tron@1364: { 1, 1, 7 }, tron@1364: { 3, 1, 7 }, tron@1364: { 0, 0, 3 }, tron@1364: { 1, 1, 7 }, tron@1364: { 3, 1, 7 } truelight@0: }; truelight@0: tron@1364: static const struct { tron@1364: int8 x; tron@1364: int8 y; tron@1364: } _inc_by_dir[] = { tron@1364: { -1, 0 }, tron@1364: { 0, 1 }, tron@1364: { 1, 0 }, tron@1364: { 0, -1 } tron@1364: }; truelight@0: tron@1364: static void BulldozerTick(Vehicle *v) truelight@0: { tron@1371: v->progress++; tron@1371: if ((v->progress & 7) == 0) { rubidium@9008: const BulldozerMovement* b = &_bulldozer_movement[v->u.effect.animation_state]; truelight@0: truelight@0: BeginVehicleMove(v); truelight@0: tron@1364: v->cur_image = SPR_BULLDOZER_NE + b->image; truelight@0: tron@1364: v->x_pos += _inc_by_dir[b->direction].x; tron@1364: v->y_pos += _inc_by_dir[b->direction].y; truelight@0: rubidium@9008: v->u.effect.animation_substate++; rubidium@9008: if (v->u.effect.animation_substate >= b->duration) { rubidium@9008: v->u.effect.animation_substate = 0; rubidium@9008: v->u.effect.animation_state++; rubidium@9008: if (v->u.effect.animation_state == lengthof(_bulldozer_movement)) { truelight@0: EndVehicleMove(v); rubidium@7398: delete v; truelight@0: return; truelight@0: } truelight@0: } truelight@0: VehiclePositionChanged(v); truelight@0: EndVehicleMove(v); truelight@0: } truelight@0: } truelight@0: tron@1371: static void BubbleInit(Vehicle *v) truelight@0: { tron@1371: v->cur_image = SPR_BUBBLE_GENERATE_0; truelight@0: v->spritenum = 0; truelight@0: v->progress = 0; truelight@0: } truelight@0: rubidium@6248: struct BubbleMovement { tron@1371: int8 x:4; tron@1371: int8 y:4; tron@1371: int8 z:4; tron@1371: byte image:4; rubidium@6248: }; truelight@0: tron@1371: #define MK(x, y, z, i) { x, y, z, i } tron@1371: #define ME(i) { i, 4, 0, 0 } tron@1371: tron@1371: static const BubbleMovement _bubble_float_sw[] = { rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(1, 0, 1, 1), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(1, 0, 1, 2), tron@1371: ME(1) truelight@0: }; truelight@0: truelight@0: tron@1371: static const BubbleMovement _bubble_float_ne[] = { rubidium@4344: MK( 0, 0, 1, 0), rubidium@4344: MK(-1, 0, 1, 1), rubidium@4344: MK( 0, 0, 1, 0), rubidium@4344: MK(-1, 0, 1, 2), tron@1371: ME(1) truelight@0: }; truelight@0: tron@1371: static const BubbleMovement _bubble_float_se[] = { rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 1, 1, 1), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 1, 1, 2), tron@1371: ME(1) truelight@0: }; truelight@0: tron@1371: static const BubbleMovement _bubble_float_nw[] = { rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, -1, 1, 1), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, -1, 1, 2), tron@1371: ME(1) truelight@0: }; truelight@0: tron@1371: static const BubbleMovement _bubble_burst[] = { rubidium@4344: MK(0, 0, 1, 2), rubidium@4344: MK(0, 0, 1, 7), rubidium@4344: MK(0, 0, 1, 8), rubidium@4344: MK(0, 0, 1, 9), tron@1371: ME(0) truelight@0: }; truelight@0: tron@1371: static const BubbleMovement _bubble_absorb[] = { rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 1), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 2), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 1), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 2), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 1), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 2), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 1), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 2), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 1), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 2), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 1), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 2), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 1), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 2), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 1), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 2), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 1), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 2), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 1), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 2), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 1), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 2), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 1), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 2), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 1), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 2), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 1), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 2), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 1), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 2), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(0, 0, 1, 1), rubidium@4344: MK(2, 1, 3, 0), rubidium@4344: MK(1, 1, 3, 1), rubidium@4344: MK(2, 1, 3, 0), rubidium@4344: MK(1, 1, 3, 2), rubidium@4344: MK(2, 1, 3, 0), rubidium@4344: MK(1, 1, 3, 1), rubidium@4344: MK(2, 1, 3, 0), rubidium@4344: MK(1, 0, 1, 2), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(1, 0, 1, 1), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(1, 0, 1, 2), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(1, 0, 1, 1), rubidium@4344: MK(0, 0, 1, 0), rubidium@4344: MK(1, 0, 1, 2), tron@1371: ME(2), rubidium@4344: MK(0, 0, 0, 0xA), rubidium@4344: MK(0, 0, 0, 0xB), rubidium@4344: MK(0, 0, 0, 0xC), rubidium@4344: MK(0, 0, 0, 0xD), rubidium@4344: MK(0, 0, 0, 0xE), tron@1371: ME(0) truelight@0: }; tron@1371: #undef ME truelight@0: #undef MK truelight@0: tron@1371: static const BubbleMovement * const _bubble_movement[] = { tron@1371: _bubble_float_sw, tron@1371: _bubble_float_ne, tron@1371: _bubble_float_se, tron@1371: _bubble_float_nw, tron@1371: _bubble_burst, tron@1371: _bubble_absorb, truelight@0: }; truelight@0: tron@1371: static void BubbleTick(Vehicle *v) truelight@0: { tron@1371: uint et; truelight@0: tron@1371: v->progress++; rubidium@8892: if ((v->progress & 3) != 0) return; truelight@0: truelight@0: BeginVehicleMove(v); truelight@0: truelight@0: if (v->spritenum == 0) { tron@1371: v->cur_image++; tron@1371: if (v->cur_image < SPR_BUBBLE_GENERATE_3) { truelight@0: VehiclePositionChanged(v); truelight@0: EndVehicleMove(v); truelight@0: return; truelight@0: } rubidium@9008: if (v->u.effect.animation_substate != 0) { glx@9955: v->spritenum = GB(Random(), 0, 2) + 1; truelight@0: } else { truelight@0: v->spritenum = 6; truelight@0: } truelight@0: et = 0; tron@1371: } else { tron@1371: et = v->engine_type + 1; truelight@0: } truelight@0: rubidium@8892: const BubbleMovement *b = &_bubble_movement[v->spritenum - 1][et]; truelight@0: tron@1371: if (b->y == 4 && b->x == 0) { truelight@0: EndVehicleMove(v); rubidium@7398: delete v; truelight@0: return; truelight@193: } truelight@193: tron@1371: if (b->y == 4 && b->x == 1) { glx@9955: if (v->z_pos > 180 || Chance16I(1, 96, Random())) { truelight@0: v->spritenum = 5; tron@541: SndPlayVehicleFx(SND_2F_POP, v); truelight@0: } truelight@0: et = 0; truelight@193: } truelight@193: tron@1371: if (b->y == 4 && b->x == 2) { tron@1371: TileIndex tile; truelight@0: truelight@0: et++; tron@541: SndPlayVehicleFx(SND_31_EXTRACT, v); truelight@0: tron@1980: tile = TileVirtXY(v->x_pos, v->y_pos); belugas@7466: if (IsTileType(tile, MP_INDUSTRY) && GetIndustryGfx(tile) == GFX_BUBBLE_CATCHER) AddAnimatedTile(tile); truelight@0: } truelight@0: tron@1371: v->engine_type = et; tron@1371: b = &_bubble_movement[v->spritenum - 1][et]; tron@1371: tron@1371: v->x_pos += b->x; tron@1371: v->y_pos += b->y; tron@1371: v->z_pos += b->z; tron@1371: v->cur_image = SPR_BUBBLE_0 + b->image; truelight@0: truelight@0: VehiclePositionChanged(v); truelight@0: EndVehicleMove(v); truelight@0: } truelight@0: truelight@0: truelight@0: typedef void EffectInitProc(Vehicle *v); truelight@0: typedef void EffectTickProc(Vehicle *v); truelight@0: truelight@0: static EffectInitProc * const _effect_init_procs[] = { tron@1371: ChimneySmokeInit, tron@1371: SteamSmokeInit, tron@1371: DieselSmokeInit, tron@1371: ElectricSparkInit, tron@1371: SmokeInit, tron@1371: ExplosionLargeInit, tron@1371: BreakdownSmokeInit, tron@1371: ExplosionSmallInit, tron@1364: BulldozerInit, tron@1371: BubbleInit, truelight@0: }; truelight@0: truelight@0: static EffectTickProc * const _effect_tick_procs[] = { tron@1371: ChimneySmokeTick, tron@1371: SteamSmokeTick, tron@1371: DieselSmokeTick, tron@1371: ElectricSparkTick, tron@1371: SmokeTick, tron@1371: ExplosionLargeTick, tron@1371: BreakdownSmokeTick, tron@1371: ExplosionSmallTick, tron@1364: BulldozerTick, tron@1371: BubbleTick, truelight@0: }; truelight@0: truelight@0: rubidium@9008: Vehicle *CreateEffectVehicle(int x, int y, int z, EffectVehicleType type) truelight@0: { rubidium@9008: Vehicle *v = new EffectVehicle(); truelight@0: if (v != NULL) { truelight@0: v->subtype = type; truelight@0: v->x_pos = x; truelight@0: v->y_pos = y; truelight@0: v->z_pos = z; truelight@0: v->tile = 0; rubidium@6558: v->UpdateDeltaXY(INVALID_DIR); truelight@0: v->vehstatus = VS_UNCLICKABLE; truelight@0: truelight@0: _effect_init_procs[type](v); truelight@0: truelight@0: VehiclePositionChanged(v); truelight@0: BeginVehicleMove(v); truelight@0: EndVehicleMove(v); truelight@0: } truelight@0: return v; truelight@0: } truelight@0: rubidium@9008: Vehicle *CreateEffectVehicleAbove(int x, int y, int z, EffectVehicleType type) truelight@0: { skidd13@7922: int safe_x = Clamp(x, 0, MapMaxX() * TILE_SIZE); skidd13@7922: int safe_y = Clamp(y, 0, MapMaxY() * TILE_SIZE); rubidium@5295: return CreateEffectVehicle(x, y, GetSlopeZ(safe_x, safe_y) + z, type); truelight@0: } truelight@0: rubidium@9008: Vehicle *CreateEffectVehicleRel(const Vehicle *v, int x, int y, int z, EffectVehicleType type) truelight@0: { truelight@0: return CreateEffectVehicle(v->x_pos + x, v->y_pos + y, v->z_pos + z, type); truelight@0: } truelight@0: rubidium@9008: void EffectVehicle::Tick() truelight@0: { rubidium@7135: _effect_tick_procs[this->subtype](this); truelight@0: } truelight@0: rubidium@9008: void EffectVehicle::UpdateDeltaXY(Direction direction) rubidium@6558: { rubidium@6558: this->x_offs = 0; rubidium@6558: this->y_offs = 0; frosch@8793: this->x_extent = 1; frosch@8793: this->y_extent = 1; frosch@8793: this->z_extent = 1; rubidium@6558: }