diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index 1f4dae220f..1a9779aa5a 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -183,6 +183,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_LINKGRAPH_SPARSE_EDGES, XSCF_NULL, 1, 1, "linkgraph_sparse_edges", nullptr, nullptr, nullptr }, { XSLFI_AUX_TILE_LOOP, XSCF_NULL, 1, 1, "aux_tile_loop", nullptr, nullptr, nullptr }, { XSLFI_NEWGRF_ENTITY_EXTRA, XSCF_NULL, 1, 1, "newgrf_entity_extra", nullptr, nullptr, nullptr }, + { XSLFI_TNNC_CHUNK, XSCF_IGNORABLE_ALL, 1, 1, "tnnc_chunk", nullptr, nullptr, "TNNC" }, { XSLFI_SCRIPT_INT64, XSCF_NULL, 1, 1, "script_int64", nullptr, nullptr, nullptr }, { XSLFI_U64_TICK_COUNTER, XSCF_NULL, 1, 1, "u64_tick_counter", nullptr, nullptr, nullptr }, { XSLFI_LINKGRAPH_TRAVEL_TIME, XSCF_NULL, 1, 1, "linkgraph_travel_time", nullptr, nullptr, nullptr }, diff --git a/src/saveload/extended_ver_sl.h b/src/saveload/extended_ver_sl.h index 0694619db0..2638190002 100644 --- a/src/saveload/extended_ver_sl.h +++ b/src/saveload/extended_ver_sl.h @@ -134,6 +134,7 @@ enum SlXvFeatureIndex { XSLFI_LINKGRAPH_SPARSE_EDGES, ///< Link graph edge matrix is stored in sparse format, and saved in order XSLFI_AUX_TILE_LOOP, ///< Auxiliary tile loop XSLFI_NEWGRF_ENTITY_EXTRA, ///< NewGRF entity mappings are 16 bit + XSLFI_TNNC_CHUNK, ///< TNNC chunk XSLFI_SCRIPT_INT64, ///< See: SLV_SCRIPT_INT64 XSLFI_U64_TICK_COUNTER, ///< See: SLV_U64_TICK_COUNTER diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index b208ab43d9..ad301ff945 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -3437,8 +3437,10 @@ static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check) SlXvResetState(); SlResetVENC(); + SlResetTNNC(); auto guard = scope_guard([&]() { SlResetVENC(); + SlResetTNNC(); }); uint32 hdr[2]; diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 512ba0bcd9..26f55f9758 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -750,6 +750,8 @@ bool SaveloadCrashWithMissingNewGRFs(); void SlResetVENC(); void SlProcessVENC(); +void SlResetTNNC(); + extern std::string _savegame_format; extern bool _do_autosave; diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index 66a72cf2ab..a2ffaf1347 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -13,12 +13,15 @@ #include "../landscape.h" #include "../subsidy_func.h" #include "../strings_func.h" +#include "../network/network.h" #include "saveload.h" #include "newgrf_sl.h" #include "../safeguards.h" +static bool _town_zone_radii_no_update = false; + HouseID SLGetCleanHouseType(TileIndex t, bool old_map_position) { if (old_map_position && SlXvIsFeatureMissing(XSLFI_MORE_HOUSES)) { @@ -54,9 +57,11 @@ void RebuildTownCaches(bool cargo_update_required, bool old_map_position) if (GetHouseNorthPart(house_id) == 0) town->cache.num_houses++; } - /* Update the population and num_house dependent values */ - for (Town *town : Town::Iterate()) { - UpdateTownRadius(town); + if (!_town_zone_radii_no_update) { + /* Update the population and num_house dependent values */ + for (Town *town : Town::Iterate()) { + UpdateTownRadius(town); + } } } @@ -363,10 +368,55 @@ static void Ptrs_TOWN() } } +void SlResetTNNC() +{ + _town_zone_radii_no_update = false; +} + +void Save_TNNC() +{ + if (!IsNetworkServerSave()) { + SlSetLength(0); + return; + } + + SlSetLength(4 + (Town::GetNumItems() * (1 + lengthof(TownCache::squared_town_zone_radius)) * 4)); + + SlWriteUint32(Town::GetNumItems()); + + for (const Town *t : Town::Iterate()) { + SlWriteUint32(t->index); + for (uint i = 0; i < lengthof(TownCache::squared_town_zone_radius); i++) { + SlWriteUint32(t->cache.squared_town_zone_radius[i]); + } + } +} + +void Load_TNNC() +{ + if (SlGetFieldLength() == 0) return; + + if (!_networking || _network_server) { + SlSkipBytes(SlGetFieldLength()); + return; + } + + _town_zone_radii_no_update = true; + + const uint32 count = SlReadUint32(); + for (uint32 idx = 0; idx < count; idx++) { + Town *t = Town::Get(SlReadUint32()); + for (uint i = 0; i < lengthof(TownCache::squared_town_zone_radius); i++) { + t->cache.squared_town_zone_radius[i] = SlReadUint32(); + } + } +} + /** Chunk handler for towns. */ static const ChunkHandler town_chunk_handlers[] = { { 'HIDS', Save_HIDS, Load_HIDS, nullptr, nullptr, CH_ARRAY }, { 'CITY', Save_TOWN, Load_TOWN, Ptrs_TOWN, nullptr, CH_ARRAY }, + { 'TNNC', Save_TNNC, Load_TNNC, nullptr, nullptr, CH_RIFF }, }; extern const ChunkHandlerTable _town_chunk_handlers(town_chunk_handlers);