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