mirror of https://github.com/OpenTTD/OpenTTD
(svn r19197) -Codechange: introduce animation callbacks for airport tiles
parent
61fe40ba73
commit
7ca4c31cf5
|
@ -27,6 +27,7 @@
|
||||||
#include "newgrf_industries.h"
|
#include "newgrf_industries.h"
|
||||||
#include "newgrf_industrytiles.h"
|
#include "newgrf_industrytiles.h"
|
||||||
#include "newgrf_station.h"
|
#include "newgrf_station.h"
|
||||||
|
#include "newgrf_airporttiles.h"
|
||||||
#include "unmovable.h"
|
#include "unmovable.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "strings_func.h"
|
#include "strings_func.h"
|
||||||
|
@ -1288,6 +1289,7 @@ static void LoadUnloadVehicle(Vehicle *v, int *cargo_left)
|
||||||
st->last_vehicle_type = v->type;
|
st->last_vehicle_type = v->type;
|
||||||
|
|
||||||
StationAnimationTrigger(st, st->xy, STAT_ANIM_CARGO_TAKEN, v->cargo_type);
|
StationAnimationTrigger(st, st->xy, STAT_ANIM_CARGO_TAKEN, v->cargo_type);
|
||||||
|
AirportAnimationTrigger(st, AAT_STATION_CARGO_TAKEN, v->cargo_type);
|
||||||
|
|
||||||
unloading_time += cap;
|
unloading_time += cap;
|
||||||
|
|
||||||
|
|
|
@ -15,12 +15,17 @@
|
||||||
#include "newgrf.h"
|
#include "newgrf.h"
|
||||||
#include "newgrf_airporttiles.h"
|
#include "newgrf_airporttiles.h"
|
||||||
#include "newgrf_spritegroup.h"
|
#include "newgrf_spritegroup.h"
|
||||||
|
#include "newgrf_sound.h"
|
||||||
|
#include "animated_tile_func.h"
|
||||||
#include "station_base.h"
|
#include "station_base.h"
|
||||||
#include "water.h"
|
#include "water.h"
|
||||||
#include "viewport_func.h"
|
#include "viewport_func.h"
|
||||||
#include "landscape.h"
|
#include "landscape.h"
|
||||||
#include "company_base.h"
|
#include "company_base.h"
|
||||||
#include "town.h"
|
#include "town.h"
|
||||||
|
#include "variables.h"
|
||||||
|
#include "functions.h"
|
||||||
|
#include "core/random_func.hpp"
|
||||||
#include "table/airporttiles.h"
|
#include "table/airporttiles.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,9 +129,7 @@ static uint32 GetAirportTileIDAtOffset(TileIndex tile, const Station *st, uint32
|
||||||
return 0xFFFF;
|
return 0xFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't use GetAirportGfx here as we want the original (not overriden)
|
StationGfx gfx = GetAirportGfx(tile);
|
||||||
* graphics id. */
|
|
||||||
StationGfx gfx = GetStationGfx(tile);
|
|
||||||
const AirportTileSpec *ats = AirportTileSpec::Get(gfx);
|
const AirportTileSpec *ats = AirportTileSpec::Get(gfx);
|
||||||
|
|
||||||
if (gfx < NEW_AIRPORTTILE_OFFSET) { // Does it belongs to an old type?
|
if (gfx < NEW_AIRPORTTILE_OFFSET) { // Does it belongs to an old type?
|
||||||
|
@ -291,4 +294,110 @@ bool DrawNewAirportTile(TileInfo *ti, Station *st, StationGfx gfx, const Airport
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AnimateAirportTile(TileIndex tile)
|
||||||
|
{
|
||||||
|
Station *st = Station::GetByTile(tile);
|
||||||
|
StationGfx gfx = GetAirportGfx(tile);
|
||||||
|
const AirportTileSpec *ats = AirportTileSpec::Get(gfx);
|
||||||
|
uint8 animation_speed = ats->animation_speed;
|
||||||
|
|
||||||
|
if (HasBit(ats->callback_flags, CBM_AIRT_ANIM_SPEED)) {
|
||||||
|
uint16 callback_res = GetAirportTileCallback(CBID_AIRPTILE_ANIMATION_SPEED, 0, 0, gfx, st, tile);
|
||||||
|
if (callback_res != CALLBACK_FAILED) animation_speed = Clamp(callback_res & 0xFF, 0, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* An animation speed of 2 means the animation frame changes 4 ticks, and
|
||||||
|
* increasing this value by one doubles the wait. 0 is the minimum value
|
||||||
|
* allowed for animation_speed, which corresponds to 30ms, and 16 is the
|
||||||
|
* maximum, corresponding to around 33 minutes. */
|
||||||
|
if ((_tick_counter % (1 << animation_speed)) != 0) return;
|
||||||
|
|
||||||
|
bool frame_set_by_callback = false;
|
||||||
|
uint8 frame = GetStationAnimationFrame(tile);
|
||||||
|
uint16 num_frames = GB(ats->animation_info, 0, 8);
|
||||||
|
|
||||||
|
if (HasBit(ats->callback_flags, CBM_AIRT_ANIM_NEXT_FRAME)) {
|
||||||
|
uint16 callback_res = GetAirportTileCallback(CBID_AIRPTILE_ANIM_NEXT_FRAME, HasBit(ats->animation_special_flags, 0) ? Random() : 0, 0, gfx, st, tile);
|
||||||
|
|
||||||
|
if (callback_res != CALLBACK_FAILED) {
|
||||||
|
frame_set_by_callback = true;
|
||||||
|
|
||||||
|
switch (callback_res & 0xFF) {
|
||||||
|
case 0xFF:
|
||||||
|
DeleteAnimatedTile(tile);
|
||||||
|
break;
|
||||||
|
case 0xFE:
|
||||||
|
/* Carry on as normal. */
|
||||||
|
frame_set_by_callback = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
frame = callback_res & 0xFF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the lower 7 bits of the upper byte of the callback
|
||||||
|
* result are not empty, it is a sound effect. */
|
||||||
|
if (GB(callback_res, 8, 7) != 0) PlayTileSound(ats->grf_prop.grffile, GB(callback_res, 8, 7), tile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!frame_set_by_callback) {
|
||||||
|
if (frame < num_frames) {
|
||||||
|
frame++;
|
||||||
|
} else if (frame == num_frames && GB(ats->animation_info, 8, 8) == 1) {
|
||||||
|
/* 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 ChangeAirportTileAnimationFrame(const AirportTileSpec *ats, TileIndex tile, AirpAnimationTrigger trigger, StationGfx gfx, Station *st)
|
||||||
|
{
|
||||||
|
uint16 callback_res = GetAirportTileCallback(CBID_AIRPTILE_ANIM_START_STOP, Random(), trigger, gfx, st, tile);
|
||||||
|
if (callback_res == CALLBACK_FAILED) return;
|
||||||
|
|
||||||
|
switch (callback_res & 0xFF) {
|
||||||
|
case 0xFD: /* Do nothing. */ break;
|
||||||
|
case 0xFE: AddAnimatedTile(tile); break;
|
||||||
|
case 0xFF: DeleteAnimatedTile(tile); break;
|
||||||
|
default:
|
||||||
|
SetStationAnimationFrame(tile, callback_res & 0xFF);
|
||||||
|
AddAnimatedTile(tile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the lower 7 bits of the upper byte of the callback
|
||||||
|
* result are not empty, it is a sound effect. */
|
||||||
|
if (GB(callback_res, 8, 7) != 0) PlayTileSound(ats->grf_prop.grffile, GB(callback_res, 8, 7), tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AirportTileAnimationTrigger(Station *st, TileIndex tile, AirpAnimationTrigger trigger, CargoID cargo_type)
|
||||||
|
{
|
||||||
|
StationGfx gfx = GetAirportGfx(tile);
|
||||||
|
const AirportTileSpec *ats = AirportTileSpec::Get(gfx);
|
||||||
|
|
||||||
|
if (!HasBit(ats->animation_triggers, trigger)) return;
|
||||||
|
|
||||||
|
ChangeAirportTileAnimationFrame(ats, tile, trigger, gfx, st);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AirportAnimationTrigger(Station *st, AirpAnimationTrigger trigger, CargoID cargo_type)
|
||||||
|
{
|
||||||
|
if (st->airport_tile == INVALID_TILE) return;
|
||||||
|
|
||||||
|
const AirportSpec *as = st->GetAirportSpec();
|
||||||
|
int w = as->size_x;
|
||||||
|
int h = as->size_y;
|
||||||
|
|
||||||
|
TILE_LOOP(tile, w, h, st->airport_tile) {
|
||||||
|
if (st->TileBelongsToAirport(tile)) AirportTileAnimationTrigger(st, tile, trigger, cargo_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,15 @@
|
||||||
#include "newgrf_commons.h"
|
#include "newgrf_commons.h"
|
||||||
#include "airport.h"
|
#include "airport.h"
|
||||||
|
|
||||||
|
/** Animation triggers for airport tiles */
|
||||||
|
enum AirpAnimationTrigger {
|
||||||
|
AAT_BUILT, ///< Triggered when the airport it build (for all tiles at the same time)
|
||||||
|
AAT_TILELOOP, ///< Triggered in the periodic tile loop
|
||||||
|
AAT_STATION_NEW_CARGO, ///< Triggered when new cargo arrives at the station (for all tiles at the same time)
|
||||||
|
AAT_STATION_CARGO_TAKEN, ///< Triggered when a cargo type is completely removed from the station (for all tiles at the same time)
|
||||||
|
AAT_STATION_250_ticks, ///< Triggered every 250 ticks (for all tiles at the same time)
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the data structure of each indivudual tile of an airport.
|
* Defines the data structure of each indivudual tile of an airport.
|
||||||
*/
|
*/
|
||||||
|
@ -40,6 +49,10 @@ private:
|
||||||
friend void AirportTileOverrideManager::SetEntitySpec(const AirportTileSpec *airpts);
|
friend void AirportTileOverrideManager::SetEntitySpec(const AirportTileSpec *airpts);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
StationGfx GetTranslatedAirportTileID(StationGfx gfx);
|
||||||
|
void AnimateAirportTile(TileIndex tile);
|
||||||
|
void AirportTileAnimationTrigger(Station *st, TileIndex tile, AirpAnimationTrigger trigger, CargoID cargo_type = CT_INVALID);
|
||||||
|
void AirportAnimationTrigger(Station *st, AirpAnimationTrigger trigger, CargoID cargo_type = CT_INVALID);
|
||||||
bool DrawNewAirportTile(TileInfo *ti, Station *st, StationGfx gfx, const AirportTileSpec *airts);
|
bool DrawNewAirportTile(TileInfo *ti, Station *st, StationGfx gfx, const AirportTileSpec *airts);
|
||||||
|
|
||||||
#endif /* NEWGRF_AIRPORTTILES_H */
|
#endif /* NEWGRF_AIRPORTTILES_H */
|
||||||
|
|
|
@ -223,6 +223,15 @@ enum CallbackID {
|
||||||
|
|
||||||
/** Called to determine the type (if any) of foundation to draw for an airport tile. */
|
/** Called to determine the type (if any) of foundation to draw for an airport tile. */
|
||||||
CBID_AIRPTILE_DRAW_FOUNDATIONS = 0x150, // 15 bit callback
|
CBID_AIRPTILE_DRAW_FOUNDATIONS = 0x150, // 15 bit callback
|
||||||
|
|
||||||
|
/** Called for periodically starting or stopping the animation. */
|
||||||
|
CBID_AIRPTILE_ANIM_START_STOP = 0x152, // 15 bit callback
|
||||||
|
|
||||||
|
/** Called to determine airport tile next animation frame. */
|
||||||
|
CBID_AIRPTILE_ANIM_NEXT_FRAME = 0x153, // 15 bit callback
|
||||||
|
|
||||||
|
/** Called to indicate how long the current animation frame should last. */
|
||||||
|
CBID_AIRPTILE_ANIMATION_SPEED = 0x154, // 8 bit callback
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2079,6 +2079,15 @@ CommandCost CmdBuildAirport(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
|
||||||
do {
|
do {
|
||||||
TileIndex cur_tile = tile + ToTileIndexDiff(it->ti);
|
TileIndex cur_tile = tile + ToTileIndexDiff(it->ti);
|
||||||
MakeAirport(cur_tile, st->owner, st->index, it->gfx);
|
MakeAirport(cur_tile, st->owner, st->index, it->gfx);
|
||||||
|
|
||||||
|
if (AirportTileSpec::Get(GetTranslatedAirportTileID(it->gfx))->animation_info != 0xFFFF) AddAnimatedTile(cur_tile);
|
||||||
|
} while ((++it)->ti.x != -0x80);
|
||||||
|
|
||||||
|
/* Only call the animation trigger after all tiles have been built */
|
||||||
|
it = as->table[0];
|
||||||
|
do {
|
||||||
|
TileIndex cur_tile = tile + ToTileIndexDiff(it->ti);
|
||||||
|
AirportTileAnimationTrigger(st, cur_tile, AAT_BUILT);
|
||||||
} while ((++it)->ti.x != -0x80);
|
} while ((++it)->ti.x != -0x80);
|
||||||
|
|
||||||
st->UpdateVirtCoord();
|
st->UpdateVirtCoord();
|
||||||
|
@ -2703,9 +2712,7 @@ static void TileLoop_Station(TileIndex tile)
|
||||||
* hardcoded.....not good */
|
* hardcoded.....not good */
|
||||||
switch (GetStationType(tile)) {
|
switch (GetStationType(tile)) {
|
||||||
case STATION_AIRPORT:
|
case STATION_AIRPORT:
|
||||||
if (AirportTileSpec::Get(GetStationGfx(tile))->animation_info != 0xFFFF) {
|
AirportTileAnimationTrigger(Station::GetByTile(tile), tile, AAT_TILELOOP);
|
||||||
AddAnimatedTile(tile);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STATION_DOCK:
|
case STATION_DOCK:
|
||||||
|
@ -2982,6 +2989,7 @@ void OnTick_Station()
|
||||||
/* Stop processing this station if it was deleted */
|
/* Stop processing this station if it was deleted */
|
||||||
if (!StationHandleBigTick(st)) continue;
|
if (!StationHandleBigTick(st)) continue;
|
||||||
StationAnimationTrigger(st, st->xy, STAT_ANIM_250_TICKS);
|
StationAnimationTrigger(st, st->xy, STAT_ANIM_250_TICKS);
|
||||||
|
if (Station::IsExpected(st)) AirportAnimationTrigger(Station::From(st), AAT_STATION_250_ticks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3016,6 +3024,7 @@ static void UpdateStationWaiting(Station *st, CargoID type, uint amount, SourceT
|
||||||
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);
|
StationAnimationTrigger(st, st->xy, STAT_ANIM_NEW_CARGO, type);
|
||||||
|
AirportAnimationTrigger(st, AAT_STATION_NEW_CARGO, type);
|
||||||
|
|
||||||
SetWindowDirty(WC_STATION_VIEW, st->index);
|
SetWindowDirty(WC_STATION_VIEW, st->index);
|
||||||
st->MarkTilesDirty(true);
|
st->MarkTilesDirty(true);
|
||||||
|
|
Loading…
Reference in New Issue