Codechange: Use EnumBitSet for StationFacility.

This commit is contained in:
Peter Nelson 2025-02-12 19:42:26 +00:00 committed by Peter Nelson
parent 8d38308ebb
commit 75387b9e2b
39 changed files with 157 additions and 167 deletions

View File

@ -144,7 +144,7 @@ static StationID FindNearestHangar(const Aircraft *v)
} }
for (const Station *st : Station::Iterate()) { for (const Station *st : Station::Iterate()) {
if (st->owner != v->owner || !(st->facilities & FACIL_AIRPORT) || !st->airport.HasHangar()) continue; if (st->owner != v->owner || !st->facilities.Test(StationFacility::Airport) || !st->airport.HasHangar()) continue;
const AirportFTAClass *afc = st->airport.GetFTA(); const AirportFTAClass *afc = st->airport.GetFTA();

View File

@ -66,7 +66,7 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
Town *town; ///< The town this station is associated with Town *town; ///< The town this station is associated with
Owner owner; ///< The owner of this station Owner owner; ///< The owner of this station
StationFacility facilities; ///< The facilities that this station has StationFacilities facilities; ///< The facilities that this station has
std::vector<SpecMapping<StationSpec>> speclist; ///< List of rail station specs of this station. std::vector<SpecMapping<StationSpec>> speclist; ///< List of rail station specs of this station.
std::vector<SpecMapping<RoadStopSpec>> roadstop_speclist; ///< List of road stop specs of this station std::vector<SpecMapping<RoadStopSpec>> roadstop_speclist; ///< List of road stop specs of this station
@ -175,7 +175,7 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
*/ */
inline bool IsInUse() const inline bool IsInUse() const
{ {
return (this->facilities & ~FACIL_WAYPOINT) != 0; return this->facilities.Any({StationFacility::Train, StationFacility::TruckStop, StationFacility::BusStop, StationFacility::Airport, StationFacility::Dock});
} }
inline uint8_t GetRoadStopRandomBits(TileIndex tile) const inline uint8_t GetRoadStopRandomBits(TileIndex tile) const
@ -214,7 +214,7 @@ private:
*/ */
template <class T, bool Tis_waypoint> template <class T, bool Tis_waypoint>
struct SpecializedStation : public BaseStation { struct SpecializedStation : public BaseStation {
static const StationFacility EXPECTED_FACIL = Tis_waypoint ? FACIL_WAYPOINT : FACIL_NONE; ///< Specialized type static constexpr StationFacilities EXPECTED_FACIL = Tis_waypoint ? StationFacility::Waypoint : StationFacilities{}; ///< Specialized type
/** /**
* Set station type correctly * Set station type correctly
@ -233,7 +233,7 @@ struct SpecializedStation : public BaseStation {
*/ */
static inline bool IsExpected(const BaseStation *st) static inline bool IsExpected(const BaseStation *st)
{ {
return (st->facilities & FACIL_WAYPOINT) == EXPECTED_FACIL; return st->facilities.Test(StationFacility::Waypoint) == Tis_waypoint;
} }
/** /**

View File

@ -118,7 +118,7 @@ static Money CalculateCompanyAssetValue(const Company *c)
uint num = 0; uint num = 0;
for (const Station *st : Station::Iterate()) { for (const Station *st : Station::Iterate()) {
if (st->owner == owner) num += CountBits((uint8_t)st->facilities); if (st->owner == owner) num += CountBits(st->facilities.base());
} }
Money value = num * _price[PR_STATION_VALUE] * 25; Money value = num * _price[PR_STATION_VALUE] * 25;
@ -239,7 +239,7 @@ int UpdateCompanyRatingAndValue(Company *c, bool update)
uint num = 0; uint num = 0;
for (const Station *st : Station::Iterate()) { for (const Station *st : Station::Iterate()) {
/* Only count stations that are actually serviced */ /* Only count stations that are actually serviced */
if (st->owner == owner && (st->time_since_load <= 20 || st->time_since_unload <= 20)) num += CountBits((uint8_t)st->facilities); if (st->owner == owner && (st->time_since_load <= 20 || st->time_since_unload <= 20)) num += CountBits(st->facilities.base());
} }
_score_part[owner][SCORE_STATIONS] = num; _score_part[owner][SCORE_STATIONS] = num;
} }

View File

@ -1512,11 +1512,11 @@ void NetworkPopulateCompanyStats(NetworkCompanyStats *stats)
if (Company::IsValidID(s->owner)) { if (Company::IsValidID(s->owner)) {
NetworkCompanyStats *npi = &stats[s->owner]; NetworkCompanyStats *npi = &stats[s->owner];
if (s->facilities & FACIL_TRAIN) npi->num_station[NETWORK_VEH_TRAIN]++; if (s->facilities.Test(StationFacility::Train)) npi->num_station[NETWORK_VEH_TRAIN]++;
if (s->facilities & FACIL_TRUCK_STOP) npi->num_station[NETWORK_VEH_LORRY]++; if (s->facilities.Test(StationFacility::TruckStop)) npi->num_station[NETWORK_VEH_LORRY]++;
if (s->facilities & FACIL_BUS_STOP) npi->num_station[NETWORK_VEH_BUS]++; if (s->facilities.Test(StationFacility::BusStop)) npi->num_station[NETWORK_VEH_BUS]++;
if (s->facilities & FACIL_AIRPORT) npi->num_station[NETWORK_VEH_PLANE]++; if (s->facilities.Test(StationFacility::Airport)) npi->num_station[NETWORK_VEH_PLANE]++;
if (s->facilities & FACIL_DOCK) npi->num_station[NETWORK_VEH_SHIP]++; if (s->facilities.Test(StationFacility::Dock)) npi->num_station[NETWORK_VEH_SHIP]++;
} }
} }
} }

View File

@ -169,7 +169,7 @@ void AirportOverrideManager::SetEntitySpec(AirportSpec *as)
/* Get a variable from the persistent storage */ /* Get a variable from the persistent storage */
case 0x7C: return (this->st->airport.psa != nullptr) ? this->st->airport.psa->GetValue(parameter) : 0; case 0x7C: return (this->st->airport.psa != nullptr) ? this->st->airport.psa->GetValue(parameter) : 0;
case 0xF0: return this->st->facilities; case 0xF0: return this->st->facilities.base();
case 0xFA: return ClampTo<uint16_t>(this->st->build_date - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR); case 0xFA: return ClampTo<uint16_t>(this->st->build_date - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR);
} }

View File

@ -200,7 +200,7 @@ uint32_t RoadStopScopeResolver::GetVariable(uint8_t variable, [[maybe_unused]] u
return 0xFFFE; return 0xFFFE;
} }
case 0xF0: return this->st == nullptr ? 0 : this->st->facilities; // facilities case 0xF0: return this->st == nullptr ? 0 : this->st->facilities.base(); // facilities
case 0xFA: return ClampTo<uint16_t>((this->st == nullptr ? TimerGameCalendar::date : this->st->build_date) - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR); // build date case 0xFA: return ClampTo<uint16_t>((this->st == nullptr ? TimerGameCalendar::date : this->st->build_date) - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR); // build date
} }

View File

@ -397,7 +397,7 @@ TownScopeResolver *StationResolverObject::GetTown()
case 0x82: return 50; case 0x82: return 50;
case 0x84: return this->st->string_id; case 0x84: return this->st->string_id;
case 0x86: return 0; case 0x86: return 0;
case 0xF0: return this->st->facilities; case 0xF0: return this->st->facilities.base();
case 0xFA: return ClampTo<uint16_t>(this->st->build_date - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR); case 0xFA: return ClampTo<uint16_t>(this->st->build_date - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR);
} }

View File

@ -809,7 +809,7 @@ CommandCost CmdInsertOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID se
default: return CMD_ERROR; default: return CMD_ERROR;
case VEH_TRAIN: { case VEH_TRAIN: {
if (!(wp->facilities & FACIL_TRAIN)) return CommandCost(STR_ERROR_CAN_T_ADD_ORDER, STR_ERROR_NO_RAIL_WAYPOINT); if (!wp->facilities.Test(StationFacility::Train)) return CommandCost(STR_ERROR_CAN_T_ADD_ORDER, STR_ERROR_NO_RAIL_WAYPOINT);
ret = CheckOwnership(wp->owner); ret = CheckOwnership(wp->owner);
if (ret.Failed()) return ret; if (ret.Failed()) return ret;
@ -817,7 +817,7 @@ CommandCost CmdInsertOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID se
} }
case VEH_ROAD: { case VEH_ROAD: {
if (!(wp->facilities & (FACIL_BUS_STOP | FACIL_TRUCK_STOP))) return CommandCost(STR_ERROR_CAN_T_ADD_ORDER, STR_ERROR_NO_ROAD_WAYPOINT); if (!wp->facilities.Test(StationFacility::BusStop) && !wp->facilities.Test(StationFacility::TruckStop)) return CommandCost(STR_ERROR_CAN_T_ADD_ORDER, STR_ERROR_NO_ROAD_WAYPOINT);
ret = CheckOwnership(wp->owner); ret = CheckOwnership(wp->owner);
if (ret.Failed()) return ret; if (ret.Failed()) return ret;
@ -825,7 +825,7 @@ CommandCost CmdInsertOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID se
} }
case VEH_SHIP: case VEH_SHIP:
if (!(wp->facilities & FACIL_DOCK)) return CommandCost(STR_ERROR_CAN_T_ADD_ORDER, STR_ERROR_NO_BUOY); if (!wp->facilities.Test(StationFacility::Dock)) return CommandCost(STR_ERROR_CAN_T_ADD_ORDER, STR_ERROR_NO_BUOY);
if (wp->owner != OWNER_NONE) { if (wp->owner != OWNER_NONE) {
ret = CheckOwnership(wp->owner); ret = CheckOwnership(wp->owner);
if (ret.Failed()) return ret; if (ret.Failed()) return ret;

View File

@ -453,15 +453,15 @@ static Order GetOrderCmdFromTile(const Vehicle *v, TileIndex tile)
st = in->neutral_station; st = in->neutral_station;
} }
if (st != nullptr && (st->owner == _local_company || st->owner == OWNER_NONE)) { if (st != nullptr && (st->owner == _local_company || st->owner == OWNER_NONE)) {
uint8_t facil; StationFacilities facil;
switch (v->type) { switch (v->type) {
case VEH_SHIP: facil = FACIL_DOCK; break; case VEH_SHIP: facil = StationFacility::Dock; break;
case VEH_TRAIN: facil = FACIL_TRAIN; break; case VEH_TRAIN: facil = StationFacility::Train; break;
case VEH_AIRCRAFT: facil = FACIL_AIRPORT; break; case VEH_AIRCRAFT: facil = StationFacility::Airport; break;
case VEH_ROAD: facil = FACIL_BUS_STOP | FACIL_TRUCK_STOP; break; case VEH_ROAD: facil = {StationFacility::BusStop, StationFacility::TruckStop}; break;
default: NOT_REACHED(); default: NOT_REACHED();
} }
if (st->facilities & facil) { if (st->facilities.Any(facil)) {
order.MakeGoToStation(st->index); order.MakeGoToStation(st->index);
if (_ctrl_pressed) order.SetLoadType(OLF_FULL_LOAD_ANY); if (_ctrl_pressed) order.SetLoadType(OLF_FULL_LOAD_ANY);
if (_settings_client.gui.new_nonstop && v->IsGroundVehicle()) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS); if (_settings_client.gui.new_nonstop && v->IsGroundVehicle()) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);

View File

@ -1253,8 +1253,8 @@ public:
{ {
for (const Station *st : Station::Iterate()) { for (const Station *st : Station::Iterate()) {
if (st->owner != _local_company) continue; if (st->owner != _local_company) continue;
if (roadstoptype == RoadStopType::Truck && !(st->facilities & FACIL_TRUCK_STOP)) continue; if (roadstoptype == RoadStopType::Truck && !st->facilities.Test(StationFacility::TruckStop)) continue;
if (roadstoptype == RoadStopType::Bus && !(st->facilities & FACIL_BUS_STOP)) continue; if (roadstoptype == RoadStopType::Bus && !st->facilities.Test(StationFacility::BusStop)) continue;
items.insert({0, 0, ROADSTOP_CLASS_DFLT, 0}); // We would need to scan the map to find out if default is used. items.insert({0, 0, ROADSTOP_CLASS_DFLT, 0}); // We would need to scan the map to find out if default is used.
for (const auto &sm : st->roadstop_speclist) { for (const auto &sm : st->roadstop_speclist) {
if (sm.spec == nullptr) continue; if (sm.spec == nullptr) continue;

View File

@ -1603,7 +1603,7 @@ bool AfterLoadGame()
* be OWNER_NONE. So replace OWNER_NONE with OWNER_WATER. */ * be OWNER_NONE. So replace OWNER_NONE with OWNER_WATER. */
if (IsSavegameVersionBefore(SLV_46)) { if (IsSavegameVersionBefore(SLV_46)) {
for (Waypoint *wp : Waypoint::Iterate()) { for (Waypoint *wp : Waypoint::Iterate()) {
if ((wp->facilities & FACIL_DOCK) != 0 && IsTileOwner(wp->xy, OWNER_NONE) && TileHeight(wp->xy) == 0) SetTileOwner(wp->xy, OWNER_WATER); if (wp->facilities.Test(StationFacility::Dock) && IsTileOwner(wp->xy, OWNER_NONE) && TileHeight(wp->xy) == 0) SetTileOwner(wp->xy, OWNER_WATER);
} }
} }
@ -2265,7 +2265,7 @@ bool AfterLoadGame()
if (IsSavegameVersionBefore(SLV_124) && !IsSavegameVersionBefore(SLV_1)) { if (IsSavegameVersionBefore(SLV_124) && !IsSavegameVersionBefore(SLV_1)) {
/* The train station tile area was added, but for really old (TTDPatch) it's already valid. */ /* The train station tile area was added, but for really old (TTDPatch) it's already valid. */
for (Waypoint *wp : Waypoint::Iterate()) { for (Waypoint *wp : Waypoint::Iterate()) {
if (wp->facilities & FACIL_TRAIN) { if (wp->facilities.Test(StationFacility::Train)) {
wp->train_station.tile = wp->xy; wp->train_station.tile = wp->xy;
wp->train_station.w = 1; wp->train_station.w = 1;
wp->train_station.h = 1; wp->train_station.h = 1;
@ -2828,7 +2828,7 @@ bool AfterLoadGame()
if (!IsSavegameVersionBefore(SLV_145)) { if (!IsSavegameVersionBefore(SLV_145)) {
for (Station *st : Station::Iterate()) { for (Station *st : Station::Iterate()) {
if (!(st->facilities & FACIL_AIRPORT)) continue; if (!st->facilities.Test(StationFacility::Airport)) continue;
assert(st->airport.psa != nullptr); assert(st->airport.psa != nullptr);
/* Check if the old storage was empty. */ /* Check if the old storage was empty. */

View File

@ -100,7 +100,7 @@ void AfterLoadCompanyStats()
/* Collect airport count. */ /* Collect airport count. */
for (const Station *st : Station::Iterate()) { for (const Station *st : Station::Iterate()) {
if ((st->facilities & FACIL_AIRPORT) && Company::IsValidID(st->owner)) { if (st->facilities.Test(StationFacility::Airport) && Company::IsValidID(st->owner)) {
Company::Get(st->owner)->infrastructure.airport++; Company::Get(st->owner)->infrastructure.airport++;
} }
} }

View File

@ -100,10 +100,10 @@ void MoveBuoysToWaypoints()
} }
wp->train_station = train_st; wp->train_station = train_st;
wp->facilities |= FACIL_TRAIN; wp->facilities.Set(StationFacility::Train);
} else if (IsBuoyTile(xy) && GetStationIndex(xy) == index) { } else if (IsBuoyTile(xy) && GetStationIndex(xy) == index) {
wp->rect.BeforeAddTile(xy, StationRect::ADD_FORCE); wp->rect.BeforeAddTile(xy, StationRect::ADD_FORCE);
wp->facilities |= FACIL_DOCK; wp->facilities.Set(StationFacility::Dock);
} }
} }
} }
@ -397,7 +397,7 @@ public:
Station *st = Station::From(bst); Station *st = Station::From(bst);
/* Before savegame version 161, persistent storages were not stored in a pool. */ /* Before savegame version 161, persistent storages were not stored in a pool. */
if (IsSavegameVersionBefore(SLV_161) && !IsSavegameVersionBefore(SLV_145) && st->facilities & FACIL_AIRPORT) { if (IsSavegameVersionBefore(SLV_161) && !IsSavegameVersionBefore(SLV_145) && st->facilities.Test(StationFacility::Airport)) {
/* Store the old persistent storage. The GRFID will be added later. */ /* Store the old persistent storage. The GRFID will be added later. */
assert(PersistentStorage::CanAllocateItem()); assert(PersistentStorage::CanAllocateItem());
st->airport.psa = new PersistentStorage(0, 0, TileIndex{}); st->airport.psa = new PersistentStorage(0, 0, TileIndex{});
@ -629,19 +629,19 @@ public:
void Save(BaseStation *bst) const override void Save(BaseStation *bst) const override
{ {
if ((bst->facilities & FACIL_WAYPOINT) != 0) return; if (bst->facilities.Test(StationFacility::Waypoint)) return;
SlObject(bst, this->GetDescription()); SlObject(bst, this->GetDescription());
} }
void Load(BaseStation *bst) const override void Load(BaseStation *bst) const override
{ {
if ((bst->facilities & FACIL_WAYPOINT) != 0) return; if (bst->facilities.Test(StationFacility::Waypoint)) return;
SlObject(bst, this->GetLoadDescription()); SlObject(bst, this->GetLoadDescription());
} }
void FixPointers(BaseStation *bst) const override void FixPointers(BaseStation *bst) const override
{ {
if ((bst->facilities & FACIL_WAYPOINT) != 0) return; if (bst->facilities.Test(StationFacility::Waypoint)) return;
SlObject(bst, this->GetDescription()); SlObject(bst, this->GetDescription());
} }
}; };
@ -664,19 +664,19 @@ public:
void Save(BaseStation *bst) const override void Save(BaseStation *bst) const override
{ {
if ((bst->facilities & FACIL_WAYPOINT) == 0) return; if (!bst->facilities.Test(StationFacility::Waypoint)) return;
SlObject(bst, this->GetDescription()); SlObject(bst, this->GetDescription());
} }
void Load(BaseStation *bst) const override void Load(BaseStation *bst) const override
{ {
if ((bst->facilities & FACIL_WAYPOINT) == 0) return; if (!bst->facilities.Test(StationFacility::Waypoint)) return;
SlObject(bst, this->GetLoadDescription()); SlObject(bst, this->GetLoadDescription());
} }
void FixPointers(BaseStation *bst) const override void FixPointers(BaseStation *bst) const override
{ {
if ((bst->facilities & FACIL_WAYPOINT) == 0) return; if (!bst->facilities.Test(StationFacility::Waypoint)) return;
SlObject(bst, this->GetDescription()); SlObject(bst, this->GetDescription());
} }
}; };
@ -713,7 +713,7 @@ struct STNNChunkHandler : ChunkHandler {
int index; int index;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
bool waypoint = (SlReadByte() & FACIL_WAYPOINT) != 0; bool waypoint = static_cast<StationFacilities>(SlReadByte()).Test(StationFacility::Waypoint);
BaseStation *bst = waypoint ? (BaseStation *)new (index) Waypoint() : new (index) Station(); BaseStation *bst = waypoint ? (BaseStation *)new (index) Waypoint() : new (index) Station();
SlObject(bst, slt); SlObject(bst, slt);

View File

@ -131,7 +131,7 @@ void MoveWaypointsToBaseStations()
/* The tile really has our waypoint, so reassign the map array */ /* The tile really has our waypoint, so reassign the map array */
MakeRailWaypoint(tile, GetTileOwner(tile), new_wp->index, (Axis)GB(tile.m5(), 0, 1), 0, GetRailType(tile)); MakeRailWaypoint(tile, GetTileOwner(tile), new_wp->index, (Axis)GB(tile.m5(), 0, 1), 0, GetRailType(tile));
new_wp->facilities |= FACIL_TRAIN; new_wp->facilities.Set(StationFacility::Train);
new_wp->owner = GetTileOwner(tile); new_wp->owner = GetTileOwner(tile);
SetRailStationReservation(tile, reserved); SetRailStationReservation(tile, reserved);

View File

@ -97,7 +97,7 @@
const Station *st = ::Station::GetByTile(tile); const Station *st = ::Station::GetByTile(tile);
if (st->owner != ScriptObject::GetCompany() && ScriptCompanyMode::IsValid()) return -1; if (st->owner != ScriptObject::GetCompany() && ScriptCompanyMode::IsValid()) return -1;
if ((st->facilities & FACIL_AIRPORT) == 0) return -1; if (!st->facilities.Test(StationFacility::Airport)) return -1;
return st->airport.GetNumHangars(); return st->airport.GetNumHangars();
} }
@ -111,7 +111,7 @@
const Station *st = ::Station::GetByTile(tile); const Station *st = ::Station::GetByTile(tile);
if (st->owner != ScriptObject::GetCompany() && ScriptCompanyMode::IsValid()) return INVALID_TILE; if (st->owner != ScriptObject::GetCompany() && ScriptCompanyMode::IsValid()) return INVALID_TILE;
if ((st->facilities & FACIL_AIRPORT) == 0) return INVALID_TILE; if (!st->facilities.Test(StationFacility::Airport)) return INVALID_TILE;
return st->airport.GetHangarTile(0); return st->airport.GetHangarTile(0);
} }

View File

@ -209,7 +209,7 @@ template <bool Tfrom, bool Tvia>
if (!IsValidStation(station_id)) return false; if (!IsValidStation(station_id)) return false;
if (!HasExactlyOneBit(station_type)) return false; if (!HasExactlyOneBit(station_type)) return false;
return (::Station::Get(station_id)->facilities & static_cast<StationFacility>(station_type)) != 0; return ::Station::Get(station_id)->facilities.Any(static_cast<StationFacilities>(station_type));
} }
/* static */ bool ScriptStation::HasRoadType(StationID station_id, ScriptRoad::RoadType road_type) /* static */ bool ScriptStation::HasRoadType(StationID station_id, ScriptRoad::RoadType road_type)

View File

@ -43,12 +43,12 @@ public:
* Type of stations known in the game. * Type of stations known in the game.
*/ */
enum StationType { enum StationType {
/* Note: these values represent part of the in-game StationFacility enum */ /* Note: these values represent part of the in-game StationFacilities enum */
STATION_TRAIN = (int)::FACIL_TRAIN, ///< Train station STATION_TRAIN = (1 << to_underlying(::StationFacility::Train)), ///< Train station
STATION_TRUCK_STOP = (int)::FACIL_TRUCK_STOP, ///< Truck station STATION_TRUCK_STOP = (1 << to_underlying(::StationFacility::TruckStop)), ///< Truck station
STATION_BUS_STOP = (int)::FACIL_BUS_STOP, ///< Bus station STATION_BUS_STOP = (1 << to_underlying(::StationFacility::BusStop)), ///< Bus station
STATION_AIRPORT = (int)::FACIL_AIRPORT, ///< Airport STATION_AIRPORT = (1 << to_underlying(::StationFacility::Airport)), ///< Airport
STATION_DOCK = (int)::FACIL_DOCK, ///< Dock STATION_DOCK = (1 << to_underlying(::StationFacility::Dock)), ///< Dock
STATION_ANY = STATION_TRAIN | STATION_TRUCK_STOP | STATION_BUS_STOP | STATION_AIRPORT | STATION_DOCK, ///< All station types STATION_ANY = STATION_TRAIN | STATION_TRUCK_STOP | STATION_BUS_STOP | STATION_AIRPORT | STATION_DOCK, ///< All station types
}; };

View File

@ -23,7 +23,7 @@ ScriptStationList::ScriptStationList(ScriptStation::StationType station_type)
::CompanyID owner = ScriptObject::GetCompany(); ::CompanyID owner = ScriptObject::GetCompany();
ScriptList::FillList<Station>(this, ScriptList::FillList<Station>(this,
[is_deity, owner, station_type](const Station *st) { [is_deity, owner, station_type](const Station *st) {
return (is_deity || st->owner == owner) && (st->facilities & static_cast<StationFacility>(station_type)) != 0; return (is_deity || st->owner == owner) && st->facilities.Any(static_cast<StationFacilities>(station_type));
} }
); );
} }

View File

@ -130,20 +130,20 @@ ScriptTileList_StationType::ScriptTileList_StationType(StationID station_id, Scr
const StationRect *rect = &::Station::Get(station_id)->rect; const StationRect *rect = &::Station::Get(station_id)->rect;
uint station_type_value = 0; EnumBitSet<StationType, uint8_t> station_types = {};
/* Convert ScriptStation::StationType to ::StationType, but do it in a /* Convert ScriptStation::StationType to ::StationType, but do it in a
* bitmask, so we can scan for multiple entries at the same time. */ * bitmask, so we can scan for multiple entries at the same time. */
if ((station_type & ScriptStation::STATION_TRAIN) != 0) station_type_value |= (1 << to_underlying(::StationType::Rail)); if ((station_type & ScriptStation::STATION_TRAIN) != 0) station_types.Set(::StationType::Rail);
if ((station_type & ScriptStation::STATION_TRUCK_STOP) != 0) station_type_value |= (1 << to_underlying(::StationType::Truck)); if ((station_type & ScriptStation::STATION_TRUCK_STOP) != 0) station_types.Set(::StationType::Truck);
if ((station_type & ScriptStation::STATION_BUS_STOP) != 0) station_type_value |= (1 << to_underlying(::StationType::Bus)); if ((station_type & ScriptStation::STATION_BUS_STOP) != 0) station_types.Set(::StationType::Bus);
if ((station_type & ScriptStation::STATION_AIRPORT) != 0) station_type_value |= (1 << to_underlying(::StationType::Airport)) | (1 << to_underlying(::StationType::Oilrig)); if ((station_type & ScriptStation::STATION_AIRPORT) != 0) station_types.Set(::StationType::Airport).Set(::StationType::Oilrig);
if ((station_type & ScriptStation::STATION_DOCK) != 0) station_type_value |= (1 << to_underlying(::StationType::Dock)) | (1 << to_underlying(::StationType::Oilrig)); if ((station_type & ScriptStation::STATION_DOCK) != 0) station_types.Set(::StationType::Dock).Set(::StationType::Oilrig);
TileArea ta(::TileXY(rect->left, rect->top), rect->Width(), rect->Height()); TileArea ta(::TileXY(rect->left, rect->top), rect->Width(), rect->Height());
for (TileIndex cur_tile : ta) { for (TileIndex cur_tile : ta) {
if (!::IsTileType(cur_tile, MP_STATION)) continue; if (!::IsTileType(cur_tile, MP_STATION)) continue;
if (::GetStationIndex(cur_tile) != station_id) continue; if (::GetStationIndex(cur_tile) != station_id) continue;
if (!HasBit(station_type_value, to_underlying(::GetStationType(cur_tile)))) continue; if (!station_types.Test(::GetStationType(cur_tile))) continue;
this->AddTile(cur_tile); this->AddTile(cur_tile);
} }
} }

View File

@ -376,7 +376,7 @@
int num = 0; int num = 0;
for (const Station *st : Station::Iterate()) { for (const Station *st : Station::Iterate()) {
if (st->town == t && (st->facilities & FACIL_AIRPORT) && st->airport.type != AT_OILRIG) num++; if (st->town == t && st->facilities.Test(StationFacility::Airport) && st->airport.type != AT_OILRIG) num++;
} }
return std::max(0, 2 - num); return std::max(0, 2 - num);
} }

View File

@ -33,5 +33,5 @@
if (!IsValidWaypoint(waypoint_id)) return false; if (!IsValidWaypoint(waypoint_id)) return false;
if (!HasExactlyOneBit(waypoint_type)) return false; if (!HasExactlyOneBit(waypoint_type)) return false;
return (::Waypoint::Get(waypoint_id)->facilities & static_cast<StationFacility>(waypoint_type)) != 0; return ::Waypoint::Get(waypoint_id)->facilities.Any(static_cast<StationFacilities>(waypoint_type));
} }

View File

@ -40,9 +40,9 @@ public:
* Type of waypoints known in the game. * Type of waypoints known in the game.
*/ */
enum WaypointType { enum WaypointType {
/* Note: these values represent part of the in-game StationFacility enum */ /* Note: these values represent part of the in-game StationFacilities enum */
WAYPOINT_RAIL = (int)::FACIL_TRAIN, ///< Rail waypoint WAYPOINT_RAIL = (1U << to_underlying(::StationFacility::Train)), ///< Rail waypoint
WAYPOINT_BUOY = (int)::FACIL_DOCK, ///< Buoy WAYPOINT_BUOY = (1U << to_underlying(::StationFacility::Dock)), ///< Buoy
WAYPOINT_ANY = WAYPOINT_RAIL | WAYPOINT_BUOY, ///< All waypoint types WAYPOINT_ANY = WAYPOINT_RAIL | WAYPOINT_BUOY, ///< All waypoint types
}; };

View File

@ -23,7 +23,7 @@ ScriptWaypointList::ScriptWaypointList(ScriptWaypoint::WaypointType waypoint_typ
::CompanyID owner = ScriptObject::GetCompany(); ::CompanyID owner = ScriptObject::GetCompany();
ScriptList::FillList<Waypoint>(this, ScriptList::FillList<Waypoint>(this,
[is_deity, owner, waypoint_type](const Waypoint *wp) { [is_deity, owner, waypoint_type](const Waypoint *wp) {
return (is_deity || wp->owner == owner || wp->owner == OWNER_NONE) && (wp->facilities & static_cast<StationFacility>(waypoint_type)) != 0; return (is_deity || wp->owner == owner || wp->owner == OWNER_NONE) && wp->facilities.Any(static_cast<StationFacilities>(waypoint_type));
} }
); );
} }

View File

@ -776,7 +776,7 @@ static void ShipController(Ship *v)
Station *st = Station::Get(v->current_order.GetDestination().ToStationID()); Station *st = Station::Get(v->current_order.GetDestination().ToStationID());
if (st->docking_station.Contains(gp.new_tile) && IsShipDestinationTile(gp.new_tile, st->index)) { if (st->docking_station.Contains(gp.new_tile) && IsShipDestinationTile(gp.new_tile, st->index)) {
v->last_station_visited = st->index; v->last_station_visited = st->index;
if (st->facilities & FACIL_DOCK) { // ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations if (st->facilities.Test(StationFacility::Dock)) { // ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations
ShipArrivesAt(v, st); ShipArrivesAt(v, st);
v->BeginLoading(); v->BeginLoading();
} else { // leave stations without docks right away } else { // leave stations without docks right away

View File

@ -228,11 +228,11 @@ RoadStop *Station::GetPrimaryRoadStop(const RoadVehicle *v) const
*/ */
void Station::AddFacility(StationFacility new_facility_bit, TileIndex facil_xy) void Station::AddFacility(StationFacility new_facility_bit, TileIndex facil_xy)
{ {
if (this->facilities == FACIL_NONE) { if (this->facilities == StationFacilities{}) {
this->MoveSign(facil_xy); this->MoveSign(facil_xy);
this->random_bits = Random(); this->random_bits = Random();
} }
this->facilities |= new_facility_bit; this->facilities.Set(new_facility_bit);
this->owner = _current_company; this->owner = _current_company;
this->build_date = TimerGameCalendar::date; this->build_date = TimerGameCalendar::date;
SetWindowClassesDirty(WC_VEHICLE_ORDERS); SetWindowClassesDirty(WC_VEHICLE_ORDERS);
@ -714,7 +714,7 @@ Money AirportMaintenanceCost(Owner owner)
Money total_cost = 0; Money total_cost = 0;
for (const Station *st : Station::Iterate()) { for (const Station *st : Station::Iterate()) {
if (st->owner == owner && (st->facilities & FACIL_AIRPORT)) { if (st->owner == owner && st->facilities.Test(StationFacility::Airport)) {
total_cost += _price[PR_INFRASTRUCTURE_AIRPORT] * st->airport.GetSpec()->maintenance_cost; total_cost += _price[PR_INFRASTRUCTURE_AIRPORT] * st->airport.GetSpec()->maintenance_cost;
} }
} }

View File

@ -444,7 +444,7 @@ void Station::UpdateVirtCoord()
Point pt = RemapCoords2(TileX(this->xy) * TILE_SIZE, TileY(this->xy) * TILE_SIZE); Point pt = RemapCoords2(TileX(this->xy) * TILE_SIZE, TileY(this->xy) * TILE_SIZE);
pt.y -= 32 * ZOOM_BASE; pt.y -= 32 * ZOOM_BASE;
if ((this->facilities & FACIL_AIRPORT) && this->airport.type == AT_OILRIG) pt.y -= 16 * ZOOM_BASE; if (this->facilities.Test(StationFacility::Airport) && this->airport.type == AT_OILRIG) pt.y -= 16 * ZOOM_BASE;
if (this->sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeStation(this->index)); if (this->sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeStation(this->index));
@ -637,8 +637,8 @@ void UpdateStationAcceptance(Station *st, bool show_msg)
/* Make sure the station can accept the goods type. */ /* Make sure the station can accept the goods type. */
bool is_passengers = IsCargoInClass(i, CargoClass::Passengers); bool is_passengers = IsCargoInClass(i, CargoClass::Passengers);
if ((!is_passengers && !(st->facilities & ~FACIL_BUS_STOP)) || if ((!is_passengers && !st->facilities.Any({StationFacility::Train, StationFacility::TruckStop, StationFacility::Airport, StationFacility::Dock})) ||
(is_passengers && !(st->facilities & ~FACIL_TRUCK_STOP))) { (is_passengers && !st->facilities.Any({StationFacility::Train, StationFacility::BusStop, StationFacility::Airport, StationFacility::Dock}))) {
amt = 0; amt = 0;
} }
@ -1414,7 +1414,7 @@ CommandCost CmdBuildRailStation(DoCommandFlag flags, TileIndex tile_org, RailTyp
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
st->train_station = new_location; st->train_station = new_location;
st->AddFacility(FACIL_TRAIN, new_location.tile); st->AddFacility(StationFacility::Train, new_location.tile);
st->rect.BeforeAddRect(tile_org, w_org, h_org, StationRect::ADD_TRY); st->rect.BeforeAddRect(tile_org, w_org, h_org, StationRect::ADD_TRY);
@ -1722,7 +1722,7 @@ CommandCost RemoveFromRailBaseStation(TileArea ta, std::vector<T *> &affected_st
/* if we deleted the whole station, delete the train facility. */ /* if we deleted the whole station, delete the train facility. */
if (st->train_station.tile == INVALID_TILE) { if (st->train_station.tile == INVALID_TILE) {
st->facilities &= ~FACIL_TRAIN; st->facilities.Reset(StationFacility::Train);
SetWindowClassesDirty(WC_VEHICLE_ORDERS); SetWindowClassesDirty(WC_VEHICLE_ORDERS);
SetWindowWidgetDirty(WC_STATION_VIEW, st->index, WID_SV_TRAINS); SetWindowWidgetDirty(WC_STATION_VIEW, st->index, WID_SV_TRAINS);
MarkCatchmentTilesDirty(); MarkCatchmentTilesDirty();
@ -2067,7 +2067,7 @@ CommandCost CmdBuildRoadStop(DoCommandFlag flags, TileIndex tile, uint8_t width,
} }
/* Initialize an empty station. */ /* Initialize an empty station. */
st->AddFacility(is_truck_stop ? FACIL_TRUCK_STOP : FACIL_BUS_STOP, cur_tile); st->AddFacility(is_truck_stop ? StationFacility::TruckStop : StationFacility::BusStop, cur_tile);
st->rect.BeforeAddTile(cur_tile, StationRect::ADD_TRY); st->rect.BeforeAddTile(cur_tile, StationRect::ADD_TRY);
@ -2175,7 +2175,7 @@ static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags, int repla
*primary_stop = cur_stop->next; *primary_stop = cur_stop->next;
/* removed the only stop? */ /* removed the only stop? */
if (*primary_stop == nullptr) { if (*primary_stop == nullptr) {
st->facilities &= (is_truck ? ~FACIL_TRUCK_STOP : ~FACIL_BUS_STOP); st->facilities.Reset(is_truck ? StationFacility::TruckStop : StationFacility::BusStop);
SetWindowClassesDirty(WC_VEHICLE_ORDERS); SetWindowClassesDirty(WC_VEHICLE_ORDERS);
} }
} else { } else {
@ -2294,7 +2294,7 @@ CommandCost RemoveRoadWaypointStop(TileIndex tile, DoCommandFlag flags, int repl
/* if we deleted the whole waypoint, delete the road facility. */ /* if we deleted the whole waypoint, delete the road facility. */
if (wp->road_waypoint_area.tile == INVALID_TILE) { if (wp->road_waypoint_area.tile == INVALID_TILE) {
wp->facilities &= ~(FACIL_BUS_STOP | FACIL_TRUCK_STOP); wp->facilities.Reset(StationFacility::BusStop).Reset(StationFacility::TruckStop);
SetWindowWidgetDirty(WC_STATION_VIEW, wp->index, WID_SV_ROADVEHS); SetWindowWidgetDirty(WC_STATION_VIEW, wp->index, WID_SV_ROADVEHS);
wp->UpdateVirtCoord(); wp->UpdateVirtCoord();
DeleteStationIfEmpty(wp); DeleteStationIfEmpty(wp);
@ -2571,7 +2571,7 @@ CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, uint8_t airport
Town *t = ClosestTownFromTile(tile, UINT_MAX); Town *t = ClosestTownFromTile(tile, UINT_MAX);
uint num = 0; uint num = 0;
for (const Station *st : Station::Iterate()) { for (const Station *st : Station::Iterate()) {
if (st->town == t && (st->facilities & FACIL_AIRPORT) && st->airport.type != AT_OILRIG) num++; if (st->town == t && st->facilities.Test(StationFacility::Airport) && st->airport.type != AT_OILRIG) num++;
} }
if (num >= 2) { if (num >= 2) {
authority_refuse_message = STR_ERROR_LOCAL_AUTHORITY_REFUSES_AIRPORT; authority_refuse_message = STR_ERROR_LOCAL_AUTHORITY_REFUSES_AIRPORT;
@ -2606,7 +2606,7 @@ CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, uint8_t airport
/* Always add the noise, so there will be no need to recalculate when option toggles */ /* Always add the noise, so there will be no need to recalculate when option toggles */
nearest->noise_reached += newnoise_level; nearest->noise_reached += newnoise_level;
st->AddFacility(FACIL_AIRPORT, tile); st->AddFacility(StationFacility::Airport, tile);
st->airport.type = airport_type; st->airport.type = airport_type;
st->airport.layout = layout; st->airport.layout = layout;
st->airport.flags = 0; st->airport.flags = 0;
@ -2709,7 +2709,7 @@ static CommandCost RemoveAirport(TileIndex tile, DoCommandFlag flags)
st->rect.AfterRemoveRect(st, st->airport); st->rect.AfterRemoveRect(st, st->airport);
st->airport.Clear(); st->airport.Clear();
st->facilities &= ~FACIL_AIRPORT; st->facilities.Reset(StationFacility::Airport);
SetWindowClassesDirty(WC_VEHICLE_ORDERS); SetWindowClassesDirty(WC_VEHICLE_ORDERS);
InvalidateWindowData(WC_STATION_VIEW, st->index, -1); InvalidateWindowData(WC_STATION_VIEW, st->index, -1);
@ -2735,7 +2735,7 @@ CommandCost CmdOpenCloseAirport(DoCommandFlag flags, StationID station_id)
if (!Station::IsValidID(station_id)) return CMD_ERROR; if (!Station::IsValidID(station_id)) return CMD_ERROR;
Station *st = Station::Get(station_id); Station *st = Station::Get(station_id);
if (!(st->facilities & FACIL_AIRPORT) || st->owner == OWNER_NONE) return CMD_ERROR; if (!st->facilities.Test(StationFacility::Airport) || st->owner == OWNER_NONE) return CMD_ERROR;
CommandCost ret = CheckOwnership(st->owner); CommandCost ret = CheckOwnership(st->owner);
if (ret.Failed()) return ret; if (ret.Failed()) return ret;
@ -2850,7 +2850,7 @@ CommandCost CmdBuildDock(DoCommandFlag flags, TileIndex tile, StationID station_
st->ship_station.Add(tile); st->ship_station.Add(tile);
TileIndex flat_tile = tile + TileOffsByDiagDir(direction); TileIndex flat_tile = tile + TileOffsByDiagDir(direction);
st->ship_station.Add(flat_tile); st->ship_station.Add(flat_tile);
st->AddFacility(FACIL_DOCK, tile); st->AddFacility(StationFacility::Dock, tile);
st->rect.BeforeAddRect(dock_area.tile, dock_area.w, dock_area.h, StationRect::ADD_TRY); st->rect.BeforeAddRect(dock_area.tile, dock_area.w, dock_area.h, StationRect::ADD_TRY);
@ -2965,7 +2965,7 @@ static CommandCost RemoveDock(TileIndex tile, DoCommandFlag flags)
if (st->ship_station.tile == INVALID_TILE) { if (st->ship_station.tile == INVALID_TILE) {
st->ship_station.Clear(); st->ship_station.Clear();
st->docking_station.Clear(); st->docking_station.Clear();
st->facilities &= ~FACIL_DOCK; st->facilities.Reset(StationFacility::Dock);
SetWindowClassesDirty(WC_VEHICLE_ORDERS); SetWindowClassesDirty(WC_VEHICLE_ORDERS);
} }
@ -2992,7 +2992,7 @@ static CommandCost RemoveDock(TileIndex tile, DoCommandFlag flags)
/* If we no longer have a dock, mark the order as invalid and send /* If we no longer have a dock, mark the order as invalid and send
* the ship to the next order (or, if there is none, make it * the ship to the next order (or, if there is none, make it
* wander the world). */ * wander the world). */
if (s->current_order.IsType(OT_GOTO_STATION) && !(st->facilities & FACIL_DOCK)) { if (s->current_order.IsType(OT_GOTO_STATION) && !st->facilities.Test(StationFacility::Dock)) {
s->SetDestTile(s->GetOrderStationLocation(st->index)); s->SetDestTile(s->GetOrderStationLocation(st->index));
} }
} }
@ -3690,7 +3690,7 @@ static bool ClickTile_Station(TileIndex tile)
{ {
const BaseStation *bst = BaseStation::GetByTile(tile); const BaseStation *bst = BaseStation::GetByTile(tile);
if (bst->facilities & FACIL_WAYPOINT) { if (bst->facilities.Test(StationFacility::Waypoint)) {
ShowWaypointWindow(Waypoint::From(bst)); ShowWaypointWindow(Waypoint::From(bst));
} else if (IsHangar(tile)) { } else if (IsHangar(tile)) {
const Station *st = Station::From(bst); const Station *st = Station::From(bst);
@ -3795,7 +3795,7 @@ static bool StationHandleBigTick(BaseStation *st)
} }
if ((st->facilities & FACIL_WAYPOINT) == 0) UpdateStationAcceptance(Station::From(st), true); if (!st->facilities.Test(StationFacility::Waypoint)) UpdateStationAcceptance(Station::From(st), true);
return true; return true;
} }
@ -4186,7 +4186,7 @@ void IncreaseStats(Station *st, const Vehicle *front, StationID next_station_id,
/* called for every station each tick */ /* called for every station each tick */
static void StationHandleSmallTick(BaseStation *st) static void StationHandleSmallTick(BaseStation *st)
{ {
if ((st->facilities & FACIL_WAYPOINT) != 0 || !st->IsInUse()) return; if (st->facilities.Test(StationFacility::Waypoint) || !st->IsInUse()) return;
uint8_t b = st->delete_ctr + 1; uint8_t b = st->delete_ctr + 1;
if (b >= Ticks::STATION_RATING_TICKS) b = 0; if (b >= Ticks::STATION_RATING_TICKS) b = 0;
@ -4383,10 +4383,10 @@ static bool CanMoveGoodsToStation(const Station *st, CargoType type)
if (IsCargoInClass(type, CargoClass::Passengers)) { if (IsCargoInClass(type, CargoClass::Passengers)) {
/* Passengers are never served by just a truck stop. */ /* Passengers are never served by just a truck stop. */
if (st->facilities == FACIL_TRUCK_STOP) return false; if (st->facilities == StationFacility::TruckStop) return false;
} else { } else {
/* Non-passengers are never served by just a bus stop. */ /* Non-passengers are never served by just a bus stop. */
if (st->facilities == FACIL_BUS_STOP) return false; if (st->facilities == StationFacility::BusStop) return false;
} }
return true; return true;
} }
@ -4526,7 +4526,7 @@ void BuildOilRig(TileIndex tile)
st->airport.type = AT_OILRIG; st->airport.type = AT_OILRIG;
st->airport.Add(tile); st->airport.Add(tile);
st->ship_station.Add(tile); st->ship_station.Add(tile);
st->facilities = FACIL_AIRPORT | FACIL_DOCK; st->facilities = {StationFacility::Airport, StationFacility::Dock};
st->build_date = TimerGameCalendar::date; st->build_date = TimerGameCalendar::date;
UpdateStationDockingTiles(st); UpdateStationDockingTiles(st);
@ -4557,7 +4557,8 @@ void DeleteOilRig(TileIndex tile)
MakeWaterKeepingClass(tile, OWNER_NONE); MakeWaterKeepingClass(tile, OWNER_NONE);
/* The oil rig station is not supposed to be shared with anything else */ /* The oil rig station is not supposed to be shared with anything else */
assert(st->facilities == (FACIL_AIRPORT | FACIL_DOCK) && st->airport.type == AT_OILRIG); [[maybe_unused]] static constexpr StationFacilities expected_facility{StationFacility::Airport, StationFacility::Dock};
assert(st->facilities == expected_facility && st->airport.type == AT_OILRIG);
if (st->industry != nullptr && st->industry->neutral_station == st) { if (st->industry != nullptr && st->industry->neutral_station == st) {
/* Don't leave dangling neutral station pointer */ /* Don't leave dangling neutral station pointer */
st->industry->neutral_station = nullptr; st->industry->neutral_station = nullptr;
@ -4567,6 +4568,7 @@ void DeleteOilRig(TileIndex tile)
static void ChangeTileOwner_Station(TileIndex tile, Owner old_owner, Owner new_owner) static void ChangeTileOwner_Station(TileIndex tile, Owner old_owner, Owner new_owner)
{ {
if (IsAnyRoadStopTile(tile)) { if (IsAnyRoadStopTile(tile)) {
for (RoadTramType rtt : _roadtramtypes) { for (RoadTramType rtt : _roadtramtypes) {
/* Update all roadtypes, no matter if they are present */ /* Update all roadtypes, no matter if they are present */

View File

@ -263,14 +263,14 @@ protected:
/* Runtime saved values */ /* Runtime saved values */
struct FilterState { struct FilterState {
Listing last_sorting; Listing last_sorting;
uint8_t facilities; ///< types of stations of interest StationFacilities facilities; ///< types of stations of interest
bool include_no_rating; ///< Whether we should include stations with no cargo rating. bool include_no_rating; ///< Whether we should include stations with no cargo rating.
CargoTypes cargoes; ///< bitmap of cargo types to include CargoTypes cargoes; ///< bitmap of cargo types to include
}; };
static inline FilterState initial_state = { static inline FilterState initial_state = {
{false, 0}, {false, 0},
FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK, {StationFacility::Train, StationFacility::TruckStop, StationFacility::BusStop, StationFacility::Airport, StationFacility::Dock},
true, true,
ALL_CARGOTYPES, ALL_CARGOTYPES,
}; };
@ -310,7 +310,7 @@ protected:
this->stations_per_cargo_type_no_rating = 0; this->stations_per_cargo_type_no_rating = 0;
for (const Station *st : Station::Iterate()) { for (const Station *st : Station::Iterate()) {
if ((this->filter.facilities & st->facilities) != 0) { // only stations with selected facilities if (this->filter.facilities.Any(st->facilities)) { // only stations with selected facilities
if (st->owner == owner || (st->owner == OWNER_NONE && HasStationInUse(st->index, true, owner))) { if (st->owner == owner || (st->owner == OWNER_NONE && HasStationInUse(st->index, true, owner))) {
bool has_rating = false; bool has_rating = false;
/* Add to the station/cargo counts. */ /* Add to the station/cargo counts. */
@ -436,7 +436,7 @@ public:
if (this->filter.cargoes == ALL_CARGOTYPES) this->filter.cargoes = _cargo_mask; if (this->filter.cargoes == ALL_CARGOTYPES) this->filter.cargoes = _cargo_mask;
for (uint i = 0; i < 5; i++) { for (uint i = 0; i < 5; i++) {
if (HasBit(this->filter.facilities, i)) this->LowerWidget(i + WID_STL_TRAIN); if (HasBit(this->filter.facilities.base(), i)) this->LowerWidget(i + WID_STL_TRAIN);
} }
this->GetWidget<NWidgetCore>(WID_STL_SORTDROPBTN)->SetString(CompanyStationsWindow::sorter_names[this->stations.SortType()]); this->GetWidget<NWidgetCore>(WID_STL_SORTDROPBTN)->SetString(CompanyStationsWindow::sorter_names[this->stations.SortType()]);
@ -634,13 +634,14 @@ public:
case WID_STL_AIRPLANE: case WID_STL_AIRPLANE:
case WID_STL_SHIP: case WID_STL_SHIP:
if (_ctrl_pressed) { if (_ctrl_pressed) {
ToggleBit(this->filter.facilities, widget - WID_STL_TRAIN); this->filter.facilities.Flip(static_cast<StationFacility>(widget - WID_STL_TRAIN));
this->ToggleWidgetLoweredState(widget); this->ToggleWidgetLoweredState(widget);
} else { } else {
for (uint i : SetBitIterator(this->filter.facilities)) { for (uint i : SetBitIterator(this->filter.facilities.base())) {
this->RaiseWidget(i + WID_STL_TRAIN); this->RaiseWidget(i + WID_STL_TRAIN);
} }
this->filter.facilities = 1 << (widget - WID_STL_TRAIN); this->filter.facilities = {};
this->filter.facilities.Set(static_cast<StationFacility>(widget - WID_STL_TRAIN));
this->LowerWidget(widget); this->LowerWidget(widget);
} }
this->stations.ForceRebuild(); this->stations.ForceRebuild();
@ -652,7 +653,7 @@ public:
this->LowerWidget(i); this->LowerWidget(i);
} }
this->filter.facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK; this->filter.facilities = {StationFacility::Train, StationFacility::TruckStop, StationFacility::BusStop, StationFacility::Airport, StationFacility::Dock};
this->stations.ForceRebuild(); this->stations.ForceRebuild();
this->SetDirty(); this->SetDirty();
break; break;
@ -1442,7 +1443,7 @@ struct StationViewWindow : public Window {
break; break;
case WID_SV_CLOSE_AIRPORT: case WID_SV_CLOSE_AIRPORT:
if (!(Station::Get(this->window_number)->facilities & FACIL_AIRPORT)) { if (!Station::Get(this->window_number)->facilities.Test(StationFacility::Airport)) {
/* Hide 'Close Airport' button if no airport present. */ /* Hide 'Close Airport' button if no airport present. */
size.width = 0; size.width = 0;
resize.width = 0; resize.width = 0;
@ -1462,15 +1463,15 @@ struct StationViewWindow : public Window {
/* disable some buttons */ /* disable some buttons */
this->SetWidgetDisabledState(WID_SV_RENAME, st->owner != _local_company); this->SetWidgetDisabledState(WID_SV_RENAME, st->owner != _local_company);
this->SetWidgetDisabledState(WID_SV_TRAINS, !(st->facilities & FACIL_TRAIN)); this->SetWidgetDisabledState(WID_SV_TRAINS, !st->facilities.Test(StationFacility::Train));
this->SetWidgetDisabledState(WID_SV_ROADVEHS, !(st->facilities & FACIL_TRUCK_STOP) && !(st->facilities & FACIL_BUS_STOP)); this->SetWidgetDisabledState(WID_SV_ROADVEHS, !st->facilities.Test(StationFacility::TruckStop) && !st->facilities.Test(StationFacility::BusStop));
this->SetWidgetDisabledState(WID_SV_SHIPS, !(st->facilities & FACIL_DOCK)); this->SetWidgetDisabledState(WID_SV_SHIPS, !st->facilities.Test(StationFacility::Dock));
this->SetWidgetDisabledState(WID_SV_PLANES, !(st->facilities & FACIL_AIRPORT)); this->SetWidgetDisabledState(WID_SV_PLANES, !st->facilities.Test(StationFacility::Airport));
this->SetWidgetDisabledState(WID_SV_CLOSE_AIRPORT, !(st->facilities & FACIL_AIRPORT) || st->owner != _local_company || st->owner == OWNER_NONE); // Also consider SE, where _local_company == OWNER_NONE this->SetWidgetDisabledState(WID_SV_CLOSE_AIRPORT, !st->facilities.Test(StationFacility::Airport) || st->owner != _local_company || st->owner == OWNER_NONE); // Also consider SE, where _local_company == OWNER_NONE
this->SetWidgetLoweredState(WID_SV_CLOSE_AIRPORT, (st->facilities & FACIL_AIRPORT) && (st->airport.flags & AIRPORT_CLOSED_block) != 0); this->SetWidgetLoweredState(WID_SV_CLOSE_AIRPORT, st->facilities.Test(StationFacility::Airport) && (st->airport.flags & AIRPORT_CLOSED_block) != 0);
extern const Station *_viewport_highlight_station; extern const Station *_viewport_highlight_station;
this->SetWidgetDisabledState(WID_SV_CATCHMENT, st->facilities == FACIL_NONE); this->SetWidgetDisabledState(WID_SV_CATCHMENT, st->facilities == StationFacilities{});
this->SetWidgetLoweredState(WID_SV_CATCHMENT, _viewport_highlight_station == st); this->SetWidgetLoweredState(WID_SV_CATCHMENT, _viewport_highlight_station == st);
this->DrawWidgets(); this->DrawWidgets();

View File

@ -51,19 +51,18 @@ enum class RoadStopType : uint8_t {
}; };
/** The facilities a station might be having */ /** The facilities a station might be having */
enum StationFacility : uint8_t { enum class StationFacility : uint8_t {
FACIL_NONE = 0, ///< The station has no facilities at all Train = 0, ///< Station with train station
FACIL_TRAIN = 1 << 0, ///< Station with train station TruckStop = 1, ///< Station with truck stops
FACIL_TRUCK_STOP = 1 << 1, ///< Station with truck stops BusStop = 2, ///< Station with bus stops
FACIL_BUS_STOP = 1 << 2, ///< Station with bus stops Airport = 3, ///< Station with an airport
FACIL_AIRPORT = 1 << 3, ///< Station with an airport Dock = 4, ///< Station with a dock
FACIL_DOCK = 1 << 4, ///< Station with a dock Waypoint = 7, ///< Station is a waypoint
FACIL_WAYPOINT = 1 << 7, ///< Station is a waypoint
}; };
DECLARE_ENUM_AS_BIT_SET(StationFacility) using StationFacilities = EnumBitSet<StationFacility, uint8_t>;
/** Fake 'facility' to allow toggling display of recently-removed station signs. */ /** Fake 'facility' to allow toggling display of recently-removed station signs. */
static constexpr StationFacility FACIL_GHOST{1U << 6}; static constexpr StationFacility STATION_FACILITY_GHOST{6};
/** The vehicles that may have visited a station */ /** The vehicles that may have visited a station */
enum StationHadVehicleOfType : uint8_t { enum StationHadVehicleOfType : uint8_t {

View File

@ -248,7 +248,7 @@ bool HaveDParamChanged(const std::span<const StringParameterData> backup)
return false; return false;
} }
static void StationGetSpecialString(StringBuilder &builder, StationFacility x); static void StationGetSpecialString(StringBuilder &builder, StationFacilities x);
static bool GetSpecialNameString(StringBuilder &builder, StringID string, StringParameters &args); static bool GetSpecialNameString(StringBuilder &builder, StringID string, StringParameters &args);
static void FormatString(StringBuilder &builder, const char *str, StringParameters &args, uint case_index = 0, bool game_script = false, bool dry_run = false); static void FormatString(StringBuilder &builder, const char *str, StringParameters &args, uint case_index = 0, bool game_script = false, bool dry_run = false);
@ -1824,7 +1824,7 @@ static void FormatString(StringBuilder &builder, const char *str_arg, StringPara
} }
case SCC_STATION_FEATURES: { // {STATIONFEATURES} case SCC_STATION_FEATURES: { // {STATIONFEATURES}
StationGetSpecialString(builder, args.GetNextParameter<StationFacility>()); StationGetSpecialString(builder, args.GetNextParameter<StationFacilities>());
break; break;
} }
@ -1846,13 +1846,13 @@ static void FormatString(StringBuilder &builder, const char *str_arg, StringPara
} }
static void StationGetSpecialString(StringBuilder &builder, StationFacility x) static void StationGetSpecialString(StringBuilder &builder, StationFacilities x)
{ {
if ((x & FACIL_TRAIN) != 0) builder.Utf8Encode(SCC_TRAIN); if (x.Test(StationFacility::Train)) builder.Utf8Encode(SCC_TRAIN);
if ((x & FACIL_TRUCK_STOP) != 0) builder.Utf8Encode(SCC_LORRY); if (x.Test(StationFacility::TruckStop)) builder.Utf8Encode(SCC_LORRY);
if ((x & FACIL_BUS_STOP) != 0) builder.Utf8Encode(SCC_BUS); if (x.Test(StationFacility::BusStop)) builder.Utf8Encode(SCC_BUS);
if ((x & FACIL_DOCK) != 0) builder.Utf8Encode(SCC_SHIP); if (x.Test(StationFacility::Dock)) builder.Utf8Encode(SCC_SHIP);
if ((x & FACIL_AIRPORT) != 0) builder.Utf8Encode(SCC_PLANE); if (x.Test(StationFacility::Airport)) builder.Utf8Encode(SCC_PLANE);
} }
static const char * const _silly_company_names[] = { static const char * const _silly_company_names[] = {

View File

@ -69,7 +69,7 @@ full = _display_opt_modes
name = ""facility_display_opt"" name = ""facility_display_opt""
type = SLE_UINT8 type = SLE_UINT8
var = _facility_display_opt var = _facility_display_opt
def = (FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK | FACIL_GHOST) def = StationFacilities({StationFacility::Train, StationFacility::TruckStop, StationFacility::BusStop, StationFacility::Airport, StationFacility::Dock, STATION_FACILITY_GHOST})
full = _facility_display_opt_modes full = _facility_display_opt_modes
[SDTG_BOOL] [SDTG_BOOL]

View File

@ -277,12 +277,12 @@ static CallBackFunction ToolbarOptionsClick(Window *w)
list.push_back(MakeDropDownListDividerItem()); list.push_back(MakeDropDownListDividerItem());
list.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt, DO_SHOW_TOWN_NAMES), STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED, OME_SHOW_TOWNNAMES)); list.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt, DO_SHOW_TOWN_NAMES), STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED, OME_SHOW_TOWNNAMES));
list.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt, DO_SHOW_STATION_NAMES), STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED, OME_SHOW_STATIONNAMES)); list.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt, DO_SHOW_STATION_NAMES), STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED, OME_SHOW_STATIONNAMES));
list.push_back(MakeDropDownListCheckedItem((_facility_display_opt & FACIL_TRAIN) != 0, STR_SETTINGS_MENU_STATION_NAMES_TRAIN, OME_SHOW_STATIONNAMES_TRAIN, false, false, 1)); list.push_back(MakeDropDownListCheckedItem(_facility_display_opt.Test(StationFacility::Train), STR_SETTINGS_MENU_STATION_NAMES_TRAIN, OME_SHOW_STATIONNAMES_TRAIN, false, false, 1));
list.push_back(MakeDropDownListCheckedItem((_facility_display_opt & FACIL_TRUCK_STOP) != 0, STR_SETTINGS_MENU_STATION_NAMES_LORRY, OME_SHOW_STATIONNAMES_LORRY, false, false, 1)); list.push_back(MakeDropDownListCheckedItem(_facility_display_opt.Test(StationFacility::TruckStop), STR_SETTINGS_MENU_STATION_NAMES_LORRY, OME_SHOW_STATIONNAMES_LORRY, false, false, 1));
list.push_back(MakeDropDownListCheckedItem((_facility_display_opt & FACIL_BUS_STOP) != 0, STR_SETTINGS_MENU_STATION_NAMES_BUS, OME_SHOW_STATIONNAMES_BUS, false, false, 1)); list.push_back(MakeDropDownListCheckedItem(_facility_display_opt.Test(StationFacility::BusStop), STR_SETTINGS_MENU_STATION_NAMES_BUS, OME_SHOW_STATIONNAMES_BUS, false, false, 1));
list.push_back(MakeDropDownListCheckedItem((_facility_display_opt & FACIL_DOCK) != 0, STR_SETTINGS_MENU_STATION_NAMES_SHIP, OME_SHOW_STATIONNAMES_SHIP, false, false, 1)); list.push_back(MakeDropDownListCheckedItem(_facility_display_opt.Test(StationFacility::Dock), STR_SETTINGS_MENU_STATION_NAMES_SHIP, OME_SHOW_STATIONNAMES_SHIP, false, false, 1));
list.push_back(MakeDropDownListCheckedItem((_facility_display_opt & FACIL_AIRPORT) != 0, STR_SETTINGS_MENU_STATION_NAMES_PLANE, OME_SHOW_STATIONNAMES_PLANE, false, false, 1)); list.push_back(MakeDropDownListCheckedItem(_facility_display_opt.Test(StationFacility::Airport), STR_SETTINGS_MENU_STATION_NAMES_PLANE, OME_SHOW_STATIONNAMES_PLANE, false, false, 1));
list.push_back(MakeDropDownListCheckedItem((_facility_display_opt & FACIL_GHOST) != 0, STR_SETTINGS_MENU_STATION_NAMES_GHOST, OME_SHOW_STATIONNAMES_GHOST, false, false, 1)); list.push_back(MakeDropDownListCheckedItem(_facility_display_opt.Test(STATION_FACILITY_GHOST), STR_SETTINGS_MENU_STATION_NAMES_GHOST, OME_SHOW_STATIONNAMES_GHOST, false, false, 1));
list.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES), STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED, OME_SHOW_WAYPOINTNAMES)); list.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES), STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED, OME_SHOW_WAYPOINTNAMES));
list.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt, DO_SHOW_SIGNS), STR_SETTINGS_MENU_SIGNS_DISPLAYED, OME_SHOW_SIGNS)); list.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt, DO_SHOW_SIGNS), STR_SETTINGS_MENU_SIGNS_DISPLAYED, OME_SHOW_SIGNS));
list.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS), STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS, OME_SHOW_COMPETITOR_SIGNS)); list.push_back(MakeDropDownListCheckedItem(HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS), STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS, OME_SHOW_COMPETITOR_SIGNS));
@ -296,19 +296,6 @@ static CallBackFunction ToolbarOptionsClick(Window *w)
return CBF_NONE; return CBF_NONE;
} }
/**
* Toggle display station names for a facility.
* @param facility Facility to toggle.
*/
static void ToggleFacilityDisplay(const uint8_t facility)
{
if ((_facility_display_opt & facility) == 0) {
SETBITS(_facility_display_opt, facility);
} else {
CLRBITS(_facility_display_opt, facility);
}
}
/** /**
* Handle click on one of the entries in the Options button menu. * Handle click on one of the entries in the Options button menu.
* *
@ -328,12 +315,12 @@ static CallBackFunction MenuClickSettings(int index)
case OME_SHOW_TOWNNAMES: ToggleBit(_display_opt, DO_SHOW_TOWN_NAMES); break; case OME_SHOW_TOWNNAMES: ToggleBit(_display_opt, DO_SHOW_TOWN_NAMES); break;
case OME_SHOW_STATIONNAMES: ToggleBit(_display_opt, DO_SHOW_STATION_NAMES); break; case OME_SHOW_STATIONNAMES: ToggleBit(_display_opt, DO_SHOW_STATION_NAMES); break;
case OME_SHOW_STATIONNAMES_TRAIN: ToggleFacilityDisplay(FACIL_TRAIN); break; case OME_SHOW_STATIONNAMES_TRAIN: _facility_display_opt.Flip(StationFacility::Train); break;
case OME_SHOW_STATIONNAMES_LORRY: ToggleFacilityDisplay(FACIL_TRUCK_STOP); break; case OME_SHOW_STATIONNAMES_LORRY: _facility_display_opt.Flip(StationFacility::TruckStop); break;
case OME_SHOW_STATIONNAMES_BUS: ToggleFacilityDisplay(FACIL_BUS_STOP); break; case OME_SHOW_STATIONNAMES_BUS: _facility_display_opt.Flip(StationFacility::BusStop); break;
case OME_SHOW_STATIONNAMES_SHIP: ToggleFacilityDisplay(FACIL_DOCK); break; case OME_SHOW_STATIONNAMES_SHIP: _facility_display_opt.Flip(StationFacility::Dock); break;
case OME_SHOW_STATIONNAMES_PLANE: ToggleFacilityDisplay(FACIL_AIRPORT); break; case OME_SHOW_STATIONNAMES_PLANE: _facility_display_opt.Flip(StationFacility::Airport); break;
case OME_SHOW_STATIONNAMES_GHOST: ToggleFacilityDisplay(FACIL_GHOST); break; case OME_SHOW_STATIONNAMES_GHOST: _facility_display_opt.Flip(STATION_FACILITY_GHOST); break;
case OME_SHOW_WAYPOINTNAMES: ToggleBit(_display_opt, DO_SHOW_WAYPOINT_NAMES); break; case OME_SHOW_WAYPOINTNAMES: ToggleBit(_display_opt, DO_SHOW_WAYPOINT_NAMES); break;
case OME_SHOW_SIGNS: ToggleBit(_display_opt, DO_SHOW_SIGNS); break; case OME_SHOW_SIGNS: ToggleBit(_display_opt, DO_SHOW_SIGNS); break;
case OME_SHOW_COMPETITOR_SIGNS: case OME_SHOW_COMPETITOR_SIGNS:

View File

@ -3251,7 +3251,7 @@ CommandCost CmdDeleteTown(DoCommandFlag flags, TownID town_id)
for (const Station *st : Station::Iterate()) { for (const Station *st : Station::Iterate()) {
if (st->town == t) { if (st->town == t) {
/* Non-oil rig stations are always a problem. */ /* Non-oil rig stations are always a problem. */
if (!(st->facilities & FACIL_AIRPORT) || st->airport.type != AT_OILRIG) return CMD_ERROR; if (!st->facilities.Test(StationFacility::Airport) || st->airport.type != AT_OILRIG) return CMD_ERROR;
/* We can only automatically delete oil rigs *if* there's no vehicle on them. */ /* We can only automatically delete oil rigs *if* there's no vehicle on them. */
CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, st->airport.tile); CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, st->airport.tile);
if (ret.Failed()) return ret; if (ret.Failed()) return ret;

View File

@ -2953,7 +2953,7 @@ TileIndex Train::GetOrderStationLocation(StationID station)
if (station == this->last_station_visited) this->last_station_visited = INVALID_STATION; if (station == this->last_station_visited) this->last_station_visited = INVALID_STATION;
const Station *st = Station::Get(station); const Station *st = Station::Get(station);
if (!(st->facilities & FACIL_TRAIN)) { if (!st->facilities.Test(StationFacility::Train)) {
/* The destination station has no trainstation tiles. */ /* The destination station has no trainstation tiles. */
this->IncrementRealOrderIndex(); this->IncrementRealOrderIndex();
return TileIndex{}; return TileIndex{};

View File

@ -13,6 +13,7 @@
#include "gfx_func.h" #include "gfx_func.h"
#include "openttd.h" #include "openttd.h"
#include "core/bitmath_func.hpp" #include "core/bitmath_func.hpp"
#include "station_type.h"
/** /**
* Transparency option bits: which position in _transparency_opt stands for which transparency. * Transparency option bits: which position in _transparency_opt stands for which transparency.
@ -38,7 +39,7 @@ extern TransparencyOptionBits _transparency_opt;
extern TransparencyOptionBits _transparency_lock; extern TransparencyOptionBits _transparency_lock;
extern TransparencyOptionBits _invisibility_opt; extern TransparencyOptionBits _invisibility_opt;
extern uint8_t _display_opt; extern uint8_t _display_opt;
extern uint8_t _facility_display_opt; extern StationFacilities _facility_display_opt;
/** /**
* Check if the transparency option bit is set * Check if the transparency option bit is set

View File

@ -24,7 +24,7 @@ TransparencyOptionBits _transparency_opt; ///< The bits that should be transpar
TransparencyOptionBits _transparency_lock; ///< Prevent these bits from flipping with X. TransparencyOptionBits _transparency_lock; ///< Prevent these bits from flipping with X.
TransparencyOptionBits _invisibility_opt; ///< The bits that should be invisible. TransparencyOptionBits _invisibility_opt; ///< The bits that should be invisible.
uint8_t _display_opt; ///< What do we want to draw/do? uint8_t _display_opt; ///< What do we want to draw/do?
uint8_t _facility_display_opt; ///< What station facilities to draw. StationFacilities _facility_display_opt; ///< What station facilities to draw.
class TransparenciesWindow : public Window class TransparenciesWindow : public Window
{ {

View File

@ -3062,19 +3062,19 @@ bool CanVehicleUseStation(EngineID engine_type, const Station *st)
switch (e->type) { switch (e->type) {
case VEH_TRAIN: case VEH_TRAIN:
return (st->facilities & FACIL_TRAIN) != 0; return st->facilities.Test(StationFacility::Train);
case VEH_ROAD: case VEH_ROAD:
/* For road vehicles we need the vehicle to know whether it can actually /* For road vehicles we need the vehicle to know whether it can actually
* use the station, but if it doesn't have facilities for RVs it is * use the station, but if it doesn't have facilities for RVs it is
* certainly not possible that the station can be used. */ * certainly not possible that the station can be used. */
return (st->facilities & (FACIL_BUS_STOP | FACIL_TRUCK_STOP)) != 0; return st->facilities.Any({StationFacility::BusStop, StationFacility::TruckStop});
case VEH_SHIP: case VEH_SHIP:
return (st->facilities & FACIL_DOCK) != 0; return st->facilities.Test(StationFacility::Dock);
case VEH_AIRCRAFT: case VEH_AIRCRAFT:
return (st->facilities & FACIL_AIRPORT) != 0 && return st->facilities.Test(StationFacility::Airport) &&
st->airport.GetFTA()->flags.Test(e->u.air.subtype & AIR_CTOL ? AirportFTAClass::Flag::Airplanes : AirportFTAClass::Flag::Helicopters); st->airport.GetFTA()->flags.Test(e->u.air.subtype & AIR_CTOL ? AirportFTAClass::Flag::Airplanes : AirportFTAClass::Flag::Helicopters);
default: default:
@ -3135,7 +3135,7 @@ StringID GetVehicleCannotUseStationReason(const Vehicle *v, const Station *st)
return STR_ERROR_NO_DOCK; return STR_ERROR_NO_DOCK;
case VEH_AIRCRAFT: case VEH_AIRCRAFT:
if ((st->facilities & FACIL_AIRPORT) == 0) return STR_ERROR_NO_AIRPORT; if (!st->facilities.Test(StationFacility::Airport)) return STR_ERROR_NO_AIRPORT;
if (v->GetEngine()->u.air.subtype & AIR_CTOL) { if (v->GetEngine()->u.air.subtype & AIR_CTOL) {
return STR_ERROR_AIRPORT_NO_PLANES; return STR_ERROR_AIRPORT_NO_PLANES;
} else { } else {

View File

@ -1450,10 +1450,10 @@ static void ViewportAddKdtreeSigns(DrawPixelInfo *dpi)
const BaseStation *st = BaseStation::Get(std::get<StationID>(item.id)); const BaseStation *st = BaseStation::Get(std::get<StationID>(item.id));
/* If no facilities are present the station is a ghost station. */ /* If no facilities are present the station is a ghost station. */
StationFacility facilities = st->facilities; StationFacilities facilities = st->facilities;
if (facilities == FACIL_NONE) facilities = FACIL_GHOST; if (facilities == StationFacilities{}) facilities = STATION_FACILITY_GHOST;
if ((_facility_display_opt & facilities) == 0) break; if (!facilities.Any(_facility_display_opt)) break;
/* Don't draw if station is owned by another company and competitor station names are hidden. Stations owned by none are never ignored. */ /* Don't draw if station is owned by another company and competitor station names are hidden. Stations owned by none are never ignored. */
if (!show_competitors && _local_company != st->owner && st->owner != OWNER_NONE) break; if (!show_competitors && _local_company != st->owner && st->owner != OWNER_NONE) break;

View File

@ -61,7 +61,7 @@ struct Waypoint final : SpecializedStation<Waypoint, true> {
*/ */
inline bool IsSingleTile() const inline bool IsSingleTile() const
{ {
return (this->facilities & FACIL_TRAIN) != 0 && this->train_station.w == 1 && this->train_station.h == 1; return this->facilities.Test(StationFacility::Train) && this->train_station.w == 1 && this->train_station.h == 1;
} }
/** /**

View File

@ -276,7 +276,7 @@ CommandCost CmdBuildRailWaypoint(DoCommandFlag flags, TileIndex start_tile, Axis
wp->rect.BeforeAddRect(start_tile, width, height, StationRect::ADD_TRY); wp->rect.BeforeAddRect(start_tile, width, height, StationRect::ADD_TRY);
wp->delete_ctr = 0; wp->delete_ctr = 0;
wp->facilities |= FACIL_TRAIN; wp->facilities.Set(StationFacility::Train);
wp->build_date = TimerGameCalendar::date; wp->build_date = TimerGameCalendar::date;
wp->string_id = STR_SV_STNAME_WAYPOINT; wp->string_id = STR_SV_STNAME_WAYPOINT;
wp->train_station = new_location; wp->train_station = new_location;
@ -409,7 +409,7 @@ CommandCost CmdBuildRoadWaypoint(DoCommandFlag flags, TileIndex start_tile, Axis
} }
wp->delete_ctr = 0; wp->delete_ctr = 0;
wp->facilities |= FACIL_BUS_STOP | FACIL_TRUCK_STOP; wp->facilities.Set(StationFacility::BusStop).Set(StationFacility::TruckStop);
wp->build_date = TimerGameCalendar::date; wp->build_date = TimerGameCalendar::date;
wp->string_id = STR_SV_STNAME_WAYPOINT; wp->string_id = STR_SV_STNAME_WAYPOINT;
@ -494,7 +494,7 @@ CommandCost CmdBuildBuoy(DoCommandFlag flags, TileIndex tile)
wp->string_id = STR_SV_STNAME_BUOY; wp->string_id = STR_SV_STNAME_BUOY;
wp->facilities |= FACIL_DOCK; wp->facilities.Set(StationFacility::Dock);
wp->owner = OWNER_NONE; wp->owner = OWNER_NONE;
wp->build_date = TimerGameCalendar::date; wp->build_date = TimerGameCalendar::date;
@ -535,7 +535,7 @@ CommandCost RemoveBuoy(TileIndex tile, DoCommandFlag flags)
} }
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
wp->facilities &= ~FACIL_DOCK; wp->facilities.Reset(StationFacility::Dock);
InvalidateWindowData(WC_WAYPOINT_VIEW, wp->index); InvalidateWindowData(WC_WAYPOINT_VIEW, wp->index);