summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSamuXarick <43006711+SamuXarick@users.noreply.github.com>2021-08-11 18:25:59 +0100
committerGitHub <noreply@github.com>2021-08-11 19:25:59 +0200
commit26f7f592cd0d93ec79aa2bbfd0a435c4465b95cc (patch)
tree601c3ac30cc2b4f9b4d13716609eea7f6694226a /src
parent76b83437775ccae7e722fc41d7e4564b64188776 (diff)
downloadopenttd-26f7f592cd0d93ec79aa2bbfd0a435c4465b95cc.tar.xz
Fix #8316: Make sort industries by production and transported with a cargo filter possible (#8468)
Diffstat (limited to 'src')
-rw-r--r--src/industry_gui.cpp98
1 files changed, 76 insertions, 22 deletions
diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp
index d3e3d2a16..69462c6f0 100644
--- a/src/industry_gui.cpp
+++ b/src/industry_gui.cpp
@@ -1309,7 +1309,7 @@ protected:
/* Runtime saved values */
static Listing last_sorting;
- /* Constants for sorting stations */
+ /* Constants for sorting industries */
static const StringID sorter_names[];
static GUIIndustryList::SortFunction * const sorter_funcs[];
@@ -1320,6 +1320,14 @@ protected:
StringID cargo_filter_texts[NUM_CARGO + 3]; ///< Texts for filter_cargo, terminated by INVALID_STRING_ID
byte produced_cargo_filter_criteria; ///< Selected produced cargo filter index
byte accepted_cargo_filter_criteria; ///< Selected accepted cargo filter index
+ static CargoID produced_cargo_filter;
+
+ enum class SorterType : uint8 {
+ IDW_SORT_BY_NAME, ///< Sorter type to sort by name
+ IDW_SORT_BY_TYPE, ///< Sorter type to sort by type
+ IDW_SORT_BY_PRODUCTION, ///< Sorter type to sort by production amount
+ IDW_SORT_BY_TRANSPORTED, ///< Sorter type to sort by transported percentage
+ };
/**
* Set cargo filter list item index.
@@ -1409,6 +1417,8 @@ protected:
this->cargo_filter[this->produced_cargo_filter_criteria]);
this->industries.Filter(filter);
+
+ IndustryDirectoryWindow::produced_cargo_filter = this->cargo_filter[this->produced_cargo_filter_criteria];
this->industries.Sort();
this->vscroll->SetCount((uint)this->industries.size()); // Update scrollbar as well.
@@ -1427,7 +1437,7 @@ protected:
{
assert(id < lengthof(i->produced_cargo));
- if (i->produced_cargo[id] == CT_INVALID) return 101;
+ if (i->produced_cargo[id] == CT_INVALID) return -1;
return ToPercent8(i->last_month_pct_transported[id]);
}
@@ -1440,12 +1450,27 @@ protected:
*/
static int GetCargoTransportedSortValue(const Industry *i)
{
- int p1 = GetCargoTransportedPercentsIfValid(i, 0);
- int p2 = GetCargoTransportedPercentsIfValid(i, 1);
+ CargoID filter = IndustryDirectoryWindow::produced_cargo_filter;
+ if (filter == CF_NONE) return 0;
- if (p1 > p2) Swap(p1, p2); // lower value has higher priority
+ int percentage = 0, produced_cargo_count = 0;
+ for (uint id = 0; id < lengthof(i->produced_cargo); id++) {
+ if (filter == CF_ANY) {
+ int transported = GetCargoTransportedPercentsIfValid(i, id);
+ if (transported != -1) {
+ produced_cargo_count++;
+ percentage += transported;
+ }
+ if (produced_cargo_count == 0 && id == lengthof(i->produced_cargo) - 1 && percentage == 0) {
+ return transported;
+ }
+ } else if (filter == i->produced_cargo[id]) {
+ return GetCargoTransportedPercentsIfValid(i, id);
+ }
+ }
- return (p1 << 8) + p2;
+ if (produced_cargo_count == 0) return percentage;
+ return percentage / produced_cargo_count;
}
/** Sort industries by name */
@@ -1470,10 +1495,18 @@ protected:
/** Sort industries by production and name */
static bool IndustryProductionSorter(const Industry * const &a, const Industry * const &b)
{
+ CargoID filter = IndustryDirectoryWindow::produced_cargo_filter;
+ if (filter == CF_NONE) return IndustryTypeSorter(a, b);
+
uint prod_a = 0, prod_b = 0;
for (uint i = 0; i < lengthof(a->produced_cargo); i++) {
- if (a->produced_cargo[i] != CT_INVALID) prod_a += a->last_month_production[i];
- if (b->produced_cargo[i] != CT_INVALID) prod_b += b->last_month_production[i];
+ if (filter == CF_ANY) {
+ if (a->produced_cargo[i] != CT_INVALID) prod_a += a->last_month_production[i];
+ if (b->produced_cargo[i] != CT_INVALID) prod_b += b->last_month_production[i];
+ } else {
+ if (a->produced_cargo[i] == filter) prod_a += a->last_month_production[i];
+ if (b->produced_cargo[i] == filter) prod_b += b->last_month_production[i];
+ }
}
int r = prod_a - prod_b;
@@ -1504,26 +1537,45 @@ protected:
GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_DIR, i, i->type, indsp, i->produced_cargo, cargo_suffix);
/* Get industry productions (CargoID, production, suffix, transported) */
- typedef std::tuple<CargoID, uint16, const char*, uint> CargoInfo;
+ struct CargoInfo {
+ CargoID cargo_id;
+ uint16 production;
+ const char *suffix;
+ uint transported;
+ };
std::vector<CargoInfo> cargos;
for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
if (i->produced_cargo[j] == CT_INVALID) continue;
- cargos.emplace_back(i->produced_cargo[j], i->last_month_production[j], cargo_suffix[j].text, ToPercent8(i->last_month_pct_transported[j]));
- }
+ cargos.push_back({ i->produced_cargo[j], i->last_month_production[j], cargo_suffix[j].text, ToPercent8(i->last_month_pct_transported[j]) });
+ }
+
+ switch (static_cast<IndustryDirectoryWindow::SorterType>(this->industries.SortType())) {
+ case IndustryDirectoryWindow::SorterType::IDW_SORT_BY_NAME:
+ case IndustryDirectoryWindow::SorterType::IDW_SORT_BY_TYPE:
+ case IndustryDirectoryWindow::SorterType::IDW_SORT_BY_PRODUCTION:
+ /* Sort by descending production, then descending transported */
+ std::sort(cargos.begin(), cargos.end(), [](const CargoInfo &a, const CargoInfo &b) {
+ if (a.production != b.production) return a.production > b.production;
+ return a.transported > b.transported;
+ });
+ break;
- /* Sort by descending production, then descending transported */
- std::sort(cargos.begin(), cargos.end(), [](const CargoInfo a, const CargoInfo b) {
- if (std::get<1>(a) != std::get<1>(b)) return std::get<1>(a) > std::get<1>(b);
- return std::get<3>(a) > std::get<3>(b);
- });
+ case IndustryDirectoryWindow::SorterType::IDW_SORT_BY_TRANSPORTED:
+ /* Sort by descending transported, then descending production */
+ std::sort(cargos.begin(), cargos.end(), [](const CargoInfo &a, const CargoInfo &b) {
+ if (a.transported != b.transported) return a.transported > b.transported;
+ return a.production > b.production;
+ });
+ break;
+ }
/* If the produced cargo filter is active then move the filtered cargo to the beginning of the list,
* because this is the one the player interested in, and that way it is not hidden in the 'n' more cargos */
const CargoID cid = this->cargo_filter[this->produced_cargo_filter_criteria];
if (cid != CF_ANY && cid != CF_NONE) {
- auto filtered_ci = std::find_if(cargos.begin(), cargos.end(), [cid](const CargoInfo& ci) -> bool {
- return std::get<0>(ci) == cid;
+ auto filtered_ci = std::find_if(cargos.begin(), cargos.end(), [cid](const CargoInfo &ci) -> bool {
+ return ci.cargo_id == cid;
});
if (filtered_ci != cargos.end()) {
std::rotate(cargos.begin(), filtered_ci, filtered_ci + 1);
@@ -1534,10 +1586,10 @@ protected:
for (size_t j = 0; j < std::min<size_t>(3, cargos.size()); j++) {
CargoInfo ci = cargos[j];
SetDParam(p++, STR_INDUSTRY_DIRECTORY_ITEM_INFO);
- SetDParam(p++, std::get<0>(ci));
- SetDParam(p++, std::get<1>(ci));
- SetDParamStr(p++, std::get<2>(ci));
- SetDParam(p++, std::get<3>(ci));
+ SetDParam(p++, ci.cargo_id);
+ SetDParam(p++, ci.production);
+ SetDParamStr(p++, ci.suffix);
+ SetDParam(p++, ci.transported);
}
/* Undisplayed cargos if any */
@@ -1785,6 +1837,8 @@ const StringID IndustryDirectoryWindow::sorter_names[] = {
INVALID_STRING_ID
};
+CargoID IndustryDirectoryWindow::produced_cargo_filter = CF_ANY;
+
/** Window definition of the industry directory gui */
static WindowDesc _industry_directory_desc(