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