diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 05d6d4c055..89bb0ad4d1 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -144,7 +144,7 @@ static StationID FindNearestHangar(const Aircraft *v) } 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(); diff --git a/src/base_station_base.h b/src/base_station_base.h index 585dfc6fd0..91c37a942f 100644 --- a/src/base_station_base.h +++ b/src/base_station_base.h @@ -66,7 +66,7 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> { Town *town; ///< The town this station is associated with 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> speclist; ///< List of rail station specs of this station. std::vector> roadstop_speclist; ///< List of road stop specs of this station @@ -175,7 +175,7 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> { */ 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 @@ -214,7 +214,7 @@ private: */ template 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 @@ -233,7 +233,7 @@ struct SpecializedStation : public BaseStation { */ static inline bool IsExpected(const BaseStation *st) { - return (st->facilities & FACIL_WAYPOINT) == EXPECTED_FACIL; + return st->facilities.Test(StationFacility::Waypoint) == Tis_waypoint; } /** diff --git a/src/economy.cpp b/src/economy.cpp index ea9b094fb2..d0b3cd905a 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -118,7 +118,7 @@ static Money CalculateCompanyAssetValue(const Company *c) uint num = 0; 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; @@ -239,7 +239,7 @@ int UpdateCompanyRatingAndValue(Company *c, bool update) uint num = 0; for (const Station *st : Station::Iterate()) { /* 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; } diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 236f2718d2..90b4c12da0 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -1512,11 +1512,11 @@ void NetworkPopulateCompanyStats(NetworkCompanyStats *stats) if (Company::IsValidID(s->owner)) { NetworkCompanyStats *npi = &stats[s->owner]; - if (s->facilities & FACIL_TRAIN) npi->num_station[NETWORK_VEH_TRAIN]++; - if (s->facilities & FACIL_TRUCK_STOP) npi->num_station[NETWORK_VEH_LORRY]++; - if (s->facilities & FACIL_BUS_STOP) npi->num_station[NETWORK_VEH_BUS]++; - if (s->facilities & FACIL_AIRPORT) npi->num_station[NETWORK_VEH_PLANE]++; - if (s->facilities & FACIL_DOCK) npi->num_station[NETWORK_VEH_SHIP]++; + if (s->facilities.Test(StationFacility::Train)) npi->num_station[NETWORK_VEH_TRAIN]++; + if (s->facilities.Test(StationFacility::TruckStop)) npi->num_station[NETWORK_VEH_LORRY]++; + if (s->facilities.Test(StationFacility::BusStop)) npi->num_station[NETWORK_VEH_BUS]++; + if (s->facilities.Test(StationFacility::Airport)) npi->num_station[NETWORK_VEH_PLANE]++; + if (s->facilities.Test(StationFacility::Dock)) npi->num_station[NETWORK_VEH_SHIP]++; } } } diff --git a/src/newgrf_airport.cpp b/src/newgrf_airport.cpp index d5dfbfa308..729791d6a8 100644 --- a/src/newgrf_airport.cpp +++ b/src/newgrf_airport.cpp @@ -169,7 +169,7 @@ void AirportOverrideManager::SetEntitySpec(AirportSpec *as) /* Get a variable from the persistent storage */ 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(this->st->build_date - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR); } diff --git a/src/newgrf_roadstop.cpp b/src/newgrf_roadstop.cpp index 4014fabfc9..d858fdb7a5 100644 --- a/src/newgrf_roadstop.cpp +++ b/src/newgrf_roadstop.cpp @@ -200,7 +200,7 @@ uint32_t RoadStopScopeResolver::GetVariable(uint8_t variable, [[maybe_unused]] u 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((this->st == nullptr ? TimerGameCalendar::date : this->st->build_date) - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR); // build date } diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index 3fb2d6ac82..8ae8e1e8af 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -397,7 +397,7 @@ TownScopeResolver *StationResolverObject::GetTown() case 0x82: return 50; case 0x84: return this->st->string_id; case 0x86: return 0; - case 0xF0: return this->st->facilities; + case 0xF0: return this->st->facilities.base(); case 0xFA: return ClampTo(this->st->build_date - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR); } diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 408862b5f7..6662c26970 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -809,7 +809,7 @@ CommandCost CmdInsertOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID se default: return CMD_ERROR; 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); if (ret.Failed()) return ret; @@ -817,7 +817,7 @@ CommandCost CmdInsertOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID se } 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); if (ret.Failed()) return ret; @@ -825,7 +825,7 @@ CommandCost CmdInsertOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID se } 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) { ret = CheckOwnership(wp->owner); if (ret.Failed()) return ret; diff --git a/src/order_gui.cpp b/src/order_gui.cpp index dd7d9e6003..026aced011 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -453,15 +453,15 @@ static Order GetOrderCmdFromTile(const Vehicle *v, TileIndex tile) st = in->neutral_station; } if (st != nullptr && (st->owner == _local_company || st->owner == OWNER_NONE)) { - uint8_t facil; + StationFacilities facil; switch (v->type) { - case VEH_SHIP: facil = FACIL_DOCK; break; - case VEH_TRAIN: facil = FACIL_TRAIN; break; - case VEH_AIRCRAFT: facil = FACIL_AIRPORT; break; - case VEH_ROAD: facil = FACIL_BUS_STOP | FACIL_TRUCK_STOP; break; + case VEH_SHIP: facil = StationFacility::Dock; break; + case VEH_TRAIN: facil = StationFacility::Train; break; + case VEH_AIRCRAFT: facil = StationFacility::Airport; break; + case VEH_ROAD: facil = {StationFacility::BusStop, StationFacility::TruckStop}; break; default: NOT_REACHED(); } - if (st->facilities & facil) { + if (st->facilities.Any(facil)) { order.MakeGoToStation(st->index); 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); diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 0d7cc3531a..5d76d63080 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -1253,8 +1253,8 @@ public: { for (const Station *st : Station::Iterate()) { if (st->owner != _local_company) continue; - if (roadstoptype == RoadStopType::Truck && !(st->facilities & FACIL_TRUCK_STOP)) continue; - if (roadstoptype == RoadStopType::Bus && !(st->facilities & FACIL_BUS_STOP)) continue; + if (roadstoptype == RoadStopType::Truck && !st->facilities.Test(StationFacility::TruckStop)) 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. for (const auto &sm : st->roadstop_speclist) { if (sm.spec == nullptr) continue; diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index f951ae7752..bb15939789 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -1603,7 +1603,7 @@ bool AfterLoadGame() * be OWNER_NONE. So replace OWNER_NONE with OWNER_WATER. */ if (IsSavegameVersionBefore(SLV_46)) { 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)) { /* The train station tile area was added, but for really old (TTDPatch) it's already valid. */ 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.w = 1; wp->train_station.h = 1; @@ -2828,7 +2828,7 @@ bool AfterLoadGame() if (!IsSavegameVersionBefore(SLV_145)) { for (Station *st : Station::Iterate()) { - if (!(st->facilities & FACIL_AIRPORT)) continue; + if (!st->facilities.Test(StationFacility::Airport)) continue; assert(st->airport.psa != nullptr); /* Check if the old storage was empty. */ diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index 50c65469d1..d7ab309a94 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -100,7 +100,7 @@ void AfterLoadCompanyStats() /* Collect airport count. */ 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++; } } diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index 7d323a87ad..5b5c26d522 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -100,10 +100,10 @@ void MoveBuoysToWaypoints() } wp->train_station = train_st; - wp->facilities |= FACIL_TRAIN; + wp->facilities.Set(StationFacility::Train); } else if (IsBuoyTile(xy) && GetStationIndex(xy) == index) { 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); /* 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. */ assert(PersistentStorage::CanAllocateItem()); st->airport.psa = new PersistentStorage(0, 0, TileIndex{}); @@ -629,19 +629,19 @@ public: void Save(BaseStation *bst) const override { - if ((bst->facilities & FACIL_WAYPOINT) != 0) return; + if (bst->facilities.Test(StationFacility::Waypoint)) return; SlObject(bst, this->GetDescription()); } void Load(BaseStation *bst) const override { - if ((bst->facilities & FACIL_WAYPOINT) != 0) return; + if (bst->facilities.Test(StationFacility::Waypoint)) return; SlObject(bst, this->GetLoadDescription()); } void FixPointers(BaseStation *bst) const override { - if ((bst->facilities & FACIL_WAYPOINT) != 0) return; + if (bst->facilities.Test(StationFacility::Waypoint)) return; SlObject(bst, this->GetDescription()); } }; @@ -664,19 +664,19 @@ public: void Save(BaseStation *bst) const override { - if ((bst->facilities & FACIL_WAYPOINT) == 0) return; + if (!bst->facilities.Test(StationFacility::Waypoint)) return; SlObject(bst, this->GetDescription()); } void Load(BaseStation *bst) const override { - if ((bst->facilities & FACIL_WAYPOINT) == 0) return; + if (!bst->facilities.Test(StationFacility::Waypoint)) return; SlObject(bst, this->GetLoadDescription()); } void FixPointers(BaseStation *bst) const override { - if ((bst->facilities & FACIL_WAYPOINT) == 0) return; + if (!bst->facilities.Test(StationFacility::Waypoint)) return; SlObject(bst, this->GetDescription()); } }; @@ -713,7 +713,7 @@ struct STNNChunkHandler : ChunkHandler { int index; while ((index = SlIterateArray()) != -1) { - bool waypoint = (SlReadByte() & FACIL_WAYPOINT) != 0; + bool waypoint = static_cast(SlReadByte()).Test(StationFacility::Waypoint); BaseStation *bst = waypoint ? (BaseStation *)new (index) Waypoint() : new (index) Station(); SlObject(bst, slt); diff --git a/src/saveload/waypoint_sl.cpp b/src/saveload/waypoint_sl.cpp index 859151f52a..676d162195 100644 --- a/src/saveload/waypoint_sl.cpp +++ b/src/saveload/waypoint_sl.cpp @@ -131,7 +131,7 @@ void MoveWaypointsToBaseStations() /* 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)); - new_wp->facilities |= FACIL_TRAIN; + new_wp->facilities.Set(StationFacility::Train); new_wp->owner = GetTileOwner(tile); SetRailStationReservation(tile, reserved); diff --git a/src/script/api/script_airport.cpp b/src/script/api/script_airport.cpp index 11817485ce..683e9af291 100644 --- a/src/script/api/script_airport.cpp +++ b/src/script/api/script_airport.cpp @@ -97,7 +97,7 @@ const Station *st = ::Station::GetByTile(tile); 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(); } @@ -111,7 +111,7 @@ const Station *st = ::Station::GetByTile(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); } diff --git a/src/script/api/script_station.cpp b/src/script/api/script_station.cpp index 3872fe667f..c65678e75e 100644 --- a/src/script/api/script_station.cpp +++ b/src/script/api/script_station.cpp @@ -209,7 +209,7 @@ template if (!IsValidStation(station_id)) return false; if (!HasExactlyOneBit(station_type)) return false; - return (::Station::Get(station_id)->facilities & static_cast(station_type)) != 0; + return ::Station::Get(station_id)->facilities.Any(static_cast(station_type)); } /* static */ bool ScriptStation::HasRoadType(StationID station_id, ScriptRoad::RoadType road_type) diff --git a/src/script/api/script_station.hpp b/src/script/api/script_station.hpp index 385da29bd8..b9b95bc467 100644 --- a/src/script/api/script_station.hpp +++ b/src/script/api/script_station.hpp @@ -43,12 +43,12 @@ public: * Type of stations known in the game. */ enum StationType { - /* Note: these values represent part of the in-game StationFacility enum */ - STATION_TRAIN = (int)::FACIL_TRAIN, ///< Train station - STATION_TRUCK_STOP = (int)::FACIL_TRUCK_STOP, ///< Truck station - STATION_BUS_STOP = (int)::FACIL_BUS_STOP, ///< Bus station - STATION_AIRPORT = (int)::FACIL_AIRPORT, ///< Airport - STATION_DOCK = (int)::FACIL_DOCK, ///< Dock + /* Note: these values represent part of the in-game StationFacilities enum */ + STATION_TRAIN = (1 << to_underlying(::StationFacility::Train)), ///< Train station + STATION_TRUCK_STOP = (1 << to_underlying(::StationFacility::TruckStop)), ///< Truck station + STATION_BUS_STOP = (1 << to_underlying(::StationFacility::BusStop)), ///< Bus station + STATION_AIRPORT = (1 << to_underlying(::StationFacility::Airport)), ///< Airport + 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 }; diff --git a/src/script/api/script_stationlist.cpp b/src/script/api/script_stationlist.cpp index 1d431e2ef5..fba73187f7 100644 --- a/src/script/api/script_stationlist.cpp +++ b/src/script/api/script_stationlist.cpp @@ -23,7 +23,7 @@ ScriptStationList::ScriptStationList(ScriptStation::StationType station_type) ::CompanyID owner = ScriptObject::GetCompany(); ScriptList::FillList(this, [is_deity, owner, station_type](const Station *st) { - return (is_deity || st->owner == owner) && (st->facilities & static_cast(station_type)) != 0; + return (is_deity || st->owner == owner) && st->facilities.Any(static_cast(station_type)); } ); } diff --git a/src/script/api/script_tilelist.cpp b/src/script/api/script_tilelist.cpp index cad5396695..5b80269e17 100644 --- a/src/script/api/script_tilelist.cpp +++ b/src/script/api/script_tilelist.cpp @@ -130,20 +130,20 @@ ScriptTileList_StationType::ScriptTileList_StationType(StationID station_id, Scr const StationRect *rect = &::Station::Get(station_id)->rect; - uint station_type_value = 0; + EnumBitSet station_types = {}; /* Convert ScriptStation::StationType to ::StationType, but do it in a * 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_TRUCK_STOP) != 0) station_type_value |= (1 << to_underlying(::StationType::Truck)); - if ((station_type & ScriptStation::STATION_BUS_STOP) != 0) station_type_value |= (1 << to_underlying(::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_DOCK) != 0) station_type_value |= (1 << to_underlying(::StationType::Dock)) | (1 << to_underlying(::StationType::Oilrig)); + if ((station_type & ScriptStation::STATION_TRAIN) != 0) station_types.Set(::StationType::Rail); + if ((station_type & ScriptStation::STATION_TRUCK_STOP) != 0) station_types.Set(::StationType::Truck); + if ((station_type & ScriptStation::STATION_BUS_STOP) != 0) station_types.Set(::StationType::Bus); + if ((station_type & ScriptStation::STATION_AIRPORT) != 0) station_types.Set(::StationType::Airport).Set(::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()); for (TileIndex cur_tile : ta) { if (!::IsTileType(cur_tile, MP_STATION)) 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); } } diff --git a/src/script/api/script_town.cpp b/src/script/api/script_town.cpp index 6b253ad348..a2d9608692 100644 --- a/src/script/api/script_town.cpp +++ b/src/script/api/script_town.cpp @@ -376,7 +376,7 @@ int num = 0; 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); } diff --git a/src/script/api/script_waypoint.cpp b/src/script/api/script_waypoint.cpp index 8de6bb12a2..168d85ac94 100644 --- a/src/script/api/script_waypoint.cpp +++ b/src/script/api/script_waypoint.cpp @@ -33,5 +33,5 @@ if (!IsValidWaypoint(waypoint_id)) return false; if (!HasExactlyOneBit(waypoint_type)) return false; - return (::Waypoint::Get(waypoint_id)->facilities & static_cast(waypoint_type)) != 0; + return ::Waypoint::Get(waypoint_id)->facilities.Any(static_cast(waypoint_type)); } diff --git a/src/script/api/script_waypoint.hpp b/src/script/api/script_waypoint.hpp index 79220544fc..5b8f0b65f9 100644 --- a/src/script/api/script_waypoint.hpp +++ b/src/script/api/script_waypoint.hpp @@ -40,9 +40,9 @@ public: * Type of waypoints known in the game. */ enum WaypointType { - /* Note: these values represent part of the in-game StationFacility enum */ - WAYPOINT_RAIL = (int)::FACIL_TRAIN, ///< Rail waypoint - WAYPOINT_BUOY = (int)::FACIL_DOCK, ///< Buoy + /* Note: these values represent part of the in-game StationFacilities enum */ + WAYPOINT_RAIL = (1U << to_underlying(::StationFacility::Train)), ///< Rail waypoint + WAYPOINT_BUOY = (1U << to_underlying(::StationFacility::Dock)), ///< Buoy WAYPOINT_ANY = WAYPOINT_RAIL | WAYPOINT_BUOY, ///< All waypoint types }; diff --git a/src/script/api/script_waypointlist.cpp b/src/script/api/script_waypointlist.cpp index 64d0728f66..4d51825368 100644 --- a/src/script/api/script_waypointlist.cpp +++ b/src/script/api/script_waypointlist.cpp @@ -23,7 +23,7 @@ ScriptWaypointList::ScriptWaypointList(ScriptWaypoint::WaypointType waypoint_typ ::CompanyID owner = ScriptObject::GetCompany(); ScriptList::FillList(this, [is_deity, owner, waypoint_type](const Waypoint *wp) { - return (is_deity || wp->owner == owner || wp->owner == OWNER_NONE) && (wp->facilities & static_cast(waypoint_type)) != 0; + return (is_deity || wp->owner == owner || wp->owner == OWNER_NONE) && wp->facilities.Any(static_cast(waypoint_type)); } ); } diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index 96f829735e..b1698d5e9e 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -776,7 +776,7 @@ static void ShipController(Ship *v) Station *st = Station::Get(v->current_order.GetDestination().ToStationID()); if (st->docking_station.Contains(gp.new_tile) && IsShipDestinationTile(gp.new_tile, 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); v->BeginLoading(); } else { // leave stations without docks right away diff --git a/src/station.cpp b/src/station.cpp index ba2049adfd..51443b28b9 100644 --- a/src/station.cpp +++ b/src/station.cpp @@ -228,11 +228,11 @@ RoadStop *Station::GetPrimaryRoadStop(const RoadVehicle *v) const */ void Station::AddFacility(StationFacility new_facility_bit, TileIndex facil_xy) { - if (this->facilities == FACIL_NONE) { + if (this->facilities == StationFacilities{}) { this->MoveSign(facil_xy); this->random_bits = Random(); } - this->facilities |= new_facility_bit; + this->facilities.Set(new_facility_bit); this->owner = _current_company; this->build_date = TimerGameCalendar::date; SetWindowClassesDirty(WC_VEHICLE_ORDERS); @@ -714,7 +714,7 @@ Money AirportMaintenanceCost(Owner owner) Money total_cost = 0; 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; } } diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 550564a9bd..2e41bf7455 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -444,7 +444,7 @@ void Station::UpdateVirtCoord() Point pt = RemapCoords2(TileX(this->xy) * TILE_SIZE, TileY(this->xy) * TILE_SIZE); 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)); @@ -637,8 +637,8 @@ void UpdateStationAcceptance(Station *st, bool show_msg) /* Make sure the station can accept the goods type. */ bool is_passengers = IsCargoInClass(i, CargoClass::Passengers); - if ((!is_passengers && !(st->facilities & ~FACIL_BUS_STOP)) || - (is_passengers && !(st->facilities & ~FACIL_TRUCK_STOP))) { + if ((!is_passengers && !st->facilities.Any({StationFacility::Train, StationFacility::TruckStop, StationFacility::Airport, StationFacility::Dock})) || + (is_passengers && !st->facilities.Any({StationFacility::Train, StationFacility::BusStop, StationFacility::Airport, StationFacility::Dock}))) { amt = 0; } @@ -1414,7 +1414,7 @@ CommandCost CmdBuildRailStation(DoCommandFlag flags, TileIndex tile_org, RailTyp if (flags & DC_EXEC) { 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); @@ -1722,7 +1722,7 @@ CommandCost RemoveFromRailBaseStation(TileArea ta, std::vector &affected_st /* if we deleted the whole station, delete the train facility. */ if (st->train_station.tile == INVALID_TILE) { - st->facilities &= ~FACIL_TRAIN; + st->facilities.Reset(StationFacility::Train); SetWindowClassesDirty(WC_VEHICLE_ORDERS); SetWindowWidgetDirty(WC_STATION_VIEW, st->index, WID_SV_TRAINS); MarkCatchmentTilesDirty(); @@ -2067,7 +2067,7 @@ CommandCost CmdBuildRoadStop(DoCommandFlag flags, TileIndex tile, uint8_t width, } /* 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); @@ -2175,7 +2175,7 @@ static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags, int repla *primary_stop = cur_stop->next; /* removed the only stop? */ 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); } } else { @@ -2294,7 +2294,7 @@ CommandCost RemoveRoadWaypointStop(TileIndex tile, DoCommandFlag flags, int repl /* if we deleted the whole waypoint, delete the road facility. */ 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); wp->UpdateVirtCoord(); DeleteStationIfEmpty(wp); @@ -2571,7 +2571,7 @@ CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, uint8_t airport Town *t = ClosestTownFromTile(tile, UINT_MAX); uint num = 0; 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) { 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 */ nearest->noise_reached += newnoise_level; - st->AddFacility(FACIL_AIRPORT, tile); + st->AddFacility(StationFacility::Airport, tile); st->airport.type = airport_type; st->airport.layout = layout; st->airport.flags = 0; @@ -2709,7 +2709,7 @@ static CommandCost RemoveAirport(TileIndex tile, DoCommandFlag flags) st->rect.AfterRemoveRect(st, st->airport); st->airport.Clear(); - st->facilities &= ~FACIL_AIRPORT; + st->facilities.Reset(StationFacility::Airport); SetWindowClassesDirty(WC_VEHICLE_ORDERS); 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; 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); if (ret.Failed()) return ret; @@ -2850,7 +2850,7 @@ CommandCost CmdBuildDock(DoCommandFlag flags, TileIndex tile, StationID station_ st->ship_station.Add(tile); TileIndex flat_tile = tile + TileOffsByDiagDir(direction); 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); @@ -2965,7 +2965,7 @@ static CommandCost RemoveDock(TileIndex tile, DoCommandFlag flags) if (st->ship_station.tile == INVALID_TILE) { st->ship_station.Clear(); st->docking_station.Clear(); - st->facilities &= ~FACIL_DOCK; + st->facilities.Reset(StationFacility::Dock); 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 * the ship to the next order (or, if there is none, make it * 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)); } } @@ -3690,7 +3690,7 @@ static bool ClickTile_Station(TileIndex tile) { const BaseStation *bst = BaseStation::GetByTile(tile); - if (bst->facilities & FACIL_WAYPOINT) { + if (bst->facilities.Test(StationFacility::Waypoint)) { ShowWaypointWindow(Waypoint::From(bst)); } else if (IsHangar(tile)) { 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; } @@ -4186,7 +4186,7 @@ void IncreaseStats(Station *st, const Vehicle *front, StationID next_station_id, /* called for every station each tick */ 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; 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)) { /* 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 { /* 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; } @@ -4526,7 +4526,7 @@ void BuildOilRig(TileIndex tile) st->airport.type = AT_OILRIG; st->airport.Add(tile); st->ship_station.Add(tile); - st->facilities = FACIL_AIRPORT | FACIL_DOCK; + st->facilities = {StationFacility::Airport, StationFacility::Dock}; st->build_date = TimerGameCalendar::date; UpdateStationDockingTiles(st); @@ -4557,7 +4557,8 @@ void DeleteOilRig(TileIndex tile) MakeWaterKeepingClass(tile, OWNER_NONE); /* 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) { /* Don't leave dangling neutral station pointer */ 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) { + if (IsAnyRoadStopTile(tile)) { for (RoadTramType rtt : _roadtramtypes) { /* Update all roadtypes, no matter if they are present */ diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 423a26a96e..89ef22b1a0 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -263,14 +263,14 @@ protected: /* Runtime saved values */ struct FilterState { 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. CargoTypes cargoes; ///< bitmap of cargo types to include }; static inline FilterState initial_state = { {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, ALL_CARGOTYPES, }; @@ -310,7 +310,7 @@ protected: this->stations_per_cargo_type_no_rating = 0; 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))) { bool has_rating = false; /* Add to the station/cargo counts. */ @@ -436,7 +436,7 @@ public: if (this->filter.cargoes == ALL_CARGOTYPES) this->filter.cargoes = _cargo_mask; 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(WID_STL_SORTDROPBTN)->SetString(CompanyStationsWindow::sorter_names[this->stations.SortType()]); @@ -634,13 +634,14 @@ public: case WID_STL_AIRPLANE: case WID_STL_SHIP: if (_ctrl_pressed) { - ToggleBit(this->filter.facilities, widget - WID_STL_TRAIN); + this->filter.facilities.Flip(static_cast(widget - WID_STL_TRAIN)); this->ToggleWidgetLoweredState(widget); } else { - for (uint i : SetBitIterator(this->filter.facilities)) { + for (uint i : SetBitIterator(this->filter.facilities.base())) { this->RaiseWidget(i + WID_STL_TRAIN); } - this->filter.facilities = 1 << (widget - WID_STL_TRAIN); + this->filter.facilities = {}; + this->filter.facilities.Set(static_cast(widget - WID_STL_TRAIN)); this->LowerWidget(widget); } this->stations.ForceRebuild(); @@ -652,7 +653,7 @@ public: 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->SetDirty(); break; @@ -1442,7 +1443,7 @@ struct StationViewWindow : public Window { break; 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. */ size.width = 0; resize.width = 0; @@ -1462,15 +1463,15 @@ struct StationViewWindow : public Window { /* disable some buttons */ this->SetWidgetDisabledState(WID_SV_RENAME, st->owner != _local_company); - this->SetWidgetDisabledState(WID_SV_TRAINS, !(st->facilities & FACIL_TRAIN)); - this->SetWidgetDisabledState(WID_SV_ROADVEHS, !(st->facilities & FACIL_TRUCK_STOP) && !(st->facilities & FACIL_BUS_STOP)); - this->SetWidgetDisabledState(WID_SV_SHIPS, !(st->facilities & FACIL_DOCK)); - this->SetWidgetDisabledState(WID_SV_PLANES, !(st->facilities & FACIL_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->SetWidgetLoweredState(WID_SV_CLOSE_AIRPORT, (st->facilities & FACIL_AIRPORT) && (st->airport.flags & AIRPORT_CLOSED_block) != 0); + this->SetWidgetDisabledState(WID_SV_TRAINS, !st->facilities.Test(StationFacility::Train)); + this->SetWidgetDisabledState(WID_SV_ROADVEHS, !st->facilities.Test(StationFacility::TruckStop) && !st->facilities.Test(StationFacility::BusStop)); + this->SetWidgetDisabledState(WID_SV_SHIPS, !st->facilities.Test(StationFacility::Dock)); + this->SetWidgetDisabledState(WID_SV_PLANES, !st->facilities.Test(StationFacility::Airport)); + 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.Test(StationFacility::Airport) && (st->airport.flags & AIRPORT_CLOSED_block) != 0); 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->DrawWidgets(); diff --git a/src/station_type.h b/src/station_type.h index b6438d2eb8..651f06b155 100644 --- a/src/station_type.h +++ b/src/station_type.h @@ -51,19 +51,18 @@ enum class RoadStopType : uint8_t { }; /** The facilities a station might be having */ -enum StationFacility : uint8_t { - FACIL_NONE = 0, ///< The station has no facilities at all - FACIL_TRAIN = 1 << 0, ///< Station with train station - FACIL_TRUCK_STOP = 1 << 1, ///< Station with truck stops - FACIL_BUS_STOP = 1 << 2, ///< Station with bus stops - FACIL_AIRPORT = 1 << 3, ///< Station with an airport - FACIL_DOCK = 1 << 4, ///< Station with a dock - FACIL_WAYPOINT = 1 << 7, ///< Station is a waypoint +enum class StationFacility : uint8_t { + Train = 0, ///< Station with train station + TruckStop = 1, ///< Station with truck stops + BusStop = 2, ///< Station with bus stops + Airport = 3, ///< Station with an airport + Dock = 4, ///< Station with a dock + Waypoint = 7, ///< Station is a waypoint }; -DECLARE_ENUM_AS_BIT_SET(StationFacility) +using StationFacilities = EnumBitSet; /** 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 */ enum StationHadVehicleOfType : uint8_t { diff --git a/src/strings.cpp b/src/strings.cpp index 7979ab984d..74b96a804c 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -248,7 +248,7 @@ bool HaveDParamChanged(const std::span backup) 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 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} - StationGetSpecialString(builder, args.GetNextParameter()); + StationGetSpecialString(builder, args.GetNextParameter()); 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 & FACIL_TRUCK_STOP) != 0) builder.Utf8Encode(SCC_LORRY); - if ((x & FACIL_BUS_STOP) != 0) builder.Utf8Encode(SCC_BUS); - if ((x & FACIL_DOCK) != 0) builder.Utf8Encode(SCC_SHIP); - if ((x & FACIL_AIRPORT) != 0) builder.Utf8Encode(SCC_PLANE); + if (x.Test(StationFacility::Train)) builder.Utf8Encode(SCC_TRAIN); + if (x.Test(StationFacility::TruckStop)) builder.Utf8Encode(SCC_LORRY); + if (x.Test(StationFacility::BusStop)) builder.Utf8Encode(SCC_BUS); + if (x.Test(StationFacility::Dock)) builder.Utf8Encode(SCC_SHIP); + if (x.Test(StationFacility::Airport)) builder.Utf8Encode(SCC_PLANE); } static const char * const _silly_company_names[] = { diff --git a/src/table/settings/misc_settings.ini b/src/table/settings/misc_settings.ini index 1d5e5d244a..630ff5fef2 100644 --- a/src/table/settings/misc_settings.ini +++ b/src/table/settings/misc_settings.ini @@ -69,7 +69,7 @@ full = _display_opt_modes name = ""facility_display_opt"" type = SLE_UINT8 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 [SDTG_BOOL] diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index 313a5b6e5f..44cbe713bc 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -277,12 +277,12 @@ static CallBackFunction ToolbarOptionsClick(Window *w) 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_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 & FACIL_TRUCK_STOP) != 0, 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 & FACIL_DOCK) != 0, 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 & FACIL_GHOST) != 0, STR_SETTINGS_MENU_STATION_NAMES_GHOST, OME_SHOW_STATIONNAMES_GHOST, 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.Test(StationFacility::TruckStop), STR_SETTINGS_MENU_STATION_NAMES_LORRY, OME_SHOW_STATIONNAMES_LORRY, 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.Test(StationFacility::Dock), STR_SETTINGS_MENU_STATION_NAMES_SHIP, OME_SHOW_STATIONNAMES_SHIP, 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.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_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)); @@ -296,19 +296,6 @@ static CallBackFunction ToolbarOptionsClick(Window *w) 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. * @@ -328,12 +315,12 @@ static CallBackFunction MenuClickSettings(int index) 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_TRAIN: ToggleFacilityDisplay(FACIL_TRAIN); break; - case OME_SHOW_STATIONNAMES_LORRY: ToggleFacilityDisplay(FACIL_TRUCK_STOP); break; - case OME_SHOW_STATIONNAMES_BUS: ToggleFacilityDisplay(FACIL_BUS_STOP); break; - case OME_SHOW_STATIONNAMES_SHIP: ToggleFacilityDisplay(FACIL_DOCK); break; - case OME_SHOW_STATIONNAMES_PLANE: ToggleFacilityDisplay(FACIL_AIRPORT); break; - case OME_SHOW_STATIONNAMES_GHOST: ToggleFacilityDisplay(FACIL_GHOST); break; + case OME_SHOW_STATIONNAMES_TRAIN: _facility_display_opt.Flip(StationFacility::Train); break; + case OME_SHOW_STATIONNAMES_LORRY: _facility_display_opt.Flip(StationFacility::TruckStop); break; + case OME_SHOW_STATIONNAMES_BUS: _facility_display_opt.Flip(StationFacility::BusStop); break; + case OME_SHOW_STATIONNAMES_SHIP: _facility_display_opt.Flip(StationFacility::Dock); break; + case OME_SHOW_STATIONNAMES_PLANE: _facility_display_opt.Flip(StationFacility::Airport); 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_SIGNS: ToggleBit(_display_opt, DO_SHOW_SIGNS); break; case OME_SHOW_COMPETITOR_SIGNS: diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index abd578ed96..8badb0129d 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -3251,7 +3251,7 @@ CommandCost CmdDeleteTown(DoCommandFlag flags, TownID town_id) for (const Station *st : Station::Iterate()) { if (st->town == t) { /* 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. */ CommandCost ret = Command::Do(flags, st->airport.tile); if (ret.Failed()) return ret; diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index e4fc0261ad..ef7eba72d6 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -2953,7 +2953,7 @@ TileIndex Train::GetOrderStationLocation(StationID station) if (station == this->last_station_visited) this->last_station_visited = INVALID_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. */ this->IncrementRealOrderIndex(); return TileIndex{}; diff --git a/src/transparency.h b/src/transparency.h index 0ebd90475d..68e6860d73 100644 --- a/src/transparency.h +++ b/src/transparency.h @@ -13,6 +13,7 @@ #include "gfx_func.h" #include "openttd.h" #include "core/bitmath_func.hpp" +#include "station_type.h" /** * 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 _invisibility_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 diff --git a/src/transparency_gui.cpp b/src/transparency_gui.cpp index 4afa8330ae..4591a610c8 100644 --- a/src/transparency_gui.cpp +++ b/src/transparency_gui.cpp @@ -24,7 +24,7 @@ TransparencyOptionBits _transparency_opt; ///< The bits that should be transpar TransparencyOptionBits _transparency_lock; ///< Prevent these bits from flipping with X. TransparencyOptionBits _invisibility_opt; ///< The bits that should be invisible. 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 { diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 9929084052..6b6c1a4af7 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -3062,19 +3062,19 @@ bool CanVehicleUseStation(EngineID engine_type, const Station *st) switch (e->type) { case VEH_TRAIN: - return (st->facilities & FACIL_TRAIN) != 0; + return st->facilities.Test(StationFacility::Train); case VEH_ROAD: /* 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 * 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: - return (st->facilities & FACIL_DOCK) != 0; + return st->facilities.Test(StationFacility::Dock); 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); default: @@ -3135,7 +3135,7 @@ StringID GetVehicleCannotUseStationReason(const Vehicle *v, const Station *st) return STR_ERROR_NO_DOCK; 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) { return STR_ERROR_AIRPORT_NO_PLANES; } else { diff --git a/src/viewport.cpp b/src/viewport.cpp index 8785ded2dc..1799e2e0d3 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -1450,10 +1450,10 @@ static void ViewportAddKdtreeSigns(DrawPixelInfo *dpi) const BaseStation *st = BaseStation::Get(std::get(item.id)); /* If no facilities are present the station is a ghost station. */ - StationFacility facilities = st->facilities; - if (facilities == FACIL_NONE) facilities = FACIL_GHOST; + StationFacilities facilities = st->facilities; + 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. */ if (!show_competitors && _local_company != st->owner && st->owner != OWNER_NONE) break; diff --git a/src/waypoint_base.h b/src/waypoint_base.h index 45ec17c00d..3369f0ea9b 100644 --- a/src/waypoint_base.h +++ b/src/waypoint_base.h @@ -61,7 +61,7 @@ struct Waypoint final : SpecializedStation { */ 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; } /** diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index e216a89caf..7ac1a7df3d 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -276,7 +276,7 @@ CommandCost CmdBuildRailWaypoint(DoCommandFlag flags, TileIndex start_tile, Axis wp->rect.BeforeAddRect(start_tile, width, height, StationRect::ADD_TRY); wp->delete_ctr = 0; - wp->facilities |= FACIL_TRAIN; + wp->facilities.Set(StationFacility::Train); wp->build_date = TimerGameCalendar::date; wp->string_id = STR_SV_STNAME_WAYPOINT; wp->train_station = new_location; @@ -409,7 +409,7 @@ CommandCost CmdBuildRoadWaypoint(DoCommandFlag flags, TileIndex start_tile, Axis } 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->string_id = STR_SV_STNAME_WAYPOINT; @@ -494,7 +494,7 @@ CommandCost CmdBuildBuoy(DoCommandFlag flags, TileIndex tile) wp->string_id = STR_SV_STNAME_BUOY; - wp->facilities |= FACIL_DOCK; + wp->facilities.Set(StationFacility::Dock); wp->owner = OWNER_NONE; wp->build_date = TimerGameCalendar::date; @@ -535,7 +535,7 @@ CommandCost RemoveBuoy(TileIndex tile, DoCommandFlag flags) } if (flags & DC_EXEC) { - wp->facilities &= ~FACIL_DOCK; + wp->facilities.Reset(StationFacility::Dock); InvalidateWindowData(WC_WAYPOINT_VIEW, wp->index);