From ec492cb26791a9210398f4682530f3383cc60359 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Sat, 8 Feb 2025 10:08:36 +0100 Subject: [PATCH] Codechange: make CompanyMask a BaseBitSet implementation --- src/build_vehicle_gui.cpp | 2 +- src/company_base.h | 2 +- src/company_cmd.cpp | 10 ++++---- src/company_type.h | 8 ++++++- src/core/base_bitset_type.hpp | 11 +++++++++ src/economy.cpp | 16 ++++++------- src/engine.cpp | 36 ++++++++++++++-------------- src/engine_base.h | 2 +- src/graph_gui.cpp | 16 ++++++------- src/linkgraph/linkgraph_gui.cpp | 12 +++++----- src/main_gui.cpp | 4 ++-- src/network/network_server.cpp | 14 +++++------ src/newgrf_town.cpp | 4 ++-- src/object_cmd.cpp | 8 +++---- src/rail.cpp | 2 +- src/road.cpp | 2 +- src/saveload/afterload.cpp | 6 ++--- src/saveload/oldloader_sl.cpp | 4 ++-- src/script/api/script_enginelist.cpp | 2 +- src/script/api/script_town.cpp | 4 ++-- src/smallmap_gui.cpp | 2 +- src/station_cmd.cpp | 4 ++-- src/toolbar_gui.cpp | 14 +++++------ src/town_cmd.cpp | 10 ++++---- src/town_gui.cpp | 10 ++++---- src/vehicle.cpp | 6 ++--- src/viewport.cpp | 4 ++-- 27 files changed, 116 insertions(+), 99 deletions(-) diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 991a339a08..8411a549e3 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -1070,7 +1070,7 @@ void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_li const uint num_engines = GetGroupNumEngines(_local_company, selected_group, item.engine_id); const Engine *e = Engine::Get(item.engine_id); - bool hidden = HasBit(e->company_hidden, _local_company); + bool hidden = e->company_hidden.Test(_local_company); StringID str = hidden ? STR_HIDDEN_ENGINE_NAME : STR_ENGINE_NAME; TextColour tc = (item.engine_id == selected_id) ? TC_WHITE : ((hidden | shaded) ? (TC_GREY | TC_FORCED | TC_NO_SHADE) : TC_BLACK); diff --git a/src/company_base.h b/src/company_base.h index 810c6c90d3..aa06ec88c4 100644 --- a/src/company_base.h +++ b/src/company_base.h @@ -126,7 +126,7 @@ struct CompanyProperties { : name_2(0), name_1(0), president_name_1(0), president_name_2(0), face(0), money(0), money_fraction(0), current_loan(0), max_loan(COMPANY_MAX_LOAN_DEFAULT), colour(COLOUR_BEGIN), block_preview(0), location_of_HQ(0), last_build_coordinate(0), inaugurated_year(0), - months_of_bankruptcy(0), bankrupt_asked(0), bankrupt_timeout(0), bankrupt_value(0), + months_of_bankruptcy(0), bankrupt_asked(), bankrupt_timeout(0), bankrupt_value(0), terraform_limit(0), clear_limit(0), tree_limit(0), build_object_limit(0), is_ai(false), engine_renew_list(nullptr) {} }; diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 15bd34ad4e..c8a85c7bba 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -706,7 +706,7 @@ static void HandleBankruptcyTakeover(Company *c) * Note that the company going bankrupt can't buy itself. */ static const int TAKE_OVER_TIMEOUT = 3 * 30 * Ticks::DAY_TICKS / (MAX_COMPANIES - 1); - assert(c->bankrupt_asked != 0); + assert(c->bankrupt_asked.Any()); /* We're currently asking some company to buy 'us' */ if (c->bankrupt_timeout != 0) { @@ -725,8 +725,8 @@ static void HandleBankruptcyTakeover(Company *c) /* Ask the company with the highest performance history first */ for (Company *c2 : Company::Iterate()) { - if (c2->bankrupt_asked == 0 && // Don't ask companies going bankrupt themselves - !HasBit(c->bankrupt_asked, c2->index) && + if (c2->bankrupt_asked.None() && // Don't ask companies going bankrupt themselves + !c->bankrupt_asked.Test(c2->index) && best_performance < c2->old_economy[1].performance_history && CheckTakeoverVehicleLimit(c2->index, c->index)) { best_performance = c2->old_economy[1].performance_history; @@ -740,7 +740,7 @@ static void HandleBankruptcyTakeover(Company *c) return; } - SetBit(c->bankrupt_asked, best->index); + c->bankrupt_asked.Set(best->index); c->bankrupt_timeout = TAKE_OVER_TIMEOUT; @@ -758,7 +758,7 @@ void OnTick_Companies() Company *c = Company::GetIfValid(_cur_company_tick_index); if (c != nullptr) { if (c->name_1 != 0) GenerateCompanyName(c); - if (c->bankrupt_asked != 0) HandleBankruptcyTakeover(c); + if (c->bankrupt_asked.Any()) HandleBankruptcyTakeover(c); } if (_new_competitor_timeout.HasFired() && _game_mode != GM_MENU && AI::CanStartNew()) { diff --git a/src/company_type.h b/src/company_type.h index 0118e0e4a0..e36f4934de 100644 --- a/src/company_type.h +++ b/src/company_type.h @@ -47,7 +47,13 @@ static const uint MAX_COMPETITORS_INTERVAL = 500; ///< The maximum interval (in typedef Owner CompanyID; -typedef uint16_t CompanyMask; +class CompanyMask : public BaseBitSet { +public: + constexpr CompanyMask() : BaseBitSet() {} + static constexpr size_t DecayValueType(CompanyID value) { return to_underlying(value); } + + constexpr auto operator <=>(const CompanyMask &) const noexcept = default; +}; struct Company; typedef uint32_t CompanyManagerFace; ///< Company manager face bits, info see in company_manager_face.h diff --git a/src/core/base_bitset_type.hpp b/src/core/base_bitset_type.hpp index 07fd3b76c4..74201dec77 100644 --- a/src/core/base_bitset_type.hpp +++ b/src/core/base_bitset_type.hpp @@ -41,6 +41,17 @@ public: return static_cast(*this); } + /** + * Assign the value-th bit. + * @param value Bit to assign to. + * @param set true if the bit should be set, false if the bit should be reset. + * @returns The EnumBitset + */ + inline constexpr Timpl &Set(Tvalue_type value, bool set) + { + return set ? this->Set(value) : this->Reset(value); + } + /** * Reset the value-th bit. * @param value Bit to reset. diff --git a/src/economy.cpp b/src/economy.cpp index a4ec35c19b..3bc48f42d1 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -378,12 +378,12 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) for (Town *t : Town::Iterate()) { /* If a company takes over, give the ratings to that company. */ if (new_owner != INVALID_OWNER) { - if (HasBit(t->have_ratings, old_owner)) { - if (HasBit(t->have_ratings, new_owner)) { + if (t->have_ratings.Test(old_owner)) { + if (t->have_ratings.Test(new_owner)) { /* use max of the two ratings. */ t->ratings[new_owner] = std::max(t->ratings[new_owner], t->ratings[old_owner]); } else { - SetBit(t->have_ratings, new_owner); + t->have_ratings.Set(new_owner); t->ratings[new_owner] = t->ratings[old_owner]; } } @@ -391,7 +391,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) /* Reset the ratings for the old owner */ t->ratings[old_owner] = RATING_INITIAL; - ClrBit(t->have_ratings, old_owner); + t->have_ratings.Reset(old_owner); /* Transfer exclusive rights */ if (t->exclusive_counter > 0 && t->exclusivity == old_owner) { @@ -571,7 +571,7 @@ static void CompanyCheckBankrupt(Company *c) if (c->money - c->current_loan >= -c->GetMaxLoan()) { int previous_months_of_bankruptcy = CeilDiv(c->months_of_bankruptcy, 3); c->months_of_bankruptcy = 0; - c->bankrupt_asked = 0; + c->bankrupt_asked = CompanyMask{}; if (previous_months_of_bankruptcy != 0) CompanyAdminUpdate(c); return; } @@ -610,7 +610,7 @@ static void CompanyCheckBankrupt(Company *c) Money val = CalculateCompanyValue(c, false); c->bankrupt_value = val; - c->bankrupt_asked = 1 << c->index; // Don't ask the owner + c->bankrupt_asked = CompanyMask{}.Set(c->index); // Don't ask the owner c->bankrupt_timeout = 0; /* The company assets should always have some value */ @@ -2047,10 +2047,10 @@ CommandCost CmdBuyCompany(DoCommandFlag flags, CompanyID target_company, bool ho if (c == nullptr) return CMD_ERROR; /* If you do a hostile takeover but the company went bankrupt, buy it via bankruptcy rules. */ - if (hostile_takeover && HasBit(c->bankrupt_asked, _current_company)) hostile_takeover = false; + if (hostile_takeover && c->bankrupt_asked.Test(_current_company)) hostile_takeover = false; /* Disable takeovers when not asked */ - if (!hostile_takeover && !HasBit(c->bankrupt_asked, _current_company)) return CMD_ERROR; + if (!hostile_takeover && !c->bankrupt_asked.Test(_current_company)) return CMD_ERROR; /* Only allow hostile takeover of AI companies and when in single player */ if (hostile_takeover && !c->is_ai) return CMD_ERROR; diff --git a/src/engine.cpp b/src/engine.cpp index 664aa8b43a..99c05a26ac 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -656,12 +656,12 @@ void CalcEngineReliability(Engine *e, bool new_month) if (new_month && re->index > e->index && age != INT32_MAX) age++; /* parent variant's age has not yet updated. */ /* Check for early retirement */ - if (e->company_avail != 0 && !_settings_game.vehicle.never_expire_vehicles && e->info.base_life != 0xFF) { + if (e->company_avail.Any() && !_settings_game.vehicle.never_expire_vehicles && e->info.base_life != 0xFF) { int retire_early = e->info.retire_early; uint retire_early_max_age = std::max(0, e->duration_phase_1 + e->duration_phase_2 - retire_early * 12); if (retire_early != 0 && age >= retire_early_max_age) { /* Early retirement is enabled and we're past the date... */ - e->company_avail = 0; + e->company_avail = CompanyMask{}; ClearLastVariant(e->index, e->type); AddRemoveEngineFromAutoreplaceAndBuildWindows(e->type); } @@ -680,7 +680,7 @@ void CalcEngineReliability(Engine *e, bool new_month) } else { /* time's up for this engine. * We will now completely retire this design */ - e->company_avail = 0; + e->company_avail = CompanyMask{}; e->reliability = e->reliability_final; /* Kick this engine out of the lists */ ClearLastVariant(e->index, e->type); @@ -721,8 +721,8 @@ void StartupOneEngine(Engine *e, const TimerGameCalendar::YearMonthDay &aging_ym e->age = 0; e->flags = {}; - e->company_avail = 0; - e->company_hidden = 0; + e->company_avail = CompanyMask{}; + e->company_hidden = CompanyMask{}; /* Vehicles with the same base_intro date shall be introduced at the same time. * Make sure they use the same randomisation of the date. */ @@ -788,7 +788,7 @@ void StartupOneEngine(Engine *e, const TimerGameCalendar::YearMonthDay &aging_ym /* prevent certain engines from ever appearing. */ if (!ei->climates.Test(_settings_game.game_creation.landscape)) { e->flags.Set(EngineFlag::Available); - e->company_avail = 0; + e->company_avail = CompanyMask{}; } } @@ -833,7 +833,7 @@ static void EnableEngineForCompany(EngineID eid, CompanyID company) Engine *e = Engine::Get(eid); Company *c = Company::Get(company); - SetBit(e->company_avail, company); + e->company_avail.Set(company); if (e->type == VEH_TRAIN) { c->avail_railtypes = GetCompanyRailTypes(c->index); } else if (e->type == VEH_ROAD) { @@ -861,7 +861,7 @@ static void DisableEngineForCompany(EngineID eid, CompanyID company) Engine *e = Engine::Get(eid); Company *c = Company::Get(company); - ClrBit(e->company_avail, company); + e->company_avail.Reset(company); if (e->type == VEH_TRAIN) { c->avail_railtypes = GetCompanyRailTypes(c->index); } else if (e->type == VEH_ROAD) { @@ -921,7 +921,7 @@ static CompanyID GetPreviewCompany(Engine *e) int32_t best_hist = -1; for (const Company *c : Company::Iterate()) { - if (c->block_preview == 0 && !HasBit(e->preview_asked, c->index) && + if (c->block_preview == 0 && !e->preview_asked.Test(c->index) && c->old_economy[0].performance_history > best_hist) { /* Check whether the company uses similar vehicles */ @@ -976,7 +976,7 @@ static IntervalTimer _calendar_engines_daily({TimerGameCalend CloseWindowById(WC_ENGINE_PREVIEW, i); e->preview_company = INVALID_COMPANY; } - } else if (CountBits(e->preview_asked) < MAX_COMPANIES) { + } else if (CountBits(e->preview_asked.base()) < MAX_COMPANIES) { e->preview_company = GetPreviewCompany(e); if (e->preview_company == INVALID_COMPANY) { @@ -984,7 +984,7 @@ static IntervalTimer _calendar_engines_daily({TimerGameCalend continue; } - SetBit(e->preview_asked, e->preview_company); + e->preview_asked.Set(e->preview_company); e->preview_wait = 20; /* AIs are intentionally not skipped for preview even if they cannot build a certain * vehicle type. This is done to not give poor performing human companies an "unfair" @@ -1005,7 +1005,7 @@ static IntervalTimer _calendar_engines_daily({TimerGameCalend void ClearEnginesHiddenFlagOfCompany(CompanyID cid) { for (Engine *e : Engine::Iterate()) { - SB(e->company_hidden, cid, 1, 0); + e->company_hidden.Reset(cid); } } @@ -1023,7 +1023,7 @@ CommandCost CmdSetVehicleVisibility(DoCommandFlag flags, EngineID engine_id, boo if (!IsEngineBuildable(e->index, e->type, _current_company)) return CMD_ERROR; if ((flags & DC_EXEC) != 0) { - AssignBit(e->company_hidden, _current_company, hide); + e->company_hidden.Set(_current_company, hide); AddRemoveEngineFromAutoreplaceAndBuildWindows(e->type); } @@ -1087,7 +1087,7 @@ static void NewVehicleAvailable(Engine *e) for (Company *c : Company::Iterate()) { uint block_preview = c->block_preview; - if (!HasBit(e->company_avail, c->index)) continue; + if (!e->company_avail.Test(c->index)) continue; /* We assume the user did NOT build it.. prove me wrong ;) */ c->block_preview = 20; @@ -1178,7 +1178,7 @@ void CalendarEnginesMonthlyLoop() /* Show preview dialog to one of the companies. */ e->flags.Set(EngineFlag::ExclusivePreview); e->preview_company = INVALID_COMPANY; - e->preview_asked = 0; + e->preview_asked = CompanyMask{}; } } @@ -1264,10 +1264,10 @@ bool IsEngineBuildable(EngineID engine, VehicleType type, CompanyID company) /* check if it's available ... */ if (company == OWNER_DEITY) { /* ... for any company (preview does not count) */ - if (!e->flags.Test(EngineFlag::Available) || e->company_avail == 0) return false; + if (!e->flags.Test(EngineFlag::Available) || e->company_avail.None()) return false; } else { /* ... for this company */ - if (!HasBit(e->company_avail, company)) return false; + if (!e->company_avail.Test(company)) return false; } if (!e->IsEnabled()) return false; @@ -1329,7 +1329,7 @@ void CheckEngines() if (e->type == VEH_TRAIN && e->u.rail.railveh_type == RAILVEH_WAGON) continue; /* We have an available engine... yay! */ - if (e->flags.Test(EngineFlag::Available) && e->company_avail != 0) return; + if (e->flags.Test(EngineFlag::Available) && e->company_avail.Any()) return; /* Okay, try to find the earliest date. */ min_date = std::min(min_date, e->info.base_intro); diff --git a/src/engine_base.h b/src/engine_base.h index 004710028a..c3e73a3225 100644 --- a/src/engine_base.h +++ b/src/engine_base.h @@ -140,7 +140,7 @@ struct Engine : EnginePool::PoolItem<&_engine_pool> { */ inline bool IsHidden(CompanyID c) const { - return c < MAX_COMPANIES && HasBit(this->company_hidden, c); + return c < MAX_COMPANIES && this->company_hidden.Test(c); } /** diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index e186fb4ca5..69623cd385 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -55,7 +55,7 @@ struct GraphLegendWindow : Window { this->InitNested(window_number); for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { - if (!HasBit(_legend_excluded_companies, c)) this->LowerWidget(WID_GL_FIRST_COMPANY + c); + if (!_legend_excluded_companies.Test(c)) this->LowerWidget(WID_GL_FIRST_COMPANY + c); this->OnInvalidateData(c); } @@ -78,14 +78,14 @@ struct GraphLegendWindow : Window { const Rect tr = ir.Indent(d.width + WidgetDimensions::scaled.hsep_normal, rtl); SetDParam(0, cid); SetDParam(1, cid); - DrawString(tr.left, tr.right, CenterBounds(tr.top, tr.bottom, GetCharacterHeight(FS_NORMAL)), STR_COMPANY_NAME_COMPANY_NUM, HasBit(_legend_excluded_companies, cid) ? TC_BLACK : TC_WHITE); + DrawString(tr.left, tr.right, CenterBounds(tr.top, tr.bottom, GetCharacterHeight(FS_NORMAL)), STR_COMPANY_NAME_COMPANY_NUM, _legend_excluded_companies.Test(cid) ? TC_BLACK : TC_WHITE); } void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override { if (!IsInsideMM(widget, WID_GL_FIRST_COMPANY, WID_GL_FIRST_COMPANY + MAX_COMPANIES)) return; - ToggleBit(_legend_excluded_companies, widget - WID_GL_FIRST_COMPANY); + _legend_excluded_companies.Flip(static_cast(widget - WID_GL_FIRST_COMPANY)); this->ToggleWidgetLoweredState(widget); this->SetDirty(); InvalidateWindowData(WC_INCOME_GRAPH, 0); @@ -105,7 +105,7 @@ struct GraphLegendWindow : Window { if (!gui_scope) return; if (Company::IsValidID(data)) return; - SetBit(_legend_excluded_companies, data); + _legend_excluded_companies.Set(static_cast(data)); this->RaiseWidget(data + WID_GL_FIRST_COMPANY); } }; @@ -677,7 +677,7 @@ public: /* Exclude the companies which aren't valid */ for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { - if (!Company::IsValidID(c)) SetBit(excluded_companies, c); + if (!Company::IsValidID(c)) excluded_companies.Set(c); } uint8_t nums = 0; @@ -692,13 +692,13 @@ public: mo += 12; } - if (!initialize && this->excluded_data == excluded_companies && this->num_on_x_axis == nums && + if (!initialize && this->excluded_data == excluded_companies.base() && this->num_on_x_axis == nums && this->year == yr && this->month == mo) { /* There's no reason to get new stats */ return; } - this->excluded_data = excluded_companies; + this->excluded_data = excluded_companies.base(); this->num_on_x_axis = nums; this->year = yr; this->month = mo; @@ -1841,7 +1841,7 @@ void ShowPerformanceRatingDetail() void InitializeGraphGui() { - _legend_excluded_companies = 0; + _legend_excluded_companies = CompanyMask{}; _legend_excluded_cargo_payment_rates = 0; _legend_excluded_cargo_production_history = 0; } diff --git a/src/linkgraph/linkgraph_gui.cpp b/src/linkgraph/linkgraph_gui.cpp index d9111753ee..a247965a7e 100644 --- a/src/linkgraph/linkgraph_gui.cpp +++ b/src/linkgraph/linkgraph_gui.cpp @@ -72,7 +72,7 @@ void LinkGraphOverlay::RebuildCache() { this->cached_links.clear(); this->cached_stations.clear(); - if (this->company_mask == 0) return; + if (this->company_mask.None()) return; DrawPixelInfo dpi; this->GetWidgetDpi(&dpi); @@ -103,7 +103,7 @@ void LinkGraphOverlay::RebuildCache() assert(sta != stb); /* Show links between stations of selected companies or "neutral" ones like oilrigs. */ - if (stb->owner != OWNER_NONE && sta->owner != OWNER_NONE && !HasBit(this->company_mask, stb->owner)) continue; + if (stb->owner != OWNER_NONE && sta->owner != OWNER_NONE && !this->company_mask.Test(stb->owner)) continue; if (stb->rect.IsEmpty()) continue; if (!this->IsLinkVisible(pta, this->GetStationMiddle(stb), &dpi)) continue; @@ -568,9 +568,9 @@ void LinkGraphLegendWindow::SetOverlay(std::shared_ptr overlay { this->overlay = overlay; CompanyMask companies = this->overlay->GetCompanyMask(); - for (uint c = 0; c < MAX_COMPANIES; c++) { + for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { if (!this->IsWidgetDisabled(WID_LGL_COMPANY_FIRST + c)) { - this->SetWidgetLoweredState(WID_LGL_COMPANY_FIRST + c, HasBit(companies, c)); + this->SetWidgetLoweredState(WID_LGL_COMPANY_FIRST + c, companies.Test(c)); } } CargoTypes cargoes = this->overlay->GetCargoMask(); @@ -662,11 +662,11 @@ bool LinkGraphLegendWindow::OnTooltip([[maybe_unused]] Point, WidgetID widget, T */ void LinkGraphLegendWindow::UpdateOverlayCompanies() { - uint32_t mask = 0; + CompanyMask mask; for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { if (this->IsWidgetDisabled(WID_LGL_COMPANY_FIRST + c)) continue; if (!this->IsWidgetLowered(WID_LGL_COMPANY_FIRST + c)) continue; - SetBit(mask, c); + mask.Set(c); } this->overlay->SetCompanyMask(mask); } diff --git a/src/main_gui.cpp b/src/main_gui.cpp index 0953228b9c..237ab899a1 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -218,7 +218,7 @@ struct MainWindow : Window NWidgetViewport *nvp = this->GetWidget(WID_M_VIEWPORT); nvp->InitializeViewport(this, TileXY(32, 32), ScaleZoomGUI(ZOOM_LVL_VIEWPORT)); - this->viewport->overlay = std::make_shared(this, WID_M_VIEWPORT, 0, 0, 2); + this->viewport->overlay = std::make_shared(this, WID_M_VIEWPORT, 0, CompanyMask{}, 2); this->refresh_timeout.Reset(); } @@ -226,7 +226,7 @@ struct MainWindow : Window void RefreshLinkGraph() { if (this->viewport->overlay->GetCargoMask() == 0 || - this->viewport->overlay->GetCompanyMask() == 0) { + this->viewport->overlay->GetCompanyMask().None()) { return; } diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 22a5aa5034..f3f884a3d5 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -1549,25 +1549,25 @@ void NetworkUpdateClientInfo(ClientID client_id) */ static void NetworkAutoCleanCompanies() { - CompanyMask has_clients = 0; - CompanyMask has_vehicles = 0; + CompanyMask has_clients{}; + CompanyMask has_vehicles{}; if (!_settings_client.network.autoclean_companies) return; /* Detect the active companies */ for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { - if (Company::IsValidID(ci->client_playas)) SetBit(has_clients, ci->client_playas); + if (Company::IsValidID(ci->client_playas)) has_clients.Set(ci->client_playas); } if (!_network_dedicated) { const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER); assert(ci != nullptr); - if (Company::IsValidID(ci->client_playas)) SetBit(has_clients, ci->client_playas); + if (Company::IsValidID(ci->client_playas)) has_clients.Set(ci->client_playas); } if (_settings_client.network.autoclean_novehicles != 0) { for (const Company *c : Company::Iterate()) { - if (std::any_of(std::begin(c->group_all), std::end(c->group_all), [](const GroupStatistics &gs) { return gs.num_vehicle != 0; })) SetBit(has_vehicles, c->index); + if (std::any_of(std::begin(c->group_all), std::end(c->group_all), [](const GroupStatistics &gs) { return gs.num_vehicle != 0; })) has_vehicles.Set(c->index); } } @@ -1576,7 +1576,7 @@ static void NetworkAutoCleanCompanies() /* Skip the non-active once */ if (c->is_ai) continue; - if (!HasBit(has_clients, c->index)) { + if (!has_clients.Test(c->index)) { /* The company is empty for one month more */ if (c->months_empty != std::numeric_limitsmonths_empty)>::max()) c->months_empty++; @@ -1587,7 +1587,7 @@ static void NetworkAutoCleanCompanies() IConsolePrint(CC_INFO, "Auto-cleaned company #{}.", c->index + 1); } /* Is the company empty for autoclean_novehicles-months, and has no vehicles? */ - if (_settings_client.network.autoclean_novehicles != 0 && c->months_empty > _settings_client.network.autoclean_novehicles && !HasBit(has_vehicles, c->index)) { + if (_settings_client.network.autoclean_novehicles != 0 && c->months_empty > _settings_client.network.autoclean_novehicles && !has_vehicles.Test(c->index)) { /* Shut the company down */ Command::Post(CCA_DELETE, c->index, CRR_AUTOCLEAN, INVALID_CLIENT_ID); IConsolePrint(CC_INFO, "Auto-cleaned company #{} with no vehicles.", c->index + 1); diff --git a/src/newgrf_town.cpp b/src/newgrf_town.cpp index ba105e1be5..8778893efc 100644 --- a/src/newgrf_town.cpp +++ b/src/newgrf_town.cpp @@ -83,8 +83,8 @@ case 0xAB: return GB(this->t->ratings[6], 8, 8); case 0xAC: return this->t->ratings[7]; case 0xAD: return GB(this->t->ratings[7], 8, 8); - case 0xAE: return this->t->have_ratings; - case 0xB2: return this->t->statues; + case 0xAE: return this->t->have_ratings.base(); + case 0xB2: return this->t->statues.base(); case 0xB6: return ClampTo(this->t->cache.num_houses); case 0xB9: return this->t->growth_rate / Ticks::TOWN_GROWTH_TICKS; case 0xBA: cargo_type = GetCargoTypeByLabel(CT_PASSENGERS); return IsValidCargoType(cargo_type) ? ClampTo(this->t->supplied[cargo_type].new_max) : 0; diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index 8695a9fe4f..69cd0395b3 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -602,7 +602,7 @@ static CommandCost ClearTile_Object(TileIndex tile, DoCommandFlag flags) case OBJECT_STATUE: if (flags & DC_EXEC) { Town *town = o->town; - ClrBit(town->statues, GetTileOwner(tile)); + town->statues.Reset(GetTileOwner(tile)); SetWindowDirty(WC_TOWN_AUTHORITY, town->index); } break; @@ -887,10 +887,10 @@ static void ChangeTileOwner_Object(TileIndex tile, Owner old_owner, Owner new_ow } } else if (type == OBJECT_STATUE) { Town *t = Object::GetByTile(tile)->town; - ClrBit(t->statues, old_owner); - if (new_owner != INVALID_OWNER && !HasBit(t->statues, new_owner)) { + t->statues.Reset(old_owner); + if (new_owner != INVALID_OWNER && !t->statues.Test(new_owner)) { /* Transfer ownership to the new company */ - SetBit(t->statues, new_owner); + t->statues.Set(new_owner); SetTileOwner(tile, new_owner); } else { do_clear = true; diff --git a/src/rail.cpp b/src/rail.cpp index 597653bfef..e68a376365 100644 --- a/src/rail.cpp +++ b/src/rail.cpp @@ -256,7 +256,7 @@ RailTypes GetCompanyRailTypes(CompanyID company, bool introduces) const EngineInfo *ei = &e->info; if (ei->climates.Test(_settings_game.game_creation.landscape) && - (HasBit(e->company_avail, company) || TimerGameCalendar::date >= e->intro_date + CalendarTime::DAYS_IN_YEAR)) { + (e->company_avail.Test(company) || TimerGameCalendar::date >= e->intro_date + CalendarTime::DAYS_IN_YEAR)) { const RailVehicleInfo *rvi = &e->u.rail; if (rvi->railveh_type != RAILVEH_WAGON) { diff --git a/src/road.cpp b/src/road.cpp index 1cfcb41f9e..b4858401c5 100644 --- a/src/road.cpp +++ b/src/road.cpp @@ -204,7 +204,7 @@ RoadTypes GetCompanyRoadTypes(CompanyID company, bool introduces) const EngineInfo *ei = &e->info; if (ei->climates.Test(_settings_game.game_creation.landscape) && - (HasBit(e->company_avail, company) || TimerGameCalendar::date >= e->intro_date + CalendarTime::DAYS_IN_YEAR)) { + (e->company_avail.Test(company) || TimerGameCalendar::date >= e->intro_date + CalendarTime::DAYS_IN_YEAR)) { const RoadVehicleInfo *rvi = &e->u.road; assert(rvi->roadtype < ROADTYPE_END); if (introduces) { diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index a38ad58ab3..cbca3852cf 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -2041,15 +2041,15 @@ bool AfterLoadGame() /* More companies ... */ for (Company *c : Company::Iterate()) { - if (c->bankrupt_asked == 0xFF) c->bankrupt_asked = std::numeric_limits::max(); + if (c->bankrupt_asked.base() == 0xFF) c->bankrupt_asked = std::numeric_limits::max(); } for (Engine *e : Engine::Iterate()) { - if (e->company_avail == 0xFF) e->company_avail = std::numeric_limits::max(); + if (e->company_avail.base() == 0xFF) e->company_avail = std::numeric_limits::max(); } for (Town *t : Town::Iterate()) { - if (t->have_ratings == 0xFF) t->have_ratings = std::numeric_limits::max(); + if (t->have_ratings.base() == 0xFF) t->have_ratings = std::numeric_limits::max(); for (uint i = 8; i != MAX_COMPANIES; i++) t->ratings[i] = RATING_INITIAL; } } diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index 89cc1357c0..7f4fa1efa5 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -425,12 +425,12 @@ static bool FixTTOEngines() e->duration_phase_3 = oe->duration_phase_3; e->flags = oe->flags; - e->company_avail = 0; + e->company_avail = CompanyMask{}; /* One or more engines were remapped to this one. Make this engine available * if at least one of them was available. */ for (uint j = 0; j < lengthof(tto_to_ttd); j++) { - if (tto_to_ttd[j] == i && _old_engines[j].company_avail != 0) { + if (tto_to_ttd[j] == i && _old_engines[j].company_avail.Any()) { e->company_avail = std::numeric_limits::max(); e->flags.Set(EngineFlag::Available); break; diff --git a/src/script/api/script_enginelist.cpp b/src/script/api/script_enginelist.cpp index ffd26e4619..b3235cf20e 100644 --- a/src/script/api/script_enginelist.cpp +++ b/src/script/api/script_enginelist.cpp @@ -19,6 +19,6 @@ ScriptEngineList::ScriptEngineList(ScriptVehicle::VehicleType vehicle_type) bool is_deity = ScriptCompanyMode::IsDeity(); ::CompanyID owner = ScriptObject::GetCompany(); for (const Engine *e : Engine::IterateType((::VehicleType)vehicle_type)) { - if (is_deity || HasBit(e->company_avail, owner)) this->AddItem(e->index); + if (is_deity || e->company_avail.Test(owner)) this->AddItem(e->index); } } diff --git a/src/script/api/script_town.cpp b/src/script/api/script_town.cpp index dc024a2ff3..a806500c9b 100644 --- a/src/script/api/script_town.cpp +++ b/src/script/api/script_town.cpp @@ -214,7 +214,7 @@ EnforceCompanyModeValid(false); if (!IsValidTown(town_id)) return false; - return ::HasBit(::Town::Get(town_id)->statues, ScriptObject::GetCompany()); + return ::Town::Get(town_id)->statues.Test(ScriptObject::GetCompany()); } /* static */ bool ScriptTown::IsCity(TownID town_id) @@ -319,7 +319,7 @@ ::CompanyID c = ScriptCompany::FromScriptCompanyID(company); const Town *t = ::Town::Get(town_id); - if (!HasBit(t->have_ratings, c)) { + if (!t->have_ratings.Test(c)) { return TOWN_RATING_NONE; } else if (t->ratings[c] <= RATING_APPALLING) { return TOWN_RATING_APPALLING; diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp index de27f008e1..404f4b0e49 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -724,7 +724,7 @@ protected: */ inline CompanyMask GetOverlayCompanyMask() const { - return Company::IsValidID(_local_company) ? 1U << _local_company : std::numeric_limits::max(); + return Company::IsValidID(_local_company) ? CompanyMask{}.Set(_local_company) : std::numeric_limits::max(); } /** Blink the industries (if selected) on a regular interval. */ diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index b7198f628a..d461ee5718 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -720,7 +720,7 @@ static CommandCost BuildStationPart(Station **st, DoCommandFlag flags, bool reus (*st)->string_id = GenerateStationName(*st, area.tile, name_class); if (Company::IsValidID(_current_company)) { - SetBit((*st)->town->have_ratings, _current_company); + (*st)->town->have_ratings.Set(_current_company); } } } @@ -3918,7 +3918,7 @@ static void UpdateStationRating(Station *st) if (ge->max_waiting_cargo <= 100) rating += 10; } - if (Company::IsValidID(st->owner) && HasBit(st->town->statues, st->owner)) rating += 26; + if (Company::IsValidID(st->owner) && st->town->statues.Test(st->owner)) rating += 26; uint8_t age = ge->last_age; if (age < 3) rating += 10; diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index f10831c5e4..1b2996c2d2 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -151,7 +151,7 @@ static const int CTMN_SPECTATOR = -3; ///< Show a company window as spectator * @param widget The button widget id. * @param grey A bitmask of which companies to mark as disabled. */ -static void PopupMainCompanyToolbMenu(Window *w, WidgetID widget, CompanyMask grey = 0) +static void PopupMainCompanyToolbMenu(Window *w, WidgetID widget, CompanyMask grey = {}) { DropDownList list; @@ -177,7 +177,7 @@ static void PopupMainCompanyToolbMenu(Window *w, WidgetID widget, CompanyMask gr for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { if (!Company::IsValidID(c)) continue; - list.push_back(std::make_unique(c, HasBit(grey, c))); + list.push_back(std::make_unique(c, grey.Test(c))); } PopupMainToolbarMenu(w, widget, std::move(list), _local_company == COMPANY_SPECTATOR ? (widget == WID_TN_COMPANIES ? CTMN_CLIENT_LIST : CTMN_SPECTATOR) : (int)_local_company); @@ -571,7 +571,7 @@ static CallBackFunction MenuClickFinances(int index) static CallBackFunction ToolbarCompaniesClick(Window *w) { - PopupMainCompanyToolbMenu(w, WID_TN_COMPANIES, 0); + PopupMainCompanyToolbMenu(w, WID_TN_COMPANIES); return CBF_NONE; } @@ -607,7 +607,7 @@ static CallBackFunction MenuClickCompany(int index) static CallBackFunction ToolbarStoryClick(Window *w) { - PopupMainCompanyToolbMenu(w, WID_TN_STORY, 0); + PopupMainCompanyToolbMenu(w, WID_TN_STORY); return CBF_NONE; } @@ -627,7 +627,7 @@ static CallBackFunction MenuClickStory(int index) static CallBackFunction ToolbarGoalClick(Window *w) { - PopupMainCompanyToolbMenu(w, WID_TN_GOAL, 0); + PopupMainCompanyToolbMenu(w, WID_TN_GOAL); return CBF_NONE; } @@ -768,10 +768,10 @@ static CallBackFunction MenuClickIndustry(int index) static void ToolbarVehicleClick(Window *w, VehicleType veh) { - CompanyMask dis = 0; + CompanyMask dis{}; for (const Company *c : Company::Iterate()) { - if (c->group_all[veh].num_vehicle == 0) SetBit(dis, c->index); + if (c->group_all[veh].num_vehicle == 0) dis.Set(c->index); } PopupMainCompanyToolbMenu(w, WID_TN_VEHICLE_START + veh, dis); } diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index a0f380b0fa..72816a7727 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -2059,10 +2059,10 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSi for (uint i = 0; i != MAX_COMPANIES; i++) t->ratings[i] = RATING_INITIAL; - t->have_ratings = 0; + t->have_ratings = {}; t->exclusivity = INVALID_COMPANY; t->exclusive_counter = 0; - t->statues = 0; + t->statues = {}; { TownNameParams tnp(_settings_game.game_creation.town_name); @@ -3479,7 +3479,7 @@ static CommandCost TownActionBuildStatue(Town *t, DoCommandFlag flags) Command::Do(DC_EXEC, statue_data.best_position); cur_company.Restore(); BuildObject(OBJECT_STATUE, statue_data.best_position, _current_company, t); - SetBit(t->statues, _current_company); // Once found and built, "inform" the Town. + t->statues.Set(_current_company); // Once found and built, "inform" the Town. MarkTileDirtyByTile(statue_data.best_position); } return CommandCost(); @@ -3649,7 +3649,7 @@ TownActions GetMaskOfTownActions(CompanyID cid, const Town *t) if (cur == TACT_ROAD_REBUILD && !_settings_game.economy.fund_roads) continue; /* Is the company not able to build a statue ? */ - if (cur == TACT_BUILD_STATUE && HasBit(t->statues, cid)) continue; + if (cur == TACT_BUILD_STATUE && t->statues.Test(cid)) continue; if (avail >= _town_action_costs[i] * _price[PR_TOWN_ACTION] >> 8) { buttons |= cur; @@ -4006,7 +4006,7 @@ void ChangeTownRating(Town *t, int add, int max, DoCommandFlag flags) if (_town_rating_test) { _town_test_ratings[t] = rating; } else { - SetBit(t->have_ratings, _current_company); + t->have_ratings.Set(_current_company); t->ratings[_current_company] = rating; SetWindowDirty(WC_TOWN_AUTHORITY, t->index); } diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 1a9c471702..29c09e06b4 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -186,7 +186,7 @@ public: /* Draw list of companies */ for (const Company *c : Company::Iterate()) { - if ((HasBit(this->town->have_ratings, c->index) || this->town->exclusivity == c->index)) { + if ((this->town->have_ratings.Test(c->index) || this->town->exclusivity == c->index)) { DrawCompanyIcon(c->index, icon.left, text.top + icon_y_offset); SetDParam(0, c->index); @@ -793,8 +793,8 @@ private: bool before = !order; // Value to get 'a' before 'b'. /* Towns without rating are always after towns with rating. */ - if (HasBit(a->have_ratings, _local_company)) { - if (HasBit(b->have_ratings, _local_company)) { + if (a->have_ratings.Test(_local_company)) { + if (b->have_ratings.Test(_local_company)) { int16_t a_rating = a->ratings[_local_company]; int16_t b_rating = b->ratings[_local_company]; if (a_rating == b_rating) return TownDirectoryWindow::TownNameSorter(a, b, order); @@ -802,7 +802,7 @@ private: } return before; } - if (HasBit(b->have_ratings, _local_company)) return !before; + if (b->have_ratings.Test(_local_company)) return !before; /* Sort unrated towns always on ascending town name. */ if (before) return TownDirectoryWindow::TownNameSorter(a, b, order); @@ -881,7 +881,7 @@ public: assert(t->xy != INVALID_TILE); /* Draw rating icon. */ - if (_game_mode == GM_EDITOR || !HasBit(t->have_ratings, _local_company)) { + if (_game_mode == GM_EDITOR || !t->have_ratings.Test(_local_company)) { DrawSprite(SPR_TOWN_RATING_NA, PAL_NONE, icon_x, tr.top + (this->resize.step_height - icon_size.height) / 2); } else { SpriteID icon = SPR_TOWN_RATING_APALLING; diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 867cfa36f1..d06bfa4070 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -227,7 +227,7 @@ bool Vehicle::NeedsServicing() const EngineID new_engine = EngineReplacementForCompany(c, v->engine_type, v->group_id, &replace_when_old); /* Check engine availability */ - if (new_engine == INVALID_ENGINE || !HasBit(Engine::Get(new_engine)->company_avail, v->owner)) continue; + if (new_engine == INVALID_ENGINE || !Engine::Get(new_engine)->company_avail.Test(v->owner)) continue; /* Is the vehicle old if we are not always replacing? */ if (replace_when_old && !v->NeedsAutorenewing(c, false)) continue; @@ -1462,7 +1462,7 @@ void AgeVehicle(Vehicle *v) const Company *c = Company::Get(v->owner); /* Don't warn if a renew is active */ - if (c->settings.engine_renew && v->GetEngine()->company_avail != 0) return; + if (c->settings.engine_renew && v->GetEngine()->company_avail.Any()) return; /* Don't warn if a replacement is active */ if (EngineHasReplacementForCompany(c, v->engine_type, v->group_id)) return; @@ -1945,7 +1945,7 @@ bool CanBuildVehicleInfrastructure(VehicleType type, uint8_t subtype) /* Can we actually build the vehicle type? */ for (const Engine *e : Engine::IterateType(type)) { if (type == VEH_ROAD && GetRoadTramType(e->u.road.roadtype) != (RoadTramType)subtype) continue; - if (HasBit(e->company_avail, _local_company)) return true; + if (e->company_avail.Test(_local_company)) return true; } return false; } diff --git a/src/viewport.cpp b/src/viewport.cpp index 4b1132c4c8..4dfbfd9193 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -1840,7 +1840,7 @@ void ViewportDoDraw(const Viewport *vp, int left, int top, int right, int bottom dp.height = UnScaleByZoom(dp.height, zoom); _cur_dpi = &dp; - if (vp->overlay != nullptr && vp->overlay->GetCargoMask() != 0 && vp->overlay->GetCompanyMask() != 0) { + if (vp->overlay != nullptr && vp->overlay->GetCargoMask() != 0 && vp->overlay->GetCompanyMask().Any()) { /* translate to window coordinates */ dp.left = x; dp.top = y; @@ -2507,7 +2507,7 @@ bool HandleViewportClicked(const Viewport *vp, int x, int y) void RebuildViewportOverlay(Window *w) { if (w->viewport->overlay != nullptr && - w->viewport->overlay->GetCompanyMask() != 0 && + w->viewport->overlay->GetCompanyMask().Any() && w->viewport->overlay->GetCargoMask() != 0) { w->viewport->overlay->SetDirty(); w->SetDirty();