mirror of https://github.com/OpenTTD/OpenTTD
(svn r12798) -Feature: Add some support for NewGRF station animation. (Thanks to mart3p for samples and fixes)
parent
de015fbf90
commit
210d757499
|
@ -26,6 +26,7 @@
|
||||||
#include "newgrf_callbacks.h"
|
#include "newgrf_callbacks.h"
|
||||||
#include "newgrf_industries.h"
|
#include "newgrf_industries.h"
|
||||||
#include "newgrf_industrytiles.h"
|
#include "newgrf_industrytiles.h"
|
||||||
|
#include "newgrf_station.h"
|
||||||
#include "unmovable.h"
|
#include "unmovable.h"
|
||||||
#include "cargotype.h"
|
#include "cargotype.h"
|
||||||
#include "player_face.h"
|
#include "player_face.h"
|
||||||
|
@ -1691,6 +1692,8 @@ static void LoadUnloadVehicle(Vehicle *v, int *cargo_left)
|
||||||
st->time_since_load = 0;
|
st->time_since_load = 0;
|
||||||
st->last_vehicle_type = v->type;
|
st->last_vehicle_type = v->type;
|
||||||
|
|
||||||
|
StationAnimationTrigger(st, st->xy, STAT_ANIM_CARGO_TAKEN, v->cargo_type);
|
||||||
|
|
||||||
unloading_time += cap;
|
unloading_time += cap;
|
||||||
|
|
||||||
result |= 2;
|
result |= 2;
|
||||||
|
|
|
@ -1120,19 +1120,17 @@ static bool StationChangeInfo(uint stid, int numinfo, int prop, byte **bufp, int
|
||||||
statspec->blocked = grf_load_byte(&buf);
|
statspec->blocked = grf_load_byte(&buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x16: // @todo Animation info
|
case 0x16: // Animation info
|
||||||
grf_load_word(&buf);
|
statspec->anim_frames = grf_load_byte(&buf);
|
||||||
ret = true;
|
statspec->anim_status = grf_load_byte(&buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x17: // @todo Animation speed
|
case 0x17: // Animation speed
|
||||||
grf_load_byte(&buf);
|
statspec->anim_speed = grf_load_byte(&buf);
|
||||||
ret = true;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x18: // @todo Animation triggers
|
case 0x18: // Animation triggers
|
||||||
grf_load_word(&buf);
|
statspec->anim_triggers = grf_load_word(&buf);
|
||||||
ret = true;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -173,13 +173,13 @@ enum CallbackID {
|
||||||
/* There are no callbacks 0x3E - 0x13F */
|
/* There are no callbacks 0x3E - 0x13F */
|
||||||
|
|
||||||
/** Called for periodically starting or stopping the animation. */
|
/** Called for periodically starting or stopping the animation. */
|
||||||
CBID_STATION_ANIM_START_STOP = 0x140, // not implemented
|
CBID_STATION_ANIM_START_STOP = 0x140,
|
||||||
|
|
||||||
/** Called to determine station tile next animation frame. */
|
/** Called to determine station tile next animation frame. */
|
||||||
CBID_STATION_ANIM_NEXT_FRAME = 0x141, // not implemented
|
CBID_STATION_ANIM_NEXT_FRAME = 0x141,
|
||||||
|
|
||||||
/** Called to indicate how long the current animation frame should last. */
|
/** Called to indicate how long the current animation frame should last. */
|
||||||
CBID_STATION_ANIMATION_SPEED = 0x142, // not implemented
|
CBID_STATION_ANIMATION_SPEED = 0x142,
|
||||||
|
|
||||||
/** Called to determine whether a town building can be destroyed. */
|
/** Called to determine whether a town building can be destroyed. */
|
||||||
CBID_HOUSE_DENY_DESTRUCTION = 0x143,
|
CBID_HOUSE_DENY_DESTRUCTION = 0x143,
|
||||||
|
|
|
@ -740,8 +740,12 @@ void DeallocateSpecFromStation(Station* st, byte specindex)
|
||||||
free(st->speclist);
|
free(st->speclist);
|
||||||
st->num_specs = 0;
|
st->num_specs = 0;
|
||||||
st->speclist = NULL;
|
st->speclist = NULL;
|
||||||
|
st->cached_anim_triggers = 0;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StationUpdateAnimTriggers(st);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Draw representation of a station tile for GUI purposes.
|
/** Draw representation of a station tile for GUI purposes.
|
||||||
|
@ -853,3 +857,178 @@ bool IsStationTileElectrifiable(TileIndex tile)
|
||||||
HasBit(statspec->pylons, GetStationGfx(tile)) ||
|
HasBit(statspec->pylons, GetStationGfx(tile)) ||
|
||||||
!HasBit(statspec->wires, GetStationGfx(tile));
|
!HasBit(statspec->wires, GetStationGfx(tile));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AnimateStationTile(TileIndex tile)
|
||||||
|
{
|
||||||
|
const StationSpec *ss = GetStationSpec(tile);
|
||||||
|
if (ss == NULL) return;
|
||||||
|
|
||||||
|
const Station *st = GetStationByTile(tile);
|
||||||
|
|
||||||
|
uint8 animation_speed = ss->anim_speed;
|
||||||
|
|
||||||
|
if (HasBit(ss->callbackmask, CBM_STATION_ANIMATION_SPEED)) {
|
||||||
|
uint16 callback = GetStationCallback(CBID_STATION_ANIMATION_SPEED, 0, 0, ss, st, tile);
|
||||||
|
if (callback != CALLBACK_FAILED) animation_speed = Clamp(callback & 0xFF, 0, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_tick_counter % (1 << animation_speed) != 0) return;
|
||||||
|
|
||||||
|
uint8 frame = GetStationAnimationFrame(tile);
|
||||||
|
uint8 num_frames = ss->anim_frames;
|
||||||
|
|
||||||
|
bool frame_set_by_callback = false;
|
||||||
|
|
||||||
|
if (HasBit(ss->callbackmask, CBM_STATION_ANIMATION_NEXT_FRAME)) {
|
||||||
|
uint32 param = HasBit(ss->flags, 2) ? Random() : 0;
|
||||||
|
uint16 callback = GetStationCallback(CBID_STATION_ANIM_NEXT_FRAME, param, 0, ss, st, tile);
|
||||||
|
|
||||||
|
if (callback != CALLBACK_FAILED) {
|
||||||
|
frame_set_by_callback = true;
|
||||||
|
|
||||||
|
switch (callback & 0xFF) {
|
||||||
|
case 0xFF:
|
||||||
|
DeleteAnimatedTile(tile);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xFE:
|
||||||
|
frame_set_by_callback = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
frame = callback & 0xFF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!frame_set_by_callback) {
|
||||||
|
if (frame < num_frames) {
|
||||||
|
frame++;
|
||||||
|
} else if (frame == num_frames && HasBit(ss->anim_status, 0)) {
|
||||||
|
/* This animation loops, so start again from the beginning */
|
||||||
|
frame = 0;
|
||||||
|
} else {
|
||||||
|
/* This animation doesn't loop, so stay here */
|
||||||
|
DeleteAnimatedTile(tile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetStationAnimationFrame(tile, frame);
|
||||||
|
MarkTileDirtyByTile(tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void ChangeStationAnimationFrame(const StationSpec *ss, const Station *st, TileIndex tile, uint16 random_bits, StatAnimTrigger trigger, CargoID cargo_type)
|
||||||
|
{
|
||||||
|
uint16 callback = GetStationCallback(CBID_STATION_ANIM_START_STOP, (random_bits << 16) | Random(), (uint8)trigger | (cargo_type << 8), ss, st, tile);
|
||||||
|
if (callback == CALLBACK_FAILED) return;
|
||||||
|
|
||||||
|
switch (callback & 0xFF) {
|
||||||
|
case 0xFD: /* Do nothing. */ break;
|
||||||
|
case 0xFE: AddAnimatedTile(tile); break;
|
||||||
|
case 0xFF: DeleteAnimatedTile(tile); break;
|
||||||
|
default:
|
||||||
|
SetStationAnimationFrame(tile, callback);
|
||||||
|
AddAnimatedTile(tile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum TriggerArea {
|
||||||
|
TA_TILE,
|
||||||
|
TA_PLATFORM,
|
||||||
|
TA_WHOLE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TileArea {
|
||||||
|
TileIndex tile;
|
||||||
|
uint8 w;
|
||||||
|
uint8 h;
|
||||||
|
|
||||||
|
TileArea(const Station *st, TileIndex tile, TriggerArea ta)
|
||||||
|
{
|
||||||
|
switch (ta) {
|
||||||
|
default: NOT_REACHED();
|
||||||
|
|
||||||
|
case TA_TILE:
|
||||||
|
this->tile = tile;
|
||||||
|
this->w = 1;
|
||||||
|
this->h = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TA_PLATFORM: {
|
||||||
|
TileIndex start, end;
|
||||||
|
Axis axis = GetRailStationAxis(tile);
|
||||||
|
TileIndexDiff delta = TileOffsByDiagDir(AxisToDiagDir(axis));
|
||||||
|
|
||||||
|
for (end = tile; IsRailwayStationTile(end + delta) && IsCompatibleTrainStationTile(tile, end + delta); end += delta);
|
||||||
|
for (start = tile; IsRailwayStationTile(start - delta) && IsCompatibleTrainStationTile(tile, start - delta); start -= delta);
|
||||||
|
|
||||||
|
this->tile = start;
|
||||||
|
this->w = TileX(end) - TileX(start) + 1;
|
||||||
|
this->h = TileY(end) - TileY(start) + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TA_WHOLE:
|
||||||
|
this->tile = st->train_tile;
|
||||||
|
this->w = st->trainst_w + 1;
|
||||||
|
this->h = st->trainst_h + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void StationAnimationTrigger(const Station *st, TileIndex tile, StatAnimTrigger trigger, CargoID cargo_type)
|
||||||
|
{
|
||||||
|
/* List of coverage areas for each animation trigger */
|
||||||
|
static const TriggerArea tas[] = {
|
||||||
|
TA_TILE, TA_WHOLE, TA_WHOLE, TA_PLATFORM, TA_PLATFORM, TA_PLATFORM, TA_WHOLE
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Get Station if it wasn't supplied */
|
||||||
|
if (st == NULL) st = GetStationByTile(tile);
|
||||||
|
|
||||||
|
/* Check the cached animation trigger bitmask to see if we need
|
||||||
|
* to bother with any further processing. */
|
||||||
|
if (!HasBit(st->cached_anim_triggers, trigger)) return;
|
||||||
|
|
||||||
|
uint16 random_bits = Random();
|
||||||
|
TileArea area = TileArea(st, tile, tas[trigger]);
|
||||||
|
|
||||||
|
for (uint y = 0; y < area.h; y++) {
|
||||||
|
for (uint x = 0; x < area.w; x++) {
|
||||||
|
if (st->TileBelongsToRailStation(area.tile)) {
|
||||||
|
const StationSpec *ss = GetStationSpec(area.tile);
|
||||||
|
if (ss != NULL && HasBit(ss->anim_triggers, trigger)) {
|
||||||
|
CargoID cargo;
|
||||||
|
if (cargo_type == CT_INVALID) {
|
||||||
|
cargo = CT_INVALID;
|
||||||
|
} else {
|
||||||
|
cargo = GetReverseCargoTranslation(cargo_type, ss->grffile);
|
||||||
|
}
|
||||||
|
ChangeStationAnimationFrame(ss, st, area.tile, random_bits, trigger, cargo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
area.tile += TileDiffXY(1, 0);
|
||||||
|
}
|
||||||
|
area.tile += TileDiffXY(-area.w, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the cached animation trigger bitmask for a station.
|
||||||
|
* @param st Station to update.
|
||||||
|
*/
|
||||||
|
void StationUpdateAnimTriggers(Station *st)
|
||||||
|
{
|
||||||
|
st->cached_anim_triggers = 0;
|
||||||
|
|
||||||
|
/* Combine animation trigger bitmask for all station specs
|
||||||
|
* of this station. */
|
||||||
|
for (uint i = 0; i < st->num_specs; i++) {
|
||||||
|
const StationSpec *ss = st->speclist[i].spec;
|
||||||
|
if (ss != NULL) st->cached_anim_triggers |= ss->anim_triggers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -83,6 +83,11 @@ struct StationSpec {
|
||||||
StationLayout **layouts;
|
StationLayout **layouts;
|
||||||
bool copied_layouts;
|
bool copied_layouts;
|
||||||
|
|
||||||
|
uint8 anim_frames;
|
||||||
|
uint8 anim_status;
|
||||||
|
uint8 anim_speed;
|
||||||
|
uint16 anim_triggers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NUM_CARGO real cargo plus three pseudo cargo sprite groups.
|
* NUM_CARGO real cargo plus three pseudo cargo sprite groups.
|
||||||
* Used for obtaining the sprite offset of custom sprites, and for
|
* Used for obtaining the sprite offset of custom sprites, and for
|
||||||
|
@ -132,4 +137,18 @@ void DeallocateSpecFromStation(Station* st, byte specindex);
|
||||||
/* Draw representation of a station tile for GUI purposes. */
|
/* Draw representation of a station tile for GUI purposes. */
|
||||||
bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID sclass, uint station);
|
bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID sclass, uint station);
|
||||||
|
|
||||||
|
enum StatAnimTrigger {
|
||||||
|
STAT_ANIM_BUILT,
|
||||||
|
STAT_ANIM_NEW_CARGO,
|
||||||
|
STAT_ANIM_CARGO_TAKEN,
|
||||||
|
STAT_ANIM_TRAIN_ARRIVES,
|
||||||
|
STAT_ANIM_TRAIN_DEPARTS,
|
||||||
|
STAT_ANIM_TRAIN_LOADS,
|
||||||
|
STAT_ANIM_250_TICKS,
|
||||||
|
};
|
||||||
|
|
||||||
|
void AnimateStationTile(TileIndex tile);
|
||||||
|
void StationAnimationTrigger(const Station *st, TileIndex tile, StatAnimTrigger trigger, CargoID cargo_type = CT_INVALID);
|
||||||
|
void StationUpdateAnimTriggers(Station *st);
|
||||||
|
|
||||||
#endif /* NEWGRF_STATION_H */
|
#endif /* NEWGRF_STATION_H */
|
||||||
|
|
|
@ -159,6 +159,7 @@ public:
|
||||||
|
|
||||||
uint16 random_bits;
|
uint16 random_bits;
|
||||||
byte waiting_triggers;
|
byte waiting_triggers;
|
||||||
|
uint8 cached_anim_triggers; ///< Combined animation trigger bitmask, used to determine if trigger processing should happen.
|
||||||
|
|
||||||
StationRect rect; ///< Station spread out rectangle (not saved) maintained by StationRect_xxx() functions
|
StationRect rect; ///< Station spread out rectangle (not saved) maintained by StationRect_xxx() functions
|
||||||
|
|
||||||
|
|
|
@ -1038,6 +1038,12 @@ CommandCost CmdBuildRailroadStation(TileIndex tile_org, uint32 flags, uint32 p1,
|
||||||
|
|
||||||
st->rect.BeforeAddRect(tile_org, w_org, h_org, StationRect::ADD_TRY);
|
st->rect.BeforeAddRect(tile_org, w_org, h_org, StationRect::ADD_TRY);
|
||||||
|
|
||||||
|
if (statspec != NULL) {
|
||||||
|
/* Include this station spec's animation trigger bitmask
|
||||||
|
* in the station's cached copy. */
|
||||||
|
st->cached_anim_triggers |= statspec->anim_triggers;
|
||||||
|
}
|
||||||
|
|
||||||
tile_delta = (axis == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
|
tile_delta = (axis == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
|
||||||
track = AxisToTrack(axis);
|
track = AxisToTrack(axis);
|
||||||
|
|
||||||
|
@ -1054,6 +1060,7 @@ CommandCost CmdBuildRailroadStation(TileIndex tile_org, uint32 flags, uint32 p1,
|
||||||
MakeRailStation(tile, st->owner, st->index, axis, layout & ~1, (RailType)GB(p2, 0, 4));
|
MakeRailStation(tile, st->owner, st->index, axis, layout & ~1, (RailType)GB(p2, 0, 4));
|
||||||
SetCustomStationSpecIndex(tile, specindex);
|
SetCustomStationSpecIndex(tile, specindex);
|
||||||
SetStationTileRandomBits(tile, GB(Random(), 0, 4));
|
SetStationTileRandomBits(tile, GB(Random(), 0, 4));
|
||||||
|
SetStationAnimationFrame(tile, 0);
|
||||||
|
|
||||||
if (statspec != NULL) {
|
if (statspec != NULL) {
|
||||||
/* Use a fixed axis for GetPlatformInfo as our platforms / numtracks are always the right way around */
|
/* Use a fixed axis for GetPlatformInfo as our platforms / numtracks are always the right way around */
|
||||||
|
@ -1062,6 +1069,9 @@ CommandCost CmdBuildRailroadStation(TileIndex tile_org, uint32 flags, uint32 p1,
|
||||||
/* As the station is not yet completely finished, the station does not yet exist. */
|
/* As the station is not yet completely finished, the station does not yet exist. */
|
||||||
uint16 callback = GetStationCallback(CBID_STATION_TILE_LAYOUT, platinfo, 0, statspec, NULL, tile);
|
uint16 callback = GetStationCallback(CBID_STATION_TILE_LAYOUT, platinfo, 0, statspec, NULL, tile);
|
||||||
if (callback != CALLBACK_FAILED && callback < 8) SetStationGfx(tile, (callback & ~1) + axis);
|
if (callback != CALLBACK_FAILED && callback < 8) SetStationGfx(tile, (callback & ~1) + axis);
|
||||||
|
|
||||||
|
/* Trigger station animation -- after building? */
|
||||||
|
StationAnimationTrigger(st, tile, STAT_ANIM_BUILT);
|
||||||
}
|
}
|
||||||
|
|
||||||
tile += tile_delta;
|
tile += tile_delta;
|
||||||
|
@ -1283,6 +1293,7 @@ static CommandCost RemoveRailroadStation(Station *st, TileIndex tile, uint32 fla
|
||||||
free(st->speclist);
|
free(st->speclist);
|
||||||
st->num_specs = 0;
|
st->num_specs = 0;
|
||||||
st->speclist = NULL;
|
st->speclist = NULL;
|
||||||
|
st->cached_anim_triggers = 0;
|
||||||
|
|
||||||
InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_TRAINS);
|
InvalidateWindowWidget(WC_STATION_VIEW, st->index, SVW_TRAINS);
|
||||||
UpdateStationVirtCoordDirty(st);
|
UpdateStationVirtCoordDirty(st);
|
||||||
|
@ -2368,6 +2379,11 @@ static void AnimateTile_Station(TileIndex tile)
|
||||||
{ GFX_WINDSACK_INTERCON_FIRST, GFX_WINDSACK_INTERCON_LAST, 1 }
|
{ GFX_WINDSACK_INTERCON_FIRST, GFX_WINDSACK_INTERCON_LAST, 1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (IsRailwayStation(tile)) {
|
||||||
|
AnimateStationTile(tile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
StationGfx gfx = GetStationGfx(tile);
|
StationGfx gfx = GetStationGfx(tile);
|
||||||
|
|
||||||
for (const AnimData *i = data; i != endof(data); i++) {
|
for (const AnimData *i = data; i != endof(data); i++) {
|
||||||
|
@ -2614,7 +2630,16 @@ void OnTick_Station()
|
||||||
if (IsValidStationID(i)) StationHandleBigTick(GetStation(i));
|
if (IsValidStationID(i)) StationHandleBigTick(GetStation(i));
|
||||||
|
|
||||||
Station *st;
|
Station *st;
|
||||||
FOR_ALL_STATIONS(st) StationHandleSmallTick(st);
|
FOR_ALL_STATIONS(st) {
|
||||||
|
StationHandleSmallTick(st);
|
||||||
|
|
||||||
|
/* Run 250 tick interval trigger for station animation.
|
||||||
|
* Station index is included so that triggers are not all done
|
||||||
|
* at the same time. */
|
||||||
|
if ((_tick_counter + st->index) % 250 == 0) {
|
||||||
|
StationAnimationTrigger(st, st->xy, STAT_ANIM_250_TICKS);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StationMonthlyLoop()
|
void StationMonthlyLoop()
|
||||||
|
@ -2646,6 +2671,8 @@ static void UpdateStationWaiting(Station *st, CargoID type, uint amount)
|
||||||
st->goods[type].cargo.Append(new CargoPacket(st->index, amount));
|
st->goods[type].cargo.Append(new CargoPacket(st->index, amount));
|
||||||
SetBit(st->goods[type].acceptance_pickup, GoodsEntry::PICKUP);
|
SetBit(st->goods[type].acceptance_pickup, GoodsEntry::PICKUP);
|
||||||
|
|
||||||
|
StationAnimationTrigger(st, st->xy, STAT_ANIM_NEW_CARGO, type);
|
||||||
|
|
||||||
InvalidateWindow(WC_STATION_VIEW, st->index);
|
InvalidateWindow(WC_STATION_VIEW, st->index);
|
||||||
st->MarkTilesDirty(true);
|
st->MarkTilesDirty(true);
|
||||||
}
|
}
|
||||||
|
@ -3008,6 +3035,8 @@ void AfterLoadStations()
|
||||||
}
|
}
|
||||||
|
|
||||||
for (CargoID c = 0; c < NUM_CARGO; c++) st->goods[c].cargo.InvalidateCache();
|
for (CargoID c = 0; c < NUM_CARGO; c++) st->goods[c].cargo.InvalidateCache();
|
||||||
|
|
||||||
|
StationUpdateAnimTriggers(st);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include "gfx_func.h"
|
#include "gfx_func.h"
|
||||||
#include "settings_type.h"
|
#include "settings_type.h"
|
||||||
#include "order_func.h"
|
#include "order_func.h"
|
||||||
|
#include "newgrf_station.h"
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
#include "table/train_cmd.h"
|
#include "table/train_cmd.h"
|
||||||
|
@ -2218,6 +2219,8 @@ void Train::PlayLeaveStationSound() const
|
||||||
SND_41_MAGLEV
|
SND_41_MAGLEV
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (IsTileType(this->tile, MP_STATION)) StationAnimationTrigger(NULL, this->tile, STAT_ANIM_TRAIN_DEPARTS);
|
||||||
|
|
||||||
if (PlayVehicleSound(this, VSE_START)) return;
|
if (PlayVehicleSound(this, VSE_START)) return;
|
||||||
|
|
||||||
EngineID engtype = this->engine_type;
|
EngineID engtype = this->engine_type;
|
||||||
|
@ -2638,6 +2641,8 @@ static void TrainEnterStation(Vehicle *v, StationID station)
|
||||||
}
|
}
|
||||||
|
|
||||||
v->BeginLoading();
|
v->BeginLoading();
|
||||||
|
|
||||||
|
StationAnimationTrigger(st, v->tile, STAT_ANIM_TRAIN_ARRIVES);
|
||||||
}
|
}
|
||||||
|
|
||||||
static byte AfterSetTrainPos(Vehicle *v, bool new_tile)
|
static byte AfterSetTrainPos(Vehicle *v, bool new_tile)
|
||||||
|
|
Loading…
Reference in New Issue