Fix town production and acceptance cache saveload/update handling
This commit is contained in:
@@ -1341,8 +1341,8 @@ void CheckCaches(bool force_check, std::function<void(const char *)> log)
|
|||||||
|
|
||||||
const CargoTypes old_town_cargoes_accepted = _town_cargoes_accepted;
|
const CargoTypes old_town_cargoes_accepted = _town_cargoes_accepted;
|
||||||
|
|
||||||
extern void RebuildTownCaches();
|
extern void RebuildTownCaches(bool cargo_update_required);
|
||||||
RebuildTownCaches();
|
RebuildTownCaches(false);
|
||||||
RebuildSubsidisedSourceAndDestinationCache();
|
RebuildSubsidisedSourceAndDestinationCache();
|
||||||
|
|
||||||
Station::RecomputeCatchmentForAll();
|
Station::RecomputeCatchmentForAll();
|
||||||
|
@@ -3093,17 +3093,21 @@ bool AfterLoadGame()
|
|||||||
* which is done by StartupEngines(). */
|
* which is done by StartupEngines(). */
|
||||||
if (gcf_res != GLC_ALL_GOOD) StartupEngines();
|
if (gcf_res != GLC_ALL_GOOD) StartupEngines();
|
||||||
|
|
||||||
if (IsSavegameVersionBefore(SLV_166)) {
|
if (SlXvIsFeatureMissing(XSLFI_TOWN_CARGO_MATRIX)) {
|
||||||
/* Update cargo acceptance map of towns. */
|
/* Update cargo acceptance map of towns. */
|
||||||
|
Town *town;
|
||||||
|
FOR_ALL_TOWNS(town) {
|
||||||
|
town->cargo_accepted.Clear();
|
||||||
|
}
|
||||||
for (TileIndex t = 0; t < map_size; t++) {
|
for (TileIndex t = 0; t < map_size; t++) {
|
||||||
if (!IsTileType(t, MP_HOUSE)) continue;
|
if (!IsTileType(t, MP_HOUSE)) continue;
|
||||||
Town::Get(GetTownIndex(t))->cargo_accepted.Add(t);
|
Town::Get(GetTownIndex(t))->cargo_accepted.Add(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
Town *town;
|
|
||||||
FOR_ALL_TOWNS(town) {
|
FOR_ALL_TOWNS(town) {
|
||||||
UpdateTownCargoes(town);
|
UpdateTownCargoes(town);
|
||||||
}
|
}
|
||||||
|
UpdateTownCargoBitmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set some breakdown-related variables to the correct values. */
|
/* Set some breakdown-related variables to the correct values. */
|
||||||
|
@@ -107,6 +107,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
|||||||
{ XSLFI_LINKGRAPH_MODES, XSCF_NULL, 1, 1, "linkgraph_modes", nullptr, nullptr, nullptr },
|
{ XSLFI_LINKGRAPH_MODES, XSCF_NULL, 1, 1, "linkgraph_modes", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_GAME_EVENTS, XSCF_NULL, 1, 1, "game_events", nullptr, nullptr, nullptr },
|
{ XSLFI_GAME_EVENTS, XSCF_NULL, 1, 1, "game_events", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_ROAD_LAYOUT_CHANGE_CTR, XSCF_NULL, 1, 1, "road_layout_change_ctr", nullptr, nullptr, nullptr },
|
{ XSLFI_ROAD_LAYOUT_CHANGE_CTR, XSCF_NULL, 1, 1, "road_layout_change_ctr", nullptr, nullptr, nullptr },
|
||||||
|
{ XSLFI_TOWN_CARGO_MATRIX, XSCF_NULL, 1, 1, "town_cargo_matrix", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_DEBUG, XSCF_IGNORABLE_ALL, 1, 1, "debug", nullptr, nullptr, "DBGL" },
|
{ XSLFI_DEBUG, XSCF_IGNORABLE_ALL, 1, 1, "debug", nullptr, nullptr, "DBGL" },
|
||||||
{ XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker
|
{ XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker
|
||||||
};
|
};
|
||||||
|
@@ -74,6 +74,7 @@ enum SlXvFeatureIndex {
|
|||||||
XSLFI_LINKGRAPH_MODES, ///< Linkgraph additional distribution modes
|
XSLFI_LINKGRAPH_MODES, ///< Linkgraph additional distribution modes
|
||||||
XSLFI_GAME_EVENTS, ///< Game event flags
|
XSLFI_GAME_EVENTS, ///< Game event flags
|
||||||
XSLFI_ROAD_LAYOUT_CHANGE_CTR, ///< Road layout change counter
|
XSLFI_ROAD_LAYOUT_CHANGE_CTR, ///< Road layout change counter
|
||||||
|
XSLFI_TOWN_CARGO_MATRIX, ///< Town cargo matrix savegame format changes
|
||||||
XSLFI_DEBUG, ///< Debugging info
|
XSLFI_DEBUG, ///< Debugging info
|
||||||
|
|
||||||
XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit
|
XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit
|
||||||
|
@@ -24,7 +24,7 @@
|
|||||||
/**
|
/**
|
||||||
* Rebuild all the cached variables of towns.
|
* Rebuild all the cached variables of towns.
|
||||||
*/
|
*/
|
||||||
void RebuildTownCaches()
|
void RebuildTownCaches(bool cargo_update_required)
|
||||||
{
|
{
|
||||||
Town *town;
|
Town *town;
|
||||||
InitializeBuildingCounts();
|
InitializeBuildingCounts();
|
||||||
@@ -51,7 +51,11 @@ void RebuildTownCaches()
|
|||||||
/* Update the population and num_house dependent values */
|
/* Update the population and num_house dependent values */
|
||||||
FOR_ALL_TOWNS(town) {
|
FOR_ALL_TOWNS(town) {
|
||||||
UpdateTownRadius(town);
|
UpdateTownRadius(town);
|
||||||
UpdateTownCargoes(town);
|
if (cargo_update_required) {
|
||||||
|
UpdateTownCargoes(town);
|
||||||
|
} else {
|
||||||
|
UpdateTownCargoTotal(town);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
UpdateTownCargoBitmap();
|
UpdateTownCargoBitmap();
|
||||||
}
|
}
|
||||||
@@ -66,6 +70,8 @@ void RebuildTownCaches()
|
|||||||
*/
|
*/
|
||||||
void UpdateHousesAndTowns()
|
void UpdateHousesAndTowns()
|
||||||
{
|
{
|
||||||
|
bool cargo_update_required = false;
|
||||||
|
|
||||||
for (TileIndex t = 0; t < MapSize(); t++) {
|
for (TileIndex t = 0; t < MapSize(); t++) {
|
||||||
if (!IsTileType(t, MP_HOUSE)) continue;
|
if (!IsTileType(t, MP_HOUSE)) continue;
|
||||||
|
|
||||||
@@ -75,6 +81,7 @@ void UpdateHousesAndTowns()
|
|||||||
* replace it with the substitute original house type. */
|
* replace it with the substitute original house type. */
|
||||||
house_id = _house_mngr.GetSubstituteID(house_id);
|
house_id = _house_mngr.GetSubstituteID(house_id);
|
||||||
SetHouseType(t, house_id);
|
SetHouseType(t, house_id);
|
||||||
|
cargo_update_required = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,15 +111,19 @@ void UpdateHousesAndTowns()
|
|||||||
/* If not all tiles of this house are present remove the house.
|
/* If not all tiles of this house are present remove the house.
|
||||||
* The other tiles will get removed later in this loop because
|
* The other tiles will get removed later in this loop because
|
||||||
* their north tile is not the correct type anymore. */
|
* their north tile is not the correct type anymore. */
|
||||||
if (!valid_house) DoClearSquare(t);
|
if (!valid_house) {
|
||||||
|
DoClearSquare(t);
|
||||||
|
cargo_update_required = true;
|
||||||
|
}
|
||||||
} else if (!IsTileType(north_tile, MP_HOUSE) || GetCleanHouseType(north_tile) != house_type) {
|
} else if (!IsTileType(north_tile, MP_HOUSE) || GetCleanHouseType(north_tile) != house_type) {
|
||||||
/* This tile should be part of a multi-tile building but the
|
/* This tile should be part of a multi-tile building but the
|
||||||
* north tile of this house isn't on the map. */
|
* north tile of this house isn't on the map. */
|
||||||
DoClearSquare(t);
|
DoClearSquare(t);
|
||||||
|
cargo_update_required = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RebuildTownCaches();
|
RebuildTownCaches(cargo_update_required);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Save and load of towns. */
|
/** Save and load of towns. */
|
||||||
@@ -273,7 +284,7 @@ static void RealSave_Town(Town *t)
|
|||||||
SlObject(&t->cargo_accepted, GetTileMatrixDesc());
|
SlObject(&t->cargo_accepted, GetTileMatrixDesc());
|
||||||
if (t->cargo_accepted.area.w != 0) {
|
if (t->cargo_accepted.area.w != 0) {
|
||||||
uint arr_len = t->cargo_accepted.area.w / AcceptanceMatrix::GRID * t->cargo_accepted.area.h / AcceptanceMatrix::GRID;
|
uint arr_len = t->cargo_accepted.area.w / AcceptanceMatrix::GRID * t->cargo_accepted.area.h / AcceptanceMatrix::GRID;
|
||||||
SlArray(t->cargo_accepted.data, arr_len, SLE_UINT32);
|
SlArray(t->cargo_accepted.data, arr_len, SLE_UINT64);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,16 +324,24 @@ static void Load_TOWN()
|
|||||||
SlErrorCorrupt("Invalid town name generator");
|
SlErrorCorrupt("Invalid town name generator");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsSavegameVersionBefore(SLV_166)) continue;
|
if (!IsSavegameVersionBefore(SLV_166) && SlXvIsFeatureMissing(XSLFI_TOWN_CARGO_MATRIX)) {
|
||||||
|
SlSkipBytes(4); // tile
|
||||||
|
uint16 w = SlReadUint16();
|
||||||
|
uint16 h = SlReadUint16();
|
||||||
|
if (w != 0) {
|
||||||
|
SlSkipBytes(4 * (w / 4 * h / 4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (SlXvIsFeaturePresent(XSLFI_TOWN_CARGO_MATRIX)) {
|
||||||
|
SlObject(&t->cargo_accepted, GetTileMatrixDesc());
|
||||||
|
if (t->cargo_accepted.area.w != 0) {
|
||||||
|
uint arr_len = t->cargo_accepted.area.w / AcceptanceMatrix::GRID * t->cargo_accepted.area.h / AcceptanceMatrix::GRID;
|
||||||
|
t->cargo_accepted.data = MallocT<CargoTypes>(arr_len);
|
||||||
|
SlArray(t->cargo_accepted.data, arr_len, SLE_UINT64);
|
||||||
|
|
||||||
SlObject(&t->cargo_accepted, GetTileMatrixDesc());
|
/* Rebuild total cargo acceptance. */
|
||||||
if (t->cargo_accepted.area.w != 0) {
|
UpdateTownCargoTotal(t);
|
||||||
uint arr_len = t->cargo_accepted.area.w / AcceptanceMatrix::GRID * t->cargo_accepted.area.h / AcceptanceMatrix::GRID;
|
}
|
||||||
t->cargo_accepted.data = MallocT<CargoTypes>(arr_len);
|
|
||||||
SlArray(t->cargo_accepted.data, arr_len, SLE_UINT32);
|
|
||||||
|
|
||||||
/* Rebuild total cargo acceptance. */
|
|
||||||
UpdateTownCargoTotal(t);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -76,6 +76,13 @@ public:
|
|||||||
free(this->data);
|
free(this->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
this->area = TileArea(INVALID_TILE, 0, 0);
|
||||||
|
free(this->data);
|
||||||
|
this->data = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the total covered area.
|
* Get the total covered area.
|
||||||
* @return The area covered by the matrix.
|
* @return The area covered by the matrix.
|
||||||
|
@@ -93,7 +93,7 @@ struct Town : TownPool::PoolItem<&_town_pool> {
|
|||||||
|
|
||||||
/* Cargo production and acceptance stats. */
|
/* Cargo production and acceptance stats. */
|
||||||
CargoTypes cargo_produced; ///< Bitmap of all cargoes produced by houses in this town.
|
CargoTypes cargo_produced; ///< Bitmap of all cargoes produced by houses in this town.
|
||||||
AcceptanceMatrix cargo_accepted; ///< Bitmap of cargoes accepted by houses for each 4*4 map square of the town.
|
AcceptanceMatrix cargo_accepted; ///< Bitmap of cargoes accepted by houses for each 4*4 (really 6*6) map square of the town.
|
||||||
CargoTypes cargo_accepted_total; ///< NOSAVE: Bitmap of all cargoes accepted by houses in this town.
|
CargoTypes cargo_accepted_total; ///< NOSAVE: Bitmap of all cargoes accepted by houses in this town.
|
||||||
StationList stations_near; ///< NOSAVE: List of nearby stations.
|
StationList stations_near; ///< NOSAVE: List of nearby stations.
|
||||||
|
|
||||||
|
@@ -964,14 +964,12 @@ void UpdateTownCargoTotal(Town *t)
|
|||||||
* @param start Update the values around this tile.
|
* @param start Update the values around this tile.
|
||||||
* @param update_total Set to true if the total cargo acceptance should be updated.
|
* @param update_total Set to true if the total cargo acceptance should be updated.
|
||||||
*/
|
*/
|
||||||
static void UpdateTownCargoes(Town *t, TileIndex start, bool update_total = true)
|
static void UpdateTownCargoesSingleGridArea(Town *t, TileIndex start, bool update_total = true)
|
||||||
{
|
{
|
||||||
CargoArray accepted, produced;
|
CargoArray accepted, produced;
|
||||||
CargoTypes dummy = 0;
|
CargoTypes dummy = 0;
|
||||||
|
|
||||||
/* Gather acceptance for all houses in an area around the start tile.
|
/* Gather acceptance for all houses in an area around the start tile. */
|
||||||
* The area is composed of the square the tile is in, extended one square in all
|
|
||||||
* directions as the coverage area of a single station is bigger than just one square. */
|
|
||||||
TileArea area = AcceptanceMatrix::GetAreaForTile(start, 1);
|
TileArea area = AcceptanceMatrix::GetAreaForTile(start, 1);
|
||||||
TILE_AREA_LOOP(tile, area) {
|
TILE_AREA_LOOP(tile, area) {
|
||||||
if (!IsTileType(tile, MP_HOUSE) || GetTownIndex(tile) != t->index) continue;
|
if (!IsTileType(tile, MP_HOUSE) || GetTownIndex(tile) != t->index) continue;
|
||||||
@@ -991,6 +989,18 @@ static void UpdateTownCargoes(Town *t, TileIndex start, bool update_total = true
|
|||||||
if (update_total) UpdateTownCargoTotal(t);
|
if (update_total) UpdateTownCargoTotal(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void UpdateTownCargoesHouse(Town *t, TileIndex start, bool x_two_tiles, bool y_two_tiles, bool update_total = true)
|
||||||
|
{
|
||||||
|
TileIndex lower = TileAddWrap(start, -1, -1);
|
||||||
|
TileIndex upper = TileAddWrap(start, x_two_tiles ? 2 : 1, y_two_tiles ? 2 : 1);
|
||||||
|
for (uint x = TileX(lower) & ~(AcceptanceMatrix::GRID - 1); x <= TileX(upper); x += AcceptanceMatrix::GRID) {
|
||||||
|
for (uint y = TileY(lower) & ~(AcceptanceMatrix::GRID - 1); y <= TileY(upper); y += AcceptanceMatrix::GRID) {
|
||||||
|
UpdateTownCargoesSingleGridArea(t, TileXY(x, y), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (update_total) UpdateTownCargoTotal(t);
|
||||||
|
}
|
||||||
|
|
||||||
/** Update cargo acceptance for the complete town.
|
/** Update cargo acceptance for the complete town.
|
||||||
* @param t The town to update.
|
* @param t The town to update.
|
||||||
*/
|
*/
|
||||||
@@ -1003,7 +1013,7 @@ void UpdateTownCargoes(Town *t)
|
|||||||
|
|
||||||
/* Update acceptance for each grid square. */
|
/* Update acceptance for each grid square. */
|
||||||
TILE_AREA_LOOP_STEP(tile, area, AcceptanceMatrix::GRID) {
|
TILE_AREA_LOOP_STEP(tile, area, AcceptanceMatrix::GRID) {
|
||||||
UpdateTownCargoes(t, tile, false);
|
UpdateTownCargoesSingleGridArea(t, tile, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the total acceptance. */
|
/* Update the total acceptance. */
|
||||||
@@ -2643,7 +2653,7 @@ static void DoBuildHouse(Town *t, TileIndex tile, HouseID house, byte random_bit
|
|||||||
MakeTownHouse(tile, t, construction_counter, construction_stage, house, random_bits);
|
MakeTownHouse(tile, t, construction_counter, construction_stage, house, random_bits);
|
||||||
UpdateTownRadius(t);
|
UpdateTownRadius(t);
|
||||||
UpdateTownGrowthRate(t);
|
UpdateTownGrowthRate(t);
|
||||||
UpdateTownCargoes(t, tile);
|
UpdateTownCargoesHouse(t, tile, hs->building_flags & BUILDING_2_TILES_X, hs->building_flags & BUILDING_2_TILES_Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2852,7 +2862,7 @@ void ClearTownHouse(Town *t, TileIndex tile)
|
|||||||
UpdateTownRadius(t);
|
UpdateTownRadius(t);
|
||||||
|
|
||||||
/* Update cargo acceptance. */
|
/* Update cargo acceptance. */
|
||||||
UpdateTownCargoes(t, tile);
|
UpdateTownCargoesHouse(t, tile, eflags & BUILDING_2_TILES_X, eflags & BUILDING_2_TILES_Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user