Codechange: Use iteration when dealing with all HouseSpecs.

This commit is contained in:
Peter Nelson 2024-03-12 17:28:45 +00:00 committed by Michael Lutz
parent 3e83dcedfd
commit e16b982b6a
4 changed files with 43 additions and 42 deletions

View File

@ -2504,12 +2504,11 @@ struct CargoesRow {
} else { } else {
/* Houses only display what is demanded. */ /* Houses only display what is demanded. */
for (uint i = 0; i < cargo_fld->u.cargo.num_cargoes; i++) { for (uint i = 0; i < cargo_fld->u.cargo.num_cargoes; i++) {
for (uint h = 0; h < NUM_HOUSES; h++) { for (const auto &hs : HouseSpec::Specs()) {
HouseSpec *hs = HouseSpec::Get(h); if (!hs.enabled) continue;
if (!hs->enabled) continue;
for (uint j = 0; j < lengthof(hs->accepts_cargo); j++) { for (uint j = 0; j < lengthof(hs.accepts_cargo); j++) {
if (hs->cargo_acceptance[j] > 0 && cargo_fld->u.cargo.vertical_cargoes[i] == hs->accepts_cargo[j]) { if (hs.cargo_acceptance[j] > 0 && cargo_fld->u.cargo.vertical_cargoes[i] == hs.accepts_cargo[j]) {
cargo_fld->ConnectCargo(cargo_fld->u.cargo.vertical_cargoes[i], false); cargo_fld->ConnectCargo(cargo_fld->u.cargo.vertical_cargoes[i], false);
goto next_cargo; goto next_cargo;
} }
@ -2724,12 +2723,11 @@ struct IndustryCargoesWindow : public Window {
for (uint i = 0; i < length; i++) { for (uint i = 0; i < length; i++) {
if (!IsValidCargoID(cargoes[i])) continue; if (!IsValidCargoID(cargoes[i])) continue;
for (uint h = 0; h < NUM_HOUSES; h++) { for (const auto &hs : HouseSpec::Specs()) {
HouseSpec *hs = HouseSpec::Get(h); if (!hs.enabled || !(hs.building_availability & climate_mask)) continue;
if (!hs->enabled || !(hs->building_availability & climate_mask)) continue;
for (uint j = 0; j < lengthof(hs->accepts_cargo); j++) { for (uint j = 0; j < lengthof(hs.accepts_cargo); j++) {
if (hs->cargo_acceptance[j] > 0 && cargoes[i] == hs->accepts_cargo[j]) return true; if (hs.cargo_acceptance[j] > 0 && cargoes[i] == hs.accepts_cargo[j]) return true;
} }
} }
} }

View File

@ -9337,20 +9337,18 @@ static void EnsureEarlyHouse(HouseZones bitmask)
{ {
TimerGameCalendar::Year min_year = CalendarTime::MAX_YEAR; TimerGameCalendar::Year min_year = CalendarTime::MAX_YEAR;
for (int i = 0; i < NUM_HOUSES; i++) { for (const auto &hs : HouseSpec::Specs()) {
HouseSpec *hs = HouseSpec::Get(i); if (!hs.enabled) continue;
if (hs == nullptr || !hs->enabled) continue; if ((hs.building_availability & bitmask) != bitmask) continue;
if ((hs->building_availability & bitmask) != bitmask) continue; if (hs.min_year < min_year) min_year = hs.min_year;
if (hs->min_year < min_year) min_year = hs->min_year;
} }
if (min_year == 0) return; if (min_year == 0) return;
for (int i = 0; i < NUM_HOUSES; i++) { for (auto &hs : HouseSpec::Specs()) {
HouseSpec *hs = HouseSpec::Get(i); if (!hs.enabled) continue;
if (hs == nullptr || !hs->enabled) continue; if ((hs.building_availability & bitmask) != bitmask) continue;
if ((hs->building_availability & bitmask) != bitmask) continue; if (hs.min_year == min_year) hs.min_year = 0;
if (hs->min_year == min_year) hs->min_year = 0;
} }
} }
@ -9390,7 +9388,7 @@ static void FinaliseHouseArray()
} }
} }
for (size_t i = 0; i < NUM_HOUSES; i++) { for (size_t i = 0; i < HouseSpec::Specs().size(); i++) {
HouseSpec *hs = HouseSpec::Get(i); HouseSpec *hs = HouseSpec::Get(i);
const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : nullptr); const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : nullptr);
const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : nullptr); const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : nullptr);

View File

@ -52,6 +52,15 @@ std::vector<HouseSpec> &HouseSpec::Specs()
return _house_specs; return _house_specs;
} }
/**
* Gets the index of this spec.
* @return The index.
*/
HouseID HouseSpec::Index() const
{
return static_cast<HouseID>(this - _house_specs.data());
}
/** /**
* Get the spec for a house ID. * Get the spec for a house ID.
* @param house_id The ID of the house. * @param house_id The ID of the house.

View File

@ -2658,31 +2658,28 @@ static bool BuildTownHouse(Town *t, TileIndex tile)
/* bits 0-4 are used /* bits 0-4 are used
* bits 11-15 are used * bits 11-15 are used
* bits 5-10 are not used. */ * bits 5-10 are not used. */
HouseID houses[NUM_HOUSES]; static std::vector<std::pair<HouseID, uint>> probs;
uint num = 0; probs.clear();
uint probs[NUM_HOUSES];
uint probability_max = 0; uint probability_max = 0;
/* Generate a list of all possible houses that can be built. */ /* Generate a list of all possible houses that can be built. */
for (uint i = 0; i < NUM_HOUSES; i++) { for (const auto &hs : HouseSpec::Specs()) {
const HouseSpec *hs = HouseSpec::Get(i);
/* Verify that the candidate house spec matches the current tile status */ /* Verify that the candidate house spec matches the current tile status */
if ((~hs->building_availability & bitmask) != 0 || !hs->enabled || hs->grf_prop.override != INVALID_HOUSE_ID) continue; if ((~hs.building_availability & bitmask) != 0 || !hs.enabled || hs.grf_prop.override != INVALID_HOUSE_ID) continue;
/* Don't let these counters overflow. Global counters are 32bit, there will never be that many houses. */ /* Don't let these counters overflow. Global counters are 32bit, there will never be that many houses. */
if (hs->class_id != HOUSE_NO_CLASS) { if (hs.class_id != HOUSE_NO_CLASS) {
/* id_count is always <= class_count, so it doesn't need to be checked */ /* id_count is always <= class_count, so it doesn't need to be checked */
if (t->cache.building_counts.class_count[hs->class_id] == UINT16_MAX) continue; if (t->cache.building_counts.class_count[hs.class_id] == UINT16_MAX) continue;
} else { } else {
/* If the house has no class, check id_count instead */ /* If the house has no class, check id_count instead */
if (t->cache.building_counts.id_count[i] == UINT16_MAX) continue; if (t->cache.building_counts.id_count[hs.Index()] == UINT16_MAX) continue;
} }
uint cur_prob = hs->probability; uint cur_prob = hs.probability;
probability_max += cur_prob; probability_max += cur_prob;
probs[num] = cur_prob; probs.emplace_back(std::make_pair(hs.Index(), cur_prob));
houses[num++] = (HouseID)i;
} }
TileIndex baseTile = tile; TileIndex baseTile = tile;
@ -2697,18 +2694,17 @@ static bool BuildTownHouse(Town *t, TileIndex tile)
uint r = RandomRange(probability_max); uint r = RandomRange(probability_max);
uint i; uint i;
for (i = 0; i < num; i++) { for (i = 0; i < probs.size(); i++) {
if (probs[i] > r) break; if (probs[i].second > r) break;
r -= probs[i]; r -= probs[i].second;
} }
HouseID house = houses[i]; HouseID house = probs[i].first;
probability_max -= probs[i]; probability_max -= probs[i].second;
/* remove tested house from the set */ /* remove tested house from the set */
num--; probs[i] = probs.back();
houses[i] = houses[num]; probs.pop_back();
probs[i] = probs[num];
const HouseSpec *hs = HouseSpec::Get(house); const HouseSpec *hs = HouseSpec::Get(house);