Fix 4c2e42fa: Wrong town caches when loading pre more-houses savegame

pull/251/head
Jonathan G Rennison 4 years ago
parent 7faa279250
commit e623560120

@ -1416,8 +1416,8 @@ void CheckCaches(bool force_check, std::function<void(const char *)> log)
old_industry_stations_nears.push_back(ind->stations_near); old_industry_stations_nears.push_back(ind->stations_near);
} }
extern void RebuildTownCaches(bool cargo_update_required); extern void RebuildTownCaches(bool cargo_update_required, bool old_map_position);
RebuildTownCaches(false); RebuildTownCaches(false, false);
RebuildSubsidisedSourceAndDestinationCache(); RebuildSubsidisedSourceAndDestinationCache();
Station::RecomputeCatchmentForAll(); Station::RecomputeCatchmentForAll();

@ -19,10 +19,19 @@
#include "../safeguards.h" #include "../safeguards.h"
HouseID SLGetCleanHouseType(TileIndex t, bool old_map_position)
{
if (old_map_position && SlXvIsFeatureMissing(XSLFI_MORE_HOUSES)) {
return _m[t].m4 | (GB(_m[t].m3, 6, 1) << 8);
} else {
return GetCleanHouseType(t);
}
}
/** /**
* Rebuild all the cached variables of towns. * Rebuild all the cached variables of towns.
*/ */
void RebuildTownCaches(bool cargo_update_required) void RebuildTownCaches(bool cargo_update_required, bool old_map_position)
{ {
InitializeBuildingCounts(); InitializeBuildingCounts();
RebuildTownKdtree(); RebuildTownKdtree();
@ -36,7 +45,7 @@ void RebuildTownCaches(bool cargo_update_required)
for (TileIndex t = 0; t < MapSize(); t++) { for (TileIndex t = 0; t < MapSize(); t++) {
if (!IsTileType(t, MP_HOUSE)) continue; if (!IsTileType(t, MP_HOUSE)) continue;
HouseID house_id = GetHouseType(t); HouseID house_id = GetTranslatedHouseID(SLGetCleanHouseType(t, old_map_position));
Town *town = Town::GetByTile(t); Town *town = Town::GetByTile(t);
IncreaseBuildingCount(town, house_id); IncreaseBuildingCount(town, house_id);
if (IsHouseCompleted(t)) town->cache.population += HouseSpec::Get(house_id)->population; if (IsHouseCompleted(t)) town->cache.population += HouseSpec::Get(house_id)->population;
@ -61,17 +70,13 @@ void RebuildTownCaches(bool cargo_update_required)
*/ */
void UpdateHousesAndTowns(bool cargo_update_required, bool old_map_position) void UpdateHousesAndTowns(bool cargo_update_required, bool old_map_position)
{ {
auto get_house_type = [&](TileIndex t) -> HouseID { auto get_clean_house_type = [&](TileIndex t) -> HouseID {
if (old_map_position && SlXvIsFeatureMissing(XSLFI_MORE_HOUSES)) { return SLGetCleanHouseType(t, old_map_position);
return _m[t].m4 | (GB(_m[t].m3, 6, 1) << 8);
} else {
return GetCleanHouseType(t);
}
}; };
for (TileIndex t = 0; t < MapSize(); t++) { for (TileIndex t = 0; t < MapSize(); t++) {
if (!IsTileType(t, MP_HOUSE)) continue; if (!IsTileType(t, MP_HOUSE)) continue;
HouseID house_id = get_house_type(t); HouseID house_id = get_clean_house_type(t);
if (!HouseSpec::Get(house_id)->enabled && house_id >= NEW_HOUSE_OFFSET) { if (!HouseSpec::Get(house_id)->enabled && house_id >= NEW_HOUSE_OFFSET) {
/* The specs for this type of house are not available any more, so /* The specs for this type of house are not available any more, so
* replace it with the substitute original house type. */ * replace it with the substitute original house type. */
@ -90,24 +95,24 @@ void UpdateHousesAndTowns(bool cargo_update_required, bool old_map_position)
for (TileIndex t = 0; t < MapSize(); t++) { for (TileIndex t = 0; t < MapSize(); t++) {
if (!IsTileType(t, MP_HOUSE)) continue; if (!IsTileType(t, MP_HOUSE)) continue;
HouseID house_type = get_house_type(t); HouseID house_type = get_clean_house_type(t);
TileIndex north_tile = t + GetHouseNorthPart(house_type); // modifies 'house_type'! TileIndex north_tile = t + GetHouseNorthPart(house_type); // modifies 'house_type'!
if (t == north_tile) { if (t == north_tile) {
const HouseSpec *hs = HouseSpec::Get(house_type); const HouseSpec *hs = HouseSpec::Get(house_type);
bool valid_house = true; bool valid_house = true;
if (hs->building_flags & TILE_SIZE_2x1) { if (hs->building_flags & TILE_SIZE_2x1) {
TileIndex tile = t + TileDiffXY(1, 0); TileIndex tile = t + TileDiffXY(1, 0);
if (!IsTileType(tile, MP_HOUSE) || get_house_type(tile) != house_type + 1) valid_house = false; if (!IsTileType(tile, MP_HOUSE) || get_clean_house_type(tile) != house_type + 1) valid_house = false;
} else if (hs->building_flags & TILE_SIZE_1x2) { } else if (hs->building_flags & TILE_SIZE_1x2) {
TileIndex tile = t + TileDiffXY(0, 1); TileIndex tile = t + TileDiffXY(0, 1);
if (!IsTileType(tile, MP_HOUSE) || get_house_type(tile) != house_type + 1) valid_house = false; if (!IsTileType(tile, MP_HOUSE) || get_clean_house_type(tile) != house_type + 1) valid_house = false;
} else if (hs->building_flags & TILE_SIZE_2x2) { } else if (hs->building_flags & TILE_SIZE_2x2) {
TileIndex tile = t + TileDiffXY(0, 1); TileIndex tile = t + TileDiffXY(0, 1);
if (!IsTileType(tile, MP_HOUSE) || get_house_type(tile) != house_type + 1) valid_house = false; if (!IsTileType(tile, MP_HOUSE) || get_clean_house_type(tile) != house_type + 1) valid_house = false;
tile = t + TileDiffXY(1, 0); tile = t + TileDiffXY(1, 0);
if (!IsTileType(tile, MP_HOUSE) || get_house_type(tile) != house_type + 2) valid_house = false; if (!IsTileType(tile, MP_HOUSE) || get_clean_house_type(tile) != house_type + 2) valid_house = false;
tile = t + TileDiffXY(1, 1); tile = t + TileDiffXY(1, 1);
if (!IsTileType(tile, MP_HOUSE) || get_house_type(tile) != house_type + 3) valid_house = false; if (!IsTileType(tile, MP_HOUSE) || get_clean_house_type(tile) != house_type + 3) valid_house = false;
} }
/* If not all tiles of this house are present remove the house. /* If not all tiles of this house are present remove the house.
* The other tiles will get removed later in this loop because * The other tiles will get removed later in this loop because
@ -116,7 +121,7 @@ void UpdateHousesAndTowns(bool cargo_update_required, bool old_map_position)
DoClearSquare(t); DoClearSquare(t);
cargo_update_required = true; cargo_update_required = true;
} }
} else if (!IsTileType(north_tile, MP_HOUSE) || get_house_type(north_tile) != house_type) { } else if (!IsTileType(north_tile, MP_HOUSE) || get_clean_house_type(north_tile) != house_type) {
/* This tile should be part of a multi-tile building but the /* This tile should be part of a multi-tile building but the
* north tile of this house isn't on the map. */ * north tile of this house isn't on the map. */
DoClearSquare(t); DoClearSquare(t);
@ -124,7 +129,7 @@ void UpdateHousesAndTowns(bool cargo_update_required, bool old_map_position)
} }
} }
RebuildTownCaches(cargo_update_required); RebuildTownCaches(cargo_update_required, old_map_position);
} }
/** Save and load of towns. */ /** Save and load of towns. */

Loading…
Cancel
Save