diff --git a/src/newgrf_town.cpp b/src/newgrf_town.cpp index eb581d9328..370769cde6 100644 --- a/src/newgrf_town.cpp +++ b/src/newgrf_town.cpp @@ -63,7 +63,7 @@ static uint16_t TownHistoryHelper(const Town *t, CargoLabel label, uint period, case 0x82: return ClampTo(this->t->cache.population); case 0x83: return GB(ClampTo(this->t->cache.population), 8, 8); case 0x8A: return this->t->grow_counter / Ticks::TOWN_GROWTH_TICKS; - case 0x92: return this->t->flags; // In original game, 0x92 and 0x93 are really one word. Since flags is a byte, this is to adjust + case 0x92: return this->t->flags.base(); // In original game, 0x92 and 0x93 are one word. case 0x93: return 0; case 0x94: return ClampTo(this->t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownEdge)]); case 0x95: return GB(ClampTo(this->t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownEdge)]), 8, 8); diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 908249e533..4a901a3b39 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -3120,7 +3120,7 @@ bool AfterLoadGame() /* Convert towns growth_rate and grow_counter to ticks */ for (Town *t : Town::Iterate()) { /* 0x8000 = TOWN_GROWTH_RATE_CUSTOM previously */ - if (t->growth_rate & 0x8000) SetBit(t->flags, TOWN_CUSTOM_GROWTH); + if (t->growth_rate & 0x8000) t->flags.Set(TownFlag::CustomGrowth); if (t->growth_rate != TOWN_GROWTH_RATE_NONE) { t->growth_rate = TownTicksToGameTicks(t->growth_rate & ~0x8000); } diff --git a/src/town.h b/src/town.h index a8786767c9..38ba6c1798 100644 --- a/src/town.h +++ b/src/town.h @@ -37,6 +37,16 @@ static const uint16_t MAX_TOWN_GROWTH_TICKS = 930; ///< Max amount of original t typedef Pool TownPool; extern TownPool _town_pool; +/** Flags controlling various town behaviours. */ +enum class TownFlag : uint8_t { + IsGrowing = 0, ///< Conditions for town growth are met. Grow according to Town::growth_rate. + HasChurch = 1, ///< There can be only one church by town. + HasStadium = 2, ///< There can be only one stadium by town. + CustomGrowth = 3, ///< Growth rate is controlled by GS. +}; + +using TownFlags = EnumBitSet; + /** Data structure with cached data of towns. */ struct TownCache { uint32_t num_houses = 0; ///< Amount of houses @@ -62,7 +72,7 @@ struct Town : TownPool::PoolItem<&_town_pool> { std::string name{}; ///< Custom town name. If empty, the town was not renamed and uses the generated name. mutable std::string cached_name{}; ///< NOSAVE: Cache of the resolved name of the town, if not using a custom town name - uint8_t flags = 0; ///< See #TownFlags. + TownFlags flags{}; ///< See #TownFlags. uint16_t noise_reached = 0; ///< level of noise that all the airports are generating @@ -224,20 +234,6 @@ enum TownDirectoryInvalidateWindowData { TDIWD_FORCE_RESORT, }; -/** - * This enum is used in conjunction with town->flags. - * IT simply states what bit is used for. - * It is pretty unrealistic (IMHO) to only have one church/stadium - * per town, NO MATTER the population of it. - * And there are 5 more bits available on flags... - */ -enum TownFlags { - TOWN_IS_GROWING = 0, ///< Conditions for town growth are met. Grow according to Town::growth_rate. - TOWN_HAS_CHURCH = 1, ///< There can be only one church by town. - TOWN_HAS_STADIUM = 2, ///< There can be only one stadium by town. - TOWN_CUSTOM_GROWTH = 3, ///< Growth rate is controlled by GS. -}; - CommandCost CheckforTownRating(DoCommandFlags flags, Town *t, TownRatingCheckType type); diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index bcb03da78e..abf59d90bc 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -666,7 +666,7 @@ static void TileLoop_Town(TileIndex tile) Backup cur_company(_current_company, OWNER_TOWN); if (hs->building_flags.Any(BUILDING_HAS_1_TILE) && - HasBit(t->flags, TOWN_IS_GROWING) && + t->flags.Test(TownFlag::IsGrowing) && CanDeleteHouse(tile) && GetHouseAge(tile) >= hs->minimum_life && --t->time_until_rebuild == 0) { @@ -917,7 +917,7 @@ static bool GrowTown(Town *t, TownExpandModes modes); */ static void TownTickHandler(Town *t) { - if (HasBit(t->flags, TOWN_IS_GROWING)) { + if (t->flags.Test(TownFlag::IsGrowing)) { TownExpandModes modes{TownExpandMode::Buildings}; if (_settings_game.economy.allow_town_roads) modes.Set(TownExpandMode::Roads); int i = (int)t->grow_counter - 1; @@ -2046,7 +2046,7 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSi t->cache.num_houses = 0; t->time_until_rebuild = 10; UpdateTownRadius(t); - t->flags = 0; + t->flags.Reset(); t->cache.population = 0; InitializeBuildingCounts(t); /* Spread growth across ticks so even if there are many @@ -2867,15 +2867,15 @@ static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes) if (TimerGameCalendar::year < hs->min_year || TimerGameCalendar::year > hs->max_year) continue; /* Special houses that there can be only one of. */ - uint oneof = 0; + TownFlags oneof{}; if (hs->building_flags.Test(BuildingFlag::IsChurch)) { - SetBit(oneof, TOWN_HAS_CHURCH); + oneof.Set(TownFlag::HasChurch); } else if (hs->building_flags.Test(BuildingFlag::IsStadium)) { - SetBit(oneof, TOWN_HAS_STADIUM); + oneof.Set(TownFlag::HasStadium); } - if (t->flags & oneof) continue; + if (t->flags.Any(oneof)) continue; /* Make sure there is no slope? */ bool noslope = hs->building_flags.Test(BuildingFlag::NotSloped); @@ -2899,7 +2899,7 @@ static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes) } /* Special houses that there can be only one of. */ - t->flags |= oneof; + t->flags.Set(oneof); BuildTownHouse(t, tile, hs, house, random_bits, false, hs->extra_flags.Test(HouseExtraFlag::BuildingIsProtected)); @@ -3034,9 +3034,9 @@ void ClearTownHouse(Town *t, TileIndex tile) /* Clear flags for houses that only may exist once/town. */ if (hs->building_flags.Test(BuildingFlag::IsChurch)) { - ClrBit(t->flags, TOWN_HAS_CHURCH); + t->flags.Reset(TownFlag::HasChurch); } else if (hs->building_flags.Test(BuildingFlag::IsStadium)) { - ClrBit(t->flags, TOWN_HAS_STADIUM); + t->flags.Reset(TownFlag::HasStadium); } /* Do the actual clearing of tiles */ @@ -3168,7 +3168,7 @@ CommandCost CmdTownGrowthRate(DoCommandFlags flags, TownID town_id, uint16_t gro if (flags.Test(DoCommandFlag::Execute)) { if (growth_rate == 0) { /* Just clear the flag, UpdateTownGrowth will determine a proper growth rate */ - ClrBit(t->flags, TOWN_CUSTOM_GROWTH); + t->flags.Reset(TownFlag::CustomGrowth); } else { uint old_rate = t->growth_rate; if (t->grow_counter >= old_rate) { @@ -3179,7 +3179,7 @@ CommandCost CmdTownGrowthRate(DoCommandFlags flags, TownID town_id, uint16_t gro t->grow_counter = t->grow_counter * growth_rate / old_rate; } t->growth_rate = growth_rate; - SetBit(t->flags, TOWN_CUSTOM_GROWTH); + t->flags.Set(TownFlag::CustomGrowth); } UpdateTownGrowth(t); InvalidateWindowData(WC_TOWN_VIEW, town_id); @@ -3829,7 +3829,7 @@ static uint GetNormalGrowthRate(Town *t) */ static void UpdateTownGrowthRate(Town *t) { - if (HasBit(t->flags, TOWN_CUSTOM_GROWTH)) return; + if (t->flags.Test(TownFlag::CustomGrowth)) return; uint old_rate = t->growth_rate; t->growth_rate = GetNormalGrowthRate(t); UpdateTownGrowCounter(t, old_rate); @@ -3844,7 +3844,7 @@ static void UpdateTownGrowth(Town *t) { UpdateTownGrowthRate(t); - ClrBit(t->flags, TOWN_IS_GROWING); + t->flags.Reset(TownFlag::IsGrowing); SetWindowDirty(WC_TOWN_VIEW, t->index); if (_settings_game.economy.town_growth_rate == 0 && t->fund_buildings_months == 0) return; @@ -3866,15 +3866,15 @@ static void UpdateTownGrowth(Town *t) } } - if (HasBit(t->flags, TOWN_CUSTOM_GROWTH)) { - if (t->growth_rate != TOWN_GROWTH_RATE_NONE) SetBit(t->flags, TOWN_IS_GROWING); + if (t->flags.Test(TownFlag::CustomGrowth)) { + if (t->growth_rate != TOWN_GROWTH_RATE_NONE) t->flags.Set(TownFlag::IsGrowing); SetWindowDirty(WC_TOWN_VIEW, t->index); return; } if (t->fund_buildings_months == 0 && CountActiveStations(t) == 0 && !Chance16(1, 12)) return; - SetBit(t->flags, TOWN_IS_GROWING); + t->flags.Set(TownFlag::IsGrowing); SetWindowDirty(WC_TOWN_VIEW, t->index); } diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 8456176344..2659adc38a 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -453,7 +453,7 @@ public: tr.top += GetCharacterHeight(FS_NORMAL); } - if (HasBit(this->town->flags, TOWN_IS_GROWING)) { + if (this->town->flags.Test(TownFlag::IsGrowing)) { DrawString(tr, GetString(this->town->fund_buildings_months == 0 ? STR_TOWN_VIEW_TOWN_GROWS_EVERY : STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED, RoundDivSU(this->town->growth_rate + 1, Ticks::DAY_TICKS))); tr.top += GetCharacterHeight(FS_NORMAL); } else {