OpenTTD
town_sl.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
10 #include "../stdafx.h"
11 #include "../newgrf_house.h"
12 #include "../town.h"
13 #include "../landscape.h"
14 #include "../subsidy_func.h"
15 #include "../strings_func.h"
16 
17 #include "saveload.h"
18 #include "newgrf_sl.h"
19 
20 #include "../safeguards.h"
21 
26 {
27  InitializeBuildingCounts();
28  RebuildTownKdtree();
29 
30  /* Reset town population and num_houses */
31  for (Town *town : Town::Iterate()) {
32  town->cache.population = 0;
33  town->cache.num_houses = 0;
34  }
35 
36  for (TileIndex t = 0; t < MapSize(); t++) {
37  if (!IsTileType(t, MP_HOUSE)) continue;
38 
39  HouseID house_id = GetHouseType(t);
40  Town *town = Town::GetByTile(t);
41  IncreaseBuildingCount(town, house_id);
42  if (IsHouseCompleted(t)) town->cache.population += HouseSpec::Get(house_id)->population;
43 
44  /* Increase the number of houses for every house, but only once. */
45  if (GetHouseNorthPart(house_id) == 0) town->cache.num_houses++;
46  }
47 
48  /* Update the population and num_house dependent values */
49  for (Town *town : Town::Iterate()) {
50  UpdateTownRadius(town);
51  UpdateTownCargoes(town);
52  }
54 }
55 
65 {
66  for (TileIndex t = 0; t < MapSize(); t++) {
67  if (!IsTileType(t, MP_HOUSE)) continue;
68 
69  HouseID house_id = GetCleanHouseType(t);
70  if (!HouseSpec::Get(house_id)->enabled && house_id >= NEW_HOUSE_OFFSET) {
71  /* The specs for this type of house are not available any more, so
72  * replace it with the substitute original house type. */
73  house_id = _house_mngr.GetSubstituteID(house_id);
74  SetHouseType(t, house_id);
75  }
76  }
77 
78  /* Check for cases when a NewGRF has set a wrong house substitute type. */
79  for (TileIndex t = 0; t < MapSize(); t++) {
80  if (!IsTileType(t, MP_HOUSE)) continue;
81 
82  HouseID house_type = GetCleanHouseType(t);
83  TileIndex north_tile = t + GetHouseNorthPart(house_type); // modifies 'house_type'!
84  if (t == north_tile) {
85  const HouseSpec *hs = HouseSpec::Get(house_type);
86  bool valid_house = true;
87  if (hs->building_flags & TILE_SIZE_2x1) {
88  TileIndex tile = t + TileDiffXY(1, 0);
89  if (!IsTileType(tile, MP_HOUSE) || GetCleanHouseType(tile) != house_type + 1) valid_house = false;
90  } else if (hs->building_flags & TILE_SIZE_1x2) {
91  TileIndex tile = t + TileDiffXY(0, 1);
92  if (!IsTileType(tile, MP_HOUSE) || GetCleanHouseType(tile) != house_type + 1) valid_house = false;
93  } else if (hs->building_flags & TILE_SIZE_2x2) {
94  TileIndex tile = t + TileDiffXY(0, 1);
95  if (!IsTileType(tile, MP_HOUSE) || GetCleanHouseType(tile) != house_type + 1) valid_house = false;
96  tile = t + TileDiffXY(1, 0);
97  if (!IsTileType(tile, MP_HOUSE) || GetCleanHouseType(tile) != house_type + 2) valid_house = false;
98  tile = t + TileDiffXY(1, 1);
99  if (!IsTileType(tile, MP_HOUSE) || GetCleanHouseType(tile) != house_type + 3) valid_house = false;
100  }
101  /* If not all tiles of this house are present remove the house.
102  * The other tiles will get removed later in this loop because
103  * their north tile is not the correct type anymore. */
104  if (!valid_house) DoClearSquare(t);
105  } else if (!IsTileType(north_tile, MP_HOUSE) || GetCleanHouseType(north_tile) != house_type) {
106  /* This tile should be part of a multi-tile building but the
107  * north tile of this house isn't on the map. */
108  DoClearSquare(t);
109  }
110  }
111 
113 }
114 
116 static const SaveLoad _town_desc[] = {
117  SLE_CONDVAR(Town, xy, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6),
118  SLE_CONDVAR(Town, xy, SLE_UINT32, SLV_6, SL_MAX_VERSION),
119 
121  SLE_CONDNULL(4, SLV_3, SLV_85),
123 
124  SLE_CONDVAR(Town, townnamegrfid, SLE_UINT32, SLV_66, SL_MAX_VERSION),
125  SLE_VAR(Town, townnametype, SLE_UINT16),
126  SLE_VAR(Town, townnameparts, SLE_UINT32),
128 
129  SLE_VAR(Town, flags, SLE_UINT8),
130  SLE_CONDVAR(Town, statues, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
131  SLE_CONDVAR(Town, statues, SLE_UINT16, SLV_104, SL_MAX_VERSION),
132 
134 
135  SLE_CONDVAR(Town, have_ratings, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
136  SLE_CONDVAR(Town, have_ratings, SLE_UINT16, SLV_104, SL_MAX_VERSION),
137  SLE_CONDARR(Town, ratings, SLE_INT16, 8, SL_MIN_VERSION, SLV_104),
138  SLE_CONDARR(Town, ratings, SLE_INT16, MAX_COMPANIES, SLV_104, SL_MAX_VERSION),
139  /* failed bribe attempts are stored since savegame format 4 */
140  SLE_CONDARR(Town, unwanted, SLE_INT8, 8, SLV_4, SLV_104),
141  SLE_CONDARR(Town, unwanted, SLE_INT8, MAX_COMPANIES, SLV_104, SL_MAX_VERSION),
142 
143  SLE_CONDVAR(Town, supplied[CT_PASSENGERS].old_max, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9),
144  SLE_CONDVAR(Town, supplied[CT_MAIL].old_max, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9),
145  SLE_CONDVAR(Town, supplied[CT_PASSENGERS].new_max, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9),
146  SLE_CONDVAR(Town, supplied[CT_MAIL].new_max, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9),
147  SLE_CONDVAR(Town, supplied[CT_PASSENGERS].old_act, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9),
148  SLE_CONDVAR(Town, supplied[CT_MAIL].old_act, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9),
149  SLE_CONDVAR(Town, supplied[CT_PASSENGERS].new_act, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9),
150  SLE_CONDVAR(Town, supplied[CT_MAIL].new_act, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9),
151 
152  SLE_CONDVAR(Town, supplied[CT_PASSENGERS].old_max, SLE_UINT32, SLV_9, SLV_165),
153  SLE_CONDVAR(Town, supplied[CT_MAIL].old_max, SLE_UINT32, SLV_9, SLV_165),
154  SLE_CONDVAR(Town, supplied[CT_PASSENGERS].new_max, SLE_UINT32, SLV_9, SLV_165),
155  SLE_CONDVAR(Town, supplied[CT_MAIL].new_max, SLE_UINT32, SLV_9, SLV_165),
156  SLE_CONDVAR(Town, supplied[CT_PASSENGERS].old_act, SLE_UINT32, SLV_9, SLV_165),
157  SLE_CONDVAR(Town, supplied[CT_MAIL].old_act, SLE_UINT32, SLV_9, SLV_165),
158  SLE_CONDVAR(Town, supplied[CT_PASSENGERS].new_act, SLE_UINT32, SLV_9, SLV_165),
159  SLE_CONDVAR(Town, supplied[CT_MAIL].new_act, SLE_UINT32, SLV_9, SLV_165),
160 
162 
163  SLE_CONDVAR(Town, received[TE_FOOD].old_act, SLE_UINT16, SL_MIN_VERSION, SLV_165),
164  SLE_CONDVAR(Town, received[TE_WATER].old_act, SLE_UINT16, SL_MIN_VERSION, SLV_165),
165  SLE_CONDVAR(Town, received[TE_FOOD].new_act, SLE_UINT16, SL_MIN_VERSION, SLV_165),
166  SLE_CONDVAR(Town, received[TE_WATER].new_act, SLE_UINT16, SL_MIN_VERSION, SLV_165),
167 
168  SLE_CONDARR(Town, goal, SLE_UINT32, NUM_TE, SLV_165, SL_MAX_VERSION),
169 
171 
172  SLE_CONDVAR(Town, time_until_rebuild, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_54),
173  SLE_CONDVAR(Town, grow_counter, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_54),
174  SLE_CONDVAR(Town, growth_rate, SLE_FILE_U8 | SLE_VAR_I16, SL_MIN_VERSION, SLV_54),
175 
176  SLE_CONDVAR(Town, time_until_rebuild, SLE_UINT16, SLV_54, SL_MAX_VERSION),
177  SLE_CONDVAR(Town, grow_counter, SLE_UINT16, SLV_54, SL_MAX_VERSION),
178 
179  SLE_CONDVAR(Town, growth_rate, SLE_FILE_I16 | SLE_VAR_U16, SLV_54, SLV_165),
180  SLE_CONDVAR(Town, growth_rate, SLE_UINT16, SLV_165, SL_MAX_VERSION),
181 
182  SLE_VAR(Town, fund_buildings_months, SLE_UINT8),
183  SLE_VAR(Town, road_build_months, SLE_UINT8),
184 
185  SLE_CONDVAR(Town, exclusivity, SLE_UINT8, SLV_2, SL_MAX_VERSION),
186  SLE_CONDVAR(Town, exclusive_counter, SLE_UINT8, SLV_2, SL_MAX_VERSION),
187 
188  SLE_CONDVAR(Town, larger_town, SLE_BOOL, SLV_56, SL_MAX_VERSION),
189  SLE_CONDVAR(Town, layout, SLE_UINT8, SLV_113, SL_MAX_VERSION),
190 
192 
193  SLE_CONDVAR(Town, cargo_produced, SLE_FILE_U32 | SLE_VAR_U64, SLV_166, SLV_EXTEND_CARGOTYPES),
194  SLE_CONDVAR(Town, cargo_produced, SLE_UINT64, SLV_EXTEND_CARGOTYPES, SL_MAX_VERSION),
195 
196  /* reserve extra space in savegame here. (currently 30 bytes) */
198 
199  SLE_END()
200 };
201 
202 static const SaveLoad _town_supplied_desc[] = {
207 
208  SLE_END()
209 };
210 
211 static const SaveLoad _town_received_desc[] = {
216 
217  SLE_END()
218 };
219 
220 static void Save_HIDS()
221 {
222  Save_NewGRFMapping(_house_mngr);
223 }
224 
225 static void Load_HIDS()
226 {
227  Load_NewGRFMapping(_house_mngr);
228 }
229 
230 const SaveLoad *GetTileMatrixDesc()
231 {
232  /* Here due to private member vars. */
233  static const SaveLoad _tilematrix_desc[] = {
234  SLE_VAR(AcceptanceMatrix, area.tile, SLE_UINT32),
235  SLE_VAR(AcceptanceMatrix, area.w, SLE_UINT16),
236  SLE_VAR(AcceptanceMatrix, area.h, SLE_UINT16),
237  SLE_END()
238  };
239 
240  return _tilematrix_desc;
241 }
242 
243 static void RealSave_Town(Town *t)
244 {
245  SlObject(t, _town_desc);
246 
247  for (CargoID i = 0; i < NUM_CARGO; i++) {
248  SlObject(&t->supplied[i], _town_supplied_desc);
249  }
250  for (int i = TE_BEGIN; i < NUM_TE; i++) {
251  SlObject(&t->received[i], _town_received_desc);
252  }
253 
254  if (IsSavegameVersionBefore(SLV_166)) return;
255 
256  SlObject(&t->cargo_accepted, GetTileMatrixDesc());
257  if (t->cargo_accepted.area.w != 0) {
258  uint arr_len = t->cargo_accepted.area.w / AcceptanceMatrix::GRID * t->cargo_accepted.area.h / AcceptanceMatrix::GRID;
259  SlArray(t->cargo_accepted.data, arr_len, SLE_UINT32);
260  }
261 }
262 
263 static void Save_TOWN()
264 {
265  for (Town *t : Town::Iterate()) {
266  SlSetArrayIndex(t->index);
267  SlAutolength((AutolengthProc*)RealSave_Town, t);
268  }
269 }
270 
271 static void Load_TOWN()
272 {
273  int index;
275 
276  while ((index = SlIterateArray()) != -1) {
277  Town *t = new (index) Town();
278  SlObject(t, _town_desc);
279 
280  for (CargoID i = 0; i < num_cargo; i++) {
281  SlObject(&t->supplied[i], _town_supplied_desc);
282  }
283  for (int i = TE_BEGIN; i < TE_END; i++) {
284  SlObject(&t->received[i], _town_received_desc);
285  }
286 
287  if (t->townnamegrfid == 0 && !IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1) && GetStringTab(t->townnametype) != TEXT_TAB_OLD_CUSTOM) {
288  SlErrorCorrupt("Invalid town name generator");
289  }
290 
291  if (IsSavegameVersionBefore(SLV_166)) continue;
292 
293  SlObject(&t->cargo_accepted, GetTileMatrixDesc());
294  if (t->cargo_accepted.area.w != 0) {
295  uint arr_len = t->cargo_accepted.area.w / AcceptanceMatrix::GRID * t->cargo_accepted.area.h / AcceptanceMatrix::GRID;
296  t->cargo_accepted.data = MallocT<CargoTypes>(arr_len);
297  SlArray(t->cargo_accepted.data, arr_len, SLE_UINT32);
298 
299  /* Rebuild total cargo acceptance. */
301  }
302  }
303 }
304 
306 static void Ptrs_TOWN()
307 {
308  /* Don't run when savegame version lower than 161. */
309  if (IsSavegameVersionBefore(SLV_161)) return;
310 
311  for (Town *t : Town::Iterate()) {
312  SlObject(t, _town_desc);
313  }
314 }
315 
317 extern const ChunkHandler _town_chunk_handlers[] = {
318  { 'HIDS', Save_HIDS, Load_HIDS, nullptr, nullptr, CH_ARRAY },
319  { 'CITY', Save_TOWN, Load_TOWN, Ptrs_TOWN, nullptr, CH_ARRAY | CH_LAST},
320 };
#define SLE_CONDNULL(length, from, to)
Empty space in some savegame versions.
Definition: saveload.h:642
TileIndexDiff GetHouseNorthPart(HouseID &house)
Determines if a given HouseID is part of a multitile house.
Definition: town_cmd.cpp:2604
AcceptanceMatrix cargo_accepted
Bitmap of cargoes accepted by houses for each 4*4 map square of the town.
Definition: town.h:87
static void Ptrs_TOWN()
Fix pointers when loading town data.
Definition: town_sl.cpp:306
TransportedCargoStat< uint16 > received[NUM_TE]
Cargo statistics about received cargotypes.
Definition: town.h:78
static bool IsSavegameVersionBefore(SaveLoadVersion major, byte minor=0)
Checks whether the savegame is below major.
Definition: saveload.h:763
void UpdateTownCargoes(Town *t)
Update cargo acceptance for the complete town.
Definition: town_cmd.cpp:821
Code handling saving and loading of NewGRF mappings.
void UpdateTownCargoTotal(Town *t)
Update the total cargo acceptance of the whole town.
Definition: town_cmd.cpp:773
2.0 0.3.0 2.1 0.3.1, 0.3.2
Definition: saveload.h:33
#define SLE_CONDSTR(base, variable, type, length, from, to)
Storage of a string in some savegame versions.
Definition: saveload.h:566
void NORETURN SlErrorCorrupt(const char *msg)
Error handler for corrupt savegames.
Definition: saveload.cpp:354
Maximal number of cargo types in a game.
Definition: cargo_type.h:64
void RebuildTownCaches()
Rebuild all the cached variables of towns.
Definition: town_sl.cpp:25
static const SaveLoad _town_desc[]
Save and load of towns.
Definition: town_sl.cpp:116
104 14735
Definition: saveload.h:166
void UpdateHousesAndTowns()
Check and update town and house values.
Definition: town_sl.cpp:64
Amount of town effects.
Definition: cargotype.h:33
85 11874
Definition: saveload.h:144
113 15340
Definition: saveload.h:177
Tindex index
Index of this pool item.
Definition: pool_type.hpp:189
const ChunkHandler _town_chunk_handlers[]
Chunk handler for towns.
Cargo behaves water-like.
Definition: cargotype.h:30
165 23304
Definition: saveload.h:240
static StringTab GetStringTab(StringID str)
Extract the StringTab from a StringID.
Definition: strings_func.h:23
uint16 HouseID
OpenTTD ID of house types.
Definition: house_type.h:13
uint32 population
Current population of people.
Definition: town.h:45
uint16 w
The width of the area.
Definition: tilearea_type.h:18
#define SLE_CONDLST(base, variable, type, from, to)
Storage of a list in some savegame versions.
Definition: saveload.h:576
void UpdateTownCargoBitmap()
Updates the bitmap of all cargoes accepted by houses.
Definition: town_cmd.cpp:840
static void SetHouseType(TileIndex t, HouseID house_id)
Set the house type.
Definition: town_map.h:70
byte population
population (Zero on other tiles in multi tile house.)
Definition: house.h:102
void SlArray(void *array, size_t length, VarType conv)
Save/Load an array.
Definition: saveload.cpp:995
static bool IsHouseCompleted(TileIndex t)
Get the completion of this house.
Definition: town_map.h:145
T * data
Pointer to data array.
static bool IsInsideMM(const T x, const size_t min, const size_t max)
Checks if a value is in an interval.
Definition: math_func.hpp:264
Functions/types related to saving and loading games.
#define SLE_CONDVAR(base, variable, type, from, to)
Storage of a variable in some savegame versions.
Definition: saveload.h:534
static bool IsTileType(TileIndex tile, TileType type)
Checks if a tile is a given tiletype.
Definition: tile_map.h:150
static HouseID GetCleanHouseType(TileIndex t)
Get the type of this house, which is an index into the house spec array without doing any NewGRF rela...
Definition: town_map.h:47
Highest possible saveload version.
Definition: saveload.h:305
allow control codes in the strings
Definition: saveload.h:471
First savegame version.
Definition: saveload.h:30
54 9613
Definition: saveload.h:106
84 11822
Definition: saveload.h:142
92 12381 0.6.x
Definition: saveload.h:152
6.0 1721 6.1 1768
Definition: saveload.h:45
164 23290
Definition: saveload.h:238
BuildingFlags building_flags
some flags that describe the house (size, stadium etc...)
Definition: house.h:109
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
Definition: saveload.cpp:637
Handlers and description of chunk.
Definition: saveload.h:356
TileArea area
Area covered by the matrix.
void Load_NewGRFMapping(OverrideManagerBase &mapping)
Load a GRF ID + local id -> OpenTTD&#39;s id mapping.
Definition: newgrf_sl.cpp:42
#define SLE_END()
End marker of a struct/class save or load.
Definition: saveload.h:651
9.0 1909
Definition: saveload.h:49
3.x lost
Definition: saveload.h:35
static uint MapSize()
Get the size of the map.
Definition: map_func.h:92
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition: pool_type.hpp:340
56 9667
Definition: saveload.h:109
#define SLE_CONDARR(base, variable, type, length, from, to)
Storage of an array in some savegame versions.
Definition: saveload.h:555
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:78
66 10211
Definition: saveload.h:121
static HouseID GetHouseType(TileIndex t)
Get the type of this house, which is an index into the house spec array.
Definition: town_map.h:59
void SlObject(void *object, const SaveLoad *sld)
Main SaveLoad function.
Definition: saveload.cpp:1546
TownCache cache
Container for all cacheable data.
Definition: town.h:56
static const HouseID NEW_HOUSE_OFFSET
Offset for new houses.
Definition: house.h:28
Maximum number of companies.
Definition: company_type.h:23
Town data structure.
Definition: town.h:53
End of town effects.
Definition: cargotype.h:32
void SlAutolength(AutolengthProc *proc, void *arg)
Do something of which I have no idea what it is :P.
Definition: saveload.cpp:1574
Cargo behaves food/fizzy-drinks-like.
Definition: cargotype.h:31
static TileIndexDiff TileDiffXY(int x, int y)
Calculates an offset for the given coordinate(-offset).
Definition: map_func.h:179
SaveLoad type struct.
Definition: saveload.h:496
#define SLE_VAR(base, variable, type)
Storage of a variable in every version of a savegame.
Definition: saveload.h:594
#define SLE_STR(base, variable, type, length)
Storage of a string in every savegame version.
Definition: saveload.h:620
TransportedCargoStat< uint32 > supplied[NUM_CARGO]
Cargo statistics about supplied cargo.
Definition: town.h:77
A house by a town.
Definition: tile_type.h:44
byte CargoID
Cargo slots to indicate a cargo type within a game.
Definition: cargo_type.h:20
161 22567
Definition: saveload.h:235
void IncreaseBuildingCount(Town *t, HouseID house_id)
IncreaseBuildingCount() Increase the count of a building when it has been added by a town...
uint32 num_houses
Amount of houses.
Definition: town.h:44
199 PR#6802 Extend cargotypes to 64
Definition: saveload.h:281
void Save_NewGRFMapping(const OverrideManagerBase &mapping)
Save a GRF ID + local id -> OpenTTD&#39;s id mapping.
Definition: newgrf_sl.cpp:30
uint16 h
The height of the area.
Definition: tilearea_type.h:19
168 23637
Definition: saveload.h:243
Last chunk in this array.
Definition: saveload.h:391
4.0 1 4.1 122 0.3.3, 0.3.4 4.2 1222 0.3.5 4.3 1417 4.4 1426
Definition: saveload.h:36
uint16 GetSubstituteID(uint16 entity_id) const
Gives the substitute of the entity, as specified by the grf file.
166 23415
Definition: saveload.h:241
Load/save a reference to a persistent storage.
Definition: saveload.h:380