diff --git a/src/newgrf_house.cpp b/src/newgrf_house.cpp index 88494b33e6..251207c195 100644 --- a/src/newgrf_house.cpp +++ b/src/newgrf_house.cpp @@ -31,13 +31,24 @@ static HouseClassMapping _class_mapping[HOUSE_CLASS_MAX]; HouseOverrideManager _house_mngr(NEW_HOUSE_OFFSET, HOUSE_MAX, INVALID_HOUSE_ID); -void CheckHouseIDs() +/** + * 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() { Town *town; InitializeBuildingCounts(); - /* Reset town population */ - FOR_ALL_TOWNS(town) town->population = 0; + /* Reset town population and num_houses */ + FOR_ALL_TOWNS(town) { + town->population = 0; + town->num_houses = 0; + } for (TileIndex t = 0; t < MapSize(); t++) { HouseID house_id; @@ -51,9 +62,23 @@ void CheckHouseIDs() house_id = _house_mngr.GetSubstituteID(house_id); SetHouseType(t, house_id); } + town = GetTownByTile(t); IncreaseBuildingCount(town, house_id); if (IsHouseCompleted(t)) town->population += GetHouseSpecs(house_id)->population; + + /* Increase the number of houses for every house tile which + * has a size bit set. Multi tile buildings have got only + * one tile with such a bit set, so there is no problem. */ + if (GetHouseSpecs(GetHouseType(t))->building_flags & BUILDING_HAS_1_TILE) { + town->num_houses++; + } + } + + /* Update the population and num_house dependant values */ + FOR_ALL_TOWNS(town) { + UpdateTownRadius(town); + UpdateTownMaxPass(town); } } diff --git a/src/newgrf_house.h b/src/newgrf_house.h index 5c70a2cb8e..a74906aad4 100644 --- a/src/newgrf_house.h +++ b/src/newgrf_house.h @@ -26,7 +26,7 @@ struct HouseClassMapping { uint8 class_id; ////< The class id within the grf file }; -void CheckHouseIDs(); +void UpdateHousesAndTowns(); HouseClassID AllocateHouseClassID(byte grf_class_id, uint32 grfid); diff --git a/src/newgrf_town.cpp b/src/newgrf_town.cpp index 223be98039..d28fe99383 100644 --- a/src/newgrf_town.cpp +++ b/src/newgrf_town.cpp @@ -64,7 +64,7 @@ uint32 TownGetVariable(byte variable, byte parameter, bool *available, const Tow case 0xAD: return GB(t->ratings[7], 8, 8); case 0xAE: return t->have_ratings; case 0xB2: return t->statues; - case 0xB6: return t->num_houses; + case 0xB6: return ClampToU16(t->num_houses); case 0xB9: return t->growth_rate; case 0xBA: return ClampToU16(t->new_max_pass); case 0xBB: return GB(ClampToU16(t->new_max_pass), 8, 8); diff --git a/src/oldloader.cpp b/src/oldloader.cpp index 0140f22002..434e634de7 100644 --- a/src/oldloader.cpp +++ b/src/oldloader.cpp @@ -428,7 +428,7 @@ static void ReadTTDPatchFlags() static const OldChunks town_chunk[] = { OCL_SVAR( OC_TILE, Town, xy ), - OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Town, population ), + OCL_NULL( 2 ), ///< population, no longer in use OCL_SVAR( OC_UINT16, Town, townnametype ), OCL_SVAR( OC_UINT32, Town, townnameparts ), OCL_SVAR( OC_UINT8, Town, grow_counter ), @@ -451,7 +451,7 @@ static const OldChunks town_chunk[] = { nothing changed ? ? */ OCL_SVAR( OC_FILE_U32 | OC_VAR_U8, Town, have_ratings ), OCL_SVAR( OC_FILE_U32 | OC_VAR_U8, Town, statues ), - OCL_SVAR( OC_UINT16, Town, num_houses ), + OCL_NULL( 2 ), ///< num_houses, no longer in use OCL_SVAR( OC_UINT8, Town, time_until_rebuild ), OCL_SVAR( OC_UINT8, Town, growth_rate ), diff --git a/src/openttd.cpp b/src/openttd.cpp index 98975a36d7..d4dc25aaac 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -1348,9 +1348,9 @@ bool AfterLoadGame() if (CheckSavegameVersionOldStyle(6, 1)) UpdateSignOwner(); /* In old version there seems to be a problem that water is owned by - OWNER_NONE, not OWNER_WATER.. I can't replicate it for the current - (4.3) version, so I just check when versions are older, and then - walk through the whole map.. */ + * OWNER_NONE, not OWNER_WATER.. I can't replicate it for the current + * (4.3) version, so I just check when versions are older, and then + * walk through the whole map.. */ if (CheckSavegameVersionOldStyle(4, 3)) { for (TileIndex t = 0; t < map_size; t++) { if (IsTileType(t, MP_WATER) && GetTileOwner(t) >= MAX_PLAYERS) { @@ -2034,8 +2034,8 @@ bool AfterLoadGame() } } - /* Check that house ids are still valid. */ - CheckHouseIDs(); + /* Check and update house and town values */ + UpdateHousesAndTowns(); if (CheckSavegameVersion(43)) { for (TileIndex t = 0; t < map_size; t++) { @@ -2461,8 +2461,8 @@ void ReloadNewGRFData() /* update station and waypoint graphics */ AfterLoadWaypoints(); AfterLoadStations(); - /* check that house ids are still valid */ - CheckHouseIDs(); + /* Check and update house and town values */ + UpdateHousesAndTowns(); /* redraw the whole screen */ MarkWholeScreenDirty(); } diff --git a/src/saveload.cpp b/src/saveload.cpp index 9726e8872a..68659767b6 100644 --- a/src/saveload.cpp +++ b/src/saveload.cpp @@ -34,7 +34,7 @@ #include "table/strings.h" -extern const uint16 SAVEGAME_VERSION = 91; +extern const uint16 SAVEGAME_VERSION = 92; uint16 _sl_version; ///< the major savegame version identifier byte _sl_minor_version; ///< the minor savegame version, DO NOT USE! diff --git a/src/town.h b/src/town.h index 62a49653ab..4c42c8bc54 100644 --- a/src/town.h +++ b/src/town.h @@ -90,7 +90,7 @@ struct Town : PoolItem { TileIndex xy; /* Current population of people and amount of houses. */ - uint16 num_houses; + uint32 num_houses; uint32 population; /* Town name */ @@ -320,6 +320,7 @@ void ResetHouses(); void ClearTownHouse(Town *t, TileIndex tile); void AfterLoadTown(); void UpdateTownMaxPass(Town *t); +void UpdateTownRadius(Town *t); bool CheckIfAuthorityAllows(TileIndex tile); Town *ClosestTownFromTile(TileIndex tile, uint threshold); void ChangeTownRating(Town *t, int add, int max); diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 8e809520c8..35ffed7c33 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -265,8 +265,6 @@ static void AnimateTile_Town(TileIndex tile) MarkTileDirtyByTile(tile); } -static void UpdateTownRadius(Town *t); - /** * Determines if a town is close to a tile * @param tile TileIndex of the tile to query @@ -1282,7 +1280,7 @@ static bool GrowTown(Town *t) return false; } -static void UpdateTownRadius(Town *t) +void UpdateTownRadius(Town *t) { static const uint16 _town_radius_data[23][5] = { { 4, 0, 0, 0, 0}, // 0 @@ -2074,12 +2072,12 @@ CommandCost CmdRenameTown(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) /** Called from GUI */ void ExpandTown(Town *t) { - int amount, n; + uint amount, n; _generating_world = true; /* The more houses, the faster we grow */ - amount = RandomRange(t->num_houses / 10) + 3; + amount = RandomRange(ClampToU16(t->num_houses / 10)) + 3; t->num_houses += amount; UpdateTownRadius(t); @@ -2564,10 +2562,10 @@ static const SaveLoad _town_desc[] = { SLE_CONDVAR(Town, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5), SLE_CONDVAR(Town, xy, SLE_UINT32, 6, SL_MAX_VERSION), - SLE_CONDNULL(2, 0, 2), - SLE_CONDNULL(4, 3, 84), + SLE_CONDNULL(2, 0, 2), ///< population, no longer in use + SLE_CONDNULL(4, 3, 84), ///< population, no longer in use + SLE_CONDNULL(2, 0, 91), ///< num_houses, no longer in use - SLE_VAR(Town, num_houses, SLE_UINT16), SLE_CONDVAR(Town, townnamegrfid, SLE_UINT32, 66, SL_MAX_VERSION), SLE_VAR(Town, townnametype, SLE_UINT16), SLE_VAR(Town, townnameparts, SLE_UINT32), @@ -2576,13 +2574,12 @@ static const SaveLoad _town_desc[] = { SLE_VAR(Town, flags12, SLE_UINT8), SLE_VAR(Town, statues, SLE_UINT8), - /* sort_index_obsolete was stored here in savegame format 0 - 1 */ - SLE_CONDNULL(1, 0, 1), + SLE_CONDNULL(1, 0, 1), ///< sort_index, no longer in use SLE_VAR(Town, have_ratings, SLE_UINT8), SLE_ARR(Town, ratings, SLE_INT16, 8), /* failed bribe attempts are stored since savegame format 4 */ - SLE_CONDARR(Town, unwanted, SLE_INT8, 8, 4,SL_MAX_VERSION), + SLE_CONDARR(Town, unwanted, SLE_INT8, 8, 4, SL_MAX_VERSION), SLE_CONDVAR(Town, max_pass, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), SLE_CONDVAR(Town, max_mail, SLE_FILE_U16 | SLE_VAR_U32, 0, 8), @@ -2695,10 +2692,6 @@ static void Load_TOWN() void AfterLoadTown() { - Town *t; - FOR_ALL_TOWNS(t) { - UpdateTownRadius(t); - } _town_sort_dirty = true; }