mirror of https://github.com/OpenTTD/OpenTTD
Codechange: Unify random trigger enums and turn them into enum classes. (#14066)
parent
f399b8eb29
commit
61a0a520f6
|
@ -74,7 +74,7 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
|
|||
TimerGameCalendar::Date build_date{}; ///< Date of construction
|
||||
|
||||
uint16_t random_bits = 0; ///< Random bits assigned to this station
|
||||
uint8_t waiting_random_triggers = 0; ///< Waiting triggers (NewGRF) for 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.
|
||||
CargoTypes cached_cargo_triggers{}; ///< NOSAVE: Combined cargo trigger bitmask
|
||||
|
|
|
@ -1167,7 +1167,7 @@ static void TriggerIndustryProduction(Industry *i)
|
|||
}
|
||||
}
|
||||
|
||||
TriggerIndustryRandomisation(i, INDUSTRY_TRIGGER_RECEIVED_CARGO);
|
||||
TriggerIndustryRandomisation(i, IndustryRandomTrigger::CargoReceived);
|
||||
TriggerIndustryAnimation(i, IAT_INDUSTRY_RECEIVED_CARGO);
|
||||
}
|
||||
|
||||
|
@ -1779,7 +1779,7 @@ static void LoadUnloadVehicle(Vehicle *front)
|
|||
/* If there's goods waiting at the station, and the vehicle
|
||||
* has capacity for it, load it on the vehicle. */
|
||||
if ((v->cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0 || (ge->HasData() && ge->GetData().cargo.AvailableCount() > 0)) && MayLoadUnderExclusiveRights(st, v)) {
|
||||
if (v->cargo.StoredCount() == 0) TriggerVehicleRandomisation(v, VEHICLE_TRIGGER_NEW_CARGO);
|
||||
if (v->cargo.StoredCount() == 0) TriggerVehicleRandomisation(v, VehicleRandomTrigger::NewCargo);
|
||||
if (_settings_game.order.gradual_loading) cap_left = std::min(cap_left, GetLoadAmount(v));
|
||||
|
||||
uint loaded = ge->GetOrCreateData().cargo.Load(cap_left, &v->cargo, next_station, v->GetCargoTile());
|
||||
|
@ -1811,10 +1811,10 @@ static void LoadUnloadVehicle(Vehicle *front)
|
|||
st->last_vehicle_type = v->type;
|
||||
|
||||
if (ge->GetData().cargo.TotalCount() == 0) {
|
||||
TriggerStationRandomisation(st, st->xy, SRT_CARGO_TAKEN, v->cargo_type);
|
||||
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);
|
||||
TriggerRoadStopRandomisation(st, st->xy, RSRT_CARGO_TAKEN, v->cargo_type);
|
||||
TriggerRoadStopRandomisation(st, st->xy, StationRandomTrigger::CargoTaken, v->cargo_type);
|
||||
TriggerRoadStopAnimation(st, st->xy, SAT_CARGO_TAKEN, v->cargo_type);
|
||||
}
|
||||
|
||||
|
@ -1834,10 +1834,10 @@ static void LoadUnloadVehicle(Vehicle *front)
|
|||
|
||||
if (anything_loaded || anything_unloaded) {
|
||||
if (front->type == VEH_TRAIN) {
|
||||
TriggerStationRandomisation(st, front->tile, SRT_TRAIN_LOADS);
|
||||
TriggerStationRandomisation(st, front->tile, StationRandomTrigger::VehicleLoads);
|
||||
TriggerStationAnimation(st, front->tile, SAT_TRAIN_LOADS);
|
||||
} else if (front->type == VEH_ROAD) {
|
||||
TriggerRoadStopRandomisation(st, front->tile, RSRT_VEH_LOADS);
|
||||
TriggerRoadStopRandomisation(st, front->tile, StationRandomTrigger::VehicleLoads);
|
||||
TriggerRoadStopAnimation(st, front->tile, SAT_TRAIN_LOADS);
|
||||
}
|
||||
}
|
||||
|
@ -1910,7 +1910,7 @@ static void LoadUnloadVehicle(Vehicle *front)
|
|||
/* Make sure the vehicle is marked dirty, since we need to update the NewGRF
|
||||
* properties such as weight, power and TE whenever the trigger runs. */
|
||||
dirty_vehicle = true;
|
||||
TriggerVehicleRandomisation(front, VEHICLE_TRIGGER_EMPTY);
|
||||
TriggerVehicleRandomisation(front, VehicleRandomTrigger::Empty);
|
||||
}
|
||||
|
||||
if (dirty_vehicle) {
|
||||
|
|
|
@ -15,4 +15,16 @@ typedef uint16_t HouseClassID; ///< Classes of houses.
|
|||
|
||||
struct HouseSpec;
|
||||
|
||||
/** Randomisation triggers for houses */
|
||||
enum class HouseRandomTrigger : uint8_t {
|
||||
/* The tile of the house has been triggered during the tileloop. */
|
||||
TileLoop,
|
||||
/*
|
||||
* The top tile of a (multitile) building has been triggered during and all
|
||||
* the tileloop other tiles of the same building get the same random value.
|
||||
*/
|
||||
TileLoopNorth,
|
||||
};
|
||||
using HouseRandomTriggers = EnumBitSet<HouseRandomTrigger, uint8_t>;
|
||||
|
||||
#endif /* HOUSE_TYPE_H */
|
||||
|
|
|
@ -844,7 +844,7 @@ static void TileLoop_Industry(TileIndex tile)
|
|||
* returning from TileLoop_Water. */
|
||||
if (!IsTileType(tile, MP_INDUSTRY)) return;
|
||||
|
||||
TriggerIndustryTileRandomisation(tile, INDTILE_TRIGGER_TILE_LOOP);
|
||||
TriggerIndustryTileRandomisation(tile, IndustryRandomTrigger::TileLoop);
|
||||
|
||||
if (!IsIndustryCompleted(tile)) {
|
||||
MakeIndustryTileBigger(tile);
|
||||
|
@ -1222,7 +1222,7 @@ static void ProduceIndustryGoods(Industry *i)
|
|||
if (cut) ChopLumberMillTrees(i);
|
||||
}
|
||||
|
||||
TriggerIndustryRandomisation(i, INDUSTRY_TRIGGER_INDUSTRY_TICK);
|
||||
TriggerIndustryRandomisation(i, IndustryRandomTrigger::IndustryTick);
|
||||
TriggerIndustryAnimation(i, IAT_INDUSTRY_TICK);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -247,10 +247,10 @@ inline void SetIndustryRandomBits(Tile tile, uint8_t bits)
|
|||
* @pre IsTileType(tile, MP_INDUSTRY)
|
||||
* @return requested triggers
|
||||
*/
|
||||
inline uint8_t GetIndustryRandomTriggers(Tile tile)
|
||||
inline IndustryRandomTriggers GetIndustryRandomTriggers(Tile tile)
|
||||
{
|
||||
assert(IsTileType(tile, MP_INDUSTRY));
|
||||
return GB(tile.m6(), 3, 3);
|
||||
return static_cast<IndustryRandomTriggers>(GB(tile.m6(), 3, 3));
|
||||
}
|
||||
|
||||
|
||||
|
@ -261,10 +261,10 @@ inline uint8_t GetIndustryRandomTriggers(Tile tile)
|
|||
* @param triggers the triggers to set
|
||||
* @pre IsTileType(tile, MP_INDUSTRY)
|
||||
*/
|
||||
inline void SetIndustryRandomTriggers(Tile tile, uint8_t triggers)
|
||||
inline void SetIndustryRandomTriggers(Tile tile, IndustryRandomTriggers triggers)
|
||||
{
|
||||
assert(IsTileType(tile, MP_INDUSTRY));
|
||||
SB(tile.m6(), 3, 3, triggers);
|
||||
SB(tile.m6(), 3, 3, triggers.base());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -283,7 +283,7 @@ inline void MakeIndustry(Tile t, IndustryID index, IndustryGfx gfx, uint8_t rand
|
|||
SetIndustryRandomBits(t, random); // m3
|
||||
t.m4() = 0;
|
||||
SetIndustryGfx(t, gfx); // m5, part of m6
|
||||
SetIndustryRandomTriggers(t, 0); // rest of m6
|
||||
SetIndustryRandomTriggers(t, {}); // rest of m6
|
||||
SetWaterClass(t, wc);
|
||||
t.m7() = 0;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,14 @@ struct Industry;
|
|||
struct IndustrySpec;
|
||||
struct IndustryTileSpec;
|
||||
|
||||
/** Available industry random triggers. */
|
||||
enum class IndustryRandomTrigger : uint8_t {
|
||||
TileLoop, ///< The tile of the industry has been triggered during the tileloop.
|
||||
IndustryTick, ///< The industry has been triggered via its tick.
|
||||
CargoReceived, ///< Cargo has been delivered.
|
||||
};
|
||||
using IndustryRandomTriggers = EnumBitSet<IndustryRandomTrigger, uint8_t>;
|
||||
|
||||
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
|
||||
|
|
|
@ -311,7 +311,7 @@ static uint8_t MapAircraftMovementAction(const Aircraft *v)
|
|||
|
||||
/* virtual */ uint32_t VehicleScopeResolver::GetRandomTriggers() const
|
||||
{
|
||||
return this->v == nullptr ? 0 : this->v->waiting_random_triggers;
|
||||
return this->v == nullptr ? 0 : this->v->waiting_random_triggers.base();
|
||||
}
|
||||
|
||||
|
||||
|
@ -626,7 +626,7 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec
|
|||
|
||||
if (parameter == 0x5F) {
|
||||
/* This seems to be the only variable that makes sense to access via var 61, but is not handled by VehicleGetVariable */
|
||||
return (u->random_bits << 8) | u->waiting_random_triggers;
|
||||
return (u->random_bits << 8) | u->waiting_random_triggers.base();
|
||||
} else {
|
||||
return VehicleGetVariable(u, object, parameter, GetRegister(0x10E), available);
|
||||
}
|
||||
|
@ -891,7 +891,7 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec
|
|||
case 0x78: break; // not implemented
|
||||
case 0x79: break; // not implemented
|
||||
case 0x7A: return v->random_bits;
|
||||
case 0x7B: return v->waiting_random_triggers;
|
||||
case 0x7B: return v->waiting_random_triggers.base();
|
||||
case 0x7C: break; // vehicle specific, see below
|
||||
case 0x7D: break; // vehicle specific, see below
|
||||
case 0x7E: break; // not implemented
|
||||
|
@ -1061,7 +1061,7 @@ static const GRFFile *GetEngineGrfFile(EngineID engine_type)
|
|||
*/
|
||||
VehicleResolverObject::VehicleResolverObject(EngineID engine_type, const Vehicle *v, WagonOverride wagon_override, bool rotor_in_gui,
|
||||
CallbackID callback, uint32_t callback_param1, uint32_t callback_param2)
|
||||
: ResolverObject(GetEngineGrfFile(engine_type), callback, callback_param1, callback_param2),
|
||||
: SpecializedResolverObject<VehicleRandomTriggers>(GetEngineGrfFile(engine_type), callback, callback_param1, callback_param2),
|
||||
self_scope(*this, engine_type, v, rotor_in_gui),
|
||||
parent_scope(*this, engine_type, ((v != nullptr) ? v->First() : v), rotor_in_gui),
|
||||
relative_scope(*this, engine_type, v, rotor_in_gui),
|
||||
|
@ -1247,20 +1247,20 @@ bool TestVehicleBuildProbability(Vehicle *v, EngineID engine, BuildProbabilityTy
|
|||
return p + RandomRange(PROBABILITY_RANGE) >= PROBABILITY_RANGE;
|
||||
}
|
||||
|
||||
static void DoTriggerVehicleRandomisation(Vehicle *v, VehicleTrigger trigger, uint16_t base_random_bits, bool first)
|
||||
static void DoTriggerVehicleRandomisation(Vehicle *v, VehicleRandomTrigger trigger, uint16_t base_random_bits, bool first)
|
||||
{
|
||||
/* We can't trigger a non-existent vehicle... */
|
||||
assert(v != nullptr);
|
||||
|
||||
VehicleResolverObject object(v->engine_type, v, VehicleResolverObject::WO_CACHED, false, CBID_RANDOM_TRIGGER);
|
||||
object.waiting_random_triggers = v->waiting_random_triggers | trigger;
|
||||
v->waiting_random_triggers = object.waiting_random_triggers; // store now for var 5F
|
||||
v->waiting_random_triggers.Set(trigger); // store now for var 5F
|
||||
object.SetWaitingRandomTriggers(v->waiting_random_triggers);
|
||||
|
||||
const SpriteGroup *group = object.Resolve();
|
||||
if (group == nullptr) return;
|
||||
|
||||
/* Store remaining triggers. */
|
||||
v->waiting_random_triggers = object.GetRemainingRandomTriggers();
|
||||
v->waiting_random_triggers.Reset(object.GetUsedRandomTriggers());
|
||||
|
||||
/* Rerandomise bits. Scopes other than SELF are invalid for rerandomisation. For bug-to-bug-compatibility with TTDP we ignore the scope. */
|
||||
uint16_t new_random_bits = Random();
|
||||
|
@ -1269,7 +1269,7 @@ static void DoTriggerVehicleRandomisation(Vehicle *v, VehicleTrigger trigger, ui
|
|||
v->random_bits |= (first ? new_random_bits : base_random_bits) & reseed;
|
||||
|
||||
switch (trigger) {
|
||||
case VEHICLE_TRIGGER_NEW_CARGO:
|
||||
case VehicleRandomTrigger::NewCargo:
|
||||
/* All vehicles in chain get ANY_NEW_CARGO trigger now.
|
||||
* So we call it for the first one and they will recurse.
|
||||
* Indexing part of vehicle random bits needs to be
|
||||
|
@ -1278,17 +1278,17 @@ static void DoTriggerVehicleRandomisation(Vehicle *v, VehicleTrigger trigger, ui
|
|||
* i.e.), so we give them all the NEW_CARGO triggered
|
||||
* vehicle's portion of random bits. */
|
||||
assert(first);
|
||||
DoTriggerVehicleRandomisation(v->First(), VEHICLE_TRIGGER_ANY_NEW_CARGO, new_random_bits, false);
|
||||
DoTriggerVehicleRandomisation(v->First(), VehicleRandomTrigger::AnyNewCargo, new_random_bits, false);
|
||||
break;
|
||||
|
||||
case VEHICLE_TRIGGER_DEPOT:
|
||||
case VehicleRandomTrigger::Depot:
|
||||
/* We now trigger the next vehicle in chain recursively.
|
||||
* The random bits portions may be different for each
|
||||
* vehicle in chain. */
|
||||
if (v->Next() != nullptr) DoTriggerVehicleRandomisation(v->Next(), trigger, 0, true);
|
||||
break;
|
||||
|
||||
case VEHICLE_TRIGGER_EMPTY:
|
||||
case VehicleRandomTrigger::Empty:
|
||||
/* We now trigger the next vehicle in chain
|
||||
* recursively. The random bits portions must be same
|
||||
* for each vehicle in chain, so we give them all
|
||||
|
@ -1296,20 +1296,20 @@ static void DoTriggerVehicleRandomisation(Vehicle *v, VehicleTrigger trigger, ui
|
|||
if (v->Next() != nullptr) DoTriggerVehicleRandomisation(v->Next(), trigger, first ? new_random_bits : base_random_bits, false);
|
||||
break;
|
||||
|
||||
case VEHICLE_TRIGGER_ANY_NEW_CARGO:
|
||||
case VehicleRandomTrigger::AnyNewCargo:
|
||||
/* Now pass the trigger recursively to the next vehicle
|
||||
* in chain. */
|
||||
assert(!first);
|
||||
if (v->Next() != nullptr) DoTriggerVehicleRandomisation(v->Next(), VEHICLE_TRIGGER_ANY_NEW_CARGO, base_random_bits, false);
|
||||
if (v->Next() != nullptr) DoTriggerVehicleRandomisation(v->Next(), trigger, base_random_bits, false);
|
||||
break;
|
||||
|
||||
case VEHICLE_TRIGGER_CALLBACK_32:
|
||||
case VehicleRandomTrigger::Callback32:
|
||||
/* Do not do any recursion */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void TriggerVehicleRandomisation(Vehicle *v, VehicleTrigger trigger)
|
||||
void TriggerVehicleRandomisation(Vehicle *v, VehicleRandomTrigger trigger)
|
||||
{
|
||||
v->InvalidateNewGRFCacheOfChain();
|
||||
DoTriggerVehicleRandomisation(v, trigger, 0, true);
|
||||
|
|
|
@ -44,7 +44,7 @@ struct VehicleScopeResolver : public ScopeResolver {
|
|||
};
|
||||
|
||||
/** Resolver for a vehicle (chain) */
|
||||
struct VehicleResolverObject : public ResolverObject {
|
||||
struct VehicleResolverObject : public SpecializedResolverObject<VehicleRandomTriggers> {
|
||||
/** Application of 'wagon overrides'. */
|
||||
enum WagonOverride : uint8_t {
|
||||
WO_NONE, //!< Resolve no wagon overrides.
|
||||
|
@ -107,18 +107,7 @@ enum class BuildProbabilityType : uint8_t {
|
|||
|
||||
bool TestVehicleBuildProbability(Vehicle *v, EngineID engine, BuildProbabilityType type);
|
||||
|
||||
enum VehicleTrigger : uint8_t {
|
||||
VEHICLE_TRIGGER_NEW_CARGO = 0x01,
|
||||
/* Externally triggered only for the first vehicle in chain */
|
||||
VEHICLE_TRIGGER_DEPOT = 0x02,
|
||||
/* Externally triggered only for the first vehicle in chain, only if whole chain is empty */
|
||||
VEHICLE_TRIGGER_EMPTY = 0x04,
|
||||
/* Not triggered externally (called for the whole chain if we got NEW_CARGO) */
|
||||
VEHICLE_TRIGGER_ANY_NEW_CARGO = 0x08,
|
||||
/* Externally triggered for each vehicle in chain */
|
||||
VEHICLE_TRIGGER_CALLBACK_32 = 0x10,
|
||||
};
|
||||
void TriggerVehicleRandomisation(Vehicle *veh, VehicleTrigger trigger);
|
||||
void TriggerVehicleRandomisation(Vehicle *veh, VehicleRandomTrigger trigger);
|
||||
|
||||
void AlterVehicleListOrder(EngineID engine, uint16_t target);
|
||||
void CommitVehicleListOrderChanges();
|
||||
|
|
|
@ -107,7 +107,7 @@ void ResetHouses()
|
|||
HouseResolverObject::HouseResolverObject(HouseID house_id, TileIndex tile, Town *town,
|
||||
CallbackID callback, uint32_t param1, uint32_t param2,
|
||||
bool not_yet_constructed, uint8_t initial_random_bits, CargoTypes watched_cargo_triggers, int view)
|
||||
: ResolverObject(GetHouseSpecGrf(house_id), callback, param1, param2),
|
||||
: SpecializedResolverObject<HouseRandomTriggers>(GetHouseSpecGrf(house_id), callback, param1, param2),
|
||||
house_scope(*this, house_id, tile, town, not_yet_constructed, initial_random_bits, watched_cargo_triggers, view),
|
||||
town_scope(*this, town, not_yet_constructed) // Don't access StorePSA if house is not yet constructed.
|
||||
{
|
||||
|
@ -229,7 +229,7 @@ void DecreaseBuildingCount(Town *t, HouseID house_id)
|
|||
/* virtual */ uint32_t HouseScopeResolver::GetRandomTriggers() const
|
||||
{
|
||||
/* Note: Towns build houses over houses. So during construction checks 'tile' may be a valid but unrelated house. */
|
||||
return this->not_yet_constructed ? 0 : GetHouseRandomTriggers(this->tile);
|
||||
return this->not_yet_constructed ? 0 : GetHouseRandomTriggers(this->tile).base();
|
||||
}
|
||||
|
||||
static uint32_t GetNumHouses(HouseID house_id, const Town *town)
|
||||
|
@ -591,8 +591,8 @@ bool NewHouseTileLoop(TileIndex tile)
|
|||
return true;
|
||||
}
|
||||
|
||||
TriggerHouseRandomisation(tile, HOUSE_TRIGGER_TILE_LOOP);
|
||||
if (hs->building_flags.Any(BUILDING_HAS_1_TILE)) TriggerHouseRandomisation(tile, HOUSE_TRIGGER_TILE_LOOP_TOP);
|
||||
TriggerHouseRandomisation(tile, HouseRandomTrigger::TileLoop);
|
||||
if (hs->building_flags.Any(BUILDING_HAS_1_TILE)) TriggerHouseRandomisation(tile, HouseRandomTrigger::TileLoopNorth);
|
||||
|
||||
/* Call the unsynchronized tile loop trigger */
|
||||
TriggerHouseAnimation_TileLoop(tile, false, 0);
|
||||
|
@ -620,7 +620,7 @@ bool NewHouseTileLoop(TileIndex tile)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void DoTriggerHouseRandomisation(TileIndex tile, HouseTrigger trigger, uint8_t base_random, bool first)
|
||||
static void DoTriggerHouseRandomisation(TileIndex tile, HouseRandomTrigger trigger, uint8_t base_random, bool first)
|
||||
{
|
||||
/* We can't trigger a non-existent building... */
|
||||
assert(IsTileType(tile, MP_HOUSE));
|
||||
|
@ -631,14 +631,17 @@ static void DoTriggerHouseRandomisation(TileIndex tile, HouseTrigger trigger, ui
|
|||
if (hs->grf_prop.GetSpriteGroup() == nullptr) return;
|
||||
|
||||
HouseResolverObject object(hid, tile, Town::GetByTile(tile), CBID_RANDOM_TRIGGER);
|
||||
object.waiting_random_triggers = GetHouseRandomTriggers(tile) | trigger;
|
||||
SetHouseRandomTriggers(tile, object.waiting_random_triggers); // store now for var 5F
|
||||
auto waiting_random_triggers = GetHouseRandomTriggers(tile);
|
||||
waiting_random_triggers.Set(trigger);
|
||||
SetHouseRandomTriggers(tile, waiting_random_triggers); // store now for var 5F
|
||||
object.SetWaitingRandomTriggers(waiting_random_triggers);
|
||||
|
||||
const SpriteGroup *group = object.Resolve();
|
||||
if (group == nullptr) return;
|
||||
|
||||
/* Store remaining triggers. */
|
||||
SetHouseRandomTriggers(tile, object.GetRemainingRandomTriggers());
|
||||
waiting_random_triggers.Reset(object.GetUsedRandomTriggers());
|
||||
SetHouseRandomTriggers(tile, waiting_random_triggers);
|
||||
|
||||
/* Rerandomise bits. Scopes other than SELF are invalid for houses. For bug-to-bug-compatibility with TTDP we ignore the scope. */
|
||||
uint8_t new_random_bits = Random();
|
||||
|
@ -649,11 +652,11 @@ static void DoTriggerHouseRandomisation(TileIndex tile, HouseTrigger trigger, ui
|
|||
SetHouseRandomBits(tile, random_bits);
|
||||
|
||||
switch (trigger) {
|
||||
case HOUSE_TRIGGER_TILE_LOOP:
|
||||
case HouseRandomTrigger::TileLoop:
|
||||
/* Random value already set. */
|
||||
break;
|
||||
|
||||
case HOUSE_TRIGGER_TILE_LOOP_TOP:
|
||||
case HouseRandomTrigger::TileLoopNorth:
|
||||
if (!first) {
|
||||
/* The top tile is marked dirty by the usual TileLoop */
|
||||
MarkTileDirtyByTile(tile);
|
||||
|
@ -667,7 +670,7 @@ static void DoTriggerHouseRandomisation(TileIndex tile, HouseTrigger trigger, ui
|
|||
}
|
||||
}
|
||||
|
||||
void TriggerHouseRandomisation(TileIndex t, HouseTrigger trigger)
|
||||
void TriggerHouseRandomisation(TileIndex t, HouseRandomTrigger trigger)
|
||||
{
|
||||
DoTriggerHouseRandomisation(t, trigger, 0, true);
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ struct HouseScopeResolver : public ScopeResolver {
|
|||
};
|
||||
|
||||
/** Resolver object to be used for houses (feature 07 spritegroups). */
|
||||
struct HouseResolverObject : public ResolverObject {
|
||||
struct HouseResolverObject : public SpecializedResolverObject<HouseRandomTriggers> {
|
||||
HouseScopeResolver house_scope;
|
||||
TownScopeResolver town_scope;
|
||||
|
||||
|
@ -110,15 +110,6 @@ bool CanDeleteHouse(TileIndex tile);
|
|||
|
||||
bool NewHouseTileLoop(TileIndex tile);
|
||||
|
||||
enum HouseTrigger : uint8_t {
|
||||
/* The tile of the house has been triggered during the tileloop. */
|
||||
HOUSE_TRIGGER_TILE_LOOP = 0x01,
|
||||
/*
|
||||
* The top tile of a (multitile) building has been triggered during and all
|
||||
* the tileloop other tiles of the same building get the same random value.
|
||||
*/
|
||||
HOUSE_TRIGGER_TILE_LOOP_TOP = 0x02,
|
||||
};
|
||||
void TriggerHouseRandomisation(TileIndex t, HouseTrigger trigger);
|
||||
void TriggerHouseRandomisation(TileIndex t, HouseRandomTrigger trigger);
|
||||
|
||||
#endif /* NEWGRF_HOUSE_H */
|
||||
|
|
|
@ -115,7 +115,7 @@ uint32_t GetRelativePosition(TileIndex tile, TileIndex ind_tile)
|
|||
assert(this->industry != nullptr && IsValidTile(this->tile));
|
||||
assert(this->industry->index == IndustryID::Invalid() || IsTileType(this->tile, MP_INDUSTRY));
|
||||
if (this->industry->index == IndustryID::Invalid()) return 0;
|
||||
return GetIndustryRandomTriggers(this->tile);
|
||||
return GetIndustryRandomTriggers(this->tile).base();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -140,7 +140,7 @@ static const GRFFile *GetIndTileGrffile(IndustryGfx gfx)
|
|||
*/
|
||||
IndustryTileResolverObject::IndustryTileResolverObject(IndustryGfx gfx, TileIndex tile, Industry *indus,
|
||||
CallbackID callback, uint32_t callback_param1, uint32_t callback_param2)
|
||||
: ResolverObject(GetIndTileGrffile(gfx), callback, callback_param1, callback_param2),
|
||||
: SpecializedResolverObject<IndustryRandomTriggers>(GetIndTileGrffile(gfx), callback, callback_param1, callback_param2),
|
||||
indtile_scope(*this, indus, tile),
|
||||
ind_scope(*this, tile, indus, indus->type),
|
||||
gfx(gfx)
|
||||
|
@ -310,7 +310,7 @@ bool TriggerIndustryAnimation(const Industry *ind, IndustryAnimationTrigger iat)
|
|||
* @param ind Industry of the tile.
|
||||
* @param[in,out] reseed_industry Collects bits to reseed for the industry.
|
||||
*/
|
||||
static void DoTriggerIndustryTileRandomisation(TileIndex tile, IndustryTileTrigger trigger, Industry *ind, uint32_t &reseed_industry)
|
||||
static void DoTriggerIndustryTileRandomisation(TileIndex tile, IndustryRandomTrigger trigger, Industry *ind, uint32_t &reseed_industry)
|
||||
{
|
||||
assert(IsValidTile(tile) && IsTileType(tile, MP_INDUSTRY));
|
||||
|
||||
|
@ -320,14 +320,17 @@ static void DoTriggerIndustryTileRandomisation(TileIndex tile, IndustryTileTrigg
|
|||
if (itspec->grf_prop.GetSpriteGroup() == nullptr) return;
|
||||
|
||||
IndustryTileResolverObject object(gfx, tile, ind, CBID_RANDOM_TRIGGER);
|
||||
object.waiting_random_triggers = GetIndustryRandomTriggers(tile) | trigger;
|
||||
SetIndustryRandomTriggers(tile, object.waiting_random_triggers); // store now for var 5F
|
||||
auto waiting_random_triggers = GetIndustryRandomTriggers(tile);
|
||||
waiting_random_triggers.Set(trigger);
|
||||
SetIndustryRandomTriggers(tile, waiting_random_triggers); // store now for var 5F
|
||||
object.SetWaitingRandomTriggers(waiting_random_triggers);
|
||||
|
||||
const SpriteGroup *group = object.Resolve();
|
||||
if (group == nullptr) return;
|
||||
|
||||
/* Store remaining triggers. */
|
||||
SetIndustryRandomTriggers(tile, object.GetRemainingRandomTriggers());
|
||||
waiting_random_triggers.Reset(object.GetUsedRandomTriggers());
|
||||
SetIndustryRandomTriggers(tile, waiting_random_triggers);
|
||||
|
||||
/* Rerandomise tile bits */
|
||||
uint8_t new_random_bits = Random();
|
||||
|
@ -359,7 +362,7 @@ static void DoReseedIndustry(Industry *ind, uint32_t reseed)
|
|||
* @param tile Industry tile to trigger.
|
||||
* @param trigger Trigger to trigger.
|
||||
*/
|
||||
void TriggerIndustryTileRandomisation(TileIndex tile, IndustryTileTrigger trigger)
|
||||
void TriggerIndustryTileRandomisation(TileIndex tile, IndustryRandomTrigger trigger)
|
||||
{
|
||||
uint32_t reseed_industry = 0;
|
||||
Industry *ind = Industry::GetByTile(tile);
|
||||
|
@ -372,7 +375,7 @@ void TriggerIndustryTileRandomisation(TileIndex tile, IndustryTileTrigger trigge
|
|||
* @param ind Industry to trigger.
|
||||
* @param trigger Trigger to trigger.
|
||||
*/
|
||||
void TriggerIndustryRandomisation(Industry *ind, IndustryTileTrigger trigger)
|
||||
void TriggerIndustryRandomisation(Industry *ind, IndustryRandomTrigger trigger)
|
||||
{
|
||||
uint32_t reseed_industry = 0;
|
||||
for (TileIndex tile : ind->location) {
|
||||
|
|
|
@ -36,7 +36,7 @@ struct IndustryTileScopeResolver : public ScopeResolver {
|
|||
};
|
||||
|
||||
/** Resolver for industry tiles. */
|
||||
struct IndustryTileResolverObject : public ResolverObject {
|
||||
struct IndustryTileResolverObject : public SpecializedResolverObject<IndustryRandomTriggers> {
|
||||
IndustryTileScopeResolver indtile_scope; ///< Scope resolver for the industry tile.
|
||||
IndustriesScopeResolver ind_scope; ///< Scope resolver for the industry owning the tile.
|
||||
IndustryGfx gfx;
|
||||
|
@ -65,14 +65,7 @@ void AnimateNewIndustryTile(TileIndex tile);
|
|||
bool TriggerIndustryTileAnimation(TileIndex tile, IndustryAnimationTrigger iat, uint32_t random = Random());
|
||||
bool TriggerIndustryAnimation(const Industry *ind, IndustryAnimationTrigger iat);
|
||||
|
||||
|
||||
/** Available industry tile triggers. */
|
||||
enum IndustryTileTrigger : uint8_t {
|
||||
INDTILE_TRIGGER_TILE_LOOP = 0x01, ///< The tile of the industry has been triggered during the tileloop.
|
||||
INDUSTRY_TRIGGER_INDUSTRY_TICK = 0x02, ///< The industry has been triggered via its tick.
|
||||
INDUSTRY_TRIGGER_RECEIVED_CARGO = 0x04, ///< Cargo has been delivered.
|
||||
};
|
||||
void TriggerIndustryTileRandomisation(TileIndex t, IndustryTileTrigger trigger);
|
||||
void TriggerIndustryRandomisation(Industry *ind, IndustryTileTrigger trigger);
|
||||
void TriggerIndustryTileRandomisation(TileIndex t, IndustryRandomTrigger trigger);
|
||||
void TriggerIndustryRandomisation(Industry *ind, IndustryRandomTrigger trigger);
|
||||
|
||||
#endif /* NEWGRF_INDUSTRYTILES_H */
|
||||
|
|
|
@ -65,7 +65,7 @@ uint32_t RoadStopScopeResolver::GetRandomBits() const
|
|||
|
||||
uint32_t RoadStopScopeResolver::GetRandomTriggers() const
|
||||
{
|
||||
return this->st == nullptr ? 0 : this->st->waiting_random_triggers;
|
||||
return this->st == nullptr ? 0 : this->st->waiting_random_triggers.base();
|
||||
}
|
||||
|
||||
uint32_t RoadStopScopeResolver::GetVariable(uint8_t variable, [[maybe_unused]] uint32_t parameter, bool &available) const
|
||||
|
@ -226,7 +226,7 @@ const SpriteGroup *RoadStopResolverObject::ResolveReal(const RealSpriteGroup *gr
|
|||
|
||||
RoadStopResolverObject::RoadStopResolverObject(const RoadStopSpec *roadstopspec, BaseStation *st, TileIndex tile, RoadType roadtype, StationType type, uint8_t view,
|
||||
CallbackID callback, uint32_t param1, uint32_t param2)
|
||||
: ResolverObject(roadstopspec->grf_prop.grffile, callback, param1, param2), roadstop_scope(*this, st, roadstopspec, tile, roadtype, type, view)
|
||||
: SpecializedResolverObject<StationRandomTriggers>(roadstopspec->grf_prop.grffile, callback, param1, param2), roadstop_scope(*this, st, roadstopspec, tile, roadtype, type, view)
|
||||
{
|
||||
CargoType ctype = SpriteGroupCargo::SG_DEFAULT_NA;
|
||||
|
||||
|
@ -417,7 +417,7 @@ void TriggerRoadStopAnimation(BaseStation *st, TileIndex trigger_tile, StationAn
|
|||
* @param trigger trigger type
|
||||
* @param cargo_type cargo type causing the trigger
|
||||
*/
|
||||
void TriggerRoadStopRandomisation(Station *st, TileIndex tile, RoadStopRandomTrigger trigger, CargoType cargo_type)
|
||||
void TriggerRoadStopRandomisation(Station *st, TileIndex tile, StationRandomTrigger trigger, CargoType cargo_type)
|
||||
{
|
||||
if (st == nullptr) st = Station::GetByTile(tile);
|
||||
|
||||
|
@ -426,32 +426,32 @@ void TriggerRoadStopRandomisation(Station *st, TileIndex tile, RoadStopRandomTri
|
|||
if (st->cached_roadstop_cargo_triggers == 0) return;
|
||||
if (IsValidCargoType(cargo_type) && !HasBit(st->cached_roadstop_cargo_triggers, cargo_type)) return;
|
||||
|
||||
SetBit(st->waiting_random_triggers, trigger);
|
||||
st->waiting_random_triggers.Set(trigger);
|
||||
|
||||
uint32_t whole_reseed = 0;
|
||||
|
||||
/* Bitmask of completely empty cargo types to be matched. */
|
||||
CargoTypes empty_mask = (trigger == RSRT_CARGO_TAKEN) ? GetEmptyMask(st) : 0;
|
||||
CargoTypes empty_mask = (trigger == StationRandomTrigger::CargoTaken) ? GetEmptyMask(st) : 0;
|
||||
|
||||
uint32_t used_random_triggers = 0;
|
||||
StationRandomTriggers used_random_triggers;
|
||||
auto process_tile = [&](TileIndex cur_tile) {
|
||||
const RoadStopSpec *ss = GetRoadStopSpec(cur_tile);
|
||||
if (ss == nullptr) return;
|
||||
|
||||
/* Cargo taken "will only be triggered if all of those
|
||||
* cargo types have no more cargo waiting." */
|
||||
if (trigger == RSRT_CARGO_TAKEN) {
|
||||
if (trigger == StationRandomTrigger::CargoTaken) {
|
||||
if ((ss->cargo_triggers & ~empty_mask) != 0) return;
|
||||
}
|
||||
|
||||
if (!IsValidCargoType(cargo_type) || HasBit(ss->cargo_triggers, cargo_type)) {
|
||||
RoadStopResolverObject object(ss, st, cur_tile, INVALID_ROADTYPE, GetStationType(cur_tile), GetStationGfx(cur_tile));
|
||||
object.waiting_random_triggers = st->waiting_random_triggers;
|
||||
object.SetWaitingRandomTriggers(st->waiting_random_triggers);
|
||||
|
||||
const SpriteGroup *group = object.Resolve();
|
||||
if (group == nullptr) return;
|
||||
|
||||
used_random_triggers |= object.used_random_triggers;
|
||||
used_random_triggers.Set(object.GetUsedRandomTriggers());
|
||||
|
||||
uint32_t reseed = object.GetReseedSum();
|
||||
if (reseed != 0) {
|
||||
|
@ -468,7 +468,7 @@ void TriggerRoadStopRandomisation(Station *st, TileIndex tile, RoadStopRandomTri
|
|||
}
|
||||
}
|
||||
};
|
||||
if (trigger == RSRT_NEW_CARGO || trigger == RSRT_CARGO_TAKEN) {
|
||||
if (trigger == StationRandomTrigger::NewCargo || trigger == StationRandomTrigger::CargoTaken) {
|
||||
for (const RoadStopTileData &tile_data : st->custom_roadstop_tile_data) {
|
||||
process_tile(tile_data.tile);
|
||||
}
|
||||
|
@ -477,7 +477,7 @@ void TriggerRoadStopRandomisation(Station *st, TileIndex tile, RoadStopRandomTri
|
|||
}
|
||||
|
||||
/* Update whole station random bits */
|
||||
st->waiting_random_triggers &= ~used_random_triggers;
|
||||
st->waiting_random_triggers.Reset(used_random_triggers);
|
||||
if ((whole_reseed & 0xFFFF) != 0) {
|
||||
st->random_bits &= ~whole_reseed;
|
||||
st->random_bits |= Random() & whole_reseed;
|
||||
|
|
|
@ -35,15 +35,6 @@ enum RoadStopClassID : uint16_t {
|
|||
};
|
||||
DECLARE_INCREMENT_DECREMENT_OPERATORS(RoadStopClassID)
|
||||
|
||||
/* Some Triggers etc. */
|
||||
enum RoadStopRandomTrigger : uint8_t {
|
||||
RSRT_NEW_CARGO, ///< Trigger roadstop on arrival of new cargo.
|
||||
RSRT_CARGO_TAKEN, ///< Trigger roadstop when cargo is completely taken.
|
||||
RSRT_VEH_ARRIVES, ///< Trigger roadstop when road vehicle arrives.
|
||||
RSRT_VEH_DEPARTS, ///< Trigger roadstop when road vehicle leaves.
|
||||
RSRT_VEH_LOADS, ///< Trigger roadstop when road vehicle loads.
|
||||
};
|
||||
|
||||
/**
|
||||
* Various different options for availability, restricting
|
||||
* the roadstop to be only for busses or for trucks.
|
||||
|
@ -109,7 +100,7 @@ struct RoadStopScopeResolver : public ScopeResolver {
|
|||
};
|
||||
|
||||
/** Road stop resolver. */
|
||||
struct RoadStopResolverObject : public ResolverObject {
|
||||
struct RoadStopResolverObject : public SpecializedResolverObject<StationRandomTriggers> {
|
||||
RoadStopScopeResolver roadstop_scope; ///< The stop scope resolver.
|
||||
std::optional<TownScopeResolver> town_scope = std::nullopt; ///< The town scope resolver (created on the first call).
|
||||
|
||||
|
@ -185,7 +176,7 @@ uint16_t GetRoadStopCallback(CallbackID callback, uint32_t param1, uint32_t para
|
|||
void AnimateRoadStopTile(TileIndex tile);
|
||||
uint8_t GetRoadStopTileAnimationSpeed(TileIndex tile);
|
||||
void TriggerRoadStopAnimation(BaseStation *st, TileIndex tile, StationAnimationTrigger trigger, CargoType cargo_type = INVALID_CARGO);
|
||||
void TriggerRoadStopRandomisation(Station *st, TileIndex tile, RoadStopRandomTrigger trigger, CargoType cargo_type = INVALID_CARGO);
|
||||
void TriggerRoadStopRandomisation(Station *st, TileIndex tile, StationRandomTrigger trigger, CargoType cargo_type = INVALID_CARGO);
|
||||
|
||||
bool GetIfNewStopsByType(RoadStopType rs, RoadType roadtype);
|
||||
bool GetIfClassHasNewStopsByType(const RoadStopClass *roadstopclass, RoadStopType rs, RoadType roadtype);
|
||||
|
|
|
@ -258,11 +258,11 @@ const SpriteGroup *RandomizedSpriteGroup::Resolve(ResolverObject &object) const
|
|||
ScopeResolver *scope = object.GetScope(this->var_scope, this->count);
|
||||
if (object.callback == CBID_RANDOM_TRIGGER) {
|
||||
/* Handle triggers */
|
||||
uint8_t match = this->triggers & object.waiting_random_triggers;
|
||||
uint8_t match = this->triggers & object.GetWaitingRandomTriggers();
|
||||
bool res = (this->cmp_mode == RSG_CMP_ANY) ? (match != 0) : (match == this->triggers);
|
||||
|
||||
if (res) {
|
||||
object.used_random_triggers |= match;
|
||||
object.AddUsedRandomTriggers(match);
|
||||
object.reseed[this->var_scope] |= (this->groups.size() - 1) << this->lowest_randbit;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -318,8 +318,10 @@ struct ResolverObject {
|
|||
|
||||
uint32_t last_value = 0; ///< Result of most recent DeterministicSpriteGroup (including procedure calls)
|
||||
|
||||
protected:
|
||||
uint32_t waiting_random_triggers = 0; ///< Waiting triggers to be used by any rerandomisation. (scope independent)
|
||||
uint32_t used_random_triggers = 0; ///< Subset of cur_triggers, which actually triggered some rerandomisation. (scope independent)
|
||||
public:
|
||||
std::array<uint32_t, VSG_END> reseed; ///< Collects bits to rerandomise while triggering triggers.
|
||||
|
||||
const GRFFile *grffile = nullptr; ///< GRFFile the resolved SpriteGroup belongs to
|
||||
|
@ -349,11 +351,19 @@ struct ResolverObject {
|
|||
virtual ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, uint8_t relative = 0);
|
||||
|
||||
/**
|
||||
* Returns the waiting triggers that did not trigger any rerandomisation.
|
||||
* Used by RandomizedSpriteGroup: Triggers for rerandomisation
|
||||
*/
|
||||
uint32_t GetRemainingRandomTriggers() const
|
||||
uint32_t GetWaitingRandomTriggers() const
|
||||
{
|
||||
return this->waiting_random_triggers & ~this->used_random_triggers;
|
||||
return this->waiting_random_triggers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by RandomizedSpriteGroup: Consume triggers.
|
||||
*/
|
||||
void AddUsedRandomTriggers(uint32_t triggers)
|
||||
{
|
||||
this->used_random_triggers |= triggers;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -395,4 +405,30 @@ struct ResolverObject {
|
|||
virtual uint32_t GetDebugID() const { return 0; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Specialization of ResolverObject with type-safe access to RandomTriggers.
|
||||
*/
|
||||
template <class RandomTriggers>
|
||||
struct SpecializedResolverObject : public ResolverObject {
|
||||
using ResolverObject::ResolverObject;
|
||||
|
||||
/**
|
||||
* Set waiting triggers for rerandomisation.
|
||||
* This is scope independent, even though this is broken-by-design in most cases.
|
||||
*/
|
||||
void SetWaitingRandomTriggers(RandomTriggers triggers)
|
||||
{
|
||||
this->waiting_random_triggers = triggers.base();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the triggers, which were "consumed" by some rerandomisation.
|
||||
* This is scope independent, even though this is broken-by-design in most cases.
|
||||
*/
|
||||
RandomTriggers GetUsedRandomTriggers() const
|
||||
{
|
||||
return static_cast<RandomTriggers>(this->used_random_triggers);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* NEWGRF_SPRITEGROUP_H */
|
||||
|
|
|
@ -246,7 +246,7 @@ static uint32_t GetRailContinuationInfo(TileIndex tile)
|
|||
|
||||
/* virtual */ uint32_t StationScopeResolver::GetRandomTriggers() const
|
||||
{
|
||||
return this->st == nullptr ? 0 : this->st->waiting_random_triggers;
|
||||
return this->st == nullptr ? 0 : this->st->waiting_random_triggers.base();
|
||||
}
|
||||
|
||||
|
||||
|
@ -588,7 +588,7 @@ uint32_t StationResolverObject::GetDebugID() const
|
|||
*/
|
||||
StationResolverObject::StationResolverObject(const StationSpec *statspec, BaseStation *base_station, TileIndex tile,
|
||||
CallbackID callback, uint32_t callback_param1, uint32_t callback_param2)
|
||||
: ResolverObject(statspec->grf_prop.grffile, callback, callback_param1, callback_param2),
|
||||
: SpecializedResolverObject<StationRandomTriggers>(statspec->grf_prop.grffile, callback, callback_param1, callback_param2),
|
||||
station_scope(*this, statspec, base_station, tile)
|
||||
{
|
||||
/* Invalidate all cached vars */
|
||||
|
@ -959,14 +959,14 @@ void TriggerStationRandomisation(Station *st, TileIndex trigger_tile, StationRan
|
|||
if (IsValidCargoType(cargo_type) && !HasBit(st->cached_cargo_triggers, cargo_type)) return;
|
||||
|
||||
uint32_t whole_reseed = 0;
|
||||
ETileArea area = ETileArea(st, trigger_tile, tas[trigger]);
|
||||
ETileArea area = ETileArea(st, trigger_tile, tas[static_cast<size_t>(trigger)]);
|
||||
|
||||
/* Bitmask of completely empty cargo types to be matched. */
|
||||
CargoTypes empty_mask = (trigger == SRT_CARGO_TAKEN) ? GetEmptyMask(st) : 0;
|
||||
CargoTypes empty_mask = (trigger == StationRandomTrigger::CargoTaken) ? GetEmptyMask(st) : 0;
|
||||
|
||||
/* Store triggers now for var 5F */
|
||||
SetBit(st->waiting_random_triggers, trigger);
|
||||
uint32_t used_random_triggers = 0;
|
||||
st->waiting_random_triggers.Set(trigger);
|
||||
StationRandomTriggers used_random_triggers;
|
||||
|
||||
/* Check all tiles over the station to check if the specindex is still in use */
|
||||
for (TileIndex tile : area) {
|
||||
|
@ -976,18 +976,18 @@ void TriggerStationRandomisation(Station *st, TileIndex trigger_tile, StationRan
|
|||
|
||||
/* Cargo taken "will only be triggered if all of those
|
||||
* cargo types have no more cargo waiting." */
|
||||
if (trigger == SRT_CARGO_TAKEN) {
|
||||
if (trigger == StationRandomTrigger::CargoTaken) {
|
||||
if ((ss->cargo_triggers & ~empty_mask) != 0) continue;
|
||||
}
|
||||
|
||||
if (!IsValidCargoType(cargo_type) || HasBit(ss->cargo_triggers, cargo_type)) {
|
||||
StationResolverObject object(ss, st, tile, CBID_RANDOM_TRIGGER, 0);
|
||||
object.waiting_random_triggers = st->waiting_random_triggers;
|
||||
object.SetWaitingRandomTriggers(st->waiting_random_triggers);
|
||||
|
||||
const SpriteGroup *group = object.Resolve();
|
||||
if (group == nullptr) continue;
|
||||
|
||||
used_random_triggers |= object.used_random_triggers;
|
||||
used_random_triggers.Set(object.GetUsedRandomTriggers());
|
||||
|
||||
uint32_t reseed = object.GetReseedSum();
|
||||
if (reseed != 0) {
|
||||
|
@ -1007,7 +1007,7 @@ void TriggerStationRandomisation(Station *st, TileIndex trigger_tile, StationRan
|
|||
}
|
||||
|
||||
/* Update whole station random bits */
|
||||
st->waiting_random_triggers &= ~used_random_triggers;
|
||||
st->waiting_random_triggers.Reset(used_random_triggers);
|
||||
if ((whole_reseed & 0xFFFF) != 0) {
|
||||
st->random_bits &= ~whole_reseed;
|
||||
st->random_bits |= Random() & whole_reseed;
|
||||
|
|
|
@ -49,7 +49,7 @@ struct StationScopeResolver : public ScopeResolver {
|
|||
};
|
||||
|
||||
/** Station resolver. */
|
||||
struct StationResolverObject : public ResolverObject {
|
||||
struct StationResolverObject : public SpecializedResolverObject<StationRandomTriggers> {
|
||||
StationScopeResolver station_scope; ///< The station scope resolver.
|
||||
std::optional<TownScopeResolver> town_scope = std::nullopt; ///< The town scope resolver (created on the first call).
|
||||
|
||||
|
@ -103,16 +103,6 @@ enum class StationSpecFlag : uint8_t {
|
|||
};
|
||||
using StationSpecFlags = EnumBitSet<StationSpecFlag, uint8_t>;
|
||||
|
||||
/** Randomisation triggers for stations */
|
||||
enum StationRandomTrigger : uint8_t {
|
||||
SRT_NEW_CARGO, ///< Trigger station on new cargo arrival.
|
||||
SRT_CARGO_TAKEN, ///< Trigger station when cargo is completely taken.
|
||||
SRT_TRAIN_ARRIVES, ///< Trigger platform when train arrives.
|
||||
SRT_TRAIN_DEPARTS, ///< Trigger platform when train leaves.
|
||||
SRT_TRAIN_LOADS, ///< Trigger platform when train loads/unloads.
|
||||
SRT_PATH_RESERVATION, ///< Trigger platform when train reserves path.
|
||||
};
|
||||
|
||||
/** Station specification. */
|
||||
struct StationSpec : NewGRFSpecBase<StationClassID> {
|
||||
StationSpec() : name(0),
|
||||
|
|
|
@ -80,7 +80,7 @@ private:
|
|||
tile = TileAdd(tile, diff);
|
||||
} while (IsCompatibleTrainStationTile(tile, start) && tile != this->origin_tile);
|
||||
|
||||
TriggerStationRandomisation(nullptr, start, SRT_PATH_RESERVATION);
|
||||
TriggerStationRandomisation(nullptr, start, StationRandomTrigger::PathReservation);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ bool TryReserveRailTrack(TileIndex tile, Track t, bool trigger_stations)
|
|||
case MP_STATION:
|
||||
if (HasStationRail(tile) && !HasStationReservation(tile)) {
|
||||
SetRailStationReservation(tile, true);
|
||||
if (trigger_stations && IsRailStation(tile)) TriggerStationRandomisation(nullptr, tile, SRT_PATH_RESERVATION);
|
||||
if (trigger_stations && IsRailStation(tile)) TriggerStationRandomisation(nullptr, tile, StationRandomTrigger::PathReservation);
|
||||
MarkTileDirtyByTile(tile); // some GRFs need redraw after reserving track
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1455,7 +1455,7 @@ again:
|
|||
v->last_station_visited = st->index;
|
||||
RoadVehArrivesAt(v, st);
|
||||
v->BeginLoading();
|
||||
TriggerRoadStopRandomisation(st, v->tile, RSRT_VEH_ARRIVES);
|
||||
TriggerRoadStopRandomisation(st, v->tile, StationRandomTrigger::VehicleArrives);
|
||||
TriggerRoadStopAnimation(st, v->tile, SAT_TRAIN_ARRIVES);
|
||||
}
|
||||
return false;
|
||||
|
@ -1519,7 +1519,7 @@ again:
|
|||
if (IsDriveThroughStopTile(v->tile) || (v->current_order.IsType(OT_GOTO_STATION) && v->current_order.GetDestination() == st->index)) {
|
||||
RoadVehArrivesAt(v, st);
|
||||
v->BeginLoading();
|
||||
TriggerRoadStopRandomisation(st, v->tile, RSRT_VEH_ARRIVES);
|
||||
TriggerRoadStopRandomisation(st, v->tile, StationRandomTrigger::VehicleArrives);
|
||||
TriggerRoadStopAnimation(st, v->tile, SAT_TRAIN_ARRIVES);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -4278,10 +4278,10 @@ static uint UpdateStationWaiting(Station *st, CargoType cargo, uint amount, Sour
|
|||
ge.status.Set(GoodsEntry::State::Rating);
|
||||
}
|
||||
|
||||
TriggerStationRandomisation(st, st->xy, SRT_NEW_CARGO, cargo);
|
||||
TriggerStationRandomisation(st, st->xy, StationRandomTrigger::NewCargo, cargo);
|
||||
TriggerStationAnimation(st, st->xy, SAT_NEW_CARGO, cargo);
|
||||
TriggerAirportAnimation(st, AAT_STATION_NEW_CARGO, cargo);
|
||||
TriggerRoadStopRandomisation(st, st->xy, RSRT_NEW_CARGO, cargo);
|
||||
TriggerRoadStopRandomisation(st, st->xy, StationRandomTrigger::NewCargo, cargo);
|
||||
TriggerRoadStopAnimation(st, st->xy, SAT_NEW_CARGO, cargo);
|
||||
|
||||
|
||||
|
|
|
@ -76,6 +76,17 @@ enum StationHadVehicleOfType : uint8_t {
|
|||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(StationHadVehicleOfType)
|
||||
|
||||
/** Randomisation triggers for stations and roadstops */
|
||||
enum class StationRandomTrigger : uint8_t {
|
||||
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.
|
||||
PathReservation, ///< Trigger platform when train reserves path.
|
||||
};
|
||||
using StationRandomTriggers = EnumBitSet<StationRandomTrigger, uint8_t>;
|
||||
|
||||
/* 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
|
||||
|
|
|
@ -307,10 +307,10 @@ inline uint8_t GetHouseRandomBits(Tile t)
|
|||
* @param triggers the activated triggers
|
||||
* @pre IsTileType(t, MP_HOUSE)
|
||||
*/
|
||||
inline void SetHouseRandomTriggers(Tile t, uint8_t triggers)
|
||||
inline void SetHouseRandomTriggers(Tile t, HouseRandomTriggers triggers)
|
||||
{
|
||||
assert(IsTileType(t, MP_HOUSE));
|
||||
SB(t.m3(), 0, 5, triggers);
|
||||
SB(t.m3(), 0, 5, triggers.base());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -320,10 +320,10 @@ inline void SetHouseRandomTriggers(Tile t, uint8_t triggers)
|
|||
* @pre IsTileType(t, MP_HOUSE)
|
||||
* @return triggers
|
||||
*/
|
||||
inline uint8_t GetHouseRandomTriggers(Tile t)
|
||||
inline HouseRandomTriggers GetHouseRandomTriggers(Tile t)
|
||||
{
|
||||
assert(IsTileType(t, MP_HOUSE));
|
||||
return GB(t.m3(), 0, 5);
|
||||
return static_cast<HouseRandomTriggers>(GB(t.m3(), 0, 5));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3024,7 +3024,7 @@ static void TrainEnterStation(Train *v, StationID station)
|
|||
|
||||
v->BeginLoading();
|
||||
|
||||
TriggerStationRandomisation(st, v->tile, SRT_TRAIN_ARRIVES);
|
||||
TriggerStationRandomisation(st, v->tile, StationRandomTrigger::VehicleArrives);
|
||||
TriggerStationAnimation(st, v->tile, SAT_TRAIN_ARRIVES);
|
||||
}
|
||||
|
||||
|
|
|
@ -972,7 +972,7 @@ static void RunEconomyVehicleDayProc()
|
|||
uint16_t callback = GetVehicleCallback(CBID_VEHICLE_32DAY_CALLBACK, 0, 0, v->engine_type, v);
|
||||
if (callback != CALLBACK_FAILED) {
|
||||
if (HasBit(callback, 0)) {
|
||||
TriggerVehicleRandomisation(v, VEHICLE_TRIGGER_CALLBACK_32); // Trigger vehicle trigger 10
|
||||
TriggerVehicleRandomisation(v, VehicleRandomTrigger::Callback32); // Trigger vehicle trigger 10
|
||||
}
|
||||
|
||||
/* After a vehicle trigger, the graphics and properties of the vehicle could change.
|
||||
|
@ -1614,7 +1614,7 @@ void VehicleEnterDepot(Vehicle *v)
|
|||
VehicleEnteredDepotThisTick(v);
|
||||
|
||||
/* After a vehicle trigger, the graphics and properties of the vehicle could change. */
|
||||
TriggerVehicleRandomisation(v, VEHICLE_TRIGGER_DEPOT);
|
||||
TriggerVehicleRandomisation(v, VehicleRandomTrigger::Depot);
|
||||
v->MarkDirty();
|
||||
|
||||
InvalidateWindowData(WC_VEHICLE_VIEW, v->index);
|
||||
|
@ -2394,7 +2394,7 @@ void Vehicle::LeaveStation()
|
|||
if (this->type == VEH_TRAIN && !this->vehstatus.Test(VehState::Crashed)) {
|
||||
/* Trigger station animation (trains only) */
|
||||
if (IsTileType(this->tile, MP_STATION)) {
|
||||
TriggerStationRandomisation(st, this->tile, SRT_TRAIN_DEPARTS);
|
||||
TriggerStationRandomisation(st, this->tile, StationRandomTrigger::VehicleDeparts);
|
||||
TriggerStationAnimation(st, this->tile, SAT_TRAIN_DEPARTS);
|
||||
}
|
||||
|
||||
|
@ -2403,7 +2403,7 @@ void Vehicle::LeaveStation()
|
|||
if (this->type == VEH_ROAD && !this->vehstatus.Test(VehState::Crashed)) {
|
||||
/* Trigger road stop animation */
|
||||
if (IsStationRoadStopTile(this->tile)) {
|
||||
TriggerRoadStopRandomisation(st, this->tile, RSRT_VEH_DEPARTS);
|
||||
TriggerRoadStopRandomisation(st, this->tile, StationRandomTrigger::VehicleDeparts);
|
||||
TriggerRoadStopAnimation(st, this->tile, SAT_TRAIN_DEPARTS);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -311,7 +311,7 @@ public:
|
|||
uint32_t motion_counter = 0; ///< counter to occasionally play a vehicle sound.
|
||||
uint8_t progress = 0; ///< The percentage (if divided by 256) this vehicle already crossed the tile unit.
|
||||
|
||||
uint8_t waiting_random_triggers = 0; ///< Triggers to be yet matched before rerandomizing the random bits.
|
||||
VehicleRandomTriggers waiting_random_triggers; ///< Triggers to be yet matched before rerandomizing the random bits.
|
||||
uint16_t random_bits = 0; ///< Bits used for randomized variational spritegroups.
|
||||
|
||||
StationID last_station_visited = StationID::Invalid(); ///< The last station we stopped at.
|
||||
|
|
|
@ -80,4 +80,14 @@ enum EngineImageType : uint8_t {
|
|||
EIT_PREVIEW = 0x21, ///< Vehicle drawn in preview window, news, ...
|
||||
};
|
||||
|
||||
/** Randomisation triggers for vehicles */
|
||||
enum class VehicleRandomTrigger : uint8_t {
|
||||
NewCargo, ///< Affected vehicle only: Vehicle is loaded with cargo, after it was empty.
|
||||
Depot, ///< Front vehicle only: Consist arrived in depot.
|
||||
Empty, ///< Front vehicle only: Entire consist is empty.
|
||||
AnyNewCargo, ///< All vehicles in consist: Any vehicle in the consist received new cargo.
|
||||
Callback32, ///< All vehicles in consist: 32 day callback requested rerandomisation
|
||||
};
|
||||
using VehicleRandomTriggers = EnumBitSet<VehicleRandomTrigger, uint8_t>;
|
||||
|
||||
#endif /* VEHICLE_TYPE_H */
|
||||
|
|
Loading…
Reference in New Issue