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 {
/* Houses only display what is demanded. */
for (uint i = 0; i < cargo_fld->u.cargo.num_cargoes; i++) {
for (uint h = 0; h < NUM_HOUSES; h++) {
HouseSpec *hs = HouseSpec::Get(h);
if (!hs->enabled) continue;
for (const auto &hs : HouseSpec::Specs()) {
if (!hs.enabled) continue;
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]) {
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]) {
cargo_fld->ConnectCargo(cargo_fld->u.cargo.vertical_cargoes[i], false);
goto next_cargo;
}
@ -2724,12 +2723,11 @@ struct IndustryCargoesWindow : public Window {
for (uint i = 0; i < length; i++) {
if (!IsValidCargoID(cargoes[i])) continue;
for (uint h = 0; h < NUM_HOUSES; h++) {
HouseSpec *hs = HouseSpec::Get(h);
if (!hs->enabled || !(hs->building_availability & climate_mask)) continue;
for (const auto &hs : HouseSpec::Specs()) {
if (!hs.enabled || !(hs.building_availability & climate_mask)) continue;
for (uint j = 0; j < lengthof(hs->accepts_cargo); j++) {
if (hs->cargo_acceptance[j] > 0 && cargoes[i] == hs->accepts_cargo[j]) return true;
for (uint j = 0; j < lengthof(hs.accepts_cargo); j++) {
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;
for (int i = 0; i < NUM_HOUSES; i++) {
HouseSpec *hs = HouseSpec::Get(i);
if (hs == nullptr || !hs->enabled) continue;
if ((hs->building_availability & bitmask) != bitmask) continue;
if (hs->min_year < min_year) min_year = hs->min_year;
for (const auto &hs : HouseSpec::Specs()) {
if (!hs.enabled) continue;
if ((hs.building_availability & bitmask) != bitmask) continue;
if (hs.min_year < min_year) min_year = hs.min_year;
}
if (min_year == 0) return;
for (int i = 0; i < NUM_HOUSES; i++) {
HouseSpec *hs = HouseSpec::Get(i);
if (hs == nullptr || !hs->enabled) continue;
if ((hs->building_availability & bitmask) != bitmask) continue;
if (hs->min_year == min_year) hs->min_year = 0;
for (auto &hs : HouseSpec::Specs()) {
if (!hs.enabled) continue;
if ((hs.building_availability & bitmask) != bitmask) continue;
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);
const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : 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;
}
/**
* 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.
* @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 11-15 are used
* bits 5-10 are not used. */
HouseID houses[NUM_HOUSES];
uint num = 0;
uint probs[NUM_HOUSES];
static std::vector<std::pair<HouseID, uint>> probs;
probs.clear();
uint probability_max = 0;
/* Generate a list of all possible houses that can be built. */
for (uint i = 0; i < NUM_HOUSES; i++) {
const HouseSpec *hs = HouseSpec::Get(i);
for (const auto &hs : HouseSpec::Specs()) {
/* 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. */
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 */
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 {
/* 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;
probs[num] = cur_prob;
houses[num++] = (HouseID)i;
probs.emplace_back(std::make_pair(hs.Index(), cur_prob));
}
TileIndex baseTile = tile;
@ -2697,18 +2694,17 @@ static bool BuildTownHouse(Town *t, TileIndex tile)
uint r = RandomRange(probability_max);
uint i;
for (i = 0; i < num; i++) {
if (probs[i] > r) break;
r -= probs[i];
for (i = 0; i < probs.size(); i++) {
if (probs[i].second > r) break;
r -= probs[i].second;
}
HouseID house = houses[i];
probability_max -= probs[i];
HouseID house = probs[i].first;
probability_max -= probs[i].second;
/* remove tested house from the set */
num--;
houses[i] = houses[num];
probs[i] = probs[num];
probs[i] = probs.back();
probs.pop_back();
const HouseSpec *hs = HouseSpec::Get(house);