Add cargo mask of town production cargoes
Use for all non-GUI cases (where display sort order is not required)
This commit is contained in:
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
CargoSpec CargoSpec::array[NUM_CARGO];
|
CargoSpec CargoSpec::array[NUM_CARGO];
|
||||||
std::array<std::vector<const CargoSpec *>, NUM_TPE> CargoSpec::town_production_cargoes{};
|
std::array<std::vector<const CargoSpec *>, NUM_TPE> CargoSpec::town_production_cargoes{};
|
||||||
|
std::array<CargoTypes, NUM_TPE> CargoSpec::town_production_cargo_mask{};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bitmask of cargo types available. This includes phony cargoes like regearing cargoes.
|
* Bitmask of cargo types available. This includes phony cargoes like regearing cargoes.
|
||||||
@@ -216,6 +217,7 @@ static bool CargoSpecClassSorter(const CargoSpec * const &a, const CargoSpec * c
|
|||||||
void InitializeSortedCargoSpecs()
|
void InitializeSortedCargoSpecs()
|
||||||
{
|
{
|
||||||
for (auto &tpc : CargoSpec::town_production_cargoes) tpc.clear();
|
for (auto &tpc : CargoSpec::town_production_cargoes) tpc.clear();
|
||||||
|
for (auto &tpc : CargoSpec::town_production_cargo_mask) tpc = 0;
|
||||||
_sorted_cargo_specs.clear();
|
_sorted_cargo_specs.clear();
|
||||||
/* Add each cargo spec to the list, and determine the largest cargo icon size. */
|
/* Add each cargo spec to the list, and determine the largest cargo icon size. */
|
||||||
for (const CargoSpec *cargo : CargoSpec::Iterate()) {
|
for (const CargoSpec *cargo : CargoSpec::Iterate()) {
|
||||||
@@ -236,6 +238,7 @@ void InitializeSortedCargoSpecs()
|
|||||||
for (const auto &cargo : _sorted_cargo_specs) {
|
for (const auto &cargo : _sorted_cargo_specs) {
|
||||||
assert(cargo->town_production_effect != INVALID_TPE);
|
assert(cargo->town_production_effect != INVALID_TPE);
|
||||||
CargoSpec::town_production_cargoes[cargo->town_production_effect].push_back(cargo);
|
CargoSpec::town_production_cargoes[cargo->town_production_effect].push_back(cargo);
|
||||||
|
SetBit(CargoSpec::town_production_cargo_mask[cargo->town_production_effect], cargo->Index());
|
||||||
if (cargo->classes & CC_SPECIAL) break;
|
if (cargo->classes & CC_SPECIAL) break;
|
||||||
nb_standard_cargo++;
|
nb_standard_cargo++;
|
||||||
SetBit(_standard_cargo_mask, cargo->Index());
|
SetBit(_standard_cargo_mask, cargo->Index());
|
||||||
|
@@ -199,6 +199,9 @@ struct CargoSpec {
|
|||||||
/** List of cargo specs for each Town Product Effect. */
|
/** List of cargo specs for each Town Product Effect. */
|
||||||
static std::array<std::vector<const CargoSpec *>, NUM_TPE> town_production_cargoes;
|
static std::array<std::vector<const CargoSpec *>, NUM_TPE> town_production_cargoes;
|
||||||
|
|
||||||
|
/** Mask of cargo IDs for each Town Product Effect. */
|
||||||
|
static std::array<CargoTypes, NUM_TPE> town_production_cargo_mask;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static CargoSpec array[NUM_CARGO]; ///< Array holding all CargoSpecs
|
static CargoSpec array[NUM_CARGO]; ///< Array holding all CargoSpecs
|
||||||
|
|
||||||
|
@@ -293,9 +293,18 @@ bool FindSubsidyPassengerRoute()
|
|||||||
{
|
{
|
||||||
if (!Subsidy::CanAllocateItem()) return false;
|
if (!Subsidy::CanAllocateItem()) return false;
|
||||||
|
|
||||||
|
if (CargoSpec::town_production_cargo_mask[TPE_PASSENGERS] == 0) return false;
|
||||||
|
|
||||||
/* Pick a random TPE_PASSENGER type */
|
/* Pick a random TPE_PASSENGER type */
|
||||||
uint32_t r = RandomRange(static_cast<uint>(CargoSpec::town_production_cargoes[TPE_PASSENGERS].size()));
|
uint32_t r = RandomRange(CountBits(CargoSpec::town_production_cargo_mask[TPE_PASSENGERS]));
|
||||||
CargoID cid = CargoSpec::town_production_cargoes[TPE_PASSENGERS][r]->Index();
|
CargoID cid{};
|
||||||
|
for (CargoID cargo_id : SetCargoBitIterator(CargoSpec::town_production_cargo_mask[TPE_PASSENGERS])) {
|
||||||
|
if (r == 0) {
|
||||||
|
cid = cargo_id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
r--;
|
||||||
|
}
|
||||||
|
|
||||||
const Town *src = Town::GetRandom();
|
const Town *src = Town::GetRandom();
|
||||||
if (src->cache.population < SUBSIDY_PAX_MIN_POPULATION ||
|
if (src->cache.population < SUBSIDY_PAX_MIN_POPULATION ||
|
||||||
@@ -343,8 +352,8 @@ bool FindSubsidyTownCargoRoute()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Passenger subsidies are not handled here. */
|
/* Passenger subsidies are not handled here. */
|
||||||
for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_PASSENGERS]) {
|
for (CargoID cid : SetCargoBitIterator(CargoSpec::town_production_cargo_mask[TPE_PASSENGERS])) {
|
||||||
town_cargo_produced[cs->Index()] = 0;
|
town_cargo_produced[cid] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t cargo_count = town_cargo_produced.GetCount();
|
uint8_t cargo_count = town_cargo_produced.GetCount();
|
||||||
|
@@ -688,7 +688,8 @@ static void TownGenerateCargo(Town *t, CargoID ct, uint amount, StationFinder &s
|
|||||||
*/
|
*/
|
||||||
static void TownGenerateCargoOriginal(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
|
static void TownGenerateCargoOriginal(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
|
||||||
{
|
{
|
||||||
for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
|
for (CargoID cid : SetCargoBitIterator(CargoSpec::town_production_cargo_mask[tpe])) {
|
||||||
|
const CargoSpec *cs = CargoSpec::Get(cid);
|
||||||
uint32_t r = Random();
|
uint32_t r = Random();
|
||||||
if (GB(r, 0, 8) < rate) {
|
if (GB(r, 0, 8) < rate) {
|
||||||
CargoID cid = cs->Index();
|
CargoID cid = cs->Index();
|
||||||
@@ -708,8 +709,8 @@ static void TownGenerateCargoOriginal(Town *t, TownProductionEffect tpe, uint8_t
|
|||||||
*/
|
*/
|
||||||
static void TownGenerateCargoBinominal(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
|
static void TownGenerateCargoBinominal(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
|
||||||
{
|
{
|
||||||
for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
|
for (CargoID cid : SetCargoBitIterator(CargoSpec::town_production_cargo_mask[tpe])) {
|
||||||
CargoID cid = cs->Index();
|
const CargoSpec *cs = CargoSpec::Get(cid);
|
||||||
uint32_t r = Random();
|
uint32_t r = Random();
|
||||||
|
|
||||||
/* Make a bitmask with up to 32 bits set, one for each potential pax. */
|
/* Make a bitmask with up to 32 bits set, one for each potential pax. */
|
||||||
@@ -891,13 +892,13 @@ void AddProducedHouseCargo(HouseID house_id, TileIndex tile, CargoArray &produce
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (hs->population > 0) {
|
if (hs->population > 0) {
|
||||||
for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_PASSENGERS]) {
|
for (CargoID cid : SetCargoBitIterator(CargoSpec::town_production_cargo_mask[TPE_PASSENGERS])) {
|
||||||
produced[cs->Index()]++;
|
produced[cid]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hs->mail_generation > 0) {
|
if (hs->mail_generation > 0) {
|
||||||
for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_MAIL]) {
|
for (CargoID cid : SetCargoBitIterator(CargoSpec::town_production_cargo_mask[TPE_MAIL])) {
|
||||||
produced[cs->Index()]++;
|
produced[cid]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2184,11 +2185,11 @@ void UpdateTownRadii()
|
|||||||
|
|
||||||
void UpdateTownMaxPass(Town *t)
|
void UpdateTownMaxPass(Town *t)
|
||||||
{
|
{
|
||||||
for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_PASSENGERS]) {
|
for (CargoID cid : SetCargoBitIterator(CargoSpec::town_production_cargo_mask[TPE_PASSENGERS])) {
|
||||||
t->supplied[cs->Index()].old_max = _town_cargo_scaler.Scale(t->cache.population >> 3);
|
t->supplied[cid].old_max = _town_cargo_scaler.Scale(t->cache.population >> 3);
|
||||||
}
|
}
|
||||||
for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_MAIL]) {
|
for (CargoID cid : SetCargoBitIterator(CargoSpec::town_production_cargo_mask[TPE_MAIL])) {
|
||||||
t->supplied[cs->Index()].old_max = _town_cargo_scaler.Scale(t->cache.population >> 4);
|
t->supplied[cid].old_max = _town_cargo_scaler.Scale(t->cache.population >> 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4180,8 +4181,8 @@ static uint GetNormalGrowthRate(Town *t)
|
|||||||
for (auto tpe : {TPE_PASSENGERS, TPE_MAIL}) {
|
for (auto tpe : {TPE_PASSENGERS, TPE_MAIL}) {
|
||||||
uint32_t old_max = 0;
|
uint32_t old_max = 0;
|
||||||
uint32_t old_act = 0;
|
uint32_t old_act = 0;
|
||||||
for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
|
for (CargoID cid : SetCargoBitIterator(CargoSpec::town_production_cargo_mask[tpe])) {
|
||||||
const TransportedCargoStat<uint32_t> &stat = t->supplied[cs->Index()];
|
const TransportedCargoStat<uint32_t> &stat = t->supplied[cid];
|
||||||
old_max += stat.old_max;
|
old_max += stat.old_max;
|
||||||
old_act += stat.old_act;
|
old_act += stat.old_act;
|
||||||
}
|
}
|
||||||
|
@@ -725,7 +725,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
uint GetDesiredInfoHeight(int width) const
|
uint GetDesiredInfoHeight(int width) const
|
||||||
{
|
{
|
||||||
uint aimed_height = static_cast<uint>(1 + CargoSpec::town_production_cargoes[TPE_PASSENGERS].size() + CargoSpec::town_production_cargoes[TPE_MAIL].size()) * GetCharacterHeight(FS_NORMAL);
|
uint aimed_height = static_cast<uint>(1 + CountBits(CargoSpec::town_production_cargo_mask[TPE_PASSENGERS] | CargoSpec::town_production_cargo_mask[TPE_MAIL])) * GetCharacterHeight(FS_NORMAL);
|
||||||
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (int i = TAE_BEGIN; i < TAE_END; i++) {
|
for (int i = TAE_BEGIN; i < TAE_END; i++) {
|
||||||
|
@@ -194,10 +194,8 @@ SpriteID TileZoneCheckUnservedBuildingsEvaluation(TileIndex tile, Owner owner)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto has_town_cargo = [&](const CargoArray &dat) {
|
auto has_town_cargo = [&](const CargoArray &dat) {
|
||||||
for (auto tpe : {TPE_PASSENGERS, TPE_MAIL}) {
|
for (CargoID cid : SetCargoBitIterator(CargoSpec::town_production_cargo_mask[TPE_PASSENGERS] | CargoSpec::town_production_cargo_mask[TPE_MAIL])) {
|
||||||
for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
|
if (dat[cid] > 0) return true;
|
||||||
if (dat[cs->Index()] > 0) return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user