mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r23405) -Codechange: Keep a matrix of cargos accepted by houses for each town (michi_cc).
This commit is contained in:
parent
e9e62b1629
commit
59d8b0204f
|
@ -2700,6 +2700,19 @@ bool AfterLoadGame()
|
|||
* which is done by StartupEngines(). */
|
||||
if (gcf_res != GLC_ALL_GOOD) StartupEngines();
|
||||
|
||||
if (IsSavegameVersionBefore(166)) {
|
||||
/* Update cargo acceptance map of towns. */
|
||||
for (TileIndex t = 0; t < map_size; t++) {
|
||||
if (!IsTileType(t, MP_HOUSE)) continue;
|
||||
Town::Get(GetTownIndex(t))->cargo_accepted.Add(t);
|
||||
}
|
||||
|
||||
Town *town;
|
||||
FOR_ALL_TOWNS(town) {
|
||||
UpdateTownCargos(town);
|
||||
}
|
||||
}
|
||||
|
||||
/* Road stops is 'only' updating some caches */
|
||||
AfterLoadRoadStops();
|
||||
AfterLoadLabelMaps();
|
||||
|
|
|
@ -97,6 +97,7 @@ void UpdateHousesAndTowns()
|
|||
/* Update the population and num_house dependant values */
|
||||
FOR_ALL_TOWNS(town) {
|
||||
UpdateTownRadius(town);
|
||||
UpdateTownCargos(town);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,6 +177,8 @@ static const SaveLoad _town_desc[] = {
|
|||
|
||||
SLE_CONDLST(Town, psa_list, REF_STORAGE, 161, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDVAR(Town, cargo_produced, SLE_UINT32, 166, SL_MAX_VERSION),
|
||||
|
||||
/* reserve extra space in savegame here. (currently 30 bytes) */
|
||||
SLE_CONDNULL(30, 2, SL_MAX_VERSION),
|
||||
|
||||
|
@ -210,6 +213,19 @@ static void Load_HIDS()
|
|||
Load_NewGRFMapping(_house_mngr);
|
||||
}
|
||||
|
||||
const SaveLoad *GetTileMatrixDesc()
|
||||
{
|
||||
/* Here due to private member vars. */
|
||||
static const SaveLoad _tilematrix_desc[] = {
|
||||
SLE_VAR(AcceptanceMatrix, area.tile, SLE_UINT32),
|
||||
SLE_VAR(AcceptanceMatrix, area.w, SLE_UINT16),
|
||||
SLE_VAR(AcceptanceMatrix, area.h, SLE_UINT16),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
return _tilematrix_desc;
|
||||
}
|
||||
|
||||
static void RealSave_Town(Town *t)
|
||||
{
|
||||
SlObject(t, _town_desc);
|
||||
|
@ -220,6 +236,14 @@ static void RealSave_Town(Town *t)
|
|||
for (int i = TE_BEGIN; i < NUM_TE; i++) {
|
||||
SlObject(&t->received[i], _town_received_desc);
|
||||
}
|
||||
|
||||
if (IsSavegameVersionBefore(166)) return;
|
||||
|
||||
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;
|
||||
SlArray(t->cargo_accepted.data, arr_len, SLE_UINT32);
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_TOWN()
|
||||
|
@ -250,6 +274,18 @@ static void Load_TOWN()
|
|||
if (t->townnamegrfid == 0 && !IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST)) {
|
||||
SlErrorCorrupt("Invalid town name generator");
|
||||
}
|
||||
|
||||
if (IsSavegameVersionBefore(166)) continue;
|
||||
|
||||
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<uint32>(arr_len);
|
||||
SlArray(t->cargo_accepted.data, arr_len, SLE_UINT32);
|
||||
|
||||
/* Rebuild total cargo acceptance. */
|
||||
UpdateTownCargoTotal(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
10
src/town.h
10
src/town.h
|
@ -19,6 +19,7 @@
|
|||
#include "subsidy_type.h"
|
||||
#include "newgrf_storage.h"
|
||||
#include "cargotype.h"
|
||||
#include "tilematrix_type.hpp"
|
||||
#include <list>
|
||||
|
||||
template <typename T>
|
||||
|
@ -27,6 +28,8 @@ struct BuildingCounts {
|
|||
T class_count[HOUSE_CLASS_MAX];
|
||||
};
|
||||
|
||||
typedef TileMatrix<uint32, 4> AcceptanceMatrix;
|
||||
|
||||
static const uint CUSTOM_TOWN_NUMBER_DIFFICULTY = 4; ///< value for custom town number in difficulty settings
|
||||
static const uint CUSTOM_TOWN_MAX_NUMBER = 5000; ///< this is the maximum number of towns a user can specify in customisation
|
||||
|
||||
|
@ -76,6 +79,11 @@ struct Town : TownPool::PoolItem<&_town_pool> {
|
|||
|
||||
inline byte GetPercentTransported(CargoID cid) const { return this->supplied[cid].old_act * 256 / (this->supplied[cid].old_max + 1); }
|
||||
|
||||
/* Cargo production and acceptance stats. */
|
||||
uint32 cargo_produced; ///< Bitmap of all cargos produced by houses in this town.
|
||||
AcceptanceMatrix cargo_accepted; ///< Bitmap of cargos accepted by houses for each 4*4 map square of the town.
|
||||
uint32 cargo_accepted_total; ///< NOSAVE: Bitmap of all cargos accepted by houses in this town.
|
||||
|
||||
uint16 time_until_rebuild; ///< time until we rebuild a house
|
||||
|
||||
uint16 grow_counter; ///< counter to count when to grow
|
||||
|
@ -175,6 +183,8 @@ void ResetHouses();
|
|||
void ClearTownHouse(Town *t, TileIndex tile);
|
||||
void UpdateTownMaxPass(Town *t);
|
||||
void UpdateTownRadius(Town *t);
|
||||
void UpdateTownCargos(Town *t);
|
||||
void UpdateTownCargoTotal(Town *t);
|
||||
CommandCost CheckIfAuthorityAllowsNewStation(TileIndex tile, DoCommandFlag flags);
|
||||
Town *ClosestTownFromTile(TileIndex tile, uint threshold);
|
||||
void ChangeTownRating(Town *t, int add, int max, DoCommandFlag flags);
|
||||
|
|
|
@ -673,6 +673,75 @@ static void ChangeTileOwner_Town(TileIndex tile, Owner old_owner, Owner new_owne
|
|||
/* not used */
|
||||
}
|
||||
|
||||
/** Update the total cargo acceptance of the whole town.
|
||||
* @param t The town to update.
|
||||
*/
|
||||
void UpdateTownCargoTotal(Town *t)
|
||||
{
|
||||
t->cargo_accepted_total = 0;
|
||||
|
||||
const TileArea &area = t->cargo_accepted.GetArea();
|
||||
TILE_AREA_LOOP(tile, area) {
|
||||
if (TileX(tile) % AcceptanceMatrix::GRID == 0 && TileY(tile) % AcceptanceMatrix::GRID == 0) {
|
||||
t->cargo_accepted_total |= t->cargo_accepted[tile];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update accepted town cargos around a specific tile.
|
||||
* @param t The town to update.
|
||||
* @param start Update the values around this tile.
|
||||
* @param update_total Set to true if the total cargo acceptance should be updated.
|
||||
*/
|
||||
static void UpdateTownCargos(Town *t, TileIndex start, bool update_total = true)
|
||||
{
|
||||
CargoArray accepted, produced;
|
||||
uint32 dummy;
|
||||
|
||||
/* 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);
|
||||
TILE_AREA_LOOP(tile, area) {
|
||||
if (!IsTileType(tile, MP_HOUSE) || GetTownIndex(tile) != t->index) continue;
|
||||
|
||||
AddAcceptedCargo_Town(tile, accepted, &dummy);
|
||||
AddProducedCargo_Town(tile, produced);
|
||||
}
|
||||
|
||||
/* Create bitmap of produced and accepted cargos. */
|
||||
uint32 acc = 0;
|
||||
for (uint cid = 0; cid < NUM_CARGO; cid++) {
|
||||
if (accepted[cid] >= 8) SetBit(acc, cid);
|
||||
if (produced[cid] > 0) SetBit(t->cargo_produced, cid);
|
||||
}
|
||||
t->cargo_accepted[start] = acc;
|
||||
|
||||
if (update_total) UpdateTownCargoTotal(t);
|
||||
}
|
||||
|
||||
/** Update cargo acceptance for the complete town.
|
||||
* @param t The town to update.
|
||||
*/
|
||||
void UpdateTownCargos(Town *t)
|
||||
{
|
||||
t->cargo_produced = 0;
|
||||
|
||||
const TileArea &area = t->cargo_accepted.GetArea();
|
||||
if (area.tile == INVALID_TILE) return;
|
||||
|
||||
/* Update acceptance for each grid square. */
|
||||
TILE_AREA_LOOP(tile, area) {
|
||||
if (TileX(tile) % AcceptanceMatrix::GRID == 0 && TileY(tile) % AcceptanceMatrix::GRID == 0) {
|
||||
UpdateTownCargos(t, tile, false);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the total acceptance. */
|
||||
UpdateTownCargoTotal(t);
|
||||
}
|
||||
|
||||
static bool GrowTown(Town *t);
|
||||
|
||||
static void TownTickHandler(Town *t)
|
||||
|
@ -2221,6 +2290,7 @@ static bool BuildTownHouse(Town *t, TileIndex tile)
|
|||
}
|
||||
|
||||
MakeTownHouse(tile, t, construction_counter, construction_stage, house, random_bits);
|
||||
UpdateTownCargos(t, tile);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -2302,6 +2372,9 @@ void ClearTownHouse(Town *t, TileIndex tile)
|
|||
if (eflags & BUILDING_2_TILES_Y) DoClearTownHouseHelper(tile + TileDiffXY(0, 1), t, ++house);
|
||||
if (eflags & BUILDING_2_TILES_X) DoClearTownHouseHelper(tile + TileDiffXY(1, 0), t, ++house);
|
||||
if (eflags & BUILDING_HAS_4_TILES) DoClearTownHouseHelper(tile + TileDiffXY(1, 1), t, ++house);
|
||||
|
||||
/* Update cargo acceptance. */
|
||||
UpdateTownCargos(t, tile);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3068,6 +3141,7 @@ void TownsMonthlyLoop()
|
|||
UpdateTownRating(t);
|
||||
UpdateTownGrowRate(t);
|
||||
UpdateTownUnwanted(t);
|
||||
UpdateTownCargos(t);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue