Check multi-tile ID-translated houses after house ID limit change

(Or when reloading NewGRFs)
If an overriding house type which newly fit in the limit changed the
tile layout, existing houses on the map could have the wrong layout

See: #243
This commit is contained in:
Jonathan G Rennison
2021-04-19 22:55:32 +01:00
parent 6a3e87114a
commit 14636d2512
2 changed files with 40 additions and 28 deletions

View File

@@ -147,7 +147,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_REALISTIC_TRAIN_BRAKING,XSCF_NULL, 2, 2, "realistic_train_braking", nullptr, nullptr, "VLKA" },
{ XSLFI_INFLATION_FIXED_DATES, XSCF_IGNORABLE_ALL, 1, 1, "inflation_fixed_dates", nullptr, nullptr, nullptr },
{ XSLFI_WATER_FLOODING, XSCF_NULL, 2, 2, "water_flooding", nullptr, nullptr, nullptr },
{ XSLFI_MORE_HOUSES, XSCF_NULL, 1, 1, "more_houses", nullptr, nullptr, nullptr },
{ XSLFI_MORE_HOUSES, XSCF_NULL, 2, 2, "more_houses", nullptr, nullptr, nullptr },
{ XSLFI_CUSTOM_TOWN_ZONE, XSCF_IGNORABLE_UNKNOWN, 1, 1, "custom_town_zone", nullptr, nullptr, nullptr },
{ XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker
};

View File

@@ -60,36 +60,13 @@ void RebuildTownCaches(bool cargo_update_required, bool old_map_position)
}
}
/**
* Check and update town and house values.
*
* Checked are the HouseIDs. Updated are the
* town population the number of houses per
* town, the town radius and the max passengers
* of the town.
*/
void UpdateHousesAndTowns(bool cargo_update_required, bool old_map_position)
static void CheckMultiTileHouseTypes(bool &cargo_update_required, bool old_map_position, bool translate_house_types)
{
auto get_clean_house_type = [&](TileIndex t) -> HouseID {
return SLGetCleanHouseType(t, old_map_position);
HouseID type = SLGetCleanHouseType(t, old_map_position);
if (translate_house_types) type = GetTranslatedHouseID(type);
return type;
};
for (TileIndex t = 0; t < MapSize(); t++) {
if (!IsTileType(t, MP_HOUSE)) continue;
HouseID house_id = get_clean_house_type(t);
if (!HouseSpec::Get(house_id)->enabled && house_id >= NEW_HOUSE_OFFSET) {
/* The specs for this type of house are not available any more, so
* replace it with the substitute original house type. */
house_id = _house_mngr.GetSubstituteID(house_id);
if (old_map_position && SlXvIsFeatureMissing(XSLFI_MORE_HOUSES)) {
_m[t].m4 = GB(house_id, 0, 8);
SB(_m[t].m3, 6, 1, GB(house_id, 8, 1));
} else {
SetHouseType(t, house_id);
}
cargo_update_required = true;
}
}
/* Check for cases when a NewGRF has set a wrong house substitute type. */
for (TileIndex t = 0; t < MapSize(); t++) {
@@ -128,6 +105,41 @@ void UpdateHousesAndTowns(bool cargo_update_required, bool old_map_position)
cargo_update_required = true;
}
}
}
/**
* Check and update town and house values.
*
* Checked are the HouseIDs. Updated are the
* town population the number of houses per
* town, the town radius and the max passengers
* of the town.
*/
void UpdateHousesAndTowns(bool cargo_update_required, bool old_map_position)
{
auto get_clean_house_type = [&](TileIndex t) -> HouseID {
return SLGetCleanHouseType(t, old_map_position);
};
for (TileIndex t = 0; t < MapSize(); t++) {
if (!IsTileType(t, MP_HOUSE)) continue;
HouseID house_id = get_clean_house_type(t);
if (!HouseSpec::Get(house_id)->enabled && house_id >= NEW_HOUSE_OFFSET) {
/* The specs for this type of house are not available any more, so
* replace it with the substitute original house type. */
house_id = _house_mngr.GetSubstituteID(house_id);
if (old_map_position && SlXvIsFeatureMissing(XSLFI_MORE_HOUSES)) {
_m[t].m4 = GB(house_id, 0, 8);
SB(_m[t].m3, 6, 1, GB(house_id, 8, 1));
} else {
SetHouseType(t, house_id);
}
cargo_update_required = true;
}
}
CheckMultiTileHouseTypes(cargo_update_required, old_map_position, false);
if (cargo_update_required || SlXvIsFeatureMissing(XSLFI_MORE_HOUSES, 2)) CheckMultiTileHouseTypes(cargo_update_required, old_map_position, true);
RebuildTownCaches(cargo_update_required, old_map_position);
}