mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r20609) -Fix [FS#3702]: crash when a NewGRF defined an invalid substitute type for a house and the NewGRF was removed during the game
This commit is contained in:
parent
5e08df7689
commit
3b04f510b1
|
@ -36,18 +36,55 @@ void UpdateHousesAndTowns()
|
|||
}
|
||||
|
||||
for (TileIndex t = 0; t < MapSize(); t++) {
|
||||
HouseID house_id;
|
||||
|
||||
if (!IsTileType(t, MP_HOUSE)) continue;
|
||||
|
||||
house_id = GetCleanHouseType(t);
|
||||
HouseID house_id = GetCleanHouseType(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);
|
||||
SetHouseType(t, house_id);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for cases when a NewGRF has set a wrong house substitute type. */
|
||||
for (TileIndex t = 0; t < MapSize(); t++) {
|
||||
if (!IsTileType(t, MP_HOUSE)) continue;
|
||||
|
||||
HouseID house_type = GetCleanHouseType(t);
|
||||
TileIndex north_tile = t + GetHouseNorthPart(house_type); // modifies 'house_type'!
|
||||
if (t == north_tile) {
|
||||
const HouseSpec *hs = HouseSpec::Get(house_type);
|
||||
bool valid_house = true;
|
||||
if (hs->building_flags & TILE_SIZE_2x1) {
|
||||
TileIndex tile = t + TileDiffXY(1, 0);
|
||||
if (!IsTileType(tile, MP_HOUSE) || GetCleanHouseType(tile) != house_type + 1) valid_house = false;
|
||||
} else if (hs->building_flags & TILE_SIZE_1x2) {
|
||||
TileIndex tile = t + TileDiffXY(0, 1);
|
||||
if (!IsTileType(tile, MP_HOUSE) || GetCleanHouseType(tile) != house_type + 1) valid_house = false;
|
||||
} else if (hs->building_flags & TILE_SIZE_2x2) {
|
||||
TileIndex tile = t + TileDiffXY(1, 0);
|
||||
if (!IsTileType(tile, MP_HOUSE) || GetCleanHouseType(tile) != house_type + 1) valid_house = false;
|
||||
tile = t + TileDiffXY(0, 1);
|
||||
if (!IsTileType(tile, MP_HOUSE) || GetCleanHouseType(tile) != house_type + 2) valid_house = false;
|
||||
tile = t + TileDiffXY(1, 1);
|
||||
if (!IsTileType(tile, MP_HOUSE) || GetCleanHouseType(tile) != house_type + 3) valid_house = false;
|
||||
}
|
||||
/* If not all tiles of this house are present remove the house.
|
||||
* The other tiles will get removed later in this loop because
|
||||
* their north tile is not the correct type anymore. */
|
||||
if (!valid_house) DoClearSquare(t);
|
||||
} else if (!IsTileType(north_tile, MP_HOUSE) || GetCleanHouseType(north_tile) != house_type) {
|
||||
/* This tile should be part of a multi-tile building but the
|
||||
* north tile of this house isn't on the map. */
|
||||
DoClearSquare(t);
|
||||
}
|
||||
}
|
||||
|
||||
for (TileIndex t = 0; t < MapSize(); t++) {
|
||||
if (!IsTileType(t, MP_HOUSE)) continue;
|
||||
|
||||
HouseID house_id = GetCleanHouseType(t);
|
||||
town = Town::GetByTile(t);
|
||||
IncreaseBuildingCount(town, house_id);
|
||||
if (IsHouseCompleted(t)) town->population += HouseSpec::Get(house_id)->population;
|
||||
|
|
Loading…
Reference in New Issue