From 801bf2e3d348c3bce64af5eb83ee39088e457be1 Mon Sep 17 00:00:00 2001 From: rubidium Date: Mon, 30 Aug 2010 16:52:37 +0000 Subject: [PATCH] (svn r20698) [1.0] -Backport from trunk: - Fix: Empty newgrf presets were not selectable [FS#4087] (r20694) - Fix: Desync checker checked the wrong variable (r20677) - Fix: Drawing the 'OpenTTD' text in the intro game caused crashes with very low resolutions [FS#4081] (r20618) - Fix: Crash when a NewGRF defined an invalid substitute type for a house and the NewGRF was removed during the game, disable houses with different size than their substitute [FS#3702] (r20611, r20610, r20609) --- changelog.txt | 2 +- src/main_gui.cpp | 2 +- src/newgrf.cpp | 7 ++++++ src/newgrf_gui.cpp | 17 ++++++--------- src/openttd.cpp | 2 +- src/saveload/afterload.cpp | 2 +- src/saveload/town_sl.cpp | 44 +++++++++++++++++++++++++++++++++++--- 7 files changed, 59 insertions(+), 17 deletions(-) diff --git a/changelog.txt b/changelog.txt index 32aa6cb373..879fd0fed2 100644 --- a/changelog.txt +++ b/changelog.txt @@ -20,7 +20,7 @@ - Fix: Do not allow building a rail track to the water using a tree-tile [FS#3695] (r20110) - Fix: [NoAI] AITown::GetRating() returned wrong values [FS#3934] (r20103) - Fix: Reading deleted memory when selecting a NewGRF in the content download window of which the data has not been acquired from the content server. The crash would occur after the content server's reply was processed and the ContentInfo object was replaced with another [FS#3899] (r20089, r20082) -- Fix: If after loading a savegame (including intro game) one tried to save a game (including autosave) and that failed (very) early on because it could not open the file for writing all pointers would be converted to NULLs which then causes corrupted game states [FS#3876, FS#3887, FS#3920, FS#3923] (r20087) +- Fix: If after loading a savegame (including intro game) one tried to save a game (including autosave) and that failed (very) early on because it could not open the file for writing all pointers would be converted to NULLs which then causes corrupted game states [FS#3786, FS#3887, FS#3920, FS#3923] (r20087) - Fix: gitignore and hgignore had more missing/wrong entries (r20078, r20033, r20031) - Fix: Remove the space between 'open' and 'ttd' in the title screen (r20077) - Fix: Road vehicles could get crashed twice in a tick [FS#3896] (r20053, r20034) diff --git a/src/main_gui.cpp b/src/main_gui.cpp index e3566d09c6..2c93abf4f9 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -220,7 +220,7 @@ struct MainWindow : Window if (_game_mode == GM_MENU) { static const SpriteID title_sprites[] = {SPR_OTTD_O, SPR_OTTD_P, SPR_OTTD_E, SPR_OTTD_N, SPR_OTTD_T, SPR_OTTD_T, SPR_OTTD_D}; static const uint LETTER_SPACING = 10; - uint name_width = (lengthof(title_sprites) - 1) * LETTER_SPACING; + int name_width = (lengthof(title_sprites) - 1) * LETTER_SPACING; for (uint i = 0; i < lengthof(title_sprites); i++) { name_width += GetSpriteSize(title_sprites[i]).width; diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 09d4f97e34..a68f6babc2 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -6244,6 +6244,13 @@ static void FinaliseHouseArray() continue; } + /* Substitute type is also used for override, and having an override with a different size causes crashes. */ + if ((hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->substitute_id)->building_flags & BUILDING_HAS_1_TILE)) { + hs->enabled = false; + DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d with different house size then it's substitute type. Disabling house.", (*file)->filename, hs->local_id); + continue; + } + _house_mngr.SetEntitySpec(hs); if (hs->min_year < min_year) min_year = hs->min_year; } diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index 0c94308121..669b2ce229 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -884,18 +884,15 @@ struct NewGRFWindow : public Window { virtual void OnDropdownSelect(int widget, int index) { - if (index == -1) { - ClearGRFConfigList(&this->list); - this->preset = -1; - } else { + ClearGRFConfigList(&this->list); + this->preset = index; + + if (index != -1) { GRFConfig *c = LoadGRFPresetFromConfig(_grf_preset_list[index]); - if (c != NULL) { - this->sel = NULL; - ClearGRFConfigList(&this->list); - this->list = c; - this->preset = index; - } + this->sel = NULL; + ClearGRFConfigList(&this->list); + this->list = c; } this->sel = NULL; diff --git a/src/openttd.cpp b/src/openttd.cpp index 70e9f91d92..b636402e27 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -1178,7 +1178,7 @@ static void CheckCaches() } break; case VEH_ROAD: - if (memcmp(&tra_cache[length], &RoadVehicle::From(u)->rcache, sizeof(RoadVehicleCache)) != 0) { + if (memcmp(&roa_cache[length], &RoadVehicle::From(u)->rcache, sizeof(RoadVehicleCache)) != 0) { DEBUG(desync, 2, "road vehicle cache mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length); } break; diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index fece94bcd5..fb4a578ffb 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -560,7 +560,7 @@ bool AfterLoadGame() } /* The value of _date_fract got divided, so make sure that old games are converted correctly. */ - if (CheckSavegameVersionOldStyle(11, 1)) _date_fract /= 885; + if (CheckSavegameVersionOldStyle(11, 1) || (CheckSavegameVersion(147) && _date_fract > DAY_TICKS)) _date_fract /= 885; /* Update current year * must be done before loading sprites as some newgrfs check it */ diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index d10a0c60e7..d3e3d9c4aa 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -13,6 +13,7 @@ #include "../newgrf_house.h" #include "../newgrf_commons.h" #include "../town.h" +#include "../landscape.h" #include "saveload.h" @@ -36,18 +37,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(0, 1); + if (!IsTileType(tile, MP_HOUSE) || GetCleanHouseType(tile) != house_type + 1) valid_house = false; + tile = t + TileDiffXY(1, 0); + 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;