diff --git a/src/articulated_vehicles.cpp b/src/articulated_vehicles.cpp index 49d8877f98..30eef3d19e 100644 --- a/src/articulated_vehicles.cpp +++ b/src/articulated_vehicles.cpp @@ -109,12 +109,12 @@ static inline std::pair GetVehicleDefaultCapacity(EngineID static inline CargoTypes GetAvailableVehicleCargoTypes(EngineID engine, bool include_initial_cargo_type) { const Engine *e = Engine::Get(engine); - if (!e->CanCarryCargo()) return 0; + if (!e->CanCarryCargo()) return {}; CargoTypes cargoes = e->info.refit_mask; if (include_initial_cargo_type) { - SetBit(cargoes, e->GetDefaultCargoType()); + cargoes.Set(e->GetDefaultCargoType()); } return cargoes; @@ -157,11 +157,11 @@ CargoArray GetCapacityOfArticulatedParts(EngineID engine) */ CargoTypes GetCargoTypesOfArticulatedParts(EngineID engine) { - CargoTypes cargoes = 0; + CargoTypes cargoes{}; const Engine *e = Engine::Get(engine); if (auto [cargo, cap] = GetVehicleDefaultCapacity(engine); IsValidCargoType(cargo) && cap > 0) { - SetBit(cargoes, cargo); + cargoes.Set(cargo); } if (!e->IsGroundVehicle()) return cargoes; @@ -173,7 +173,7 @@ CargoTypes GetCargoTypesOfArticulatedParts(EngineID engine) if (artic_engine == EngineID::Invalid()) break; if (auto [cargo, cap] = GetVehicleDefaultCapacity(artic_engine); IsValidCargoType(cargo) && cap > 0) { - SetBit(cargoes, cargo); + cargoes.Set(cargo); } } @@ -216,7 +216,7 @@ void GetArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type, const Engine *e = Engine::Get(engine); CargoTypes veh_cargoes = GetAvailableVehicleCargoTypes(engine, include_initial_cargo_type); *union_mask = veh_cargoes; - *intersection_mask = (veh_cargoes != 0) ? veh_cargoes : ALL_CARGOTYPES; + *intersection_mask = veh_cargoes.Any() ? veh_cargoes : ALL_CARGOTYPES; if (!e->IsGroundVehicle()) return; if (!e->info.callback_mask.Test(VehicleCallbackMask::ArticEngine)) return; @@ -226,8 +226,8 @@ void GetArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type, if (artic_engine == EngineID::Invalid()) break; veh_cargoes = GetAvailableVehicleCargoTypes(artic_engine, include_initial_cargo_type); - *union_mask |= veh_cargoes; - if (veh_cargoes != 0) *intersection_mask &= veh_cargoes; + union_mask->Set(veh_cargoes); + if (veh_cargoes.Any()) *intersection_mask = *intersection_mask & veh_cargoes; } } @@ -253,12 +253,12 @@ CargoTypes GetUnionOfArticulatedRefitMasks(EngineID engine, bool include_initial */ CargoTypes GetCargoTypesOfArticulatedVehicle(const Vehicle *v, CargoType *cargo_type) { - CargoTypes cargoes = 0; + CargoTypes cargoes{}; CargoType first_cargo = INVALID_CARGO; do { if (IsValidCargoType(v->cargo_type) && v->GetEngine()->CanCarryCargo()) { - SetBit(cargoes, v->cargo_type); + cargoes.Set(v->cargo_type); if (!IsValidCargoType(first_cargo)) first_cargo = v->cargo_type; if (first_cargo != v->cargo_type) { if (cargo_type != nullptr) { @@ -292,24 +292,24 @@ void CheckConsistencyOfArticulatedVehicle(const Vehicle *v) GetArticulatedRefitMasks(v->engine_type, true, &purchase_refit_union, &purchase_refit_intersection); CargoArray purchase_default_capacity = GetCapacityOfArticulatedParts(v->engine_type); - CargoTypes real_refit_union = 0; + CargoTypes real_refit_union{}; CargoTypes real_refit_intersection = ALL_CARGOTYPES; - CargoTypes real_default_cargoes = 0; + CargoTypes real_default_cargoes{}; do { CargoTypes refit_mask = GetAvailableVehicleCargoTypes(v->engine_type, true); - real_refit_union |= refit_mask; - if (refit_mask != 0) real_refit_intersection &= refit_mask; + real_refit_union.Set(refit_mask); + if (refit_mask.Any()) real_refit_intersection = real_refit_intersection & refit_mask; assert(v->cargo_type < NUM_CARGO); - if (v->cargo_cap > 0) SetBit(real_default_cargoes, v->cargo_type); + if (v->cargo_cap > 0) real_default_cargoes.Set(v->cargo_type); v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : nullptr; } while (v != nullptr); /* Check whether the vehicle carries more cargoes than expected */ bool carries_more = false; - for (CargoType cargo_type : SetCargoBitIterator(real_default_cargoes)) { + for (CargoType cargo_type : real_default_cargoes) { if (purchase_default_capacity[cargo_type] == 0) { carries_more = true; break; diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index 8868c55749..205e023e7d 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -47,7 +47,7 @@ static bool EnginesHaveCargoInCommon(EngineID engine_a, EngineID engine_b) { CargoTypes available_cargoes_a = GetUnionOfArticulatedRefitMasks(engine_a, true); CargoTypes available_cargoes_b = GetUnionOfArticulatedRefitMasks(engine_b, true); - return (available_cargoes_a == 0 || available_cargoes_b == 0 || (available_cargoes_a & available_cargoes_b) != 0); + return available_cargoes_a.None() || available_cargoes_b.None() || available_cargoes_a.Any(available_cargoes_b); } /** @@ -189,8 +189,8 @@ static bool VerifyAutoreplaceRefitForOrders(const Vehicle *v, EngineID engine_ty if (!o.IsRefit() || o.IsAutoRefit()) continue; CargoType cargo_type = o.GetRefitCargo(); - if (!HasBit(union_refit_mask_a, cargo_type)) continue; - if (!HasBit(union_refit_mask_b, cargo_type)) return false; + if (!union_refit_mask_a.Test(cargo_type)) continue; + if (!union_refit_mask_b.Test(cargo_type)) return false; } return true; @@ -213,7 +213,7 @@ static int GetIncompatibleRefitOrderIdForAutoreplace(const Vehicle *v, EngineID for (VehicleOrderID i = 0; i < orders->GetNumOrders(); i++) { const Order *o = orders->GetOrderAt(i); if (!o->IsRefit()) continue; - if (!HasBit(union_refit_mask, o->GetRefitCargo())) return i; + if (!union_refit_mask.Test(o->GetRefitCargo())) return i; } return -1; @@ -233,11 +233,11 @@ static CargoType GetNewCargoTypeForReplace(Vehicle *v, EngineID engine_type, boo CargoTypes available_cargo_types, union_mask; GetArticulatedRefitMasks(engine_type, true, &union_mask, &available_cargo_types); - if (union_mask == 0) return CARGO_NO_REFIT; // Don't try to refit an engine with no cargo capacity + if (union_mask.None()) return CARGO_NO_REFIT; // Don't try to refit an engine with no cargo capacity CargoType cargo_type; CargoTypes cargo_mask = GetCargoTypesOfArticulatedVehicle(v, &cargo_type); - if (!HasAtMostOneBit(cargo_mask)) { + if (!HasAtMostOneBit(cargo_mask.base())) { CargoTypes new_engine_default_cargoes = GetCargoTypesOfArticulatedParts(engine_type); if ((cargo_mask & new_engine_default_cargoes) == cargo_mask) { return CARGO_NO_REFIT; // engine_type is already a mixed cargo type which matches the incoming vehicle by default, no refit required @@ -257,12 +257,12 @@ static CargoType GetNewCargoTypeForReplace(Vehicle *v, EngineID engine_type, boo for (v = v->First(); v != nullptr; v = v->Next()) { if (!v->GetEngine()->CanCarryCargo()) continue; /* Now we found a cargo type being carried on the train and we will see if it is possible to carry to this one */ - if (HasBit(available_cargo_types, v->cargo_type)) return v->cargo_type; + if (available_cargo_types.Test(v->cargo_type)) return v->cargo_type; } return CARGO_NO_REFIT; // We failed to find a cargo type on the old vehicle and we will not refit the new one } else { - if (!HasBit(available_cargo_types, cargo_type)) return INVALID_CARGO; // We can't refit the vehicle to carry the cargo we want + if (!available_cargo_types.Test(cargo_type)) return INVALID_CARGO; // We can't refit the vehicle to carry the cargo we want if (part_of_chain && !VerifyAutoreplaceRefitForOrders(v, engine_type)) return INVALID_CARGO; // Some refit orders lose their effect diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index ed8b680df1..123dda9a57 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -471,7 +471,7 @@ static bool CargoAndEngineFilter(const GUIEngineListItem *item, const CargoType return Engine::Get(item->engine_id)->GetPower() != 0; } else { CargoTypes refit_mask = GetUnionOfArticulatedRefitMasks(item->engine_id, true) & _standard_cargo_mask; - return (cargo_type == CargoFilterCriteria::CF_NONE ? refit_mask == 0 : HasBit(refit_mask, cargo_type)); + return (cargo_type == CargoFilterCriteria::CF_NONE ? refit_mask.None() : refit_mask.Test(cargo_type)); } } @@ -482,7 +482,7 @@ static GUIEngineList::FilterFunction * const _engine_filter_funcs[] = { static uint GetCargoWeight(const CargoArray &cap, VehicleType vtype) { uint weight = 0; - for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) { + for (CargoType cargo{}; cargo < NUM_CARGO; ++cargo) { if (cap[cargo] != 0) { if (vtype == VEH_TRAIN) { weight += CargoSpec::Get(cargo)->WeightOfNUnitsInTrain(cap[cargo]); @@ -1325,7 +1325,7 @@ struct BuildVehicleWindow : Window { { /* Set the last cargo filter criteria. */ this->cargo_filter_criteria = _engine_sort_last_cargo_criteria[this->vehicle_type]; - if (this->cargo_filter_criteria < NUM_CARGO && !HasBit(_standard_cargo_mask, this->cargo_filter_criteria)) this->cargo_filter_criteria = CargoFilterCriteria::CF_ANY; + if (this->cargo_filter_criteria < NUM_CARGO && !_standard_cargo_mask.Test(this->cargo_filter_criteria)) this->cargo_filter_criteria = CargoFilterCriteria::CF_ANY; this->eng_list.SetFilterFuncs(_engine_filter_funcs); this->eng_list.SetFilterState(this->cargo_filter_criteria != CargoFilterCriteria::CF_ANY); @@ -1952,7 +1952,7 @@ struct BuildVehicleWindow : Window { case WID_BV_CARGO_FILTER_DROPDOWN: // Select a cargo filter criteria if (this->cargo_filter_criteria != index) { - this->cargo_filter_criteria = index; + this->cargo_filter_criteria = static_cast(index); _engine_sort_last_cargo_criteria[this->vehicle_type] = this->cargo_filter_criteria; /* deactivate filter if criteria is 'Show All', activate it otherwise */ this->eng_list.SetFilterState(this->cargo_filter_criteria != CargoFilterCriteria::CF_ANY); diff --git a/src/cargo_type.h b/src/cargo_type.h index 56ba7c7d18..b009480229 100644 --- a/src/cargo_type.h +++ b/src/cargo_type.h @@ -11,6 +11,7 @@ #define CARGO_TYPE_H #include "core/strong_typedef_type.hpp" +#include "core/enum_type.hpp" /** Globally unique label of a cargo type. */ using CargoLabel = StrongType::Typedef; @@ -18,7 +19,8 @@ using CargoLabel = StrongType::Typedef; -static const CargoTypes ALL_CARGOTYPES = (CargoTypes)UINT64_MAX; +static constexpr CargoTypes ALL_CARGOTYPES{UINT64_MAX}; /** Class for storing amounts of cargo */ struct CargoArray : std::array { diff --git a/src/cargomonitor.h b/src/cargomonitor.h index 3da6257a0a..2912959384 100644 --- a/src/cargomonitor.h +++ b/src/cargomonitor.h @@ -104,7 +104,7 @@ inline CompanyID DecodeMonitorCompany(CargoMonitorID num) */ inline CargoType DecodeMonitorCargoType(CargoMonitorID num) { - return GB(num, CCB_CARGO_TYPE_START, CCB_CARGO_TYPE_LENGTH); + return static_cast(GB(num, CCB_CARGO_TYPE_START, CCB_CARGO_TYPE_LENGTH)); } /** diff --git a/src/cargotype.cpp b/src/cargotype.cpp index 1128618670..4325d3e221 100644 --- a/src/cargotype.cpp +++ b/src/cargotype.cpp @@ -62,7 +62,7 @@ void SetupCargoForClimate(LandscapeType l) { assert(to_underlying(l) < std::size(_default_climate_cargo)); - _cargo_mask = 0; + _cargo_mask.Reset(); _default_cargo_labels.clear(); _climate_dependent_cargo_labels.fill(CT_INVALID); _climate_independent_cargo_labels.fill(CT_INVALID); @@ -91,7 +91,7 @@ void SetupCargoForClimate(LandscapeType l) *insert = std::visit(visitor{}, cl); if (insert->IsValid()) { - SetBit(_cargo_mask, insert->Index()); + _cargo_mask.Set(insert->Index()); _default_cargo_labels.push_back(insert->label); _climate_dependent_cargo_labels[insert->Index()] = insert->label; _climate_independent_cargo_labels[insert->bitnum] = insert->label; @@ -237,14 +237,14 @@ void InitializeSortedCargoSpecs() } /* Count the number of standard cargos and fill the mask. */ - _standard_cargo_mask = 0; + _standard_cargo_mask.Reset(); uint8_t nb_standard_cargo = 0; for (const auto &cargo : _sorted_cargo_specs) { assert(cargo->town_production_effect != TownProductionEffect::Invalid); CargoSpec::town_production_cargoes[cargo->town_production_effect].push_back(cargo); if (cargo->classes.Test(CargoClass::Special)) break; nb_standard_cargo++; - SetBit(_standard_cargo_mask, cargo->Index()); + _standard_cargo_mask.Set(cargo->Index()); } /* _sorted_standard_cargo_specs is a subset of _sorted_cargo_specs. */ diff --git a/src/cargotype.h b/src/cargotype.h index a49f409416..ad009cc9a9 100644 --- a/src/cargotype.h +++ b/src/cargotype.h @@ -108,7 +108,7 @@ struct CargoSpec { */ inline CargoType Index() const { - return this - CargoSpec::array; + return static_cast(this - CargoSpec::array); } /** @@ -238,8 +238,6 @@ inline bool IsCargoInClass(CargoType cargo, CargoClasses cc) return CargoSpec::Get(cargo)->classes.Any(cc); } -using SetCargoBitIterator = SetBitIterator; - /** Comparator to sort CargoType by according to desired order. */ struct CargoTypeComparator { bool operator() (const CargoType &lhs, const CargoType &rhs) const { return _sorted_cargo_types[lhs] < _sorted_cargo_types[rhs]; } diff --git a/src/economy.cpp b/src/economy.cpp index 3bdcecdbe4..d3431ad87a 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -1092,7 +1092,7 @@ static Money DeliverGoods(int num_pieces, CargoType cargo_type, StationID dest, uint accepted_ind = DeliverGoodsToIndustry(st, cargo_type, num_pieces, src.type == SourceType::Industry ? src.ToIndustryID() : IndustryID::Invalid(), company->index); /* If this cargo type is always accepted, accept all */ - uint accepted_total = HasBit(st->always_accepted, cargo_type) ? num_pieces : accepted_ind; + uint accepted_total = st->always_accepted.Test(cargo_type) ? num_pieces : accepted_ind; /* Update station statistics */ if (accepted_total > 0) { @@ -1394,7 +1394,7 @@ struct PrepareRefitAction bool operator()(const Vehicle *v) { this->consist_capleft[v->cargo_type] -= v->cargo_cap - v->cargo.ReservedCount(); - this->refit_mask |= EngInfo(v->engine_type)->refit_mask; + this->refit_mask.Set(EngInfo(v->engine_type)->refit_mask); return true; } }; @@ -1487,7 +1487,7 @@ static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station if (is_auto_refit) { /* Get a refittable cargo type with waiting cargo for next_station or StationID::Invalid(). */ new_cargo_type = v_start->cargo_type; - for (CargoType cargo_type : SetCargoBitIterator(refit_mask)) { + for (CargoType cargo_type : refit_mask) { if (st->goods[cargo_type].HasData() && st->goods[cargo_type].GetData().cargo.HasCargoFor(next_station)) { /* Try to find out if auto-refitting would succeed. In case the refit is allowed, * the returned refit capacity will be greater than zero. */ @@ -1648,10 +1648,10 @@ static void LoadUnloadVehicle(Vehicle *front) bool completely_emptied = true; bool anything_unloaded = false; bool anything_loaded = false; - CargoTypes full_load_amount = 0; - CargoTypes cargo_not_full = 0; - CargoTypes cargo_full = 0; - CargoTypes reservation_left = 0; + CargoTypes full_load_amount{}; + CargoTypes cargo_not_full{}; + CargoTypes cargo_full{}; + CargoTypes reservation_left{}; front->cur_speed = 0; @@ -1782,14 +1782,14 @@ static void LoadUnloadVehicle(Vehicle *front) if (v->cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) { /* Remember if there are reservations left so that we don't stop * loading before they're loaded. */ - SetBit(reservation_left, v->cargo_type); + reservation_left.Set(v->cargo_type); } /* Store whether the maximum possible load amount was loaded or not.*/ if (loaded == cap_left) { - SetBit(full_load_amount, v->cargo_type); + full_load_amount.Set(v->cargo_type); } else { - ClrBit(full_load_amount, v->cargo_type); + full_load_amount.Reset(v->cargo_type); } /* TODO: Regarding this, when we do gradual loading, we @@ -1822,9 +1822,9 @@ static void LoadUnloadVehicle(Vehicle *front) } if (v->cargo.StoredCount() >= v->cargo_cap) { - SetBit(cargo_full, v->cargo_type); + cargo_full.Set(v->cargo_type); } else { - SetBit(cargo_not_full, v->cargo_type); + cargo_not_full.Set(v->cargo_type); } } @@ -1854,7 +1854,7 @@ static void LoadUnloadVehicle(Vehicle *front) } /* We loaded less cargo than possible for all cargo types and it's not full * load and we're not supposed to wait any longer: stop loading. */ - if (!anything_unloaded && full_load_amount == 0 && reservation_left == 0 && !front->current_order.IsFullLoadOrder() && + if (!anything_unloaded && full_load_amount.None() && reservation_left.None() && !front->current_order.IsFullLoadOrder() && front->current_order_time >= std::max(front->current_order.GetTimetabledWait() - front->lateness_counter, 0)) { front->vehicle_flags.Set(VehicleFlag::StopLoading); } @@ -1868,10 +1868,10 @@ static void LoadUnloadVehicle(Vehicle *front) /* if the aircraft carries passengers and is NOT full, then * continue loading, no matter how much mail is in */ if ((front->type == VEH_AIRCRAFT && IsCargoInClass(front->cargo_type, CargoClass::Passengers) && front->cargo_cap > front->cargo.StoredCount()) || - (cargo_not_full != 0 && (cargo_full & ~cargo_not_full) == 0)) { // There are still non-full cargoes + (cargo_not_full.Any() && cargo_full.Reset(cargo_not_full).None())) { // There are still non-full cargoes finished_loading = false; } - } else if (cargo_not_full != 0) { + } else if (cargo_not_full.Any()) { finished_loading = false; } diff --git a/src/engine.cpp b/src/engine.cpp index 2c622bed3c..674e8e77ab 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -932,7 +932,7 @@ static CompanyID GetPreviewCompany(Engine *e) /* Check whether the company uses similar vehicles */ for (const Vehicle *v : Vehicle::Iterate()) { if (v->owner != c->index || v->type != e->type) continue; - if (!v->GetEngine()->CanCarryCargo() || !HasBit(cargomask, v->cargo_type)) continue; + if (!v->GetEngine()->CanCarryCargo() || !cargomask.Test(v->cargo_type)) continue; best_hist = c->old_economy[0].performance_history; best_company = c->index; @@ -1300,7 +1300,7 @@ bool IsEngineRefittable(EngineID engine) if (!e->CanCarryCargo()) return false; const EngineInfo *ei = &e->info; - if (ei->refit_mask == 0) return false; + if (ei->refit_mask.None()) return false; /* Are there suffixes? * Note: This does not mean the suffixes are actually available for every consist at any time. */ @@ -1308,9 +1308,7 @@ bool IsEngineRefittable(EngineID engine) /* Is there any cargo except the default cargo? */ CargoType default_cargo = e->GetDefaultCargoType(); - CargoTypes default_cargo_mask = 0; - SetBit(default_cargo_mask, default_cargo); - return IsValidCargoType(default_cargo) && ei->refit_mask != default_cargo_mask; + return IsValidCargoType(default_cargo) && ei->refit_mask != default_cargo; } /** diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index ee28dd3053..2e1d8d91b8 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -1203,7 +1203,7 @@ struct BaseCargoGraphWindow : BaseGraphWindow { this->cargo_types = this->GetCargoTypes(number); this->vscroll = this->GetScrollbar(WID_GRAPH_MATRIX_SCROLLBAR); - this->vscroll->SetCount(CountBits(this->cargo_types)); + this->vscroll->SetCount(this->cargo_types.Count()); auto *wid = this->GetWidget(WID_GRAPH_FOOTER); wid->SetString(TimerGameEconomy::UsingWallclockUnits() ? footer_wallclock : footer_calendar); @@ -1233,7 +1233,7 @@ struct BaseCargoGraphWindow : BaseGraphWindow { if (row >= this->vscroll->GetCount()) return std::nullopt; for (const CargoSpec *cs : _sorted_cargo_specs) { - if (!HasBit(this->cargo_types, cs->Index())) continue; + if (!this->cargo_types.Test(cs->Index())) continue; if (row-- > 0) continue; return cs->Index(); @@ -1257,7 +1257,7 @@ struct BaseCargoGraphWindow : BaseGraphWindow { size.height = GetCharacterHeight(FontSize::Small) + WidgetDimensions::scaled.framerect.Vertical(); - for (CargoType cargo_type : SetCargoBitIterator(this->cargo_types)) { + for (CargoType cargo_type : this->cargo_types) { const CargoSpec *cs = CargoSpec::Get(cargo_type); Dimension d = GetStringBoundingBox(GetString(STR_GRAPH_CARGO_PAYMENT_CARGO, cs->name)); @@ -1288,12 +1288,12 @@ struct BaseCargoGraphWindow : BaseGraphWindow { Rect line = r.WithHeight(this->line_height); for (const CargoSpec *cs : _sorted_cargo_specs) { - if (!HasBit(this->cargo_types, cs->Index())) continue; + if (!this->cargo_types.Test(cs->Index())) continue; if (pos-- > 0) continue; if (--max < 0) break; - bool lowered = !HasBit(this->excluded_data, cs->Index()); + bool lowered = !CargoTypes{this->excluded_data}.Test(cs->Index()); /* Redraw frame if lowered */ if (lowered) DrawFrameRect(line, Colours::Brown, FrameFlag::Lowered); @@ -1320,14 +1320,14 @@ struct BaseCargoGraphWindow : BaseGraphWindow { case WID_GRAPH_ENABLE_CARGOES: /* Remove all cargoes from the excluded lists. */ this->GetExcludedCargoTypes() = {}; - this->excluded_data = this->GetExcludedCargoTypes(); + this->excluded_data = this->GetExcludedCargoTypes().base(); this->SetDirty(); break; case WID_GRAPH_DISABLE_CARGOES: { /* Add all cargoes to the excluded lists. */ this->GetExcludedCargoTypes() = this->cargo_types; - this->excluded_data = this->GetExcludedCargoTypes(); + this->excluded_data = this->GetExcludedCargoTypes().base(); this->SetDirty(); break; } @@ -1339,11 +1339,11 @@ struct BaseCargoGraphWindow : BaseGraphWindow { SndClickBeep(); for (const CargoSpec *cs : _sorted_cargo_specs) { - if (!HasBit(this->cargo_types, cs->Index())) continue; + if (!this->cargo_types.Test(cs->Index())) continue; if (row-- > 0) continue; - ToggleBit(this->GetExcludedCargoTypes(), cs->Index()); - this->excluded_data = this->GetExcludedCargoTypes(); + this->GetExcludedCargoTypes().Flip(cs->Index()); + this->excluded_data = this->GetExcludedCargoTypes().base(); this->SetDirty(); break; } @@ -1415,7 +1415,7 @@ struct PaymentRatesGraphWindow : BaseCargoGraphWindow { */ void UpdatePaymentRates() { - this->excluded_data = this->GetExcludedCargoTypes(); + this->excluded_data = this->GetExcludedCargoTypes().base(); this->data.clear(); for (const CargoSpec *cs : _sorted_standard_cargo_specs) { @@ -1741,10 +1741,10 @@ struct IndustryProductionGraphWindow : BaseCargoGraphWindow { CargoTypes cargo_types{}; const Industry *i = Industry::Get(window_number); for (const auto &a : i->accepted) { - if (IsValidCargoType(a.cargo)) SetBit(cargo_types, a.cargo); + if (IsValidCargoType(a.cargo)) cargo_types.Set(a.cargo); } for (const auto &p : i->produced) { - if (IsValidCargoType(p.cargo)) SetBit(cargo_types, p.cargo); + if (IsValidCargoType(p.cargo)) cargo_types.Set(p.cargo); } return cargo_types; } @@ -1770,12 +1770,12 @@ struct IndustryProductionGraphWindow : BaseCargoGraphWindow { mo += 12; } - if (!initialize && this->excluded_data == this->GetExcludedCargoTypes() && this->num_on_x_axis == this->num_vert_lines && this->year == yr && this->month == mo) { + if (!initialize && this->excluded_data == this->GetExcludedCargoTypes().base() && this->num_on_x_axis == this->num_vert_lines && this->year == yr && this->month == mo) { /* There's no reason to get new stats */ return; } - this->excluded_data = this->GetExcludedCargoTypes(); + this->excluded_data = this->GetExcludedCargoTypes().base(); this->year = yr; this->month = mo; @@ -1911,10 +1911,10 @@ struct TownCargoGraphWindow : BaseCargoGraphWindow { CargoTypes cargo_types{}; const Town *t = Town::Get(window_number); for (const auto &s : t->supplied) { - if (IsValidCargoType(s.cargo)) SetBit(cargo_types, s.cargo); + if (IsValidCargoType(s.cargo)) cargo_types.Set(s.cargo); } for (const auto &a : t->accepted) { - if (IsValidCargoType(a.cargo)) SetBit(cargo_types, a.cargo); + if (IsValidCargoType(a.cargo)) cargo_types.Set(a.cargo); } return cargo_types; } @@ -1940,12 +1940,12 @@ struct TownCargoGraphWindow : BaseCargoGraphWindow { mo += 12; } - if (!initialize && this->excluded_data == this->GetExcludedCargoTypes() && this->num_on_x_axis == this->num_vert_lines && this->year == yr && this->month == mo) { + if (!initialize && this->excluded_data == this->GetExcludedCargoTypes().base() && this->num_on_x_axis == this->num_vert_lines && this->year == yr && this->month == mo) { /* There's no reason to get new stats */ return; } - this->excluded_data = this->GetExcludedCargoTypes(); + this->excluded_data = this->GetExcludedCargoTypes().base(); this->year = yr; this->month = mo; diff --git a/src/group_gui.cpp b/src/group_gui.cpp index 4975016d47..5e37151b09 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -1046,7 +1046,7 @@ public: break; case WID_GL_FILTER_BY_CARGO: // Select a cargo filter criteria - this->SetCargoFilter(index); + this->SetCargoFilter(static_cast(index)); break; case WID_GL_MANAGE_VEHICLES_DROPDOWN: diff --git a/src/industry.h b/src/industry.h index cd746ff70a..9ddd0dd9fc 100644 --- a/src/industry.h +++ b/src/industry.h @@ -71,7 +71,7 @@ struct Industry : IndustryPool::PoolItem<&_industry_pool> { } }; struct ProducedCargo { - CargoType cargo = 0; ///< Cargo type + CargoType cargo = INVALID_CARGO; ///< Cargo type uint16_t waiting = 0; ///< Amount of cargo produced uint8_t rate = 0; ///< Production rate HistoryData history{}; ///< History of cargo produced and transported for this month and 24 previous months @@ -83,7 +83,7 @@ struct Industry : IndustryPool::PoolItem<&_industry_pool> { }; struct AcceptedCargo { - CargoType cargo = 0; ///< Cargo type + CargoType cargo = INVALID_CARGO; ///< Cargo type uint16_t waiting = 0; ///< Amount of cargo waiting to processed uint32_t accumulated_waiting = 0; ///< Accumulated waiting total over the last month, used to calculate average. TimerGameEconomy::Date last_accepted{}; ///< Last day cargo was accepted by this industry diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index baba8a2d23..dfdff294e0 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -458,13 +458,13 @@ static void AddAcceptedCargo_Industry(TileIndex tile, CargoArray &acceptance, Ca acceptance[cargo] += cargo_acceptance[i]; /* Maybe set 'always accepted' bit (if it's not set already) */ - if (HasBit(always_accepted, cargo)) continue; + if (always_accepted.Test(cargo)) continue; /* Test whether the industry itself accepts the cargo type */ if (ind->IsCargoAccepted(cargo)) continue; /* If the industry itself doesn't accept this cargo, set 'always accepted' bit */ - SetBit(always_accepted, cargo); + always_accepted.Set(cargo); } } diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index dea3f0a8fa..414c59dd94 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -19,6 +19,7 @@ #include "viewport_func.h" #include "industry.h" #include "town.h" +#include "cargo_type.h" #include "cheat_type.h" #include "newgrf_badge.h" #include "newgrf_badge_gui.h" @@ -1832,13 +1833,13 @@ public: } case WID_ID_FILTER_BY_ACC_CARGO: { - this->SetAcceptedCargoFilter(index); + this->SetAcceptedCargoFilter(static_cast(index)); this->BuildSortIndustriesList(); break; } case WID_ID_FILTER_BY_PROD_CARGO: { - this->SetProducedCargoFilter(index); + this->SetProducedCargoFilter(static_cast(index)); this->BuildSortIndustriesList(); break; } @@ -3118,7 +3119,7 @@ struct IndustryCargoesWindow : public Window { switch (widget) { case WID_IC_CARGO_DROPDOWN: - this->ComputeCargoDisplay(index); + this->ComputeCargoDisplay(static_cast(index)); break; case WID_IC_IND_DROPDOWN: diff --git a/src/linkgraph/linkgraph_gui.cpp b/src/linkgraph/linkgraph_gui.cpp index a12e9c423b..0e37853278 100644 --- a/src/linkgraph/linkgraph_gui.cpp +++ b/src/linkgraph/linkgraph_gui.cpp @@ -86,7 +86,7 @@ void LinkGraphOverlay::RebuildCache() StationLinkMap &seen_links = this->cached_links[from]; uint supply = 0; - for (CargoType cargo : SetCargoBitIterator(this->cargo_mask)) { + for (CargoType cargo : this->cargo_mask) { if (!CargoSpec::Get(cargo)->IsValid()) continue; if (!LinkGraph::IsValidID(sta->goods[cargo].link_graph)) continue; const LinkGraph &lg = *LinkGraph::Get(sta->goods[cargo].link_graph); @@ -212,7 +212,7 @@ inline bool LinkGraphOverlay::IsLinkVisible(Point pta, Point ptb, const DrawPixe */ void LinkGraphOverlay::AddLinks(const Station *from, const Station *to) { - for (CargoType cargo : SetCargoBitIterator(this->cargo_mask)) { + for (CargoType cargo : this->cargo_mask) { if (!CargoSpec::Get(cargo)->IsValid()) continue; const GoodsEntry &ge = from->goods[cargo]; if (!LinkGraph::IsValidID(ge.link_graph) || @@ -569,7 +569,7 @@ void LinkGraphLegendWindow::SetOverlay(std::shared_ptr overlay } CargoTypes cargoes = this->overlay->GetCargoMask(); for (uint c = 0; c < this->num_cargo; c++) { - this->SetWidgetLoweredState(WID_LGL_CARGO_FIRST + c, HasBit(cargoes, _sorted_cargo_specs[c]->Index())); + this->SetWidgetLoweredState(WID_LGL_CARGO_FIRST + c, cargoes.Test(_sorted_cargo_specs[c]->Index())); } } @@ -672,10 +672,10 @@ void LinkGraphLegendWindow::UpdateOverlayCompanies() */ void LinkGraphLegendWindow::UpdateOverlayCargoes() { - CargoTypes mask = 0; + CargoTypes mask{}; for (uint c = 0; c < num_cargo; c++) { if (!this->IsWidgetLowered(WID_LGL_CARGO_FIRST + c)) continue; - SetBit(mask, _sorted_cargo_specs[c]->Index()); + mask.Set(_sorted_cargo_specs[c]->Index()); } this->overlay->SetCargoMask(mask); } diff --git a/src/linkgraph/refresh.cpp b/src/linkgraph/refresh.cpp index 8f92a8488f..ffa5aba853 100644 --- a/src/linkgraph/refresh.cpp +++ b/src/linkgraph/refresh.cpp @@ -72,7 +72,7 @@ bool LinkRefresher::HandleRefit(CargoType refit_cargo) bool any_refit = false; for (Vehicle *v = this->vehicle; v != nullptr; v = v->Next()) { const Engine *e = Engine::Get(v->engine_type); - if (!HasBit(e->info.refit_mask, this->cargo)) { + if (!e->info.refit_mask.Test(this->cargo)) { ++refit_it; continue; } @@ -188,7 +188,7 @@ void LinkRefresher::RefreshStats(VehicleOrderID cur, VehicleOrderID next) Station *st = Station::GetIfValid(orders[cur].GetDestination().ToStationID()); if (st != nullptr && next_station != StationID::Invalid() && next_station != st->index) { Station *st_to = Station::Get(next_station); - for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) { + for (CargoType cargo{}; cargo < NUM_CARGO; ++cargo) { /* Refresh the link and give it a minimum capacity. */ uint cargo_quantity = this->capacities[cargo]; @@ -260,7 +260,7 @@ void LinkRefresher::RefreshLinks(VehicleOrderID cur, VehicleOrderID next, Refres } else if (!flags.Test(RefreshFlag::InAutorefit)) { flags.Set(RefreshFlag::InAutorefit); LinkRefresher backup(*this); - for (CargoType cargo = 0; cargo != NUM_CARGO; ++cargo) { + for (CargoType cargo{}; cargo < NUM_CARGO; ++cargo) { if (CargoSpec::Get(cargo)->IsValid() && this->HandleRefit(cargo)) { this->RefreshLinks(cur, next, flags, num_hops); *this = backup; diff --git a/src/main_gui.cpp b/src/main_gui.cpp index 138c2cd03a..c722c00752 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -221,14 +221,14 @@ struct MainWindow : Window NWidgetViewport *nvp = this->GetWidget(WID_M_VIEWPORT); nvp->InitializeViewport(this, TileXY(32, 32), ScaleZoomGUI(ZoomLevel::Viewport)); - this->viewport->overlay = std::make_shared(this, WID_M_VIEWPORT, 0, CompanyMask{}, 2); + this->viewport->overlay = std::make_shared(this, WID_M_VIEWPORT, CargoTypes{}, CompanyMask{}, 2); this->refresh_timeout.Reset(); } /** Refresh the link-graph overlay. */ void RefreshLinkGraph() { - if (this->viewport->overlay->GetCargoMask() == 0 || + if (this->viewport->overlay->GetCargoMask().None() || this->viewport->overlay->GetCompanyMask().None()) { return; } diff --git a/src/newgrf.cpp b/src/newgrf.cpp index fb3a8c5935..66e309a416 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -320,10 +320,10 @@ EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16_t internal */ CargoTypes TranslateRefitMask(uint32_t refit_mask) { - CargoTypes result = 0; + CargoTypes result{}; for (uint8_t bit : SetBitIterator(refit_mask)) { CargoType cargo = GetCargoTranslation(bit, _cur_gps.grffile, true); - if (IsValidCargoType(cargo)) SetBit(result, cargo); + if (IsValidCargoType(cargo)) result.Set(cargo); } return result; } @@ -652,9 +652,9 @@ static CargoLabel GetActiveCargoLabel(const std::variantcargo_type)) ClrBit(_gted[engine].ctt_exclude_mask, ei->cargo_type); + if (IsValidCargoType(ei->cargo_type)) _gted[engine].ctt_exclude_mask.Reset(ei->cargo_type); } /* Compute refittability */ { - CargoTypes mask = 0; - CargoTypes not_mask = 0; + CargoTypes mask{}; + CargoTypes not_mask{}; CargoTypes xor_mask = ei->refit_mask; /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo. @@ -765,16 +765,17 @@ static void CalculateRefitMasks() if (_gted[engine].cargo_allowed.Any()) { /* Build up the list of cargo types from the set cargo classes. */ for (const CargoSpec *cs : CargoSpec::Iterate()) { - if (cs->classes.Any(_gted[engine].cargo_allowed) && cs->classes.All(_gted[engine].cargo_allowed_required)) SetBit(mask, cs->Index()); - if (cs->classes.Any(_gted[engine].cargo_disallowed)) SetBit(not_mask, cs->Index()); + if (cs->classes.Any(_gted[engine].cargo_allowed) && cs->classes.All(_gted[engine].cargo_allowed_required)) mask.Set(cs->Index()); + if (cs->classes.Any(_gted[engine].cargo_disallowed)) not_mask.Set(cs->Index()); } } - ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask; + CargoTypes invalid_mask = CargoTypes{_cargo_mask}.Flip(); + ei->refit_mask = mask.Reset(not_mask).Flip(xor_mask).Reset(invalid_mask); /* Apply explicit refit includes/excludes. */ - ei->refit_mask |= _gted[engine].ctt_include_mask; - ei->refit_mask &= ~_gted[engine].ctt_exclude_mask; + ei->refit_mask.Set(_gted[engine].ctt_include_mask); + ei->refit_mask.Reset(_gted[engine].ctt_exclude_mask); /* Custom refit mask callback. */ const GRFFile *file = _gted[e->index].defaultcargo_grf; @@ -787,8 +788,8 @@ static void CalculateRefitMasks() case CALLBACK_FAILED: case 0: break; // Do nothing. - case 1: SetBit(ei->refit_mask, cs->Index()); break; - case 2: ClrBit(ei->refit_mask, cs->Index()); break; + case 1: ei->refit_mask.Set(cs->Index()); break; + case 2: ei->refit_mask.Reset(cs->Index()); break; default: ErrorUnknownCallbackResult(file->grfid, CBID_VEHICLE_CUSTOM_REFIT, callback); } @@ -797,24 +798,24 @@ static void CalculateRefitMasks() } /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */ - if (IsValidCargoType(ei->cargo_type) && !HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = INVALID_CARGO; + if (IsValidCargoType(ei->cargo_type) && !_cargo_mask.Test(ei->cargo_type)) ei->cargo_type = INVALID_CARGO; /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes. * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */ - if (!only_defaultcargo && (e->type != VEH_SHIP || e->VehInfo().old_refittable) && IsValidCargoType(ei->cargo_type) && !HasBit(ei->refit_mask, ei->cargo_type)) { + if (!only_defaultcargo && (e->type != VEH_SHIP || e->VehInfo().old_refittable) && IsValidCargoType(ei->cargo_type) && !ei->refit_mask.Test(ei->cargo_type)) { ei->cargo_type = INVALID_CARGO; } /* Check if this engine's cargo type is valid. If not, set to the first refittable * cargo type. Finally disable the vehicle, if there is still no cargo. */ - if (!IsValidCargoType(ei->cargo_type) && ei->refit_mask != 0) { + if (!IsValidCargoType(ei->cargo_type) && ei->refit_mask.Any()) { /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */ const GRFFile *file = _gted[engine].defaultcargo_grf; if (file == nullptr) file = e->GetGRF(); if (file != nullptr && file->grf_version >= 8 && !file->cargo_list.empty()) { /* Use first refittable cargo from cargo translation table */ uint8_t best_local_slot = UINT8_MAX; - for (CargoType cargo_type : SetCargoBitIterator(ei->refit_mask)) { + for (CargoType cargo_type : ei->refit_mask) { uint8_t local_slot = file->cargo_map[cargo_type]; if (local_slot < best_local_slot) { best_local_slot = local_slot; @@ -825,7 +826,7 @@ static void CalculateRefitMasks() if (!IsValidCargoType(ei->cargo_type)) { /* Use first refittable cargo slot */ - ei->cargo_type = (CargoType)FindFirstBit(ei->refit_mask); + ei->cargo_type = *ei->refit_mask.begin(); } } if (!IsValidCargoType(ei->cargo_type) && e->type == VEH_TRAIN && e->VehInfo().railveh_type != RAILVEH_WAGON && e->VehInfo().capacity == 0) { @@ -833,14 +834,14 @@ static void CalculateRefitMasks() * Fallback to the first available instead, if the cargo type has not been changed (as indicated by * cargo_label not being CT_INVALID). */ if (GetActiveCargoLabel(ei->cargo_label) != CT_INVALID) { - ei->cargo_type = static_cast(FindFirstBit(_standard_cargo_mask)); + ei->cargo_type = *_standard_cargo_mask.begin(); } } if (!IsValidCargoType(ei->cargo_type)) ei->climates = {}; /* Clear refit_mask for not refittable ships */ if (e->type == VEH_SHIP && !e->VehInfo().old_refittable) { - ei->refit_mask = 0; + ei->refit_mask.Reset(); } } } diff --git a/src/newgrf/newgrf_act0_aircraft.cpp b/src/newgrf/newgrf_act0_aircraft.cpp index 3529c59adf..a9637841ed 100644 --- a/src/newgrf/newgrf_act0_aircraft.cpp +++ b/src/newgrf/newgrf_act0_aircraft.cpp @@ -153,10 +153,10 @@ static ChangeInfoResult AircraftVehicleChangeInfo(uint first, uint last, int pro _gted[e->index].UpdateRefittability(prop == 0x1D && count != 0); if (prop == 0x1D) _gted[e->index].defaultcargo_grf = _cur_gps.grffile; CargoTypes &ctt = prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask; - ctt = 0; + ctt.Reset(); while (count--) { CargoType ctype = GetCargoTranslation(buf.ReadByte(), _cur_gps.grffile); - if (IsValidCargoType(ctype)) SetBit(ctt, ctype); + if (IsValidCargoType(ctype)) ctt.Set(ctype); } break; } diff --git a/src/newgrf/newgrf_act0_cargo.cpp b/src/newgrf/newgrf_act0_cargo.cpp index 68cbd04700..cfc17c309f 100644 --- a/src/newgrf/newgrf_act0_cargo.cpp +++ b/src/newgrf/newgrf_act0_cargo.cpp @@ -64,9 +64,9 @@ static ChangeInfoResult CargoReserveInfo(uint first, uint last, int prop, ByteRe cs->bitnum = buf.ReadByte(); if (cs->IsValid()) { cs->grffile = _cur_gps.grffile; - SetBit(_cargo_mask, id); + _cargo_mask.Set(cs->Index()); } else { - ClrBit(_cargo_mask, id); + _cargo_mask.Reset(cs->Index()); } BuildCargoLabelMap(); break; diff --git a/src/newgrf/newgrf_act0_houses.cpp b/src/newgrf/newgrf_act0_houses.cpp index bad2e61206..e93ecd309d 100644 --- a/src/newgrf/newgrf_act0_houses.cpp +++ b/src/newgrf/newgrf_act0_houses.cpp @@ -305,7 +305,7 @@ static ChangeInfoResult TownHouseChangeInfo(uint first, uint last, int prop, Byt uint8_t count = buf.ReadByte(); for (uint8_t j = 0; j < count; j++) { CargoType cargo = GetCargoTranslation(buf.ReadByte(), _cur_gps.grffile); - if (IsValidCargoType(cargo)) SetBit(housespec->watched_cargoes, cargo); + if (IsValidCargoType(cargo)) housespec->watched_cargoes.Set(cargo); } break; } diff --git a/src/newgrf/newgrf_act0_roadvehs.cpp b/src/newgrf/newgrf_act0_roadvehs.cpp index 749f4a07ce..f838b192a6 100644 --- a/src/newgrf/newgrf_act0_roadvehs.cpp +++ b/src/newgrf/newgrf_act0_roadvehs.cpp @@ -194,10 +194,10 @@ static ChangeInfoResult RoadVehicleChangeInfo(uint first, uint last, int prop, B _gted[e->index].UpdateRefittability(prop == 0x24 && count != 0); if (prop == 0x24) _gted[e->index].defaultcargo_grf = _cur_gps.grffile; CargoTypes &ctt = prop == 0x24 ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask; - ctt = 0; + ctt.Reset(); while (count--) { CargoType ctype = GetCargoTranslation(buf.ReadByte(), _cur_gps.grffile); - if (IsValidCargoType(ctype)) SetBit(ctt, ctype); + if (IsValidCargoType(ctype)) ctt.Set(ctype); } break; } diff --git a/src/newgrf/newgrf_act0_ships.cpp b/src/newgrf/newgrf_act0_ships.cpp index 608dde6dd1..893e88de69 100644 --- a/src/newgrf/newgrf_act0_ships.cpp +++ b/src/newgrf/newgrf_act0_ships.cpp @@ -173,10 +173,10 @@ static ChangeInfoResult ShipVehicleChangeInfo(uint first, uint last, int prop, B _gted[e->index].UpdateRefittability(prop == 0x1E && count != 0); if (prop == 0x1E) _gted[e->index].defaultcargo_grf = _cur_gps.grffile; CargoTypes &ctt = prop == 0x1E ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask; - ctt = 0; + ctt.Reset(); while (count--) { CargoType ctype = GetCargoTranslation(buf.ReadByte(), _cur_gps.grffile); - if (IsValidCargoType(ctype)) SetBit(ctt, ctype); + if (IsValidCargoType(ctype)) ctt.Set(ctype); } break; } diff --git a/src/newgrf/newgrf_act0_trains.cpp b/src/newgrf/newgrf_act0_trains.cpp index 6a25fda80b..a7c6b48a75 100644 --- a/src/newgrf/newgrf_act0_trains.cpp +++ b/src/newgrf/newgrf_act0_trains.cpp @@ -293,10 +293,10 @@ ChangeInfoResult RailVehicleChangeInfo(uint first, uint last, int prop, ByteRead _gted[e->index].UpdateRefittability(prop == 0x2C && count != 0); if (prop == 0x2C) _gted[e->index].defaultcargo_grf = _cur_gps.grffile; CargoTypes &ctt = prop == 0x2C ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask; - ctt = 0; + ctt.Reset(); while (count--) { CargoType ctype = GetCargoTranslation(buf.ReadByte(), _cur_gps.grffile); - if (IsValidCargoType(ctype)) SetBit(ctt, ctype); + if (IsValidCargoType(ctype)) ctt.Set(ctype); } break; } diff --git a/src/newgrf_animation_base.h b/src/newgrf_animation_base.h index 892bca230a..d72afd9311 100644 --- a/src/newgrf_animation_base.h +++ b/src/newgrf_animation_base.h @@ -49,7 +49,7 @@ struct AnimationBase { * @param random_animation Whether to pass random bits to the "next frame" callback. * @param extra_data Custom extra callback data. */ - static void AnimateTile(const Tspec *spec, Tobj *obj, TileIndex tile, bool random_animation, Textra extra_data = 0) + static void AnimateTile(const Tspec *spec, Tobj *obj, TileIndex tile, bool random_animation, Textra extra_data = {}) { assert(spec != nullptr); @@ -128,7 +128,7 @@ struct AnimationBase { * @param trigger What triggered this update? To be passed as parameter to the NewGRF. * @param extra_data Custom extra data for callback processing. */ - static void ChangeAnimationFrame(CallbackID cb, const Tspec *spec, Tobj *obj, TileIndex tile, uint32_t random_bits, uint32_t trigger, Textra extra_data = 0) + static void ChangeAnimationFrame(CallbackID cb, const Tspec *spec, Tobj *obj, TileIndex tile, uint32_t random_bits, uint32_t trigger, Textra extra_data = {}) { uint16_t callback = GetCallback(cb, random_bits, trigger, spec, obj, tile, extra_data); if (callback == CALLBACK_FAILED) return; diff --git a/src/newgrf_commons.h b/src/newgrf_commons.h index ab2d88fe5a..472e5d80c3 100644 --- a/src/newgrf_commons.h +++ b/src/newgrf_commons.h @@ -462,9 +462,9 @@ struct VariableGRFFileProps : GRFFilePropsBase { * Sprite groups indexed by CargoType. */ struct CargoGRFFileProps : VariableGRFFileProps { - static constexpr CargoType SG_DEFAULT = NUM_CARGO; ///< Default type used when no more-specific cargo matches. - static constexpr CargoType SG_PURCHASE = NUM_CARGO + 1; ///< Used in purchase lists before an item exists. - static constexpr CargoType SG_DEFAULT_NA = NUM_CARGO + 2; ///< Used only by stations and roads when no more-specific cargo matches. + static constexpr CargoType SG_DEFAULT{NUM_CARGO}; ///< Default type used when no more-specific cargo matches. + static constexpr CargoType SG_PURCHASE{NUM_CARGO + 1}; ///< Used in purchase lists before an item exists. + static constexpr CargoType SG_DEFAULT_NA{NUM_CARGO + 2}; ///< Used only by stations and roads when no more-specific cargo matches. }; /** diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp index 0aada28724..3aa02f3059 100644 --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -440,7 +440,7 @@ struct NewGRFInspectWindow : Window { { switch (nip.type) { case NIT_INT: return GetString(STR_JUST_INT, value); - case NIT_CARGO: return GetString(IsValidCargoType(value) ? CargoSpec::Get(value)->name : STR_QUANTITY_N_A); + case NIT_CARGO: return GetString(IsValidCargoType(static_cast(value)) ? CargoSpec::Get(value)->name : STR_QUANTITY_N_A); default: NOT_REACHED(); } } diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index 1adf26809a..753f4b8f01 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -479,7 +479,7 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec } /* The cargo translation is specific to the accessing GRF, and thus cannot be cached. */ - CargoType common_cargo_type = (v->grf_cache.consist_cargo_information >> 8) & 0xFF; + CargoType common_cargo_type = static_cast(GB(v->grf_cache.consist_cargo_information, 8, 8)); /* Note: * - Unlike everywhere else the cargo translation table is only used since grf version 8, not 7. diff --git a/src/newgrf_generic.cpp b/src/newgrf_generic.cpp index 54082660a2..9638b6c945 100644 --- a/src/newgrf_generic.cpp +++ b/src/newgrf_generic.cpp @@ -36,7 +36,7 @@ struct GenericScopeResolver : public ScopeResolver { * @param ai_callback Callback comes from the AI. */ GenericScopeResolver(ResolverObject &ro, bool ai_callback) - : ScopeResolver(ro), cargo_type(0), default_selection(0), src_industry(0), dst_industry(0), distance(0), + : ScopeResolver(ro), cargo_type(INVALID_CARGO), default_selection(0), src_industry(0), dst_industry(0), distance(0), event(), count(0), station_size(0), feature(GrfSpecFeature::Invalid), ai_callback(ai_callback) { } diff --git a/src/newgrf_house.cpp b/src/newgrf_house.cpp index eb4842f985..26966acfdc 100644 --- a/src/newgrf_house.cpp +++ b/src/newgrf_house.cpp @@ -400,7 +400,7 @@ static uint32_t GetDistanceFromNearbyHouse(uint8_t parameter, TileIndex start_ti } /* Cargo triggered CB 148? */ - if (HasBit(this->watched_cargo_triggers, cargo_type)) SetBit(res, 4); + if (this->watched_cargo_triggers.Test(cargo_type)) SetBit(res, 4); return res; } @@ -451,6 +451,21 @@ static uint32_t GetDistanceFromNearbyHouse(uint8_t parameter, TileIndex start_ti return UINT_MAX; } +/** + * Get the result of a house callback. + * @param callback Callback ID. + * @param param1 First parameter (var 10) of the callback. + * @param param2 Second parameter (var 18) of the callback. + * @param house_id House to query. + * @param town %Town containing the house. + * @param tile %Tile containing the house. + * @param[out] regs100 Additional result values from registers 100+. + * @param not_yet_constructed House is still under construction. + * @param initial_random_bits Random bits during construction checks. + * @param watched_cargo_triggers Cargo types that triggered the watched cargo callback. + * @param view The house's 'view'. + * @return The NewGRF result of the callback. + */ uint16_t GetHouseCallback(CallbackID callback, uint32_t param1, uint32_t param2, HouseID house_id, Town *town, TileIndex tile, std::span regs100, bool not_yet_constructed, uint8_t initial_random_bits, CargoTypes watched_cargo_triggers, int view) { @@ -737,9 +752,9 @@ void TriggerHouseAnimation_WatchedCargoAccepted(TileIndex tile, CargoTypes trigg HouseID id = GetHouseType(tile); const HouseSpec *hs = HouseSpec::Get(id); - trigger_cargoes &= hs->watched_cargoes; + trigger_cargoes = trigger_cargoes & hs->watched_cargoes; /* None of the trigger cargoes is watched? */ - if (trigger_cargoes == 0) return; + if (trigger_cargoes.None()) return; /* Same random value for all tiles of a multi-tile house. */ uint16_t r = Random(); diff --git a/src/newgrf_house.h b/src/newgrf_house.h index d02f750c62..7dbbafcfa7 100644 --- a/src/newgrf_house.h +++ b/src/newgrf_house.h @@ -56,7 +56,7 @@ struct HouseResolverObject : public SpecializedResolverObject regs100 = {}, - bool not_yet_constructed = false, uint8_t initial_random_bits = 0, CargoTypes watched_cargo_triggers = 0, int view = 0); + bool not_yet_constructed = false, uint8_t initial_random_bits = 0, CargoTypes watched_cargo_triggers = {}, int view = 0); bool CanDeleteHouse(TileIndex tile); diff --git a/src/newgrf_roadstop.cpp b/src/newgrf_roadstop.cpp index dbb9ceb25b..db0906b0fb 100644 --- a/src/newgrf_roadstop.cpp +++ b/src/newgrf_roadstop.cpp @@ -239,7 +239,7 @@ RoadStopResolverObject::RoadStopResolverObject(const RoadStopSpec *roadstopspec, /* Pick the first cargo that we have waiting */ for (const auto &[cargo, spritegroup] : roadstopspec->grf_prop.spritegroups) { if (cargo < NUM_CARGO && station->goods[cargo].TotalCount() > 0) { - ctype = cargo; + ctype = static_cast(cargo); this->root_spritegroup = spritegroup; break; } @@ -449,8 +449,8 @@ void TriggerRoadStopRandomisation(BaseStation *st, TileIndex tile, StationRandom /* Check the cached cargo trigger bitmask to see if we need * to bother with any further processing. * Note: cached_roadstop_cargo_triggers must be non-zero even for cargo-independent triggers. */ - if (st->cached_roadstop_cargo_triggers == 0) return; - if (IsValidCargoType(cargo_type) && !HasBit(st->cached_roadstop_cargo_triggers, cargo_type)) return; + if (st->cached_roadstop_cargo_triggers.None()) return; + if (IsValidCargoType(cargo_type) && !st->cached_roadstop_cargo_triggers.Test(cargo_type)) return; TriggerArea ta = tas[to_underlying(trigger)]; if (ta == TA_WHOLE) st->waiting_random_triggers.Set(trigger); @@ -458,10 +458,9 @@ void TriggerRoadStopRandomisation(BaseStation *st, TileIndex tile, StationRandom uint32_t whole_reseed = 0; - /* Bitmask of completely empty cargo types to be matched. */ - CargoTypes empty_mask{}; + CargoTypes cargo_waiting{}; if (trigger == StationRandomTrigger::CargoTaken) { - empty_mask = GetEmptyMask(Station::From(st)); + cargo_waiting = GetCargoWaitingMask(Station::From(st)); } auto process_tile = [&](TileIndex cur_tile) { @@ -473,10 +472,10 @@ void TriggerRoadStopRandomisation(BaseStation *st, TileIndex tile, StationRandom /* Cargo taken "will only be triggered if all of those * cargo types have no more cargo waiting." */ if (trigger == StationRandomTrigger::CargoTaken) { - if ((ss->cargo_triggers & ~empty_mask) != 0) return; + if (ss->cargo_triggers.Any(cargo_waiting)) return; } - if (!IsValidCargoType(cargo_type) || HasBit(ss->cargo_triggers, cargo_type)) { + if (!IsValidCargoType(cargo_type) || ss->cargo_triggers.Test(cargo_type)) { RoadStopResolverObject object(ss, st, cur_tile, INVALID_ROADTYPE, GetStationType(cur_tile), GetStationGfx(cur_tile)); object.SetWaitingRandomTriggers(st->waiting_random_triggers | st->tile_waiting_random_triggers[tile]); @@ -675,7 +674,7 @@ void DeallocateSpecFromRoadStop(BaseStation *st, uint8_t specindex) } else { st->roadstop_speclist.clear(); st->cached_roadstop_anim_triggers = {}; - st->cached_roadstop_cargo_triggers = 0; + st->cached_roadstop_cargo_triggers.Reset(); return; } } @@ -690,13 +689,13 @@ void DeallocateSpecFromRoadStop(BaseStation *st, uint8_t specindex) void RoadStopUpdateCachedTriggers(BaseStation *st) { st->cached_roadstop_anim_triggers = {}; - st->cached_roadstop_cargo_triggers = 0; + st->cached_roadstop_cargo_triggers.Reset(); /* Combine animation trigger bitmask for all road stop specs * of this station. */ for (const auto &sm : GetStationSpecList(st)) { if (sm.spec == nullptr) continue; st->cached_roadstop_anim_triggers.Set(sm.spec->animation.triggers); - st->cached_roadstop_cargo_triggers |= sm.spec->cargo_triggers; + st->cached_roadstop_cargo_triggers.Set(sm.spec->cargo_triggers); } } diff --git a/src/newgrf_roadstop.h b/src/newgrf_roadstop.h index fab53e7413..2a57f65a64 100644 --- a/src/newgrf_roadstop.h +++ b/src/newgrf_roadstop.h @@ -131,7 +131,7 @@ struct RoadStopSpec : NewGRFSpecBase { RoadStopCallbackMasks callback_mask{}; RoadStopSpecFlags flags{}; - CargoTypes cargo_triggers = 0; ///< Bitmask of cargo types which cause trigger re-randomizing + CargoTypes cargo_triggers{}; ///< Bitmask of cargo types which cause trigger re-randomizing AnimationInfo animation; diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index 4bf02b50ea..34424f1358 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -427,7 +427,7 @@ uint32_t Station::GetNewGRFVariable(const ResolverObject &object, uint8_t variab { switch (variable) { case 0x48: { // Accepted cargo types - uint32_t value = GetAcceptanceMask(this); + uint32_t value = GetAcceptanceMask(this).base(); return value; } @@ -607,7 +607,7 @@ StationResolverObject::StationResolverObject(const StationSpec *statspec, BaseSt /* Pick the first cargo that we have waiting */ for (const auto &[cargo, spritegroup] : statspec->grf_prop.spritegroups) { if (cargo < NUM_CARGO && st->goods[cargo].TotalCount() > 0) { - ctype = cargo; + ctype = static_cast(cargo); break; } } @@ -804,7 +804,7 @@ void DeallocateSpecFromStation(BaseStation *st, uint8_t specindex) } else { st->speclist.clear(); st->cached_anim_triggers = {}; - st->cached_cargo_triggers = 0; + st->cached_cargo_triggers.Reset(); return; } } @@ -989,15 +989,14 @@ void TriggerStationRandomisation(BaseStation *st, TileIndex trigger_tile, Statio /* Check the cached cargo trigger bitmask to see if we need * to bother with any further processing. * Note: cached_cargo_triggers must be non-zero even for cargo-independent triggers. */ - if (st->cached_cargo_triggers == 0) return; - if (IsValidCargoType(cargo_type) && !HasBit(st->cached_cargo_triggers, cargo_type)) return; + if (st->cached_cargo_triggers.None()) return; + if (IsValidCargoType(cargo_type) && !st->cached_cargo_triggers.Test(cargo_type)) return; uint32_t whole_reseed = 0; - /* Bitmask of completely empty cargo types to be matched. */ - CargoTypes empty_mask{}; + CargoTypes cargo_waiting{}; if (trigger == StationRandomTrigger::CargoTaken) { - empty_mask = GetEmptyMask(Station::From(st)); + cargo_waiting = GetCargoWaitingMask(Station::From(st)); } /* Store triggers now for var 5F */ @@ -1017,10 +1016,10 @@ void TriggerStationRandomisation(BaseStation *st, TileIndex trigger_tile, Statio /* Cargo taken "will only be triggered if all of those * cargo types have no more cargo waiting." */ if (trigger == StationRandomTrigger::CargoTaken) { - if ((ss->cargo_triggers & ~empty_mask) != 0) continue; + if (ss->cargo_triggers.Any(cargo_waiting)) continue; } - if (!IsValidCargoType(cargo_type) || HasBit(ss->cargo_triggers, cargo_type)) { + if (!IsValidCargoType(cargo_type) || ss->cargo_triggers.Test(cargo_type)) { StationResolverObject object(ss, st, tile, CBID_RANDOM_TRIGGER, 0); object.SetWaitingRandomTriggers(st->waiting_random_triggers | st->tile_waiting_random_triggers[tile]); @@ -1061,14 +1060,14 @@ void TriggerStationRandomisation(BaseStation *st, TileIndex trigger_tile, Statio void StationUpdateCachedTriggers(BaseStation *st) { st->cached_anim_triggers = {}; - st->cached_cargo_triggers = 0; + st->cached_cargo_triggers.Reset(); /* Combine animation trigger bitmask for all station specs * of this station. */ for (const auto &sm : GetStationSpecList(st)) { if (sm.spec == nullptr) continue; st->cached_anim_triggers.Set(sm.spec->animation.triggers); - st->cached_cargo_triggers |= sm.spec->cargo_triggers; + st->cached_cargo_triggers.Set(sm.spec->cargo_triggers); } } diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index bb3e6690f6..3d4006c312 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -636,7 +636,7 @@ static void AddAcceptedCargo_Object(TileIndex tile, CargoArray &acceptance, Carg CargoType pass = GetCargoTypeByLabel(CT_PASSENGERS); if (IsValidCargoType(pass)) { acceptance[pass] += std::max(1U, level); - SetBit(always_accepted, pass); + always_accepted.Set(pass); } /* Top town building generates 4, HQ can make up to 8. The @@ -646,7 +646,7 @@ static void AddAcceptedCargo_Object(TileIndex tile, CargoArray &acceptance, Carg CargoType mail = GetCargoTypeByLabel(CT_MAIL); if (IsValidCargoType(mail)) { acceptance[mail] += std::max(1U, level / 2); - SetBit(always_accepted, mail); + always_accepted.Set(mail); } } diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index 7629545544..78e0499a82 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -631,10 +631,10 @@ static bool LoadOldTown(LoadgameState &ls, int num) t->townnametype = t->townnametype == 0x10B6 ? 0x20C1 : t->townnametype + 0x2A00; } /* Passengers and mail were always treated as slots 0 and 2 in older saves. */ - auto &pass = t->supplied.emplace_back(0); + auto &pass = t->supplied.emplace_back(CargoType{0}); pass.history[LAST_MONTH] = _old_pass_supplied[LAST_MONTH]; pass.history[THIS_MONTH] = _old_pass_supplied[THIS_MONTH]; - auto &mail = t->supplied.emplace_back(2); + auto &mail = t->supplied.emplace_back(CargoType{2}); mail.history[LAST_MONTH] = _old_mail_supplied[LAST_MONTH]; mail.history[THIS_MONTH] = _old_mail_supplied[THIS_MONTH]; } else { diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index 7873a393cb..5cc7641c76 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -398,10 +398,10 @@ struct CITYChunkHandler : ChunkHandler { if (IsSavegameVersionBefore(SLV_165)) { /* Passengers and mail were always treated as slots 0 and 2 in older saves. */ - auto &pass = t->supplied.emplace_back(0); + auto &pass = t->supplied.emplace_back(CargoType{0}); pass.history[LAST_MONTH] = _old_pass_supplied[LAST_MONTH]; pass.history[THIS_MONTH] = _old_pass_supplied[THIS_MONTH]; - auto &mail = t->supplied.emplace_back(2); + auto &mail = t->supplied.emplace_back(CargoType{2}); mail.history[LAST_MONTH] = _old_mail_supplied[LAST_MONTH]; mail.history[THIS_MONTH] = _old_mail_supplied[THIS_MONTH]; } diff --git a/src/script/api/script_cargo.cpp b/src/script/api/script_cargo.cpp index e4eb1098df..75a4eb7030 100644 --- a/src/script/api/script_cargo.cpp +++ b/src/script/api/script_cargo.cpp @@ -32,7 +32,8 @@ { if (!IsValidCargo(cargo_type)) return std::nullopt; - return ::StrMakeValid(::GetString(STR_JUST_CARGO_LIST, 1ULL << cargo_type), {}); + CargoTypes cargotypes{cargo_type}; + return ::StrMakeValid(::GetString(STR_JUST_CARGO_LIST, cargotypes), {}); } /* static */ std::optional ScriptCargo::GetCargoLabel(CargoType cargo_type) diff --git a/src/script/api/script_cargolist.cpp b/src/script/api/script_cargolist.cpp index aa403603e1..e72b11298b 100644 --- a/src/script/api/script_cargolist.cpp +++ b/src/script/api/script_cargolist.cpp @@ -53,7 +53,7 @@ ScriptCargoList_StationAccepting::ScriptCargoList_StationAccepting(StationID sta if (!ScriptStation::IsValidStation(station_id)) return; const Station *st = ::Station::Get(station_id); - for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) { + for (CargoType cargo{}; cargo < NUM_CARGO; ++cargo) { if (st->goods[cargo].status.Test(GoodsEntry::State::Acceptance)) this->AddItem(cargo); } } diff --git a/src/script/api/script_engine.cpp b/src/script/api/script_engine.cpp index 8fdabf1096..2190f12810 100644 --- a/src/script/api/script_engine.cpp +++ b/src/script/api/script_engine.cpp @@ -67,7 +67,7 @@ if (!IsValidEngine(engine_id)) return false; if (!ScriptCargo::IsValidCargo(cargo_type)) return false; - return HasBit(::GetUnionOfArticulatedRefitMasks(engine_id, true), cargo_type); + return ::GetUnionOfArticulatedRefitMasks(engine_id, true).Test(cargo_type); } /* static */ bool ScriptEngine::CanPullCargo(EngineID engine_id, CargoType cargo_type) diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp index edbd117896..057291d218 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -1260,9 +1260,9 @@ protected: */ void SetOverlayCargoMask() { - CargoTypes cargo_mask = 0; + CargoTypes cargo_mask{}; for (int i = 0; i != _smallmap_cargo_count; ++i) { - if (_legend_linkstats[i].show_on_map) SetBit(cargo_mask, _legend_linkstats[i].type); + if (_legend_linkstats[i].show_on_map) cargo_mask.Set(static_cast(_legend_linkstats[i].type)); } this->overlay->SetCargoMask(cargo_mask); } @@ -1459,7 +1459,7 @@ public: SmallMapWindow(WindowDesc &desc, int window_number) : Window(desc) { _smallmap_industry_highlight = IT_INVALID; - this->overlay = std::make_unique(this, WID_SM_MAP, 0, this->GetOverlayCompanyMask(), 1); + this->overlay = std::make_unique(this, WID_SM_MAP, CargoTypes{}, this->GetOverlayCompanyMask(), 1); this->CreateNestedTree(); this->LowerWidget(WID_SM_CONTOUR + this->map_type); diff --git a/src/station.cpp b/src/station.cpp index d60c275035..dbac838595 100644 --- a/src/station.cpp +++ b/src/station.cpp @@ -100,7 +100,7 @@ Station::~Station() if (a->targetairport == this->index) a->targetairport = StationID::Invalid(); } - for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) { + for (CargoType cargo{}; cargo < NUM_CARGO; ++cargo) { LinkGraph *lg = LinkGraph::GetIfValid(this->goods[cargo].link_graph); if (lg == nullptr) continue; diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 3e1087fd06..d5fa20f51f 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -506,25 +506,25 @@ void ClearAllStationCachedNames() */ CargoTypes GetAcceptanceMask(const Station *st) { - CargoTypes mask = 0; + CargoTypes mask{}; for (auto it = std::begin(st->goods); it != std::end(st->goods); ++it) { - if (it->status.Test(GoodsEntry::State::Acceptance)) SetBit(mask, std::distance(std::begin(st->goods), it)); + if (it->status.Test(GoodsEntry::State::Acceptance)) mask.Set(static_cast(std::distance(std::begin(st->goods), it))); } return mask; } /** - * Get a mask of the cargo types that are empty at the station. + * Get a mask of the cargo types that have cargo waiting at the station. * @param st Station to query - * @return the empty mask + * @return cargo types that have cargo waiting */ -CargoTypes GetEmptyMask(const Station *st) +CargoTypes GetCargoWaitingMask(const Station *st) { - CargoTypes mask = 0; + CargoTypes mask{}; for (auto it = std::begin(st->goods); it != std::end(st->goods); ++it) { - if (it->TotalCount() == 0) SetBit(mask, std::distance(std::begin(st->goods), it)); + if (it->TotalCount() > 0) mask.Set(static_cast(std::distance(std::begin(st->goods), it))); } return mask; } @@ -638,7 +638,7 @@ void UpdateStationAcceptance(Station *st, bool show_msg) } /* Adjust in case our station only accepts fewer kinds of goods */ - for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) { + for (CargoType cargo{}; cargo < NUM_CARGO; ++cargo) { uint amt = acceptance[cargo]; /* Make sure the station can accept the goods type. */ @@ -662,12 +662,12 @@ void UpdateStationAcceptance(Station *st, bool show_msg) /* show a message to report that the acceptance was changed? */ if (show_msg && st->owner == _local_company && st->IsInUse()) { /* Combine old and new masks to get changes */ - CargoTypes accepts = new_acc & ~old_acc; - CargoTypes rejects = ~new_acc & old_acc; + CargoTypes accepts = new_acc & CargoTypes{old_acc}.Flip(); + CargoTypes rejects = CargoTypes{new_acc}.Flip() & old_acc; /* Show news message if there are any changes */ - if (accepts != 0) ShowRejectOrAcceptNews(st, accepts, false); - if (rejects != 0) ShowRejectOrAcceptNews(st, rejects, true); + if (accepts.Any()) ShowRejectOrAcceptNews(st, accepts, false); + if (rejects.Any()) ShowRejectOrAcceptNews(st, rejects, true); } /* redraw the station view since acceptance changed */ @@ -3914,13 +3914,13 @@ static VehicleEnterTileStates VehicleEnterTile_Station(Vehicle *v, TileIndex til void TriggerWatchedCargoCallbacks(Station *st) { /* Collect cargoes accepted since the last big tick. */ - CargoTypes cargoes = 0; - for (CargoType cargo_type = 0; cargo_type < NUM_CARGO; cargo_type++) { - if (st->goods[cargo_type].status.Test(GoodsEntry::State::AcceptedBigtick)) SetBit(cargoes, cargo_type); + CargoTypes cargoes{}; + for (CargoType cargo_type{}; cargo_type < NUM_CARGO; ++cargo_type) { + if (st->goods[cargo_type].status.Test(GoodsEntry::State::AcceptedBigtick)) cargoes.Set(cargo_type); } /* Anything to do? */ - if (cargoes == 0) return; + if (cargoes.None()) return; /* Loop over all houses in the catchment. */ BitmapTileIterator it(st->catchment_tiles); @@ -4189,7 +4189,7 @@ void RerouteCargo(Station *st, CargoType cargo, StationID avoid, StationID avoid */ void DeleteStaleLinks(Station *from) { - for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) { + for (CargoType cargo{}; cargo < NUM_CARGO; ++cargo) { const bool auto_distributed = (_settings_game.linkgraph.GetDistributionType(cargo) != DistributionType::Manual); GoodsEntry &ge = from->goods[cargo]; LinkGraph *lg = LinkGraph::GetIfValid(ge.link_graph); diff --git a/src/station_func.h b/src/station_func.h index aa52f00dca..89a6bf6076 100644 --- a/src/station_func.h +++ b/src/station_func.h @@ -31,7 +31,7 @@ std::pair GetAcceptanceAroundTiles(TileIndex tile, int w void UpdateStationAcceptance(Station *st, bool show_msg); CargoTypes GetAcceptanceMask(const Station *st); -CargoTypes GetEmptyMask(const Station *st); +CargoTypes GetCargoWaitingMask(const Station *st); void SetRailStationTileFlags(TileIndex tile, const StationSpec *statspec); const DrawTileSprites *GetStationTileLayout(StationType st, uint8_t gfx); diff --git a/src/station_gui.cpp b/src/station_gui.cpp index f11528f200..edb2e846c7 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -77,7 +77,7 @@ using RoadWaypointTypeFilter = GenericWaypointTypeFilter; int DrawStationCoverageAreaText(const Rect &r, StationCoverageType sct, int rad, bool supplies) { TileIndex tile = TileVirtXY(_thd.pos.x, _thd.pos.y); - CargoTypes cargo_mask = 0; + CargoTypes cargo_mask{}; if (_thd.drawstyle == HT_RECT && tile < Map::Size()) { CargoArray cargoes; if (supplies) { @@ -87,14 +87,14 @@ int DrawStationCoverageAreaText(const Rect &r, StationCoverageType sct, int rad, } /* Convert cargo counts to a set of cargo bits, and draw the result. */ - for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) { + for (CargoType cargo{}; cargo < NUM_CARGO; ++cargo) { switch (sct) { case SCT_PASSENGERS_ONLY: if (!IsCargoInClass(cargo, CargoClass::Passengers)) continue; break; case SCT_NON_PASSENGERS_ONLY: if (IsCargoInClass(cargo, CargoClass::Passengers)) continue; break; case SCT_ALL: break; default: NOT_REACHED(); } - if (cargoes[cargo] >= (supplies ? 1U : 8U)) SetBit(cargo_mask, cargo); + if (cargoes[cargo] >= (supplies ? 1U : 8U)) cargo_mask.Set(cargo); } } return DrawStringMultiLine(r, GetString(supplies ? STR_STATION_BUILD_SUPPLIES_CARGO : STR_STATION_BUILD_ACCEPTS_CARGO, cargo_mask)); @@ -315,13 +315,13 @@ protected: if (st->owner == owner || (st->owner == OWNER_NONE && HasStationInUse(st->index, true, owner))) { bool has_rating = false; /* Add to the station/cargo counts. */ - for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) { + for (CargoType cargo{}; cargo < NUM_CARGO; ++cargo) { if (st->goods[cargo].HasRating()) this->stations_per_cargo_type[cargo]++; } - for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) { + for (CargoType cargo{}; cargo < NUM_CARGO; ++cargo) { if (st->goods[cargo].HasRating()) { has_rating = true; - if (HasBit(this->filter.cargoes, cargo)) { + if (this->filter.cargoes.Test(cargo)) { this->stations.push_back(st); break; } @@ -360,7 +360,7 @@ protected: { int diff = 0; - for (CargoType cargo : SetCargoBitIterator(filter)) { + for (CargoType cargo : filter) { diff += a->goods[cargo].TotalCount() - b->goods[cargo].TotalCount(); } @@ -372,7 +372,7 @@ protected: { int diff = 0; - for (CargoType cargo : SetCargoBitIterator(filter)) { + for (CargoType cargo : filter) { diff += a->goods[cargo].AvailableCount() - b->goods[cargo].AvailableCount(); } @@ -385,7 +385,7 @@ protected: uint8_t maxr1 = 0; uint8_t maxr2 = 0; - for (CargoType cargo : SetCargoBitIterator(filter)) { + for (CargoType cargo : filter) { if (a->goods[cargo].HasRating()) maxr1 = std::max(maxr1, a->goods[cargo].rating); if (b->goods[cargo].HasRating()) maxr2 = std::max(maxr2, b->goods[cargo].rating); } @@ -399,7 +399,7 @@ protected: uint8_t minr1 = 255; uint8_t minr2 = 255; - for (CargoType cargo : SetCargoBitIterator(filter)) { + for (CargoType cargo : filter) { if (a->goods[cargo].HasRating()) minr1 = std::min(minr1, a->goods[cargo].rating); if (b->goods[cargo].HasRating()) minr2 = std::min(minr2, b->goods[cargo].rating); } @@ -560,9 +560,9 @@ public: } if (widget == WID_STL_CARGODROPDOWN) { - if (this->filter.cargoes == 0) return GetString(this->filter.include_no_rating ? STR_STATION_LIST_CARGO_FILTER_ONLY_NO_RATING : STR_STATION_LIST_CARGO_FILTER_NO_CARGO_TYPES); + if (this->filter.cargoes.None()) return GetString(this->filter.include_no_rating ? STR_STATION_LIST_CARGO_FILTER_ONLY_NO_RATING : STR_STATION_LIST_CARGO_FILTER_NO_CARGO_TYPES); if (this->filter.cargoes == _cargo_mask) return GetString(this->filter.include_no_rating ? STR_STATION_LIST_CARGO_FILTER_ALL_AND_NO_RATING : STR_CARGO_TYPE_FILTER_ALL); - if (CountBits(this->filter.cargoes) == 1 && !this->filter.include_no_rating) return GetString(CargoSpec::Get(FindFirstBit(this->filter.cargoes))->name); + if (this->filter.cargoes.Count() == 1 && !this->filter.include_no_rating) return GetString(CargoSpec::Get(*this->filter.cargoes.begin())->name); return GetString(STR_STATION_LIST_CARGO_FILTER_MULTIPLE); } @@ -593,7 +593,7 @@ public: if (count == 0 && !expanded) { any_hidden = true; } else { - list.push_back(std::make_unique(HasBit(this->filter.cargoes, cs->Index()), fmt::format("{}", count), d, cs->GetCargoIcon(), PAL_NONE, GetString(cs->name), cs->Index(), false, count == 0)); + list.push_back(std::make_unique(this->filter.cargoes.Test(cs->Index()), fmt::format("{}", count), d, cs->GetCargoIcon(), PAL_NONE, GetString(cs->name), cs->Index(), false, count == 0)); } } @@ -690,9 +690,9 @@ public: if (index >= 0 && index < NUM_CARGO) { if (_ctrl_pressed) { - ToggleBit(this->filter.cargoes, index); + this->filter.cargoes.Flip(static_cast(index)); } else { - this->filter.cargoes = 1ULL << index; + this->filter.cargoes = static_cast(index); this->filter.include_no_rating = false; } } else if (index == CargoFilterCriteria::CF_NO_RATING) { @@ -700,7 +700,7 @@ public: this->filter.include_no_rating = !this->filter.include_no_rating; } else { this->filter.include_no_rating = true; - this->filter.cargoes = 0; + this->filter.cargoes.Reset(); } } else if (index == CargoFilterCriteria::CF_SELECT_ALL) { this->filter.cargoes = _cargo_mask; @@ -1666,7 +1666,7 @@ struct StationViewWindow : public Window { */ void BuildCargoList(CargoDataEntry *entry, const Station *st) { - for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) { + for (CargoType cargo{}; cargo < NUM_CARGO; ++cargo) { if (this->cached_destinations.Retrieve(cargo) == nullptr) { this->RecalcDestinations(cargo); diff --git a/src/strings.cpp b/src/strings.cpp index a5018f9bdd..69fb628452 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -1458,7 +1458,7 @@ static void FormatString(StringBuilder &builder, std::string_view str_arg, Strin std::string_view list_separator = GetListSeparator(); for (const auto &cs : _sorted_cargo_specs) { - if (!HasBit(cmask, cs->Index())) continue; + if (!cmask.Test(cs->Index())) continue; if (first) { first = false; diff --git a/src/subsidy.cpp b/src/subsidy.cpp index 1bc88655fb..559e952509 100644 --- a/src/subsidy.cpp +++ b/src/subsidy.cpp @@ -296,8 +296,8 @@ bool FindSubsidyTownCargoRoute() /* Choose a random cargo that is produced in the town. */ uint8_t cargo_number = RandomRange(cargo_count); - CargoType cargo_type; - for (cargo_type = 0; cargo_type < NUM_CARGO; cargo_type++) { + CargoType cargo_type{}; + for (; cargo_type < NUM_CARGO; ++cargo_type) { if (town_cargo_produced[cargo_type] > 0) { if (cargo_number == 0) break; cargo_number--; diff --git a/src/table/engines.h b/src/table/engines.h index c5fee5d0f6..9683ba9c1d 100644 --- a/src/table/engines.h +++ b/src/table/engines.h @@ -23,7 +23,7 @@ * @param f Bitmask of the climates * @note the 5 between b and f is the load amount */ -#define MT(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 5, f, INVALID_CARGO, e, 0, 8, EngineMiscFlags{}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() } +#define MT(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 5, f, INVALID_CARGO, e, CargoTypes{}, 8, EngineMiscFlags{}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() } /** * Writes the properties of a multiple-unit train into the EngineInfo struct. @@ -36,7 +36,7 @@ * @param f Bitmask of the climates * @note the 5 between b and f is the load amount */ -#define MM(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 5, f, INVALID_CARGO, e, 0, 8, EngineMiscFlags{EngineMiscFlag::RailIsMU}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() } +#define MM(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 5, f, INVALID_CARGO, e, CargoTypes{}, 8, EngineMiscFlags{EngineMiscFlag::RailIsMU}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() } /** * Writes the properties of a train carriage into the EngineInfo struct. @@ -49,7 +49,7 @@ * @see MT * @note the 5 between b and f is the load amount */ -#define MW(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 5, f, INVALID_CARGO, e, 0, 8, EngineMiscFlags{}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() } +#define MW(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 5, f, INVALID_CARGO, e, CargoTypes{}, 8, EngineMiscFlags{}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() } /** * Writes the properties of a road vehicle into the EngineInfo struct. @@ -62,7 +62,7 @@ * @param f Bitmask of the climates * @note the 5 between b and f is the load amount */ -#define MR(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 5, f, INVALID_CARGO, e, 0, 8, EngineMiscFlags{}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() } +#define MR(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 5, f, INVALID_CARGO, e, CargoTypes{}, 8, EngineMiscFlags{}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() } /** * Writes the properties of a ship into the EngineInfo struct. @@ -74,7 +74,7 @@ * @param f Bitmask of the climates * @note the 10 between b and f is the load amount */ -#define MS(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 10, f, INVALID_CARGO, e, 0, 8, EngineMiscFlags{}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() } +#define MS(a, b, c, d, e, f) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 10, f, INVALID_CARGO, e, CargoTypes{}, 8, EngineMiscFlags{}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() } /** * Writes the properties of an aeroplane into the EngineInfo struct. @@ -85,7 +85,7 @@ * @param e Bitmask of the climates * @note the 20 between b and e is the load amount */ -#define MA(a, b, c, d, e) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 20, e, INVALID_CARGO, CT_INVALID, 0, 8, EngineMiscFlags{}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() } +#define MA(a, b, c, d, e) { CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR + a, TimerGameCalendar::Year{c}, TimerGameCalendar::Year{d}, b, 20, e, INVALID_CARGO, CT_INVALID, CargoTypes{}, 8, EngineMiscFlags{}, VehicleCallbackMasks{}, 0, {}, STR_EMPTY, Ticks::CARGO_AGING_TICKS, EngineID::Invalid() } /** Climate temperate. */ #define T LandscapeType::Temperate diff --git a/src/table/town_land.h b/src/table/town_land.h index 183b48f817..c255e591bf 100644 --- a/src/table/town_land.h +++ b/src/table/town_land.h @@ -1814,7 +1814,7 @@ static_assert(lengthof(_town_draw_tile_data) == (NEW_HOUSE_OFFSET) * 4 * 4); {ca1, ca2, ca3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \ {INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO, INVALID_CARGO}, \ bf, ba, true, SubstituteGRFFileProps(INVALID_HOUSE_ID), HouseCallbackMasks{}, {Colours::Begin, Colours::Begin, Colours::Begin, Colours::Begin}, \ - 16, HouseExtraFlags{}, HOUSE_NO_CLASS, AnimationInfo{}, 0, 0, 0, {}, {cg1, cg2, cg3}, } + 16, HouseExtraFlags{}, HOUSE_NO_CLASS, AnimationInfo{}, 0, 0, CargoTypes{}, {}, {cg1, cg2, cg3}, } /** House specifications from original data */ extern const HouseSpec _original_house_specs[] = { /** diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 6b4612e41b..92065281ea 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -770,7 +770,7 @@ static void AddAcceptedCargoSetMask(CargoType cargo, uint amount, CargoArray &ac { if (!IsValidCargoType(cargo) || amount == 0) return; acceptance[cargo] += amount; - SetBit(always_accepted, cargo); + always_accepted.Set(cargo); } /** diff --git a/src/town_gui.cpp b/src/town_gui.cpp index f88eeab11c..fa539078a9 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -1641,12 +1641,12 @@ static CargoTypes GetProducedCargoOfHouse(const HouseSpec *hs) uint amt = GB(callback, 0, 8); if (amt == 0) continue; - SetBit(produced, cargo); + produced.Set(cargo); } } else { /* Cargo is not controlled by NewGRF, town production effect is used instead. */ - for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TownProductionEffect::Passengers]) SetBit(produced, cs->Index()); - for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TownProductionEffect::Mail]) SetBit(produced, cs->Index()); + for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TownProductionEffect::Passengers]) produced.Set(cs->Index()); + for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TownProductionEffect::Mail]) produced.Set(cs->Index()); } return produced; } @@ -1733,7 +1733,7 @@ struct BuildHouseWindow : public PickerWindow { } CargoTypes produced = GetProducedCargoOfHouse(hs); - if (produced != 0) { + if (produced.Any()) { line << "\n"; line << GetString(STR_HOUSE_PICKER_CARGO_PRODUCED, produced); } diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 981a12aef9..5356db8a9d 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -255,10 +255,10 @@ bool Vehicle::NeedsServicing() const CargoTypes available_cargo_types, union_mask; GetArticulatedRefitMasks(new_engine, true, &union_mask, &available_cargo_types); /* Is there anything to refit? */ - if (union_mask != 0) { + if (union_mask.Any()) { CargoType cargo_type; CargoTypes cargo_mask = GetCargoTypesOfArticulatedVehicle(v, &cargo_type); - if (!HasAtMostOneBit(cargo_mask)) { + if (!HasAtMostOneBit(cargo_mask.base())) { CargoTypes new_engine_default_cargoes = GetCargoTypesOfArticulatedParts(new_engine); if ((cargo_mask & new_engine_default_cargoes) != cargo_mask) { /* We cannot refit to mixed cargoes in an automated way */ @@ -269,7 +269,7 @@ bool Vehicle::NeedsServicing() const /* Did the old vehicle carry anything? */ if (IsValidCargoType(cargo_type)) { /* We can't refit the vehicle to carry the cargo we want */ - if (!HasBit(available_cargo_types, cargo_type)) continue; + if (!available_cargo_types.Test(cargo_type)) continue; } } } diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index a9a427f819..591fdca287 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -400,7 +400,7 @@ static std::tuple RefitVehicle(Vehicle /* If the vehicle is not refittable, or does not allow automatic refitting, * count its capacity nevertheless if the cargo matches */ - bool refittable = HasBit(e->info.refit_mask, new_cargo_type) && (!auto_refit || e->info.misc_flags.Test(EngineMiscFlag::AutoRefit)); + bool refittable = e->info.refit_mask.Test(new_cargo_type) && (!auto_refit || e->info.misc_flags.Test(EngineMiscFlag::AutoRefit)); if (!refittable && v->cargo_type != new_cargo_type) { uint amount = e->DetermineCapacity(v, nullptr); if (amount > 0) cargo_capacities[v->cargo_type] += amount; diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index f6ec3b6697..e44db3b64c 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -226,10 +226,10 @@ void BaseVehicleListWindow::BuildVehicleList() GenerateVehicleSortList(&this->vehicles, this->vli); - CargoTypes used = 0; + CargoTypes used{}; for (const Vehicle *v : this->vehicles) { for (const Vehicle *u = v; u != nullptr; u = u->Next()) { - if (u->cargo_cap > 0) SetBit(used, u->cargo_type); + if (u->cargo_cap > 0) used.Set(u->cargo_type); } } this->used_cargoes = used; @@ -509,8 +509,8 @@ DropDownList BaseVehicleListWindow::BuildCargoDropDownList(bool full) const /* Add cargos */ Dimension d = GetLargestCargoIconSize(); for (const CargoSpec *cs : _sorted_cargo_specs) { - if (!full && !HasBit(this->used_cargoes, cs->Index())) continue; - list.push_back(MakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false, !HasBit(this->used_cargoes, cs->Index()))); + if (!full && !this->used_cargoes.Test(cs->Index())) continue; + list.push_back(MakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index(), false, !this->used_cargoes.Test(cs->Index()))); } return list; @@ -625,7 +625,7 @@ uint8_t GetBestFittingSubType(Vehicle *v_from, Vehicle *v_for, CargoType dest_ca for (Vehicle *v = v_for; v != nullptr; v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : nullptr) { const Engine *e = v->GetEngine(); if (!e->CanCarryCargo() || !e->info.callback_mask.Test(VehicleCallbackMask::CargoSuffix)) continue; - if (!HasBit(e->info.refit_mask, dest_cargo_type) && v->cargo_type != dest_cargo_type) continue; + if (!e->info.refit_mask.Test(dest_cargo_type) && v->cargo_type != dest_cargo_type) continue; CargoType old_cargo_type = v->cargo_type; uint8_t old_cargo_subtype = v->cargo_subtype; @@ -797,7 +797,7 @@ struct RefitWindow : public Window { for (const auto &cs : _sorted_cargo_specs) { CargoType cargo_type = cs->Index(); /* Skip cargo type if it's not listed */ - if (!HasBit(cmask, cargo_type)) continue; + if (!cmask.Test(cargo_type)) continue; auto &list = this->refit_list[cargo_type]; bool first_vehicle = list.empty(); @@ -1372,25 +1372,24 @@ void ShowVehicleRefitWindow(const Vehicle *v, VehicleOrderID order, Window *pare uint ShowRefitOptionsList(int left, int right, int y, EngineID engine) { /* List of cargo types of this engine */ - CargoTypes cmask = GetUnionOfArticulatedRefitMasks(engine, false); - /* List of cargo types available in this climate */ - CargoTypes lmask = _cargo_mask; + CargoTypes present = GetUnionOfArticulatedRefitMasks(engine, false); /* Draw nothing if the engine is not refittable */ - if (HasAtMostOneBit(cmask)) return y; + if (HasAtMostOneBit(present.base())) return y; std::string str; - if (cmask == lmask) { + if (present == _cargo_mask) { /* Engine can be refitted to all types in this climate */ str = GetString(STR_PURCHASE_INFO_REFITTABLE_TO, STR_PURCHASE_INFO_ALL_TYPES, std::monostate{}); } else { /* Check if we are able to refit to more cargo types and unable to. If * so, invert the cargo types to list those that we can't refit to. */ - if (CountBits(cmask ^ lmask) < CountBits(cmask) && CountBits(cmask ^ lmask) <= 7) { - cmask ^= lmask; - str = GetString(STR_PURCHASE_INFO_REFITTABLE_TO, STR_PURCHASE_INFO_ALL_BUT, cmask); + CargoTypes excluded = CargoTypes{present}.Flip(_cargo_mask); + uint num_excluded = excluded.Count(); + if (num_excluded < present.Count() && num_excluded <= 7) { + str = GetString(STR_PURCHASE_INFO_REFITTABLE_TO, STR_PURCHASE_INFO_ALL_BUT, excluded); } else { - str = GetString(STR_PURCHASE_INFO_REFITTABLE_TO, STR_JUST_CARGO_LIST, cmask); + str = GetString(STR_PURCHASE_INFO_REFITTABLE_TO, STR_JUST_CARGO_LIST, present); } } @@ -1820,12 +1819,12 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int if (_settings_client.gui.show_cargo_in_vehicle_lists) { /* Get the cargoes the vehicle can carry */ - CargoTypes vehicle_cargoes = 0; + CargoTypes vehicle_cargoes{}; for (auto u = v; u != nullptr; u = u->Next()) { if (u->cargo_cap == 0) continue; - SetBit(vehicle_cargoes, u->cargo_type); + vehicle_cargoes.Set(u->cargo_type); } if (!v->name.empty()) { @@ -2212,7 +2211,7 @@ public: break; case WID_VL_FILTER_BY_CARGO: - this->SetCargoFilter(index); + this->SetCargoFilter(static_cast(index)); break; case WID_VL_MANAGE_VEHICLES_DROPDOWN: diff --git a/src/viewport.cpp b/src/viewport.cpp index 32a1a3b402..a3afcea1ed 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -1853,7 +1853,7 @@ void ViewportDoDraw(const Viewport &vp, int left, int top, int right, int bottom dp.height = UnScaleByZoom(dp.height, zoom); AutoRestoreBackup cur_dpi(_cur_dpi, &dp); - if (vp.overlay != nullptr && vp.overlay->GetCargoMask() != 0 && vp.overlay->GetCompanyMask().Any()) { + if (vp.overlay != nullptr && vp.overlay->GetCargoMask().Any() && vp.overlay->GetCompanyMask().Any()) { /* translate to window coordinates */ dp.left = x; dp.top = y; @@ -2527,7 +2527,7 @@ void RebuildViewportOverlay(Window *w) { if (w->viewport->overlay != nullptr && w->viewport->overlay->GetCompanyMask().Any() && - w->viewport->overlay->GetCargoMask() != 0) { + w->viewport->overlay->GetCargoMask().Any()) { w->viewport->overlay->SetDirty(); w->SetDirty(); }