diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index e0e33c7662..aac97c84c9 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -1430,7 +1430,7 @@ static void AircraftLandAirplane(Aircraft *v) v->UpdateDeltaXY(); - TriggerAirportTileAnimation(st, vt, AAT_STATION_AIRPLANE_LAND); + TriggerAirportTileAnimation(st, vt, AirportAnimationTrigger::AirplaneTouchdown); if (!PlayVehicleSound(v, VSE_TOUCHDOWN)) { SndPlayVehicleFx(SND_17_SKID_PLANE, v); diff --git a/src/base_station_base.h b/src/base_station_base.h index 12036085a3..fd493d7853 100644 --- a/src/base_station_base.h +++ b/src/base_station_base.h @@ -75,8 +75,8 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> { uint16_t random_bits = 0; ///< Random bits assigned to this station StationRandomTriggers waiting_random_triggers; ///< Waiting triggers (NewGRF), shared by all station parts/tiles, road stops, ... essentially useless and broken by design. - uint8_t cached_anim_triggers = 0; ///< NOSAVE: Combined animation trigger bitmask, used to determine if trigger processing should happen. - uint8_t cached_roadstop_anim_triggers = 0; ///< NOSAVE: Combined animation trigger bitmask for road stops, used to determine if trigger processing should happen. + StationAnimationTriggers cached_anim_triggers; ///< NOSAVE: Combined animation trigger bitmask, used to determine if trigger processing should happen. + StationAnimationTriggers cached_roadstop_anim_triggers; ///< NOSAVE: Combined animation trigger bitmask for road stops, used to determine if trigger processing should happen. CargoTypes cached_cargo_triggers{}; ///< NOSAVE: Combined cargo trigger bitmask CargoTypes cached_roadstop_cargo_triggers{}; ///< NOSAVE: Combined cargo trigger bitmask for road stops diff --git a/src/economy.cpp b/src/economy.cpp index 01896c9ba7..23473a128c 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -1168,7 +1168,7 @@ static void TriggerIndustryProduction(Industry *i) } TriggerIndustryRandomisation(i, IndustryRandomTrigger::CargoReceived); - TriggerIndustryAnimation(i, IAT_INDUSTRY_RECEIVED_CARGO); + TriggerIndustryAnimation(i, IndustryAnimationTrigger::CargoReceived); } /** @@ -1812,10 +1812,10 @@ static void LoadUnloadVehicle(Vehicle *front) if (ge->GetData().cargo.TotalCount() == 0) { TriggerStationRandomisation(st, st->xy, StationRandomTrigger::CargoTaken, v->cargo_type); - TriggerStationAnimation(st, st->xy, SAT_CARGO_TAKEN, v->cargo_type); - TriggerAirportAnimation(st, AAT_STATION_CARGO_TAKEN, v->cargo_type); + TriggerStationAnimation(st, st->xy, StationAnimationTrigger::CargoTaken, v->cargo_type); + TriggerAirportAnimation(st, AirportAnimationTrigger::CargoTaken, v->cargo_type); TriggerRoadStopRandomisation(st, st->xy, StationRandomTrigger::CargoTaken, v->cargo_type); - TriggerRoadStopAnimation(st, st->xy, SAT_CARGO_TAKEN, v->cargo_type); + TriggerRoadStopAnimation(st, st->xy, StationAnimationTrigger::CargoTaken, v->cargo_type); } new_load_unload_ticks += loaded; @@ -1835,10 +1835,10 @@ static void LoadUnloadVehicle(Vehicle *front) if (anything_loaded || anything_unloaded) { if (front->type == VEH_TRAIN) { TriggerStationRandomisation(st, front->tile, StationRandomTrigger::VehicleLoads); - TriggerStationAnimation(st, front->tile, SAT_TRAIN_LOADS); + TriggerStationAnimation(st, front->tile, StationAnimationTrigger::VehicleLoads); } else if (front->type == VEH_ROAD) { TriggerRoadStopRandomisation(st, front->tile, StationRandomTrigger::VehicleLoads); - TriggerRoadStopAnimation(st, front->tile, SAT_TRAIN_LOADS); + TriggerRoadStopAnimation(st, front->tile, StationAnimationTrigger::VehicleLoads); } } diff --git a/src/house.h b/src/house.h index 56405c9444..4175a501c9 100644 --- a/src/house.h +++ b/src/house.h @@ -112,7 +112,7 @@ struct HouseSpec { uint8_t probability; ///< Relative probability of appearing (16 is the standard value) HouseExtraFlags extra_flags{}; ///< some more flags HouseClassID class_id; ///< defines the class this house has (not grf file based) - AnimationInfo animation; ///< information about the animation. + AnimationInfo animation; ///< information about the animation. uint8_t processing_time; ///< Periodic refresh multiplier uint8_t minimum_life; ///< The minimum number of years this house will survive before the town rebuilds it CargoTypes watched_cargoes; ///< Cargo types watched for acceptance. diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 5c3cb2d57f..dab8b7c9b9 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -763,7 +763,7 @@ static void MakeIndustryTileBigger(TileIndex tile) uint8_t stage = GetIndustryConstructionStage(tile) + 1; SetIndustryConstructionCounter(tile, 0); SetIndustryConstructionStage(tile, stage); - TriggerIndustryTileAnimation(tile, IAT_CONSTRUCTION_STAGE_CHANGE); + TriggerIndustryTileAnimation(tile, IndustryAnimationTrigger::ConstructionStageChanged); if (stage == INDUSTRY_COMPLETED) SetIndustryCompleted(tile); MarkTileDirtyByTile(tile); @@ -853,7 +853,7 @@ static void TileLoop_Industry(TileIndex tile) if (_game_mode == GM_EDITOR) return; - if (TransportIndustryGoods(tile) && !TriggerIndustryAnimation(Industry::GetByTile(tile), IAT_INDUSTRY_DISTRIBUTES_CARGO)) { + if (TransportIndustryGoods(tile) && !TriggerIndustryAnimation(Industry::GetByTile(tile), IndustryAnimationTrigger::CargoDistributed)) { uint newgfx = GetIndustryTileSpec(GetIndustryGfx(tile))->anim_production; if (newgfx != INDUSTRYTILE_NOANIM) { @@ -865,7 +865,7 @@ static void TileLoop_Industry(TileIndex tile) } } - if (TriggerIndustryTileAnimation(tile, IAT_TILELOOP)) return; + if (TriggerIndustryTileAnimation(tile, IndustryAnimationTrigger::TileLoop)) return; IndustryGfx newgfx = GetIndustryTileSpec(GetIndustryGfx(tile))->anim_next; if (newgfx != INDUSTRYTILE_NOANIM) { @@ -1223,7 +1223,7 @@ static void ProduceIndustryGoods(Industry *i) } TriggerIndustryRandomisation(i, IndustryRandomTrigger::IndustryTick); - TriggerIndustryAnimation(i, IAT_INDUSTRY_TICK); + TriggerIndustryAnimation(i, IndustryAnimationTrigger::IndustryTick); } } diff --git a/src/industry_type.h b/src/industry_type.h index 33db310ed5..ed01773729 100644 --- a/src/industry_type.h +++ b/src/industry_type.h @@ -29,6 +29,16 @@ enum class IndustryRandomTrigger : uint8_t { }; using IndustryRandomTriggers = EnumBitSet; +/** Animation triggers of the industries. */ +enum class IndustryAnimationTrigger : uint8_t { + ConstructionStageChanged, ///< Trigger whenever the construction stage changes. + TileLoop, ///< Trigger in the periodic tile loop. + IndustryTick, ///< Trigger every tick. + CargoReceived, ///< Trigger when cargo is received . + CargoDistributed, ///< Trigger when cargo is distributed. +}; +using IndustryAnimationTriggers = EnumBitSet; + static const IndustryType NUM_INDUSTRYTYPES_PER_GRF = 128; ///< maximum number of industry types per NewGRF; limited to 128 because bit 7 has a special meaning in some variables/callbacks (see MapNewGRFIndustryType). static const IndustryType NEW_INDUSTRYOFFSET = 37; ///< original number of industry types diff --git a/src/industrytype.h b/src/industrytype.h index d384085fe4..4b6a9e3e74 100644 --- a/src/industrytype.h +++ b/src/industrytype.h @@ -162,7 +162,7 @@ struct IndustryTileSpec { bool anim_state; /* Newgrf data */ IndustryTileCallbackMasks callback_mask; ///< Bitmask of industry tile callbacks that have to be called - AnimationInfo animation; ///< Information about the animation (is it looping, how many loops etc) + AnimationInfo animation; ///< Information about the animation (is it looping, how many loops etc) IndustryTileSpecialFlags special_flags; ///< Bitmask of extra flags used by the tile bool enabled; ///< entity still available (by default true).newgrf can disable it, though GRFFileProps grf_prop; ///< properties related to the grf file diff --git a/src/newgrf/newgrf_act0_airports.cpp b/src/newgrf/newgrf_act0_airports.cpp index 407b980a06..3a11d3d079 100644 --- a/src/newgrf/newgrf_act0_airports.cpp +++ b/src/newgrf/newgrf_act0_airports.cpp @@ -210,7 +210,7 @@ static ChangeInfoResult AirportTilesChangeInfo(uint first, uint last, int prop, tsp->enabled = true; - tsp->animation = AnimationInfo{}; + tsp->animation = {}; tsp->grf_prop.local_id = id; tsp->grf_prop.subst_id = subs_id; @@ -247,7 +247,7 @@ static ChangeInfoResult AirportTilesChangeInfo(uint first, uint last, int prop, break; case 0x11: // Animation triggers - tsp->animation.triggers = buf.ReadByte(); + tsp->animation.triggers = static_cast(buf.ReadByte()); break; case 0x12: // Badge list diff --git a/src/newgrf/newgrf_act0_industries.cpp b/src/newgrf/newgrf_act0_industries.cpp index bb20156748..f1bd06c880 100644 --- a/src/newgrf/newgrf_act0_industries.cpp +++ b/src/newgrf/newgrf_act0_industries.cpp @@ -160,7 +160,7 @@ static ChangeInfoResult IndustrytilesChangeInfo(uint first, uint last, int prop, break; case 0x11: // Triggers for callback 25 - tsp->animation.triggers = buf.ReadByte(); + tsp->animation.triggers = static_cast(buf.ReadByte()); break; case 0x12: // Special flags diff --git a/src/newgrf/newgrf_act0_objects.cpp b/src/newgrf/newgrf_act0_objects.cpp index 4b76d3620a..4a61e11661 100644 --- a/src/newgrf/newgrf_act0_objects.cpp +++ b/src/newgrf/newgrf_act0_objects.cpp @@ -159,7 +159,7 @@ static ChangeInfoResult ObjectChangeInfo(uint first, uint last, int prop, ByteRe break; case 0x13: // Animation triggers - spec->animation.triggers = buf.ReadWord(); + spec->animation.triggers = static_cast(buf.ReadWord()); break; case 0x14: // Removal cost multiplier diff --git a/src/newgrf/newgrf_act0_roadstops.cpp b/src/newgrf/newgrf_act0_roadstops.cpp index 0a64a273a2..df930ff267 100644 --- a/src/newgrf/newgrf_act0_roadstops.cpp +++ b/src/newgrf/newgrf_act0_roadstops.cpp @@ -123,7 +123,7 @@ static ChangeInfoResult RoadStopChangeInfo(uint first, uint last, int prop, Byte break; case 0x10: // Animation triggers - rs->animation.triggers = buf.ReadWord(); + rs->animation.triggers = static_cast(buf.ReadWord()); break; case 0x11: // Callback mask diff --git a/src/newgrf/newgrf_act0_stations.cpp b/src/newgrf/newgrf_act0_stations.cpp index 38da11b566..e4c0a4bfc1 100644 --- a/src/newgrf/newgrf_act0_stations.cpp +++ b/src/newgrf/newgrf_act0_stations.cpp @@ -243,7 +243,7 @@ static ChangeInfoResult StationChangeInfo(uint first, uint last, int prop, ByteR break; case 0x18: // Animation triggers - statspec->animation.triggers = buf.ReadWord(); + statspec->animation.triggers = static_cast(buf.ReadWord()); break; /* 0x19 road routing (not implemented) */ diff --git a/src/newgrf_airporttiles.cpp b/src/newgrf_airporttiles.cpp index a42859d220..c4457d306b 100644 --- a/src/newgrf_airporttiles.cpp +++ b/src/newgrf_airporttiles.cpp @@ -300,15 +300,15 @@ void AnimateAirportTile(TileIndex tile) AirportTileAnimationBase::AnimateTile(ats, Station::GetByTile(tile), tile, HasBit(ats->animation_special_flags, 0)); } -void TriggerAirportTileAnimation(Station *st, TileIndex tile, AirpAnimationTrigger trigger, CargoType cargo_type) +void TriggerAirportTileAnimation(Station *st, TileIndex tile, AirportAnimationTrigger trigger, CargoType cargo_type) { const AirportTileSpec *ats = AirportTileSpec::GetByTile(tile); - if (!HasBit(ats->animation.triggers, trigger)) return; + if (!ats->animation.triggers.Test(trigger)) return; - AirportTileAnimationBase::ChangeAnimationFrame(CBID_AIRPTILE_ANIMATION_TRIGGER, ats, st, tile, Random(), (uint8_t)trigger | (cargo_type << 8)); + AirportTileAnimationBase::ChangeAnimationFrame(CBID_AIRPTILE_ANIMATION_TRIGGER, ats, st, tile, Random(), to_underlying(trigger) | (cargo_type << 8)); } -void TriggerAirportAnimation(Station *st, AirpAnimationTrigger trigger, CargoType cargo_type) +void TriggerAirportAnimation(Station *st, AirportAnimationTrigger trigger, CargoType cargo_type) { if (st->airport.tile == INVALID_TILE) return; diff --git a/src/newgrf_airporttiles.h b/src/newgrf_airporttiles.h index ef2884f2cd..08aa7c871f 100644 --- a/src/newgrf_airporttiles.h +++ b/src/newgrf_airporttiles.h @@ -68,7 +68,7 @@ struct AirportTileResolverObject : public ResolverObject { * Defines the data structure of each individual tile of an airport. */ struct AirportTileSpec { - AnimationInfo animation; ///< Information about the animation. + AnimationInfo animation; ///< Information about the animation. StringID name; ///< Tile Subname string, land information on this tile will give you "AirportName (TileSubname)" AirportTileCallbackMasks callback_mask; ///< Bitmask telling which grf callback is set uint8_t animation_special_flags; ///< Extra flags to influence the animation @@ -88,8 +88,8 @@ private: }; void AnimateAirportTile(TileIndex tile); -void TriggerAirportTileAnimation(Station *st, TileIndex tile, AirpAnimationTrigger trigger, CargoType cargo_type = INVALID_CARGO); -void TriggerAirportAnimation(Station *st, AirpAnimationTrigger trigger, CargoType cargo_type = INVALID_CARGO); +void TriggerAirportTileAnimation(Station *st, TileIndex tile, AirportAnimationTrigger trigger, CargoType cargo_type = INVALID_CARGO); +void TriggerAirportAnimation(Station *st, AirportAnimationTrigger trigger, CargoType cargo_type = INVALID_CARGO); bool DrawNewAirportTile(TileInfo *ti, Station *st, const AirportTileSpec *airts); #endif /* NEWGRF_AIRPORTTILES_H */ diff --git a/src/newgrf_animation_type.h b/src/newgrf_animation_type.h index fd20022a59..1796c6bdc4 100644 --- a/src/newgrf_animation_type.h +++ b/src/newgrf_animation_type.h @@ -17,48 +17,19 @@ enum class AnimationStatus : uint8_t { }; /** Information about animation. */ +template struct AnimationInfo { uint8_t frames = 0; ///< The number of frames. AnimationStatus status = AnimationStatus::NoAnimation; ///< Status. uint8_t speed = 2; ///< The speed: time between frames = 2^speed ticks. - uint16_t triggers = 0; ///< The triggers that trigger animation. + AnimationTriggers triggers; ///< The enabled animation triggers. }; -/** Animation triggers for station. */ -enum StationAnimationTrigger : uint8_t { - SAT_BUILT, ///< Trigger tile when built. - SAT_NEW_CARGO, ///< Trigger station on new cargo arrival. - SAT_CARGO_TAKEN, ///< Trigger station when cargo is completely taken. - SAT_TRAIN_ARRIVES, ///< Trigger platform when train arrives. - SAT_TRAIN_DEPARTS, ///< Trigger platform when train leaves. - SAT_TRAIN_LOADS, ///< Trigger platform when train loads/unloads. - SAT_250_TICKS, ///< Trigger station every 250 ticks. -}; - -/** Animation triggers of the industries. */ -enum IndustryAnimationTrigger : uint8_t { - IAT_CONSTRUCTION_STAGE_CHANGE, ///< Trigger whenever the construction stage changes. - IAT_TILELOOP, ///< Trigger in the periodic tile loop. - IAT_INDUSTRY_TICK, ///< Trigger every tick. - IAT_INDUSTRY_RECEIVED_CARGO, ///< Trigger when cargo is received . - IAT_INDUSTRY_DISTRIBUTES_CARGO, ///< Trigger when cargo is distributed. -}; - -/** Animation triggers for airport tiles */ -enum AirpAnimationTrigger : uint8_t { - AAT_BUILT, ///< Triggered when the airport is built (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). - AAT_STATION_AIRPLANE_LAND, ///< Triggered when an airplane (not a helicopter) touches down at the airport (for single tile). -}; - -/** Animation triggers for objects. */ -enum ObjectAnimationTrigger : uint8_t { - OAT_BUILT, ///< Triggered when the object is built (for all tiles at the same time). - OAT_TILELOOP, ///< Triggered in the periodic tile loop. - OAT_256_TICKS, ///< Triggered every 256 ticks (for all tiles at the same time). +template <> +struct AnimationInfo { + uint8_t frames = 0; + AnimationStatus status = AnimationStatus::NoAnimation; + uint8_t speed = 2; }; #endif /* NEWGRF_ANIMATION_TYPE_H */ diff --git a/src/newgrf_industrytiles.cpp b/src/newgrf_industrytiles.cpp index 52dd262d4a..1ace572ae2 100644 --- a/src/newgrf_industrytiles.cpp +++ b/src/newgrf_industrytiles.cpp @@ -280,9 +280,9 @@ bool TriggerIndustryTileAnimation(TileIndex tile, IndustryAnimationTrigger iat, { const IndustryTileSpec *itspec = GetIndustryTileSpec(GetIndustryGfx(tile)); - if (!HasBit(itspec->animation.triggers, iat)) return false; + if (!itspec->animation.triggers.Test(iat)) return false; - IndustryAnimationBase::ChangeAnimationFrame(CBID_INDTILE_ANIMATION_TRIGGER, itspec, Industry::GetByTile(tile), tile, random, iat); + IndustryAnimationBase::ChangeAnimationFrame(CBID_INDTILE_ANIMATION_TRIGGER, itspec, Industry::GetByTile(tile), tile, random, to_underlying(iat)); return true; } diff --git a/src/newgrf_object.cpp b/src/newgrf_object.cpp index c08c3669cc..fbc923d7d1 100644 --- a/src/newgrf_object.cpp +++ b/src/newgrf_object.cpp @@ -564,9 +564,9 @@ void AnimateNewObjectTile(TileIndex tile) */ void TriggerObjectTileAnimation(Object *o, TileIndex tile, ObjectAnimationTrigger trigger, const ObjectSpec *spec) { - if (!HasBit(spec->animation.triggers, trigger)) return; + if (!spec->animation.triggers.Test(trigger)) return; - ObjectAnimationBase::ChangeAnimationFrame(CBID_OBJECT_ANIMATION_TRIGGER, spec, o, tile, Random(), trigger); + ObjectAnimationBase::ChangeAnimationFrame(CBID_OBJECT_ANIMATION_TRIGGER, spec, o, tile, Random(), to_underlying(trigger)); } /** @@ -577,7 +577,7 @@ void TriggerObjectTileAnimation(Object *o, TileIndex tile, ObjectAnimationTrigge */ void TriggerObjectAnimation(Object *o, ObjectAnimationTrigger trigger, const ObjectSpec *spec) { - if (!HasBit(spec->animation.triggers, trigger)) return; + if (!spec->animation.triggers.Test(trigger)) return; for (TileIndex tile : o->location) { TriggerObjectTileAnimation(o, tile, trigger, spec); diff --git a/src/newgrf_object.h b/src/newgrf_object.h index c965de8aed..ca9ee79719 100644 --- a/src/newgrf_object.h +++ b/src/newgrf_object.h @@ -61,7 +61,7 @@ struct ObjectSpec : NewGRFSpecBase { /* 2 because of the "normal" and "buy" sprite stacks. */ FixedGRFFileProps<2> grf_prop; ///< Properties related the the grf file /* Animation speed default differs from other features */ - AnimationInfo animation{0, AnimationStatus::NoAnimation, 0, 0}; ///< Information about the animation. + AnimationInfo animation{0, AnimationStatus::NoAnimation, 0, {}}; ///< Information about the animation. StringID name; ///< The name for this object. LandscapeTypes climate; ///< In which climates is this object available? diff --git a/src/newgrf_roadstop.cpp b/src/newgrf_roadstop.cpp index 3096c2d2ea..3e0d967035 100644 --- a/src/newgrf_roadstop.cpp +++ b/src/newgrf_roadstop.cpp @@ -384,23 +384,23 @@ void TriggerRoadStopAnimation(BaseStation *st, TileIndex trigger_tile, StationAn /* Check the cached animation trigger bitmask to see if we need * to bother with any further processing. */ - if (!HasBit(st->cached_roadstop_anim_triggers, trigger)) return; + if (!st->cached_roadstop_anim_triggers.Test(trigger)) return; uint16_t random_bits = Random(); auto process_tile = [&](TileIndex cur_tile) { const RoadStopSpec *ss = GetRoadStopSpec(cur_tile); - if (ss != nullptr && HasBit(ss->animation.triggers, trigger)) { + if (ss != nullptr && ss->animation.triggers.Test(trigger)) { uint8_t local_cargo; if (!IsValidCargoType(cargo_type)) { local_cargo = UINT8_MAX; } else { local_cargo = ss->grf_prop.grffile->cargo_map[cargo_type]; } - RoadStopAnimationBase::ChangeAnimationFrame(CBID_STATION_ANIMATION_TRIGGER, ss, st, cur_tile, (random_bits << 16) | Random(), (uint8_t)trigger | (local_cargo << 8)); + RoadStopAnimationBase::ChangeAnimationFrame(CBID_STATION_ANIMATION_TRIGGER, ss, st, cur_tile, (random_bits << 16) | Random(), to_underlying(trigger) | (local_cargo << 8)); } }; - if (trigger == SAT_NEW_CARGO || trigger == SAT_CARGO_TAKEN || trigger == SAT_250_TICKS) { + if (trigger == StationAnimationTrigger::NewCargo || trigger == StationAnimationTrigger::CargoTaken || trigger == StationAnimationTrigger::AcceptanceTick) { for (const RoadStopTileData &tile_data : st->custom_roadstop_tile_data) { process_tile(tile_data.tile); } @@ -619,7 +619,7 @@ void DeallocateSpecFromRoadStop(BaseStation *st, uint8_t specindex) st->roadstop_speclist.resize(num_specs + 1); } else { st->roadstop_speclist.clear(); - st->cached_roadstop_anim_triggers = 0; + st->cached_roadstop_anim_triggers = {}; st->cached_roadstop_cargo_triggers = 0; return; } @@ -634,14 +634,14 @@ void DeallocateSpecFromRoadStop(BaseStation *st, uint8_t specindex) */ void RoadStopUpdateCachedTriggers(BaseStation *st) { - st->cached_roadstop_anim_triggers = 0; + st->cached_roadstop_anim_triggers = {}; st->cached_roadstop_cargo_triggers = 0; /* Combine animation trigger bitmask for all road stop specs * of this station. */ for (const auto &sm : GetStationSpecList(st)) { if (sm.spec == nullptr) continue; - st->cached_roadstop_anim_triggers |= sm.spec->animation.triggers; + st->cached_roadstop_anim_triggers.Set(sm.spec->animation.triggers); st->cached_roadstop_cargo_triggers |= sm.spec->cargo_triggers; } } diff --git a/src/newgrf_roadstop.h b/src/newgrf_roadstop.h index 7c18e93c6f..9064f96735 100644 --- a/src/newgrf_roadstop.h +++ b/src/newgrf_roadstop.h @@ -142,7 +142,7 @@ struct RoadStopSpec : NewGRFSpecBase { CargoTypes cargo_triggers = 0; ///< Bitmask of cargo types which cause trigger re-randomizing - AnimationInfo animation; + AnimationInfo animation; uint8_t bridge_height[6]; ///< Minimum height for a bridge above, 0 for none uint8_t bridge_disallowed_pillars[6]; ///< Disallowed pillar flags for a bridge above diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index 8c2bb29cf7..d8a7ed61a8 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -780,7 +780,7 @@ void DeallocateSpecFromStation(BaseStation *st, uint8_t specindex) st->speclist.resize(num_specs + 1); } else { st->speclist.clear(); - st->cached_anim_triggers = 0; + st->cached_anim_triggers = {}; st->cached_cargo_triggers = 0; return; } @@ -914,23 +914,23 @@ void TriggerStationAnimation(BaseStation *st, TileIndex trigger_tile, StationAni /* 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; + if (!st->cached_anim_triggers.Test(trigger)) return; uint16_t random_bits = Random(); - ETileArea area = ETileArea(st, trigger_tile, tas[trigger]); + ETileArea area = ETileArea(st, trigger_tile, tas[static_cast(trigger)]); /* Check all tiles over the station to check if the specindex is still in use */ for (TileIndex tile : area) { if (st->TileBelongsToRailStation(tile)) { const StationSpec *ss = GetStationSpec(tile); - if (ss != nullptr && HasBit(ss->animation.triggers, trigger)) { + if (ss != nullptr && ss->animation.triggers.Test(trigger)) { uint8_t local_cargo; if (!IsValidCargoType(cargo_type)) { local_cargo = UINT8_MAX; } else { local_cargo = ss->grf_prop.grffile->cargo_map[cargo_type]; } - StationAnimationBase::ChangeAnimationFrame(CBID_STATION_ANIMATION_TRIGGER, ss, st, tile, (random_bits << 16) | GB(Random(), 0, 16), (uint8_t)trigger | (local_cargo << 8)); + StationAnimationBase::ChangeAnimationFrame(CBID_STATION_ANIMATION_TRIGGER, ss, st, tile, (random_bits << 16) | GB(Random(), 0, 16), to_underlying(trigger) | (local_cargo << 8)); } } } @@ -1020,14 +1020,14 @@ void TriggerStationRandomisation(Station *st, TileIndex trigger_tile, StationRan */ void StationUpdateCachedTriggers(BaseStation *st) { - st->cached_anim_triggers = 0; + st->cached_anim_triggers = {}; st->cached_cargo_triggers = 0; /* Combine animation trigger bitmask for all station specs * of this station. */ for (const auto &sm : GetStationSpecList(st)) { if (sm.spec == nullptr) continue; - st->cached_anim_triggers |= sm.spec->animation.triggers; + st->cached_anim_triggers.Set(sm.spec->animation.triggers); st->cached_cargo_triggers |= sm.spec->cargo_triggers; } } diff --git a/src/newgrf_station.h b/src/newgrf_station.h index fd27dc81e3..d6a8aa9df8 100644 --- a/src/newgrf_station.h +++ b/src/newgrf_station.h @@ -160,7 +160,7 @@ struct StationSpec : NewGRFSpecBase { using TileFlags = EnumBitSet; std::vector tileflags; ///< List of tile flags. - AnimationInfo animation; + AnimationInfo animation; /** Custom platform layouts, keyed by platform and length combined. */ std::unordered_map> layouts; diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index 9271467fdb..30a0ca5206 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -130,7 +130,7 @@ void BuildObject(ObjectType type, TileIndex tile, CompanyID owner, Town *town, u } Object::IncTypeCount(type); - if (spec->flags.Test(ObjectFlag::Animation)) TriggerObjectAnimation(o, OAT_BUILT, spec); + if (spec->flags.Test(ObjectFlag::Animation)) TriggerObjectAnimation(o, ObjectAnimationTrigger::Built, spec); } /** @@ -676,8 +676,8 @@ static void TileLoop_Object(TileIndex tile) const ObjectSpec *spec = ObjectSpec::GetByTile(tile); if (spec->flags.Test(ObjectFlag::Animation)) { Object *o = Object::GetByTile(tile); - TriggerObjectTileAnimation(o, tile, OAT_TILELOOP, spec); - if (o->location.tile == tile) TriggerObjectAnimation(o, OAT_256_TICKS, spec); + TriggerObjectTileAnimation(o, tile, ObjectAnimationTrigger::TileLoop, spec); + if (o->location.tile == tile) TriggerObjectAnimation(o, ObjectAnimationTrigger::TileLoopNorth, spec); } if (IsTileOnWater(tile)) TileLoop_Water(tile); diff --git a/src/object_type.h b/src/object_type.h index 8720f8dea3..fe5137d79a 100644 --- a/src/object_type.h +++ b/src/object_type.h @@ -32,4 +32,12 @@ using ObjectID = PoolID; struct Object; struct ObjectSpec; +/** Animation triggers for objects. */ +enum class ObjectAnimationTrigger : uint8_t { + Built, ///< Triggered when the object is built (for all tiles at the same time). + TileLoop, ///< Triggered in the periodic tile loop. + TileLoopNorth, ///< Triggered every 256 ticks (for all tiles at the same time). +}; +using ObjectAnimationTriggers = EnumBitSet; + #endif /* OBJECT_TYPE_H */ diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index dfc6a7bf6a..fdddfb49ec 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -1456,7 +1456,7 @@ again: RoadVehArrivesAt(v, st); v->BeginLoading(); TriggerRoadStopRandomisation(st, v->tile, StationRandomTrigger::VehicleArrives); - TriggerRoadStopAnimation(st, v->tile, SAT_TRAIN_ARRIVES); + TriggerRoadStopAnimation(st, v->tile, StationAnimationTrigger::VehicleArrives); } return false; } @@ -1520,7 +1520,7 @@ again: RoadVehArrivesAt(v, st); v->BeginLoading(); TriggerRoadStopRandomisation(st, v->tile, StationRandomTrigger::VehicleArrives); - TriggerRoadStopAnimation(st, v->tile, SAT_TRAIN_ARRIVES); + TriggerRoadStopAnimation(st, v->tile, StationAnimationTrigger::VehicleArrives); return false; } } else { diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 0ee5738d64..5ac2898844 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -1419,7 +1419,7 @@ CommandCost CmdBuildRailStation(DoCommandFlags flags, TileIndex tile_org, RailTy if (statspec != nullptr) { /* Include this station spec's animation trigger bitmask * in the station's cached copy. */ - st->cached_anim_triggers |= statspec->animation.triggers; + st->cached_anim_triggers.Set(statspec->animation.triggers); } TileIndexDiff tile_delta = TileOffsByAxis(axis); // offset to go to the next platform tile @@ -1480,7 +1480,7 @@ CommandCost CmdBuildRailStation(DoCommandFlags flags, TileIndex tile_org, RailTy } /* Trigger station animation -- after building? */ - TriggerStationAnimation(st, tile, SAT_BUILT); + TriggerStationAnimation(st, tile, StationAnimationTrigger::Built); } SetRailStationTileFlags(tile, statspec); @@ -2050,7 +2050,7 @@ CommandCost CmdBuildRoadStop(DoCommandFlags flags, TileIndex tile, uint8_t width if (roadstopspec != nullptr) { /* Include this road stop spec's animation trigger bitmask * in the station's cached copy. */ - st->cached_roadstop_anim_triggers |= roadstopspec->animation.triggers; + st->cached_roadstop_anim_triggers.Set(roadstopspec->animation.triggers); } RoadStop *road_stop = new RoadStop(cur_tile); @@ -2095,7 +2095,7 @@ CommandCost CmdBuildRoadStop(DoCommandFlags flags, TileIndex tile, uint8_t width SetCustomRoadStopSpecIndex(cur_tile, specindex); if (roadstopspec != nullptr) { st->SetRoadStopRandomBits(cur_tile, GB(Random(), 0, 8)); - TriggerRoadStopAnimation(st, cur_tile, SAT_BUILT); + TriggerRoadStopAnimation(st, cur_tile, StationAnimationTrigger::Built); } MarkTileDirtyByTile(cur_tile); @@ -2622,7 +2622,7 @@ CommandCost CmdBuildAirport(DoCommandFlags flags, TileIndex tile, uint8_t airpor /* Only call the animation trigger after all tiles have been built */ for (AirportTileTableIterator iter(as->layouts[layout].tiles.data(), tile); iter != INVALID_TILE; ++iter) { - TriggerAirportTileAnimation(st, iter, AAT_BUILT); + TriggerAirportTileAnimation(st, iter, AirportAnimationTrigger::Built); } UpdateAirplanesOnNewStation(st); @@ -3609,7 +3609,7 @@ static void TileLoop_Station(TileIndex tile) { switch (GetStationType(tile)) { case StationType::Airport: - TriggerAirportTileAnimation(Station::GetByTile(tile), tile, AAT_TILELOOP); + TriggerAirportTileAnimation(Station::GetByTile(tile), tile, AirportAnimationTrigger::TileLoop); break; case StationType::Dock: @@ -4211,9 +4211,9 @@ void OnTick_Station() /* Spread out station animation over STATION_ACCEPTANCE_TICKS ticks. */ if ((TimerGameTick::counter + st->index) % Ticks::STATION_ACCEPTANCE_TICKS == 0) { - TriggerStationAnimation(st, st->xy, SAT_250_TICKS); - TriggerRoadStopAnimation(st, st->xy, SAT_250_TICKS); - if (Station::IsExpected(st)) TriggerAirportAnimation(Station::From(st), AAT_STATION_250_TICKS); + TriggerStationAnimation(st, st->xy, StationAnimationTrigger::AcceptanceTick); + TriggerRoadStopAnimation(st, st->xy, StationAnimationTrigger::AcceptanceTick); + if (Station::IsExpected(st)) TriggerAirportAnimation(Station::From(st), AirportAnimationTrigger::AcceptanceTick); } } } @@ -4279,10 +4279,10 @@ static uint UpdateStationWaiting(Station *st, CargoType cargo, uint amount, Sour } TriggerStationRandomisation(st, st->xy, StationRandomTrigger::NewCargo, cargo); - TriggerStationAnimation(st, st->xy, SAT_NEW_CARGO, cargo); - TriggerAirportAnimation(st, AAT_STATION_NEW_CARGO, cargo); + TriggerStationAnimation(st, st->xy, StationAnimationTrigger::NewCargo, cargo); + TriggerAirportAnimation(st, AirportAnimationTrigger::NewCargo, cargo); TriggerRoadStopRandomisation(st, st->xy, StationRandomTrigger::NewCargo, cargo); - TriggerRoadStopAnimation(st, st->xy, SAT_NEW_CARGO, cargo); + TriggerRoadStopAnimation(st, st->xy, StationAnimationTrigger::NewCargo, cargo); SetWindowDirty(WC_STATION_VIEW, st->index); diff --git a/src/station_type.h b/src/station_type.h index 25ac176f8e..0d8b672e6e 100644 --- a/src/station_type.h +++ b/src/station_type.h @@ -87,6 +87,29 @@ enum class StationRandomTrigger : uint8_t { }; using StationRandomTriggers = EnumBitSet; +/** Animation triggers for stations and roadstops. */ +enum class StationAnimationTrigger : uint8_t { + Built, ///< Trigger tile when built. + NewCargo, ///< Trigger station on new cargo arrival. + CargoTaken, ///< Trigger station when cargo is completely taken. + VehicleArrives, ///< Trigger platform when train arrives. + VehicleDeparts, ///< Trigger platform when train leaves. + VehicleLoads, ///< Trigger platform when train loads/unloads. + AcceptanceTick, ///< Trigger station every 250 ticks. +}; +using StationAnimationTriggers = EnumBitSet; + +/** Animation triggers for airport tiles */ +enum class AirportAnimationTrigger : uint8_t { + Built, ///< Triggered when the airport is built (for all tiles at the same time). + TileLoop, ///< Triggered in the periodic tile loop. + NewCargo, ///< Triggered when new cargo arrives at the station (for all tiles at the same time). + CargoTaken, ///< Triggered when a cargo type is completely removed from the station (for all tiles at the same time). + AcceptanceTick, ///< Triggered every 250 ticks (for all tiles at the same time). + AirplaneTouchdown, ///< Triggered when an airplane (not a helicopter) touches down at the airport (for single tile). +}; +using AirportAnimationTriggers = EnumBitSet; + /* The different catchment area sizes. */ static constexpr uint CA_NONE = 0; ///< Catchment when the station has no facilities static constexpr uint CA_BUS = 3; ///< Catchment for bus stops with "modified catchment" enabled diff --git a/src/table/airporttiles.h b/src/table/airporttiles.h index b38e6eac4c..f3f9deb6d1 100644 --- a/src/table/airporttiles.h +++ b/src/table/airporttiles.h @@ -13,9 +13,9 @@ #include "table/strings.h" /** Writes all airport tile properties in the AirportTile struct */ -#define AT(num_frames, anim_speed) {{num_frames, AnimationStatus::Looping, anim_speed, 0}, STR_NULL, AirportTileCallbackMasks{}, 0, true, GRFFileProps(INVALID_AIRPORTTILE), {}} +#define AT(num_frames, anim_speed) {{num_frames, AnimationStatus::Looping, anim_speed, {}}, STR_NULL, AirportTileCallbackMasks{}, 0, true, GRFFileProps(INVALID_AIRPORTTILE), {}} /** Writes an airport tile without animation in the AirportTile struct */ -#define AT_NOANIM {AnimationInfo{}, STR_NULL, AirportTileCallbackMasks{}, 0, true, GRFFileProps(INVALID_AIRPORTTILE), {}} +#define AT_NOANIM {AnimationInfo{}, STR_NULL, AirportTileCallbackMasks{}, 0, true, GRFFileProps(INVALID_AIRPORTTILE), {}} /** * All default airport tiles. diff --git a/src/table/build_industry.h b/src/table/build_industry.h index c32b2772d8..d2ddf914a4 100644 --- a/src/table/build_industry.h +++ b/src/table/build_industry.h @@ -1535,7 +1535,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { */ #define MT(ca1, c1, ca2, c2, ca3, c3, sl, a1, a2, a3) { \ {INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO}, \ - {ca1, ca2, ca3}, sl, a1, a2, a3, IndustryTileCallbackMasks{}, AnimationInfo{}, IndustryTileSpecialFlags{}, true, GRFFileProps(INVALID_INDUSTRYTILE), {}, {c1, c2, c3} \ + {ca1, ca2, ca3}, sl, a1, a2, a3, IndustryTileCallbackMasks{}, AnimationInfo{}, IndustryTileSpecialFlags{}, true, GRFFileProps(INVALID_INDUSTRYTILE), {}, {c1, c2, c3} \ } static const IndustryTileSpec _origin_industry_tile_specs[NEW_INDUSTRYTILEOFFSET] = { /* Coal Mine */ diff --git a/src/table/object_land.h b/src/table/object_land.h index 3ea1fb91c5..6988af7a72 100644 --- a/src/table/object_land.h +++ b/src/table/object_land.h @@ -106,7 +106,7 @@ static const DrawTileSpriteSpan _object_hq[] = { #undef TILE_SPRITE_LINE #undef TILE_SPRITE_LINE_NOTHING -#define M(name, size, build_cost_multiplier, clear_cost_multiplier, height, climate, gen_amount, flags) {{INVALID_OBJECT_CLASS, 0}, FixedGRFFileProps<2>{}, AnimationInfo{}, name, climate, size, build_cost_multiplier, clear_cost_multiplier, TimerGameCalendar::Date{}, CalendarTime::MAX_DATE + 1, flags, ObjectCallbackMasks{}, height, 1, gen_amount, {}} +#define M(name, size, build_cost_multiplier, clear_cost_multiplier, height, climate, gen_amount, flags) {{INVALID_OBJECT_CLASS, 0}, FixedGRFFileProps<2>{}, AnimationInfo{}, name, climate, size, build_cost_multiplier, clear_cost_multiplier, TimerGameCalendar::Date{}, CalendarTime::MAX_DATE + 1, flags, ObjectCallbackMasks{}, height, 1, gen_amount, {}} /* Climates * T = Temperate diff --git a/src/table/town_land.h b/src/table/town_land.h index 776fb23231..012ad0086a 100644 --- a/src/table/town_land.h +++ b/src/table/town_land.h @@ -1814,7 +1814,7 @@ static_assert(lengthof(_town_draw_tile_data) == (NEW_HOUSE_OFFSET) * 4 * 4); {ca1, ca2, ca3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \ {INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO}, \ bf, ba, true, GRFFileProps(INVALID_HOUSE_ID), HouseCallbackMasks{}, {COLOUR_BEGIN, COLOUR_BEGIN, COLOUR_BEGIN, COLOUR_BEGIN}, \ - 16, HouseExtraFlags{}, HOUSE_NO_CLASS, AnimationInfo{}, 0, 0, 0, {}, {cg1, cg2, cg3}, } + 16, HouseExtraFlags{}, HOUSE_NO_CLASS, AnimationInfo{}, 0, 0, 0, {}, {cg1, cg2, cg3}, } /** House specifications from original data */ extern const HouseSpec _original_house_specs[] = { /** diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index d3e780e657..f6372cbb22 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -3025,7 +3025,7 @@ static void TrainEnterStation(Train *v, StationID station) v->BeginLoading(); TriggerStationRandomisation(st, v->tile, StationRandomTrigger::VehicleArrives); - TriggerStationAnimation(st, v->tile, SAT_TRAIN_ARRIVES); + TriggerStationAnimation(st, v->tile, StationAnimationTrigger::VehicleArrives); } /* Check if the vehicle is compatible with the specified tile */ diff --git a/src/vehicle.cpp b/src/vehicle.cpp index f3a5e13253..b9b8a1821f 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -2395,7 +2395,7 @@ void Vehicle::LeaveStation() /* Trigger station animation (trains only) */ if (IsTileType(this->tile, MP_STATION)) { TriggerStationRandomisation(st, this->tile, StationRandomTrigger::VehicleDeparts); - TriggerStationAnimation(st, this->tile, SAT_TRAIN_DEPARTS); + TriggerStationAnimation(st, this->tile, StationAnimationTrigger::VehicleDeparts); } SetBit(Train::From(this)->flags, VRF_LEAVING_STATION); @@ -2404,7 +2404,7 @@ void Vehicle::LeaveStation() /* Trigger road stop animation */ if (IsStationRoadStopTile(this->tile)) { TriggerRoadStopRandomisation(st, this->tile, StationRandomTrigger::VehicleDeparts); - TriggerRoadStopAnimation(st, this->tile, SAT_TRAIN_DEPARTS); + TriggerRoadStopAnimation(st, this->tile, StationAnimationTrigger::VehicleDeparts); } } diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index acd461abba..8814cfc0a7 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -405,7 +405,7 @@ CommandCost CmdBuildRoadWaypoint(DoCommandFlags flags, TileIndex start_tile, Axi if (roadstopspec != nullptr) { /* Include this road stop spec's animation trigger bitmask * in the station's cached copy. */ - wp->cached_roadstop_anim_triggers |= roadstopspec->animation.triggers; + wp->cached_roadstop_anim_triggers.Set(roadstopspec->animation.triggers); } wp->delete_ctr = 0;