00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "../stdafx.h"
00013 #include "../newgrf_house.h"
00014 #include "../town.h"
00015 #include "../landscape.h"
00016 #include "../subsidy_func.h"
00017
00018 #include "saveload.h"
00019 #include "newgrf_sl.h"
00020
00024 void RebuildTownCaches()
00025 {
00026 Town *town;
00027 InitializeBuildingCounts();
00028
00029
00030 FOR_ALL_TOWNS(town) {
00031 town->cache.population = 0;
00032 town->cache.num_houses = 0;
00033 }
00034
00035 for (TileIndex t = 0; t < MapSize(); t++) {
00036 if (!IsTileType(t, MP_HOUSE)) continue;
00037
00038 HouseID house_id = GetHouseType(t);
00039 town = Town::GetByTile(t);
00040 IncreaseBuildingCount(town, house_id);
00041 if (IsHouseCompleted(t)) town->cache.population += HouseSpec::Get(house_id)->population;
00042
00043
00044 if (GetHouseNorthPart(house_id) == 0) town->cache.num_houses++;
00045 }
00046
00047
00048 FOR_ALL_TOWNS(town) {
00049 UpdateTownRadius(town);
00050 UpdateTownCargoes(town);
00051 }
00052 UpdateTownCargoBitmap();
00053 }
00054
00063 void UpdateHousesAndTowns()
00064 {
00065 for (TileIndex t = 0; t < MapSize(); t++) {
00066 if (!IsTileType(t, MP_HOUSE)) continue;
00067
00068 HouseID house_id = GetCleanHouseType(t);
00069 if (!HouseSpec::Get(house_id)->enabled && house_id >= NEW_HOUSE_OFFSET) {
00070
00071
00072 house_id = _house_mngr.GetSubstituteID(house_id);
00073 SetHouseType(t, house_id);
00074 }
00075 }
00076
00077
00078 for (TileIndex t = 0; t < MapSize(); t++) {
00079 if (!IsTileType(t, MP_HOUSE)) continue;
00080
00081 HouseID house_type = GetCleanHouseType(t);
00082 TileIndex north_tile = t + GetHouseNorthPart(house_type);
00083 if (t == north_tile) {
00084 const HouseSpec *hs = HouseSpec::Get(house_type);
00085 bool valid_house = true;
00086 if (hs->building_flags & TILE_SIZE_2x1) {
00087 TileIndex tile = t + TileDiffXY(1, 0);
00088 if (!IsTileType(tile, MP_HOUSE) || GetCleanHouseType(tile) != house_type + 1) valid_house = false;
00089 } else if (hs->building_flags & TILE_SIZE_1x2) {
00090 TileIndex tile = t + TileDiffXY(0, 1);
00091 if (!IsTileType(tile, MP_HOUSE) || GetCleanHouseType(tile) != house_type + 1) valid_house = false;
00092 } else if (hs->building_flags & TILE_SIZE_2x2) {
00093 TileIndex tile = t + TileDiffXY(0, 1);
00094 if (!IsTileType(tile, MP_HOUSE) || GetCleanHouseType(tile) != house_type + 1) valid_house = false;
00095 tile = t + TileDiffXY(1, 0);
00096 if (!IsTileType(tile, MP_HOUSE) || GetCleanHouseType(tile) != house_type + 2) valid_house = false;
00097 tile = t + TileDiffXY(1, 1);
00098 if (!IsTileType(tile, MP_HOUSE) || GetCleanHouseType(tile) != house_type + 3) valid_house = false;
00099 }
00100
00101
00102
00103 if (!valid_house) DoClearSquare(t);
00104 } else if (!IsTileType(north_tile, MP_HOUSE) || GetCleanHouseType(north_tile) != house_type) {
00105
00106
00107 DoClearSquare(t);
00108 }
00109 }
00110
00111 RebuildTownCaches();
00112 }
00113
00115 static const SaveLoad _town_desc[] = {
00116 SLE_CONDVAR(Town, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
00117 SLE_CONDVAR(Town, xy, SLE_UINT32, 6, SL_MAX_VERSION),
00118
00119 SLE_CONDNULL(2, 0, 2),
00120 SLE_CONDNULL(4, 3, 84),
00121 SLE_CONDNULL(2, 0, 91),
00122
00123 SLE_CONDVAR(Town, townnamegrfid, SLE_UINT32, 66, SL_MAX_VERSION),
00124 SLE_VAR(Town, townnametype, SLE_UINT16),
00125 SLE_VAR(Town, townnameparts, SLE_UINT32),
00126 SLE_CONDSTR(Town, name, SLE_STR | SLF_ALLOW_CONTROL, 0, 84, SL_MAX_VERSION),
00127
00128 SLE_VAR(Town, flags, SLE_UINT8),
00129 SLE_CONDVAR(Town, statues, SLE_FILE_U8 | SLE_VAR_U16, 0, 103),
00130 SLE_CONDVAR(Town, statues, SLE_UINT16, 104, SL_MAX_VERSION),
00131
00132 SLE_CONDNULL(1, 0, 1),
00133
00134 SLE_CONDVAR(Town, have_ratings, SLE_FILE_U8 | SLE_VAR_U16, 0, 103),
00135 SLE_CONDVAR(Town, have_ratings, SLE_UINT16, 104, SL_MAX_VERSION),
00136 SLE_CONDARR(Town, ratings, SLE_INT16, 8, 0, 103),
00137 SLE_CONDARR(Town, ratings, SLE_INT16, MAX_COMPANIES, 104, SL_MAX_VERSION),
00138
00139 SLE_CONDARR(Town, unwanted, SLE_INT8, 8, 4, 103),
00140 SLE_CONDARR(Town, unwanted, SLE_INT8, MAX_COMPANIES, 104, SL_MAX_VERSION),
00141
00142 SLE_CONDVAR(Town, supplied[CT_PASSENGERS].old_max, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
00143 SLE_CONDVAR(Town, supplied[CT_MAIL].old_max, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
00144 SLE_CONDVAR(Town, supplied[CT_PASSENGERS].new_max, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
00145 SLE_CONDVAR(Town, supplied[CT_MAIL].new_max, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
00146 SLE_CONDVAR(Town, supplied[CT_PASSENGERS].old_act, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
00147 SLE_CONDVAR(Town, supplied[CT_MAIL].old_act, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
00148 SLE_CONDVAR(Town, supplied[CT_PASSENGERS].new_act, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
00149 SLE_CONDVAR(Town, supplied[CT_MAIL].new_act, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
00150
00151 SLE_CONDVAR(Town, supplied[CT_PASSENGERS].old_max, SLE_UINT32, 9, 164),
00152 SLE_CONDVAR(Town, supplied[CT_MAIL].old_max, SLE_UINT32, 9, 164),
00153 SLE_CONDVAR(Town, supplied[CT_PASSENGERS].new_max, SLE_UINT32, 9, 164),
00154 SLE_CONDVAR(Town, supplied[CT_MAIL].new_max, SLE_UINT32, 9, 164),
00155 SLE_CONDVAR(Town, supplied[CT_PASSENGERS].old_act, SLE_UINT32, 9, 164),
00156 SLE_CONDVAR(Town, supplied[CT_MAIL].old_act, SLE_UINT32, 9, 164),
00157 SLE_CONDVAR(Town, supplied[CT_PASSENGERS].new_act, SLE_UINT32, 9, 164),
00158 SLE_CONDVAR(Town, supplied[CT_MAIL].new_act, SLE_UINT32, 9, 164),
00159
00160 SLE_CONDNULL(2, 0, 163),
00161
00162 SLE_CONDVAR(Town, received[TE_FOOD].old_act, SLE_UINT16, 0, 164),
00163 SLE_CONDVAR(Town, received[TE_WATER].old_act, SLE_UINT16, 0, 164),
00164 SLE_CONDVAR(Town, received[TE_FOOD].new_act, SLE_UINT16, 0, 164),
00165 SLE_CONDVAR(Town, received[TE_WATER].new_act, SLE_UINT16, 0, 164),
00166
00167 SLE_CONDARR(Town, goal, SLE_UINT32, NUM_TE, 165, SL_MAX_VERSION),
00168
00169 SLE_CONDSTR(Town, text, SLE_STR | SLF_ALLOW_CONTROL, 0, 168, SL_MAX_VERSION),
00170
00171 SLE_CONDVAR(Town, time_until_rebuild, SLE_FILE_U8 | SLE_VAR_U16, 0, 53),
00172 SLE_CONDVAR(Town, grow_counter, SLE_FILE_U8 | SLE_VAR_U16, 0, 53),
00173 SLE_CONDVAR(Town, growth_rate, SLE_FILE_U8 | SLE_VAR_I16, 0, 53),
00174
00175 SLE_CONDVAR(Town, time_until_rebuild, SLE_UINT16, 54, SL_MAX_VERSION),
00176 SLE_CONDVAR(Town, grow_counter, SLE_UINT16, 54, SL_MAX_VERSION),
00177
00178 SLE_CONDVAR(Town, growth_rate, SLE_FILE_I16 | SLE_VAR_U16, 54, 164),
00179 SLE_CONDVAR(Town, growth_rate, SLE_UINT16, 165, SL_MAX_VERSION),
00180
00181 SLE_VAR(Town, fund_buildings_months, SLE_UINT8),
00182 SLE_VAR(Town, road_build_months, SLE_UINT8),
00183
00184 SLE_CONDVAR(Town, exclusivity, SLE_UINT8, 2, SL_MAX_VERSION),
00185 SLE_CONDVAR(Town, exclusive_counter, SLE_UINT8, 2, SL_MAX_VERSION),
00186
00187 SLE_CONDVAR(Town, larger_town, SLE_BOOL, 56, SL_MAX_VERSION),
00188 SLE_CONDVAR(Town, layout, SLE_UINT8, 113, SL_MAX_VERSION),
00189 SLE_CONDVAR(Town, head_to_head, SLE_UINT8, SAVEGAME_VERSION_H2H, SL_MAX_VERSION),
00190 SLE_CONDVAR(Town, town_growth_counter, SLE_UINT8, 121, SL_MAX_VERSION),
00191
00192 SLE_CONDLST(Town, psa_list, REF_STORAGE, 161, SL_MAX_VERSION),
00193
00194 SLE_CONDVAR(Town, cargo_produced, SLE_UINT32, 166, SL_MAX_VERSION),
00195
00196
00197 SLE_CONDNULL(30, 2, SL_MAX_VERSION),
00198
00199 SLE_END()
00200 };
00201
00202 static const SaveLoad _town_supplied_desc[] = {
00203 SLE_CONDVAR(TransportedCargoStat<uint32>, old_max, SLE_UINT32, 165, SL_MAX_VERSION),
00204 SLE_CONDVAR(TransportedCargoStat<uint32>, new_max, SLE_UINT32, 165, SL_MAX_VERSION),
00205 SLE_CONDVAR(TransportedCargoStat<uint32>, old_act, SLE_UINT32, 165, SL_MAX_VERSION),
00206 SLE_CONDVAR(TransportedCargoStat<uint32>, new_act, SLE_UINT32, 165, SL_MAX_VERSION),
00207
00208 SLE_END()
00209 };
00210
00211 static const SaveLoad _town_received_desc[] = {
00212 SLE_CONDVAR(TransportedCargoStat<uint16>, old_max, SLE_UINT16, 165, SL_MAX_VERSION),
00213 SLE_CONDVAR(TransportedCargoStat<uint16>, new_max, SLE_UINT16, 165, SL_MAX_VERSION),
00214 SLE_CONDVAR(TransportedCargoStat<uint16>, old_act, SLE_UINT16, 165, SL_MAX_VERSION),
00215 SLE_CONDVAR(TransportedCargoStat<uint16>, new_act, SLE_UINT16, 165, SL_MAX_VERSION),
00216
00217 SLE_END()
00218 };
00219
00220 static void Save_HIDS()
00221 {
00222 Save_NewGRFMapping(_house_mngr);
00223 }
00224
00225 static void Load_HIDS()
00226 {
00227 Load_NewGRFMapping(_house_mngr);
00228 }
00229
00230 const SaveLoad *GetTileMatrixDesc()
00231 {
00232
00233 static const SaveLoad _tilematrix_desc[] = {
00234 SLE_VAR(AcceptanceMatrix, area.tile, SLE_UINT32),
00235 SLE_VAR(AcceptanceMatrix, area.w, SLE_UINT16),
00236 SLE_VAR(AcceptanceMatrix, area.h, SLE_UINT16),
00237 SLE_END()
00238 };
00239
00240 return _tilematrix_desc;
00241 }
00242
00243 static void RealSave_Town(Town *t)
00244 {
00245 SlObject(t, _town_desc);
00246
00247 for (CargoID i = 0; i < NUM_CARGO; i++) {
00248 SlObject(&t->supplied[i], _town_supplied_desc);
00249 }
00250 for (int i = TE_BEGIN; i < NUM_TE; i++) {
00251 SlObject(&t->received[i], _town_received_desc);
00252 }
00253
00254 if (IsSavegameVersionBefore(166)) return;
00255
00256 SlObject(&t->cargo_accepted, GetTileMatrixDesc());
00257 if (t->cargo_accepted.area.w != 0) {
00258 uint arr_len = t->cargo_accepted.area.w / AcceptanceMatrix::GRID * t->cargo_accepted.area.h / AcceptanceMatrix::GRID;
00259 SlArray(t->cargo_accepted.data, arr_len, SLE_UINT32);
00260 }
00261 }
00262
00263 static void Save_TOWN()
00264 {
00265 Town *t;
00266
00267 FOR_ALL_TOWNS(t) {
00268 SlSetArrayIndex(t->index);
00269 SlAutolength((AutolengthProc*)RealSave_Town, t);
00270 }
00271 }
00272
00273 static void Load_TOWN()
00274 {
00275 int index;
00276
00277 while ((index = SlIterateArray()) != -1) {
00278 Town *t = new (index) Town();
00279 SlObject(t, _town_desc);
00280
00281 for (CargoID i = 0; i < NUM_CARGO; i++) {
00282 SlObject(&t->supplied[i], _town_supplied_desc);
00283 }
00284 for (int i = TE_BEGIN; i < TE_END; i++) {
00285 SlObject(&t->received[i], _town_received_desc);
00286 }
00287
00288 if (t->townnamegrfid == 0 && !IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1) && GB(t->townnametype, 11, 5) != 15) {
00289 SlErrorCorrupt("Invalid town name generator");
00290 }
00291
00292 if (IsSavegameVersionBefore(166)) continue;
00293
00294 SlObject(&t->cargo_accepted, GetTileMatrixDesc());
00295 if (t->cargo_accepted.area.w != 0) {
00296 uint arr_len = t->cargo_accepted.area.w / AcceptanceMatrix::GRID * t->cargo_accepted.area.h / AcceptanceMatrix::GRID;
00297 t->cargo_accepted.data = MallocT<uint32>(arr_len);
00298 SlArray(t->cargo_accepted.data, arr_len, SLE_UINT32);
00299
00300
00301 UpdateTownCargoTotal(t);
00302 }
00303 }
00304 }
00305
00307 static void Ptrs_TOWN()
00308 {
00309
00310 if (IsSavegameVersionBefore(161)) return;
00311
00312 Town *t;
00313 FOR_ALL_TOWNS(t) {
00314 SlObject(t, _town_desc);
00315 }
00316 }
00317
00319 extern const ChunkHandler _town_chunk_handlers[] = {
00320 { 'HIDS', Save_HIDS, Load_HIDS, NULL, NULL, CH_ARRAY },
00321 { 'CITY', Save_TOWN, Load_TOWN, Ptrs_TOWN, NULL, CH_ARRAY | CH_LAST},
00322 };