Codechange: make CompanyMask a BaseBitSet implementation

This commit is contained in:
Rubidium 2025-02-08 10:08:36 +01:00 committed by rubidium42
parent e972033e11
commit ec492cb267
27 changed files with 116 additions and 99 deletions

View File

@ -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);

View File

@ -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) {}
};

View File

@ -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()) {

View File

@ -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<CompanyMask, CompanyID, uint16_t> {
public:
constexpr CompanyMask() : BaseBitSet<CompanyMask, CompanyID, uint16_t>() {}
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

View File

@ -41,6 +41,17 @@ public:
return static_cast<Timpl&>(*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.

View File

@ -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;

View File

@ -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<TimerGameCalendar> _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<TimerGameCalendar> _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<TimerGameCalendar> _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);

View File

@ -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);
}
/**

View File

@ -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<CompanyID>(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<CompanyID>(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;
}

View File

@ -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<LinkGraphOverlay> 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);
}

View File

@ -218,7 +218,7 @@ struct MainWindow : Window
NWidgetViewport *nvp = this->GetWidget<NWidgetViewport>(WID_M_VIEWPORT);
nvp->InitializeViewport(this, TileXY(32, 32), ScaleZoomGUI(ZOOM_LVL_VIEWPORT));
this->viewport->overlay = std::make_shared<LinkGraphOverlay>(this, WID_M_VIEWPORT, 0, 0, 2);
this->viewport->overlay = std::make_shared<LinkGraphOverlay>(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;
}

View File

@ -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_limits<decltype(c->months_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<CMD_COMPANY_CTRL>::Post(CCA_DELETE, c->index, CRR_AUTOCLEAN, INVALID_CLIENT_ID);
IConsolePrint(CC_INFO, "Auto-cleaned company #{} with no vehicles.", c->index + 1);

View File

@ -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<uint16_t>(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<uint16_t>(this->t->supplied[cargo_type].new_max) : 0;

View File

@ -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;

View File

@ -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) {

View File

@ -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) {

View File

@ -2041,15 +2041,15 @@ bool AfterLoadGame()
/* More companies ... */
for (Company *c : Company::Iterate()) {
if (c->bankrupt_asked == 0xFF) c->bankrupt_asked = std::numeric_limits<CompanyMask>::max();
if (c->bankrupt_asked.base() == 0xFF) c->bankrupt_asked = std::numeric_limits<CompanyMask>::max();
}
for (Engine *e : Engine::Iterate()) {
if (e->company_avail == 0xFF) e->company_avail = std::numeric_limits<CompanyMask>::max();
if (e->company_avail.base() == 0xFF) e->company_avail = std::numeric_limits<CompanyMask>::max();
}
for (Town *t : Town::Iterate()) {
if (t->have_ratings == 0xFF) t->have_ratings = std::numeric_limits<CompanyMask>::max();
if (t->have_ratings.base() == 0xFF) t->have_ratings = std::numeric_limits<CompanyMask>::max();
for (uint i = 8; i != MAX_COMPANIES; i++) t->ratings[i] = RATING_INITIAL;
}
}

View File

@ -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<CompanyMask>::max();
e->flags.Set(EngineFlag::Available);
break;

View File

@ -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);
}
}

View File

@ -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;

View File

@ -724,7 +724,7 @@ protected:
*/
inline CompanyMask GetOverlayCompanyMask() const
{
return Company::IsValidID(_local_company) ? 1U << _local_company : std::numeric_limits<CompanyMask>::max();
return Company::IsValidID(_local_company) ? CompanyMask{}.Set(_local_company) : std::numeric_limits<CompanyMask>::max();
}
/** Blink the industries (if selected) on a regular interval. */

View File

@ -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;

View File

@ -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<DropDownListCompanyItem>(c, HasBit(grey, c)));
list.push_back(std::make_unique<DropDownListCompanyItem>(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);
}

View File

@ -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<CMD_LANDSCAPE_CLEAR>::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);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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();