55#include "table/strings.h"
61bool _ignore_industry_restrictions;
104 std::array<int32_t, 16> regs100;
109 if (
GB(callback, 0, 8) == 0xFF)
return;
110 if (callback < 0x400) {
136 if (callback < 0x400) {
141 if (callback >= 0x800 && callback < 0xC00) {
168template <
typename TC,
typename TS>
171 static_assert(std::tuple_size_v<std::remove_reference_t<
decltype(cargoes)>> <=
lengthof(suffixes));
175 for (uint j = 0; j <
lengthof(suffixes); j++) {
179 GetCargoSuffix(cargotype, cst, ind, ind_type, indspec, suffixes[j]);
181 suffixes[j].text.clear();
187 for (uint j = 0; j <
lengthof(suffixes); j++) {
188 suffixes[j].text.clear();
244 return (r != 0) ? r < 0 : (a < b);
261static constexpr std::initializer_list<NWidgetPart> _nested_build_industry_widgets = {
272 SetStringTip(STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES, STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_TOOLTIP),
274 SetStringTip(STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES, STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES_TOOLTIP),
278 NWidget(
WWT_MATRIX, COLOUR_DARK_GREEN,
WID_DPI_MATRIX_WIDGET),
SetMatrixDataTip(1, 0, STR_FUND_INDUSTRY_SELECTION_TOOLTIP),
SetFill(1, 0),
SetResize(1, 1),
SetScrollbar(
WID_DPI_SCROLLBAR),
285 SetStringTip(STR_INDUSTRY_DISPLAY_CHAIN, STR_INDUSTRY_DISPLAY_CHAIN_TOOLTIP),
293 WDP_AUTO,
"build_industry", 170, 212,
296 _nested_build_industry_widgets
300class BuildIndustryWindow :
public Window {
302 std::vector<IndustryType>
list{};
311 void UpdateAvailability()
332 if (this->selected_type == ind) this->selected_type = IT_INVALID;
336 this->
list.push_back(ind);
343 this->UpdateAvailability();
345 this->vscroll->SetCount(this->
list.size());
366 std::string
MakeCargoListString(
const std::span<const CargoType> cargolist,
const std::span<const CargoSuffix> cargo_suffix,
StringID prefixstr)
const
368 assert(cargolist.size() == cargo_suffix.size());
370 std::string cargostring;
373 for (
size_t j = 0; j < cargolist.size(); j++) {
376 if (!cargostring.empty()) cargostring += list_separator;
378 AppendStringWithArgsInPlace(cargostring, STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION, params);
382 return GetString(prefixstr, cargostring);
391 if (_game_mode != GM_EDITOR) {
405 this->legend.width = this->legend.height * 9 / 6;
416 for (
const auto &indtype : this->list) {
419 fill.height =
resize.height = std::max<uint>({this->legend.height, d.height, count.height}) + padding.height;
421 d.height = 5 *
resize.height;
428 int height = 2 + (_game_mode == GM_EDITOR ? 0 : 1);
429 uint extra_lines_req = 0;
430 uint extra_lines_prd = 0;
431 uint extra_lines_newgrf = 0;
434 for (
const auto &indtype : this->list) {
442 if (strdim.width > max_minwidth) {
443 extra_lines_req = std::max(extra_lines_req, strdim.width / max_minwidth + 1);
444 strdim.width = max_minwidth;
450 cargostring = this->
MakeCargoListString(indsp->produced_cargo, cargo_suffix, STR_INDUSTRY_VIEW_PRODUCES_N_CARGO);
452 if (strdim.width > max_minwidth) {
453 extra_lines_prd = std::max(extra_lines_prd, strdim.width / max_minwidth + 1);
454 strdim.width = max_minwidth;
460 extra_lines_newgrf = 4;
465 height += extra_lines_prd + extra_lines_req + extra_lines_newgrf;
467 size.width = d.width + padding.width;
475 d.width += padding.width;
476 d.height += padding.height;
489 if (_game_mode == GM_EDITOR) {
491 return GetString(STR_FUND_INDUSTRY_BUILD_NEW_INDUSTRY);
493 if (this->selected_type != IT_INVALID) {
495 return GetString((
_settings_game.construction.raw_industry_construction == 2 && indsp->
IsRawIndustry()) ? STR_FUND_INDUSTRY_PROSPECT_NEW_INDUSTRY : STR_FUND_INDUSTRY_FUND_NEW_INDUSTRY);
497 return GetString(STR_FUND_INDUSTRY_FUND_NEW_INDUSTRY);
514 icon.top = r.top + (this->
resize.step_height - this->legend.height + 1) / 2;
515 icon.bottom = icon.top + this->legend.height - 1;
517 auto badge_column_widths = badge_classes.GetColumnWidths();
520 for (
auto it = first; it != last; ++it) {
521 IndustryType type = *it;
522 bool selected = this->selected_type == type;
526 if (badge_column_widths.size() >= 1 && badge_column_widths[0] > 0) {
527 DrawBadgeColumn(tr.
WithWidth(badge_column_widths[0], rtl), 0, this->badge_classes, indsp->badges, GSF_INDUSTRIES, std::nullopt, PAL_NONE);
528 tr = tr.
Indent(badge_column_widths[0], rtl);
530 if (badge_column_widths.size() >= 2 && badge_column_widths[1] > 0) {
531 DrawBadgeColumn(tr.
WithWidth(badge_column_widths[1], !rtl), 0, this->badge_classes, indsp->badges, GSF_INDUSTRIES, std::nullopt, PAL_NONE);
532 tr = tr.
Indent(badge_column_widths[1], !rtl);
550 if (this->selected_type == IT_INVALID) {
557 if (_game_mode != GM_EDITOR) {
571 cargostring = this->
MakeCargoListString(indsp->produced_cargo, cargo_suffix, STR_INDUSTRY_VIEW_PRODUCES_N_CARGO);
578 std::array<int32_t, 16> regs100;
582 if (callback_res == 0x40F) {
584 }
else if (callback_res > 0x400) {
599 static void AskManyRandomIndustriesCallback(
Window *,
bool confirmed)
601 if (!confirmed)
return;
610 old_generating_world.Restore();
614 static void AskRemoveAllIndustriesCallback(
Window *,
bool confirmed)
616 if (!confirmed)
return;
618 for (
Industry *industry : Industry::Iterate())
delete industry;
634 assert(_game_mode == GM_EDITOR);
639 nullptr, AskManyRandomIndustriesCallback);
644 assert(_game_mode == GM_EDITOR);
649 nullptr, AskRemoveAllIndustriesCallback);
655 if (it != this->list.end()) {
656 this->selected_type = *it;
657 this->UpdateAvailability();
663 if (_thd.GetCallbackWnd() ==
this &&
664 ((_game_mode != GM_EDITOR &&
_settings_game.construction.raw_industry_construction == 2 && indsp !=
nullptr && indsp->
IsRawIndustry()) || !this->enabled)) {
681 if (this->selected_type != IT_INVALID) {
682 if (_game_mode != GM_EDITOR &&
_settings_game.construction.raw_industry_construction == 2 &&
GetIndustrySpec(this->selected_type)->IsRawIndustry()) {
683 Command<Commands::BuildIndustry>::Post(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY,
TileIndex{}, this->selected_type, 0,
false, InteractiveRandom());
705 uint32_t seed = InteractiveRandom();
706 uint32_t layout_index = InteractiveRandomRange((uint32_t)indsp->
layouts.size());
708 if (_game_mode == GM_EDITOR) {
718 AutoRestoreBackup backup_ignore_industry_restritions(_ignore_industry_restrictions,
true);
720 Command<Commands::BuildIndustry>::Post(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, tile, this->selected_type, layout_index,
false, seed);
722 success = Command<Commands::BuildIndustry>::Post(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, tile, this->selected_type, layout_index,
false, seed);
730 if (_game_mode == GM_EDITOR)
return;
731 if (this->selected_type == IT_INVALID)
return;
734 this->UpdateAvailability();
735 if (
enabled != this->enabled) {
756 void OnInvalidateData([[maybe_unused]]
int data = 0, [[maybe_unused]]
bool gui_scope =
true)
override
758 if (!gui_scope)
return;
765void ShowBuildIndustryWindow()
772static void UpdateIndustryProduction(
Industry *i);
774static inline bool IsProductionAlterable(
const Industry *i)
777 bool has_prod = std::any_of(std::begin(is->production_rate), std::end(is->production_rate), [](
auto rate) { return rate != 0; });
778 return ((_game_mode == GM_EDITOR ||
_cheats.setup_prod.value) &&
845 if (expected != r.bottom) {
846 this->info_height = expected - r.top + 1;
852 void DrawCargoIcon(
const Rect &r,
CargoType cargo_type)
const
861 std::string GetAcceptedCargoString(
const Industry::AcceptedCargo &ac,
const CargoSuffix &suffix)
const
869 default: NOT_REACHED();
885 bool has_accept =
false;
891 DrawString(ir, STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE);
907 DrawCargoIcon(ir, a.cargo);
915 DrawString(ir.
Indent(label_indent, rtl), this->GetAcceptedCargoString(a, suffix));
933 DrawCargoIcon(ir, p.cargo);
939 GetString(STR_INDUSTRY_VIEW_TRANSPORTED, p.cargo, p.history[LAST_MONTH].production, suffix.
text,
ToPercent8(p.history[LAST_MONTH].PctTransported())));
943 p.rate > 0, p.rate < 255);
945 ir.top += line_height;
950 line_height = this->cheat_line_height;
954 this->production_offset_y = ir.top;
959 ir.top += line_height;
964 std::array<int32_t, 16> regs100;
968 if (callback_res == 0x40F) {
970 }
else if (callback_res > 0x400) {
982 if (!i->
text.empty()) {
1000 if (widget ==
WID_IV_INFO) size.height = this->info_height;
1010 switch (this->editable) {
1018 if (pt.y >= this->production_offset_y) {
1019 int row = (pt.y - this->production_offset_y) / this->cheat_line_height;
1020 for (
auto itp = std::begin(i->
produced); itp != std::end(i->
produced); ++itp) {
1024 line = itp - std::begin(i->
produced);
1039 switch (this->editable) {
1052 if (i->
produced[line].rate <= 0)
return;
1055 if (i->
produced[line].rate >= 255)
return;
1057 int new_prod = i->
produced[line].rate == 0 ? 1 : i->
produced[line].rate * 2;
1062 default: NOT_REACHED();
1065 UpdateIndustryProduction(i);
1068 this->clicked_line = line;
1069 this->clicked_button = (decrease ^ rtl) ? 1 : 2;
1072 this->editbox_line = line;
1073 switch (this->editable) {
1082 default: NOT_REACHED();
1113 this->clicked_button = 0;
1137 if (!str.has_value() || str->empty())
return;
1141 if (!value.has_value())
return;
1142 switch (this->editbox_line) {
1153 UpdateIndustryProduction(i);
1162 void OnInvalidateData([[maybe_unused]]
int data = 0, [[maybe_unused]]
bool gui_scope =
true)
override
1164 if (!gui_scope)
return;
1166 if (IsProductionAlterable(i)) {
1176 return ::IsNewGRFInspectable(GSF_INDUSTRIES, this->
window_number);
1185static void UpdateIndustryProduction(
Industry *i)
1224 WDP_AUTO,
"view_industry", 260, 120,
1230void ShowIndustryViewWindow(IndustryID industry)
1278 auto accepted_cargo = cargoes.first;
1279 auto produced_cargo = cargoes.second;
1281 bool accepted_cargo_matches;
1283 switch (accepted_cargo) {
1285 accepted_cargo_matches =
true;
1289 accepted_cargo_matches = !(*industry)->IsCargoAccepted();
1293 accepted_cargo_matches = (*industry)->IsCargoAccepted(accepted_cargo);
1297 bool produced_cargo_matches;
1299 switch (produced_cargo) {
1301 produced_cargo_matches =
true;
1305 produced_cargo_matches = !(*industry)->IsCargoProduced();
1309 produced_cargo_matches = (*industry)->IsCargoProduced(produced_cargo);
1313 return accepted_cargo_matches && produced_cargo_matches;
1321class IndustryDirectoryWindow :
public Window {
1330 STR_SORT_BY_PRODUCTION,
1331 STR_SORT_BY_TRANSPORTED,
1333 static const std::initializer_list<GUIIndustryList::SortFunction * const>
sorter_funcs;
1335 GUIIndustryList industries{IndustryDirectoryWindow::produced_cargo_filter};
1336 Scrollbar *vscroll{};
1337 Scrollbar *hscroll{};
1361 if (this->produced_cargo_filter_criteria != cargo_type) {
1362 this->produced_cargo_filter_criteria = cargo_type;
1378 if (this->accepted_cargo_filter_criteria != cargo_type) {
1379 this->accepted_cargo_filter_criteria = cargo_type;
1391 switch (cargo_type) {
1421 for (
auto it = first; it != last; ++it) {
1431 this->industries.clear();
1435 if (this->string_filter.
IsEmpty()) {
1436 this->industries.push_back(i);
1440 this->string_filter.AddLine(i->GetCachedName());
1441 if (this->string_filter.
GetState()) this->industries.push_back(i);
1446 auto filter = std::make_pair(this->accepted_cargo_filter_criteria, this->produced_cargo_filter_criteria);
1448 this->industries.
Filter(filter);
1450 this->vscroll->
SetCount(this->industries.size());
1453 IndustryDirectoryWindow::produced_cargo_filter = this->produced_cargo_filter_criteria;
1454 this->industries.
Sort();
1480 CargoType filter = IndustryDirectoryWindow::produced_cargo_filter;
1483 int percentage = 0, produced_cargo_count = 0;
1484 for (
const auto &p : i->
produced) {
1487 if (transported != -1) {
1488 produced_cargo_count++;
1489 percentage += transported;
1491 if (produced_cargo_count == 0 && &p == &i->
produced.back() && percentage == 0) {
1494 }
else if (filter == p.cargo) {
1499 if (produced_cargo_count == 0)
return percentage;
1500 return percentage / produced_cargo_count;
1507 if (r == 0)
return a->index < b->index;
1518 int r = it_a - it_b;
1527 uint prod_a = 0, prod_b = 0;
1529 for (
const auto &pa : a->
produced) {
1530 if (
IsValidCargoType(pa.cargo)) prod_a += pa.history[LAST_MONTH].production;
1532 for (
const auto &pb : b->
produced) {
1533 if (
IsValidCargoType(pb.cargo)) prod_b += pb.history[LAST_MONTH].production;
1536 if (
auto ita = a->
GetCargoProduced(filter); ita != std::end(a->
produced)) prod_a = ita->history[LAST_MONTH].production;
1537 if (
auto itb = b->
GetCargoProduced(filter); itb != std::end(b->
produced)) prod_b = itb->history[LAST_MONTH].production;
1539 int r = prod_a - prod_b;
1551 StringID GetStringForNumCargo(
size_t count)
const
1554 case 0:
return STR_INDUSTRY_DIRECTORY_ITEM_NOPROD;
1555 case 1:
return STR_INDUSTRY_DIRECTORY_ITEM_PROD1;
1556 case 2:
return STR_INDUSTRY_DIRECTORY_ITEM_PROD2;
1557 case 3:
return STR_INDUSTRY_DIRECTORY_ITEM_PROD3;
1558 default:
return STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE;
1574 uint16_t production;
1578 CargoInfo(
CargoType cargo_type, uint16_t production, uint transported, std::string &&suffix) : cargo_type(cargo_type), production(production), transported(transported), suffix(std::move(suffix)) {}
1580 std::vector<CargoInfo> cargos;
1582 for (
auto itp = std::begin(i->
produced); itp != std::end(i->
produced); ++itp) {
1586 cargos.emplace_back(itp->cargo, itp->history[LAST_MONTH].production,
ToPercent8(itp->history[LAST_MONTH].PctTransported()), std::move(cargo_suffix.
text));
1594 std::sort(cargos.begin(), cargos.end(), [](
const CargoInfo &a,
const CargoInfo &b) {
1595 if (a.production != b.production) return a.production > b.production;
1596 return a.transported > b.transported;
1602 std::sort(cargos.begin(), cargos.end(), [](
const CargoInfo &a,
const CargoInfo &b) {
1603 if (a.transported != b.transported) return a.transported > b.transported;
1604 return a.production > b.production;
1611 const CargoType cargo_type = this->produced_cargo_filter_criteria;
1613 auto filtered_ci = std::ranges::find(cargos, cargo_type, &CargoInfo::cargo_type);
1614 if (filtered_ci != cargos.end()) {
1615 std::rotate(cargos.begin(), filtered_ci, filtered_ci + 1);
1619 static constexpr size_t MAX_DISPLAYED_CARGOES = 3;
1620 std::array<StringParameter, 2 + 5 * MAX_DISPLAYED_CARGOES> params{};
1621 auto it = params.begin();
1627 for (CargoInfo &ci : cargos | std::views::take(MAX_DISPLAYED_CARGOES)) {
1628 *it++ = STR_INDUSTRY_DIRECTORY_ITEM_INFO;
1629 *it++ = ci.cargo_type;
1630 *it++ = ci.production;
1631 *it++ = std::move(ci.suffix);
1632 *it++ = ci.transported;
1636 if (std::size(cargos) > MAX_DISPLAYED_CARGOES) *it++ = std::size(cargos) - MAX_DISPLAYED_CARGOES;
1638 return GetStringWithArgs(GetStringForNumCargo(std::size(cargos)), {params.begin(), it});
1648 this->industries.
SetListing(this->last_sorting);
1663 this->last_sorting = this->industries.
GetListing();
1682 return GetString(STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER, this->GetCargoFilterLabel(this->accepted_cargo_filter_criteria));
1685 return GetString(STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER, this->GetCargoFilterLabel(this->produced_cargo_filter_criteria));
1706 tmp_dpi.left += ir.left;
1707 tmp_dpi.top += ir.top;
1713 if (this->industries.empty()) {
1717 const CargoType acf_cargo_type = this->accepted_cargo_filter_criteria;
1719 for (
auto it = first; it != last; ++it) {
1729 ir.top += this->
resize.step_height;
1742 d.height += padding.height;
1749 d.width += padding.width;
1750 d.height += padding.height;
1757 fill.height =
resize.height = d.height;
1759 d.width += padding.width;
1760 d.height += padding.height;
1798 static std::string acc_cargo_filter;
1804 static std::string prod_cargo_filter;
1811 if (it != this->industries.end()) {
1827 if (this->industries.
SortType() != index) {
1880 void OnInvalidateData([[maybe_unused]]
int data = 0, [[maybe_unused]]
bool gui_scope =
true)
override
1883 case IDIWD_FORCE_REBUILD:
1888 case IDIWD_PRODUCTION_CHANGE:
1898 static inline HotkeyList hotkeys {
"industrydirectory", {
1903Listing IndustryDirectoryWindow::last_sorting = {
false, 0};
1918 WDP_AUTO,
"list_industries", 428, 190,
1922 &IndustryDirectoryWindow::hotkeys
1925void ShowIndustryDirectory()
1945 SetStringTip(STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP, STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP_TOOLTIP),
1948 SetStringTip(STR_INDUSTRY_CARGOES_SELECT_INDUSTRY, STR_INDUSTRY_CARGOES_SELECT_INDUSTRY_TOOLTIP),
1950 SetStringTip(STR_INDUSTRY_CARGOES_SELECT_CARGO, STR_INDUSTRY_CARGOES_SELECT_CARGO_TOOLTIP),
1957 WDP_AUTO,
"industry_cargoes", 300, 210,
1994 using Cargoes = uint16_t;
1995 static_assert(std::numeric_limits<Cargoes>::digits >=
MAX_CARGOES);
2037 std::fill(std::begin(this->
u.industry.other_accepted), std::end(this->u.industry.other_accepted), INVALID_CARGO);
2038 std::fill(std::begin(this->
u.industry.other_produced), std::end(this->u.industry.other_produced), INVALID_CARGO);
2054 for (
int i = 0; i < this->
u.cargo.num_cargoes; i++) {
2055 if (
cargo == this->
u.cargo.vertical_cargoes[i]) {
2060 if (column < 0)
return -1;
2063 assert(!
HasBit(this->
u.cargo.supp_cargoes, column));
2064 SetBit(this->
u.cargo.supp_cargoes, column);
2066 assert(!
HasBit(this->
u.cargo.cust_cargoes, column));
2067 SetBit(this->
u.cargo.cust_cargoes, column);
2080 return this->
u.cargo.supp_cargoes != 0 || this->
u.cargo.cust_cargoes != 0;
2091 assert(std::size(
cargoes) <= std::size(this->
u.cargo.vertical_cargoes));
2093 this->
u.cargo.num_cargoes =
static_cast<uint8_t
>(std::distance(std::begin(this->
u.cargo.vertical_cargoes), insert));
2095 std::sort(std::begin(this->
u.cargo.vertical_cargoes), insert, comparator);
2096 std::fill(insert, std::end(this->
u.cargo.vertical_cargoes), INVALID_CARGO);
2097 this->
u.cargo.top_end =
false;
2098 this->
u.cargo.bottom_end =
false;
2099 this->
u.cargo.supp_cargoes = 0;
2100 this->
u.cargo.cust_cargoes = 0;
2111 assert(std::size(
cargoes) <= std::size(this->
u.cargo_label.cargoes));
2112 auto insert = std::copy(std::begin(
cargoes), std::end(
cargoes), std::begin(this->
u.cargo_label.cargoes));
2113 std::fill(insert, std::end(this->
u.cargo_label.cargoes), INVALID_CARGO);
2124 this->
u.header = textid;
2135 int n = this->
u.cargo.num_cargoes;
2145 void Draw(
int xpos,
int ypos)
const
2147 switch (this->type) {
2168 int blob_left, blob_right;
2183 std::span<const CargoType> other_right, other_left;
2185 other_right = this->
u.industry.other_accepted;
2186 other_left = this->
u.industry.other_produced;
2188 other_right = this->
u.industry.other_produced;
2189 other_left = this->
u.industry.other_accepted;
2214 int colpos = cargo_base;
2215 for (
int i = 0; i < this->
u.cargo.num_cargoes; i++) {
2227 Cargoes hor_left, hor_right;
2229 hor_left = this->
u.cargo.cust_cargoes;
2230 hor_right = this->
u.cargo.supp_cargoes;
2232 hor_left = this->
u.cargo.supp_cargoes;
2233 hor_right = this->
u.cargo.cust_cargoes;
2237 if (
HasBit(hor_left, i)) {
2241 for (; col > 0; col--) {
2248 if (
HasBit(hor_right, i)) {
2252 for (; col < this->
u.cargo.num_cargoes - 1; col++) {
2295 for (col = 0; col < this->
u.cargo.num_cargoes; col++) {
2296 if (pt.
x < cpos)
break;
2305 if (pt.
y < vpos)
return INVALID_CARGO;
2313 if (
HasBit(this->
u.cargo.supp_cargoes, row))
return this->
u.cargo.vertical_cargoes[row];
2314 if (left !=
nullptr) {
2318 return INVALID_CARGO;
2320 if (col == this->
u.cargo.num_cargoes) {
2321 if (
HasBit(this->
u.cargo.cust_cargoes, row))
return this->
u.cargo.vertical_cargoes[row];
2322 if (right !=
nullptr) {
2326 return INVALID_CARGO;
2333 if (
HasBit(this->
u.cargo.supp_cargoes, row))
return this->
u.cargo.vertical_cargoes[row];
2334 return INVALID_CARGO;
2337 if (
HasBit(this->
u.cargo.cust_cargoes, row))
return this->
u.cargo.vertical_cargoes[row];
2338 return INVALID_CARGO;
2353 if (pt.
y < vpos)
return INVALID_CARGO;
2358 return this->
u.cargo_label.cargoes[row];
2377static_assert(
MAX_CARGOES >= std::tuple_size_v<
decltype(IndustrySpec::produced_cargo)>);
2416 int other_count = 0;
2421 int col = cargo_fld->
ConnectCargo(indsp->produced_cargo[i],
true);
2422 if (col < 0) others[other_count++] = indsp->produced_cargo[i];
2426 for (uint i = 0; i < CargoesField::max_cargoes && other_count > 0; i++) {
2447 std::fill(std::begin(cargoes), std::end(cargoes), INVALID_CARGO);
2450 CargoesField *cargo_fld = this->columns + (accepting ? column - 1 : column + 1);
2475 int other_count = 0;
2481 if (col < 0) others[other_count++] = indsp->
accepts_cargo[i];
2485 for (uint i = 0; i < CargoesField::max_cargoes && other_count > 0; i++) {
2492 if (!hs.enabled)
continue;
2494 for (uint j = 0; j <
lengthof(hs.accepts_cargo); j++) {
2535struct IndustryCargoesWindow :
public Window {
2536 typedef std::vector<CargoesRow> Fields;
2586 this->ind_textsize.width = 0;
2587 this->ind_textsize.height = 0;
2591 if (!indsp->
enabled)
continue;
2596 d.width = std::max(d.width, this->ind_textsize.width);
2597 d.height = this->ind_textsize.height;
2601 this->cargo_textsize.width = 0;
2602 this->cargo_textsize.height = 0;
2606 d =
maxdim(d, this->cargo_textsize);
2631 size.width = std::max(size.width, this->ind_textsize.width + padding.width);
2635 size.width = std::max(size.width, this->cargo_textsize.width + padding.width);
2646 return GetString(STR_INDUSTRY_CARGOES_INDUSTRY_CAPTION, indsp->
name);
2649 return GetString(STR_INDUSTRY_CARGOES_CARGO_CAPTION, csp->
name);
2659 static bool HasCommonValidCargo(
const std::span<const CargoType> cargoes1,
const std::span<const CargoType> cargoes2)
2661 for (
const CargoType cargo_type1 : cargoes1) {
2663 for (
const CargoType cargo_type2 : cargoes2) {
2664 if (cargo_type1 == cargo_type2)
return true;
2677 for (
const CargoType cargo_type : cargoes) {
2694 for (
const CargoType cargo_type : cargoes) {
2698 if (!hs.enabled || !hs.building_availability.Any(climate_mask))
continue;
2700 for (uint j = 0; j <
lengthof(hs.accepts_cargo); j++) {
2701 if (hs.cargo_acceptance[j] > 0 && cargo_type == hs.accepts_cargo[j])
return true;
2718 if (!indsp->
enabled)
continue;
2735 if (!indsp->
enabled)
continue;
2754 this->fields[
top].columns[column].u.cargo.top_end =
true;
2756 while (bottom >
top && !this->fields[bottom].columns[column].HasConnection()) {
2760 this->fields[bottom].columns[column].u.cargo.bottom_end =
true;
2772 this->fields[row].columns[col].MakeIndustry(it);
2774 this->fields[row].ConnectIndustryProduced(col);
2776 this->fields[row].ConnectIndustryAccepted(col);
2798 this->ind_cargo = displayed_it;
2802 this->fields.clear();
2803 CargoesRow &first_row = this->fields.emplace_back();
2816 int num_indrows = std::max(3, std::max(num_supp, num_cust));
2817 for (
int i = 0; i < num_indrows; i++) {
2818 CargoesRow &row = this->fields.emplace_back();
2826 int central_row = 1 + num_indrows / 2;
2827 this->fields[central_row].columns[2].MakeIndustry(displayed_it);
2828 this->fields[central_row].ConnectIndustryProduced(2);
2829 this->fields[central_row].ConnectIndustryAccepted(2);
2832 this->fields[central_row - 1].MakeCargoLabel(2,
true);
2833 this->fields[central_row + 1].MakeCargoLabel(2,
false);
2840 if (!indsp->
enabled)
continue;
2843 this->
PlaceIndustry(1 + supp_count * num_indrows / num_supp, 0, it);
2848 this->
PlaceIndustry(1 + cust_count * num_indrows / num_cust, 4, it);
2853 if (houses_supply) {
2857 if (houses_accept) {
2864 this->vscroll->
SetCount(num_indrows);
2878 this->fields.clear();
2879 CargoesRow &first_row = this->fields.emplace_back();
2886 auto cargoes = std::span(&cargo_type, 1);
2891 int num_indrows = std::max(num_supp, num_cust);
2892 for (
int i = 0; i < num_indrows; i++) {
2893 CargoesRow &row = this->fields.emplace_back();
2901 this->fields[num_indrows].MakeCargoLabel(0,
false);
2908 if (!indsp->
enabled)
continue;
2911 this->
PlaceIndustry(1 + supp_count * num_indrows / num_supp, 0, it);
2916 this->
PlaceIndustry(1 + cust_count * num_indrows / num_cust, 2, it);
2921 if (houses_supply) {
2925 if (houses_accept) {
2931 this->vscroll->
SetCount(num_indrows);
2943 void OnInvalidateData([[maybe_unused]]
int data = 0, [[maybe_unused]]
bool gui_scope =
true)
override
2945 if (!gui_scope)
return;
2971 for (
const auto &field : this->fields) {
2972 if (vpos + row_height >= 0) {
2973 int xpos = left_pos;
2982 while (col >= 0 && col <= last_column) {
2983 field.columns[col].Draw(xpos, vpos);
2989 if (vpos >=
height)
break;
3008 if (pt.
y < vpos)
return false;
3011 if (row + 1 >= (
int)this->fields.size())
return false;
3016 if (pt.
x < xpos)
return false;
3018 for (column = 0; column <= 5; column++) {
3020 if (pt.
x < xpos +
width)
break;
3024 if (column > num_columns)
return false;
3031 fieldxy->
x = num_columns - column;
3034 fieldxy->
x = column;
3047 const CargoesField *fld = this->fields[fieldxy.
y].columns + fieldxy.
x;
3048 switch (fld->
type) {
3054 CargoesField *lft = (fieldxy.
x > 0) ? this->fields[fieldxy.
y].columns + fieldxy.
x - 1 :
nullptr;
3055 CargoesField *rgt = (fieldxy.
x < 4) ? this->fields[fieldxy.
y].columns + fieldxy.
x + 1 :
nullptr;
3091 static std::string cargo_filter;
3102 if (!indsp->
enabled)
continue;
3106 static std::string cargo_filter;
3107 int selected = (this->ind_cargo <
NUM_INDUSTRYTYPES) ? (
int)this->ind_cargo : -1;
3117 if (index < 0)
return;
3137 const CargoesField *fld = this->fields[fieldxy.
y].columns + fieldxy.
x;
3139 switch (fld->
type) {
3141 CargoesField *lft = (fieldxy.
x > 0) ? this->fields[fieldxy.
y].columns + fieldxy.
x - 1 :
nullptr;
3142 CargoesField *rgt = (fieldxy.
x < 4) ? this->fields[fieldxy.
y].columns + fieldxy.
x + 1 :
nullptr;
Class for backupping variables and making sure they are restored later.
static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
uint8_t CargoType
Cargo slots to indicate a cargo type within a game.
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
StrongType::Typedef< uint32_t, struct CargoLabelTag, StrongType::Compare > CargoLabel
Globally unique label of a cargo type.
Dimension GetLargestCargoIconSize()
Get dimensions of largest cargo icon.
std::span< const CargoSpec * > _sorted_standard_cargo_specs
Standard cargo specifications sorted alphabetically by name.
TownProductionEffect
Town effect when producing cargo.
@ TPE_PASSENGERS
Cargo behaves passenger-like for production.
@ TPE_MAIL
Cargo behaves mail-like for production.
Cheats _cheats
All the cheats.
Types related to cheating.
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
Build (fund or prospect) a new industry,.
IndustryType selected_type
industry corresponding to the above index
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
Dimension legend
Dimension of the legend 'blob'.
void OnInit() override
Notification that the nested widget tree gets initialized.
void SetButtons()
Update status of the fund and display-chain widgets.
static const int MAX_MINWIDTH_LINEHEIGHTS
The largest allowed minimum-width of the window, given in line heights.
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
void OnPlaceObject(Point pt, TileIndex tile) override
The user clicked some place on the map when a tile highlight mode has been set.
void OnPlaceObjectAbort() override
The user cancelled a tile highlight mode that has been set.
std::string MakeCargoListString(const std::span< const CargoType > cargolist, const std::span< const CargoSuffix > cargo_suffix, StringID prefixstr) const
Build a string of cargo names with suffixes attached.
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
void OnTimeout() override
Called when this window's timeout has been reached.
void OnResize() override
Called after the window got resized.
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
std::vector< IndustryType > list
List of industries.
bool enabled
Availability state of the selected industry.
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
std::string GetDecodedString() const
Decode the encoded string.
uint GetTotalColumnsWidth() const
Get total width of all columns.
List template of 'things' T to sort in a GUI.
bool Filter(FilterFunction *decide, F filter_data)
Filter the list.
void RebuildDone()
Notify the sortlist that the rebuild is done.
void SetListing(Listing l)
Import sort conditions.
void SetFilterState(bool state)
Enable or disable the filter.
bool IsDescSortOrder() const
Check if the sort order is descending.
void ToggleSortOrder()
Toggle the sort order Since that is the worst condition for the sort function reverse the list here.
void SetFilterFuncs(std::span< FilterFunction *const > n_funcs)
Hand the filter function pointers to the GUIList.
bool NeedRebuild() const
Check if a rebuild is needed.
void SetFilterType(uint8_t n_type)
Set the filtertype of the list.
void ForceRebuild()
Force that a rebuild is needed.
bool Sort(Comp compare)
Sort the list.
void ForceResort()
Force a resort next Sort call Reset the resort timer if used too.
uint8_t SortType() const
Get the sorttype of the list.
bool(const const Industry **item, const std::pair< CargoType, CargoType > &filter) FilterFunction
Listing GetListing() const
Export current sort conditions.
void SetSortFuncs(std::span< SortFunction *const > n_funcs)
Hand the sort function pointers to the GUIList.
void SetSortType(uint8_t n_type)
Set the sorttype of the list.
~IndustryDirectoryWindow() override
Save the last sorting state.
const IntervalTimer< TimerWindow > rebuild_interval
Rebuild the industry list on a regular interval.
void OnEditboxChanged(WidgetID wid) override
The text in an editbox has been edited.
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
static bool IndustryTypeSorter(const Industry *const &a, const Industry *const &b, const CargoType &filter)
Sort industries by type and name.
static int GetCargoTransportedSortValue(const Industry *i)
Returns value representing industry's transported cargo percentage for industry sorting.
static const StringID sorter_names[]
Strings describing how industries are sorted.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
const int MAX_FILTER_LENGTH
The max length of the filter, in chars.
void SetCargoFilterArray()
Populate the filter list and set the cargo filter criteria.
void OnResize() override
Called after the window got resized.
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
void SetProducedCargoFilter(CargoType cargo_type)
Set produced cargo filter for the industry list.
static int GetCargoTransportedPercentsIfValid(const Industry::ProducedCargo &p)
Returns percents of cargo transported if industry produces this cargo, else -1.
SorterType
Ways to sort industries.
@ ByName
Sorter type to sort by name.
@ ByTransported
Sorter type to sort by transported percentage.
@ ByProduction
Sorter type to sort by production amount.
@ ByType
Sorter type to sort by type.
std::string GetIndustryString(const Industry *i) const
Get the StringID to draw and set the appropriate DParams.
uint GetIndustryListWidth() const
Get the width needed to draw the longest industry line.
static const std::initializer_list< GUIIndustryList::SortFunction *const > sorter_funcs
Functions to sort industries.
static bool IndustryTransportedCargoSorter(const Industry *const &a, const Industry *const &b, const CargoType &filter)
Sort industries by transported cargo and name.
QueryString industry_editbox
Filter editbox.
StringFilter string_filter
Filter for industries.
static bool IndustryProductionSorter(const Industry *const &a, const Industry *const &b, const CargoType &filter)
Sort industries by production and name.
static bool IndustryNameSorter(const Industry *const &a, const Industry *const &b, const CargoType &filter)
Sort industries by name.
void BuildSortIndustriesList()
(Re)Build industries list
CargoType accepted_cargo_filter_criteria
Selected accepted cargo filter index.
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
void SetAcceptedCargoFilter(CargoType cargo_type)
Set accepted cargo filter for the industry list.
void OnDropdownSelect(WidgetID widget, int index, int) override
A dropdown option associated to this window has been selected.
CargoType produced_cargo_filter_criteria
Selected produced cargo filter index.
void OnPaint() override
The window must be repainted.
void OnInit() override
Notification that the nested widget tree gets initialized.
void OnResize() override
Called after the window got resized.
int cheat_line_height
Height of each line for the WID_IV_INFO panel.
int production_offset_y
The offset of the production texts/buttons.
void OnPaint() override
The window must be repainted.
Editability editable
Mode for changing production.
ClickedCargoLine editbox_line
The line clicked to open the edit box.
void OnTimeout() override
Called when this window's timeout has been reached.
~IndustryViewWindow() override
Close the industry production window.
bool IsNewGRFInspectable() const override
Is the data related to this window NewGRF inspectable?
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
int info_height
Height needed for the WID_IV_INFO panel.
Dimension cargo_icon_size
Largest cargo icon dimension.
void OnMouseWheel(int wheel, WidgetID widget) override
The mouse wheel has been turned.
void ShowNewGRFInspectWindow() const override
Show the NewGRF inspection window.
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
static constexpr ClickedCargoLine CCL_NONE
No cargo line has been clicked.
void OnInit() override
Notification that the nested widget tree gets initialized.
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
uint8_t clicked_button
The button that has been clicked (to raise).
void OnQueryTextFinished(std::optional< std::string > str) override
The query window opened from this window has closed.
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
int8_t ClickedCargoLine
Clicked cargo line in the info panel.
int DrawInfo(const Rect &r)
Draw the text in the WID_IV_INFO panel.
ClickedCargoLine clicked_line
The line of the button that has been clicked.
static constexpr ClickedCargoLine CCL_MULTIPLIER
Product multiplier line is clicked.
Editability
Modes for changing production.
@ Rate
Allow changing the production rates.
@ Multiplier
Allow changing the production multiplier.
An interval timer will fire every interval, and will continue to fire until it is deleted.
static bool UsingWallclockUnits(bool newgame=false)
Check if we are using wallclock units.
Map accessors for 'clear' tiles.
@ Grass
Plain grass with dirt transition (0-3).
void MakeClear(Tile t, ClearGround g, uint density)
Make a clear tile.
ClearGround GetClearGround(Tile t)
Get the type of clear tile.
Functions related to commands.
Definition of stuff that is very close to a company, like the company struct itself.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
CompanyID _current_company
Company currently doing an action.
Functions related to companies.
static constexpr Owner OWNER_NONE
The tile has no ownership.
void ShowDropDownMenu(Window *w, std::span< const StringID > strings, int selected, WidgetID button, uint32_t disabled_mask, uint32_t hidden_mask, uint width, DropDownOptions options, std::string *const persistent_filter_text)
Show a dropdown menu window near a widget of the parent window.
std::unique_ptr< DropDownListItem > MakeDropDownListIconItem(SpriteID sprite, PaletteID palette, StringID str, int value, bool masked, bool shaded)
Creates new DropDownListIconItem.
std::unique_ptr< DropDownListItem > MakeDropDownListStringItem(StringID str, int value, bool masked, bool shaded)
Creates new DropDownListStringItem.
void ShowDropDownList(Window *w, DropDownList &&list, int selected, WidgetID button, uint width, DropDownOptions options, std::string *const persistent_filter_text)
Show a drop down list.
Functions related to the drop down widget.
Types related to the drop down widget.
std::vector< std::unique_ptr< const DropDownListItem > > DropDownList
A drop down list is a collection of drop down list items.
@ Filterable
Set if the dropdown is filterable.
uint ScaleByCargoScale(uint num, bool town)
Scale a number by the cargo scale setting.
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23).
Functions related to errors.
@ WL_INFO
Used for DoCommand-like (and some non-fatal AI GUI) errors/information.
void ShowErrorMessage(EncodedString &&summary_msg, int x, int y, CommandCost &cc)
Display an error message in a window.
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
bool _generating_world
Whether we are generating the map or not.
Functions related to world/map generation.
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
int CentreBounds(int min, int max, int size)
Determine where to position a centred object.
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
Dimension GetStringListBoundingBox(std::span< const StringID > list, FontSize fontsize)
Get maximum dimension of a list of strings.
int DrawString(int left, int right, int top, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
bool _ctrl_pressed
Is Ctrl pressed?
void DrawRectOutline(const Rect &r, PixelColour colour, int width, int dash)
Draw the outline of a Rect.
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
int DrawStringMultiLine(int left, int right, int top, int bottom, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly over multiple lines.
void GfxFillRect(int left, int top, int right, int bottom, const std::variant< PixelColour, PaletteID > &colour, FillRectMode mode)
Applies a certain FillRectMode-operation to a rectangle [left, right] x [top, bottom] on the screen.
bool FillDrawPixelInfo(DrawPixelInfo *n, int left, int top, int width, int height)
Set up a clipping area for only drawing into a certain area.
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
@ FS_SMALL
Index of the small font in the font tables.
@ FS_NORMAL
Index of the normal font in the font tables.
@ SA_LEFT
Left align the text.
@ SA_RIGHT
Right align the text (must be a single bit).
@ SA_HOR_CENTER
Horizontally center the text.
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
@ TC_FORCED
Ignore colour changes from strings.
@ FILLRECT_OPAQUE
Fill rectangle with a single colour.
void SetDirty() const
Mark entire window as dirty (in need of re-paint).
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
GUI functions that shouldn't be here.
void ShowExtraViewportWindow(TileIndex tile=INVALID_TILE)
Show a new Extra Viewport window.
Hotkey related functions.
HouseZones GetClimateMaskForLandscape()
Get the HouseZones climate mask for the current landscape type.
static constexpr uint8_t PRODLEVEL_MAXIMUM
the industry is running at full speed
static constexpr uint8_t PRODLEVEL_DEFAULT
default level set when the industry is created
static constexpr uint8_t PRODLEVEL_MINIMUM
below this level, the industry is set to be closing
static constexpr uint8_t PRODLEVEL_CLOSURE
signal set to actually close the industry
const IndustrySpec * GetIndustrySpec(IndustryType thistype)
Accessor for array _industry_specs.
Command definitions related to industries.
static WindowDesc _build_industry_desc(WDP_AUTO, "build_industry", 170, 212, WC_BUILD_INDUSTRY, WC_NONE, WindowDefaultFlag::Construction, _nested_build_industry_widgets)
Window definition of the dynamic place industries gui.
static constexpr std::initializer_list< NWidgetPart > _nested_industry_directory_widgets
Widget definition of the industry directory gui.
void ShowIndustryCargoesWindow()
Open the industry and cargoes window with an industry.
static void GetCargoSuffix(uint cargo, CargoSuffixType cst, const Industry *ind, IndustryType ind_type, const IndustrySpec *indspec, CargoSuffix &suffix)
Gets the string to display after the cargo name (using callback 37).
CargoSuffixType
Cargo suffix type (for which window is it requested).
@ View
View-industry window.
@ Fund
Fund-industry window.
@ Directory
Industry-directory window.
static const uint MAX_CARGOES
Maximum number of cargoes carried in a CargoesFieldType::Cargo field in CargoesField.
static WindowDesc _industry_directory_desc(WDP_AUTO, "list_industries", 428, 190, WC_INDUSTRY_DIRECTORY, WC_NONE, {}, _nested_industry_directory_widgets, &IndustryDirectoryWindow::hotkeys)
Window definition of the industry directory gui.
static WindowDesc _industry_cargoes_desc(WDP_AUTO, "industry_cargoes", 300, 210, WC_INDUSTRY_CARGOES, WC_NONE, {}, _nested_industry_cargoes_widgets)
Window description for the industry cargoes window.
static bool CargoFilter(const Industry *const *industry, const std::pair< CargoType, CargoType > &cargoes)
Cargo filter functions.
static WindowDesc _industry_view_desc(WDP_AUTO, "view_industry", 260, 120, WC_INDUSTRY_VIEW, WC_NONE, {}, _nested_industry_view_widgets)
Window definition of the view industry gui.
CargoSuffixDirection
Cargo direction for cargo suffixes.
@ Out
Get cargo suffix for output cargoes.
@ In
Get cargo suffix for input cargoes.
void GenerateIndustries()
This function will create random industries during game creation.
static bool IndustryTypeNameSorter(const IndustryType &a, const IndustryType &b)
Sort industry types by their name.
CargoSuffixDisplay
Ways of displaying the cargo.
@ AmountAndText
Display the cargo, amount, and string (cb37 result 000-3FF).
@ None
Display the cargo without sub-type (cb37 result 401).
@ Text
Display the cargo and supplied string (cb37 result 800-BFF).
@ Amount
Display the cargo and amount (if useful), but no sub-type (cb37 result 400 or fail).
std::array< IndustryType, NUM_INDUSTRYTYPES > _sorted_industry_types
Industry types sorted by name.
static void GetAllCargoSuffixes(CargoSuffixDirection use_input, CargoSuffixType cst, const Industry *ind, IndustryType ind_type, const IndustrySpec *indspec, const TC &cargoes, TS &suffixes)
Gets all strings to display after the cargoes of industries (using callback 37).
std::bitset< NUM_INDUSTRYTYPES > _displayed_industries
Communication from the industry chain window to the smallmap window about what industries to display.
static constexpr std::initializer_list< NWidgetPart > _nested_industry_view_widgets
Widget definition of the view industry gui.
CargoesFieldType
Available types of field.
@ SmallEmpty
Empty small field (for the header).
@ CargoLabel
Display cargo labels.
@ Industry
Display industry.
@ Cargo
Display cargo connections.
void SortIndustryTypes()
Initialize the list of sorted industry types.
static constexpr std::initializer_list< NWidgetPart > _nested_industry_cargoes_widgets
Widgets of the industry cargoes window.
static const int INDUSTRY_ORIGINAL_NUM_INPUTS
Original number of accepted cargo types.
static const IndustryType NUM_INDUSTRYTYPES
total number of industry types, new and old; limited to 240 because we need some special ids like IT_...
static const int INDUSTRY_ORIGINAL_NUM_OUTPUTS
Original number of produced cargo types.
@ CargoTypesUnlimited
Allow produced/accepted cargoes callbacks to supply more than 2 and 3 types.
#define Rect
Macro that prevents name conflicts between included headers.
#define Point
Macro that prevents name conflicts between included headers.
bool DoZoomInOutWindow(ZoomStateChange how, Window *w)
Zooms a viewport in a window in or out.
bool HandlePlacePushButton(Window *w, WidgetID widget, CursorID cursor, HighLightStyle mode)
This code is shared for the majority of the pushbuttons.
constexpr bool IsInsideBS(const T x, const size_t base, const size_t size)
Checks if a value is between a window started at some base point.
constexpr int RoundDivSU(int a, uint b)
Computes round(a / b) for signed a and unsigned b.
constexpr uint ToPercent8(uint i)
Converts a "fract" value 0..255 to "percent" value 0..100.
constexpr uint ClampU(const uint a, const uint min, const uint max)
Clamp an unsigned integer between an interval.
constexpr To ClampTo(From value)
Clamp the given value down to lie within the requested type.
void GuiShowTooltips(Window *parent, EncodedString &&text, TooltipCloseCondition close_tooltip)
Shows a tooltip.
void ShowQuery(EncodedString &&caption, EncodedString &&message, Window *parent, QueryCallbackProc *callback, bool focus)
Show a confirmation window with standard 'yes' and 'no' buttons The window is aligned to the centre o...
void ShowQueryString(std::string_view str, StringID caption, uint maxsize, Window *parent, CharSetFilter afilter, QueryStringFlags flags)
Show a query popup window with a textbox in it.
static constexpr CargoType CF_NONE
Show only items which do not carry cargo (e.g. train engines).
static constexpr CargoType CF_ANY
Show all items independent of carried cargo (i.e. no filtering).
bool _networking
are we in networking mode?
Basic functions/variables used all over the place.
Functions related to NewGRF badges.
int DrawBadgeNameList(Rect r, std::span< const BadgeID > badges, GrfSpecFeature)
Draw names for a list of badge labels.
void DrawBadgeColumn(Rect r, int column_group, const GUIBadgeClasses &gui_classes, std::span< const BadgeID > badges, GrfSpecFeature feature, std::optional< TimerGameCalendar::Date > introduction_date, PaletteID remap)
Draw a badge column group.
GUI functions related to NewGRF badges.
@ CargoSuffix
Show suffix after cargo name.
@ WindowMoreText
additional text in industry window
@ FundMoreText
additional text in fund window
@ Production256Ticks
call production callback every 256 ticks
@ ProductionCargoArrival
call production callback when cargo arrives at the industry
@ CargoSuffix
cargo sub-type display
@ CBID_INDUSTRY_WINDOW_MORE_TEXT
Called to determine more text in the industry window.
@ CBID_INDUSTRY_CARGO_SUFFIX
Called to determine text to display after cargo name.
@ CBID_INDUSTRY_FUND_MORE_TEXT
Called to determine more text in the fund industry window.
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
void ErrorUnknownCallbackResult(uint32_t grfid, uint16_t cbid, uint16_t cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
Functions/types related to NewGRF debugging.
uint16_t GetIndustryCallback(CallbackID callback, uint32_t param1, uint32_t param2, Industry *industry, IndustryType type, TileIndex tile, std::span< int32_t > regs100)
Perform an industry callback.
uint32_t GetIndustryProbabilityCallback(IndustryType type, IndustryAvailabilityCallType creation_type, uint32_t default_prob)
Check with callback CBID_INDUSTRY_PROBABILITY whether the industry can be built.
bool IndustryTemporarilyRefusesCargo(Industry *ind, CargoType cargo_type)
Check whether an industry temporarily refuses to accept a certain cargo.
Functions for NewGRF industries.
@ IACT_USERCREATION
from the Fund/build window
@ PSM_ENTER_GAMELOOP
Enter the gameloop, changes will be permanent.
@ PSM_LEAVE_GAMELOOP
Leave the gameloop, changes will be temporary.
std::string GetGRFStringWithTextStack(const struct GRFFile *grffile, GRFStringID grfstringid, std::span< const int32_t > textstack)
Format a GRF string using the text ref stack for parameters.
Header of Action 04 "universal holder" structure and functions.
StrongType::Typedef< uint32_t, struct GRFStringIDTag, StrongType::Compare, StrongType::Integer > GRFStringID
Type for GRF-internal string IDs.
static constexpr GRFStringID GRFSTR_MISC_GRF_TEXT
Miscellaneous GRF text range.
static constexpr PixelColour PC_YELLOW
Yellow palette colour.
static constexpr PixelColour PC_BLACK
Black palette colour.
static constexpr PixelColour PC_WHITE
White palette colour.
Base for the GUIs that have an edit box in them.
Pseudo random number generator.
A number of safeguards to prevent using unsafe methods.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
ClientSettings _settings_client
The current settings for this game.
void DrawArrowButtons(int x, int y, Colours button_colour, uint8_t state, bool clickable_left, bool clickable_right)
Draw [<][>] boxes.
Functions for setting GUIs.
#define SETTING_BUTTON_WIDTH
Width of setting buttons.
#define SETTING_BUTTON_HEIGHT
Height of setting buttons.
@ Off
Scroll wheel has no effect.
void ShowSmallMap()
Show the smallmap window.
Base types for having sorted lists in GUIs.
void SndClickBeep()
Play a beep sound for a click event if enabled in settings.
Functions related to sound.
Definition of base types and functions in a cross-platform compatible way.
#define lengthof(array)
Return the length of an fixed size array.
int StrNaturalCompare(std::string_view s1, std::string_view s2, bool ignore_garbage_at_front)
Compares two strings using case insensitive natural sort.
static std::optional< T > ParseInteger(std::string_view arg, int base=10, bool clamp=false)
Change a string into its number representation.
Functions related to low-level strings.
@ CS_ALPHANUMERAL
Both numeric and alphabetic and spaces and stuff.
Searching and filtering using a stringterm.
void GetStringWithArgs(StringBuilder &builder, StringID string, StringParameters &args, uint case_index, bool game_script)
Get a parsed string with most special stringcodes replaced by the string parameters.
std::string_view GetListSeparator()
Get the list separator string for the current language.
void AppendStringInPlace(std::string &result, StringID string)
Resolve the given StringID and append in place into an existing std::string with formatting but no pa...
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
TextDirection _current_text_dir
Text direction of the currently selected language.
uint64_t GetParamMaxDigits(uint count, FontSize size)
Get some number that is suitable for string size computations.
Functions related to OTTD's strings.
auto MakeParameters(Args &&... args)
Helper to create the StringParameters with its own buffer with the given parameter values.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
@ TD_RTL
Text is written right-to-left by default.
static const int MAX_CHAR_LENGTH
Max. length of UTF-8 encoded unicode character.
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
static void SwitchMode(PersistentStorageMode mode, bool ignore_prev_mode=false)
Clear temporary changes made since the last call to SwitchMode, and set whether subsequent changes sh...
Specification of a cargo type.
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo type.
SpriteID GetCargoIcon() const
Get sprite for showing cargo of this type.
static IterateWrapper Iterate(size_t from=0)
Returns an iterable ensemble of all valid CargoSpec.
StringID name
Name of this type of cargo.
TownProductionEffect town_production_effect
The effect on town cargo production.
Transfer storage of cargo suffix information.
std::string text
Cargo suffix text.
CargoSuffixDisplay display
How to display the cargo and text.
Comparator to sort CargoType by according to desired order.
Data about a single field in the IndustryCargoesWindow panel.
static const PixelColour CARGO_LINE_COLOUR
Line colour around the cargo.
StringID header
Header text (for CargoesFieldType::Header).
std::array< CargoType, MAX_CARGOES > cargoes
Cargoes to display (or INVALID_CARGO).
CargoesFieldType type
Type of field.
static int blob_distance
Distance of the industry legend colour from the edge of the industry box.
static Dimension cargo_border
Dimensions of border between cargo lines and industry boxes.
uint8_t top_end
Stop at the top of the vertical cargoes.
Cargoes cust_cargoes
Cargoes in vertical_cargoes leaving to the right.
int GetCargoBase(int xpos) const
For a CargoesFieldType::Cargo, compute the left position of the left-most vertical cargo connection.
std::array< CargoType, MAX_CARGOES > other_accepted
Cargoes accepted but not used in this figure.
int ConnectCargo(CargoType cargo, bool producer)
Connect a cargo from an industry to the CargoesFieldType::Cargo column.
static int small_height
Height of the header row.
CargoType CargoLabelClickedAt(Point pt) const
Decide what cargo the user clicked in the cargo label field.
static Dimension cargo_space
Dimensions of space between cargo lines.
static int normal_height
Height of the non-header rows.
static int cargo_field_width
Width of a cargo field.
bool left_align
Align all cargo texts to the left (else align to the right).
static uint max_cargoes
Largest number of cargoes actually on any industry.
bool HasConnection()
Does this CargoesFieldType::Cargo field have a horizontal connection?
static Dimension cargo_line
Dimensions of cargo lines.
void MakeIndustry(IndustryType ind_type)
Make an industry type field.
static void DrawHorConnection(int left, int right, int top, const CargoSpec *csp)
Draw a horizontal cargo connection.
IndustryType ind_type
Industry type (NUM_INDUSTRYTYPES means 'houses').
struct CargoesField::@163200273102357245024106251007063276336245070176::@243103260313115260077253264317120110047327036000 cargo_label
Label data (for CargoesFieldType::CargoLabel).
struct CargoesField::@163200273102357245024106251007063276336245070176::@267143254045067360107006147207152052155243026163 cargo
Cargo data (for CargoesFieldType::Cargo).
static int vert_inter_industry_space
Amount of space between two industries in a column.
static Dimension cargo_stub
Dimensions of cargo stub (unconnected cargo line.).
static Dimension legend
Dimension of the legend blob.
void MakeCargo(const std::span< const CargoType > cargoes)
Make a piece of cargo column.
Cargoes supp_cargoes
Cargoes in vertical_cargoes entering from the left.
static const PixelColour INDUSTRY_LINE_COLOUR
Line colour of the industry type box.
CargoType CargoClickedAt(const CargoesField *left, const CargoesField *right, Point pt) const
Decide which cargo was clicked at in a CargoesFieldType::Cargo field.
union CargoesField::@163200273102357245024106251007063276336245070176 u
Data for each type.
void Draw(int xpos, int ypos) const
Draw the field.
std::array< CargoType, MAX_CARGOES > other_produced
Cargoes produced but not used in this figure.
static int industry_width
Width of an industry field.
std::array< CargoType, MAX_CARGOES > vertical_cargoes
Cargoes running from top to bottom (cargo type or INVALID_CARGO).
uint8_t num_cargoes
Number of cargoes.
void MakeHeader(StringID textid)
Make a header above an industry column.
uint8_t bottom_end
Stop at the bottom of the vertical cargoes.
void MakeCargoLabel(const std::span< const CargoType > cargoes, bool left_align)
Make a field displaying cargo type names.
void MakeEmpty(CargoesFieldType type)
Make one of the empty fields (CargoesFieldType::Empty or CargoesFieldType::SmallEmpty).
struct CargoesField::@163200273102357245024106251007063276336245070176::@002015101225166035271011323266367366265233313323 industry
Industry data (for CargoesFieldType::Industry).
A single row of CargoesField.
CargoesField columns[5]
One row of fields.
void ConnectIndustryProduced(int column)
Connect industry production cargoes to the cargo column after it.
void ConnectIndustryAccepted(int column)
Connect industry accepted cargoes to the cargo column before it.
void MakeCargoLabel(int column, bool accepting)
Construct a CargoesFieldType::CargoLabel field.
Dimensions (a width and height) of a rectangle in 2D.
Data about how and where to blit pixels.
const struct GRFFile * grffile
grf file that introduced this entity
uint32_t grfid
grfid that introduced this entity.
bool HasGrfFile() const
Test if this entity was introduced by NewGRF.
std::array< uint8_t, NUM_CARGO > cargo_map
Inverse cargo translation table (CargoType -> local ID).
List of hotkeys for a window.
All data for a single hotkey.
static std::vector< HouseSpec > & Specs()
Get a reference to all HouseSpecs.
Window displaying the cargo connections around an industry (or cargo).
Dimension cargo_textsize
Size to hold any cargo text, as well as STR_INDUSTRY_CARGOES_SELECT_CARGO.
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
void OnInit() override
Notification that the nested widget tree gets initialized.
static bool HousesCanSupply(const std::span< const CargoType > cargoes)
Can houses be used to supply one of the cargoes?
bool OnTooltip(Point pt, WidgetID widget, TooltipCloseCondition close_cond) override
Event to display a custom tooltip.
Dimension ind_textsize
Size to hold any industry type text, as well as STR_INDUSTRY_CARGOES_SELECT_INDUSTRY.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
void ShortenCargoColumn(int column, int top, int bottom)
Shorten the cargo column to just the part between industries.
static int CountMatchingAcceptingIndustries(const std::span< const CargoType > cargoes)
Count how many industries have accepted cargoes in common with one of the supplied set.
void PlaceIndustry(int row, int col, IndustryType it)
Place an industry in the fields.
void OnResize() override
Called after the window got resized.
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
Fields fields
Fields to display in the WID_IC_PANEL.
static int CountMatchingProducingIndustries(const std::span< const CargoType > cargoes)
Count how many industries have produced cargoes in common with one of the supplied set.
void ComputeIndustryDisplay(IndustryType displayed_it)
Compute what and where to display for industry type it.
void NotifySmallmap()
Notify smallmap that new displayed industries have been selected (in _displayed_industries).
bool CalculatePositionInWidget(Point pt, Point *fieldxy, Point *xy)
Calculate in which field was clicked, and within the field, at what position.
void ComputeCargoDisplay(CargoType cargo_type)
Compute what and where to display for cargo type cargo_type.
uint ind_cargo
If less than NUM_INDUSTRYTYPES, an industry type, else a cargo type + NUM_INDUSTRYTYPES.
static bool HasCommonValidCargo(const std::span< const CargoType > cargoes1, const std::span< const CargoType > cargoes2)
Do the two sets of cargoes have a valid cargo in common?
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
static bool HousesCanAccept(const std::span< const CargoType > cargoes)
Can houses be used as customers of the produced cargoes?
void OnDropdownSelect(WidgetID widget, int index, int) override
A dropdown option associated to this window has been selected.
Defines the data structure for constructing industry.
IndustryCallbackMasks callback_mask
Bitmask of industry callbacks that have to be called.
std::array< CargoType, INDUSTRY_NUM_INPUTS > accepts_cargo
16 accepted cargoes.
bool UsesOriginalEconomy() const
Determines whether this industrytype uses standard/newgrf production changes.
SubstituteGRFFileProps grf_prop
properties related to the grf file
StringID name
Displayed name of the industry.
bool IsRawIndustry() const
Is an industry with the spec a raw industry?
IndustryBehaviours behaviour
How this industry will behave, and how others entities can use it.
std::vector< IndustryTileLayout > layouts
List of possible tile layouts for the industry.
bool enabled
entity still available (by default true).newgrf can disable it, though
Money GetConstructionCost() const
Get the cost for constructing this industry.
PixelColour map_colour
colour used for the small map
CargoType cargo
Cargo type.
uint16_t waiting
Amount of cargo waiting to processed.
CargoType cargo
Cargo type.
HistoryData< ProducedHistory > history
History of cargo produced and transported for this month and 24 previous months.
Defines the internal data of a functional industry.
IndustryType type
type of industry.
bool IsCargoAccepted() const
Test if this industry accepts any cargo.
uint8_t prod_level
general production level
void RecomputeProductionMultipliers()
Recompute production_rate for current prod_level.
EncodedString text
General text with additional information.
ProducedCargoes::iterator GetCargoProduced(CargoType cargo)
Get produced cargo slot for a specific cargo type.
ProducedCargoes produced
produced cargo slots
AcceptedCargoes accepted
accepted cargo slots
static uint16_t GetIndustryTypeCount(IndustryType type)
Get the count of industries for this type.
TileArea location
Location of the industry.
bool IsCargoProduced() const
Test if this industry produces any cargo.
Data structure describing how to show the list (what sort direction and criteria).
static IterateWrapper Iterate()
Returns an iterable ensemble of all Tiles.
TileIndex GetCenterTile() const
Get the center tile.
TileIndex tile
The base tile of the area.
Colour for pixel/line drawing.
static Pool::IterateWrapper< Industry > Iterate(size_t from=0)
static Industry * Get(auto index)
static size_t GetNumItems()
static bool IsValidID(auto index)
Data stored about a string that can be modified in the GUI.
int cancel_button
Widget button of parent window to simulate when pressing CANCEL in OSK.
static const int ACTION_CLEAR
Clear editbox.
Specification of a rectangle with absolute coordinates of all edges.
Rect WithWidth(int width, bool end) const
Copy Rect and set its width.
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
Rect WithHeight(int height, bool end=false) const
Copy Rect and set its height.
Rect Indent(int indent, bool end) const
Copy Rect and indent it from its position.
Rect Translate(int x, int y) const
Copy and translate Rect by x,y pixels.
bool Contains(const Point &pt) const
Test if a point falls inside this Rect.
bool IsEmpty() const
Check whether any filter words were entered.
void SetFilterTerm(std::string_view str)
Set the term to filter on.
void ResetState()
Reset the matching state to process a new item.
bool GetState() const
Get the matching state of the current item.
std::string_view GetText() const
Get the current text.
High level window description.
Number to differentiate different windows of the same class.
Data structure for an opened window.
void ReInit(int rx=0, int ry=0, bool reposition=false)
Re-initialize a window, and optionally change its size.
static int SortButtonWidth()
Get width of up/down arrow of sort button state.
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
std::map< WidgetID, QueryString * > querystrings
QueryString associated to WWT_EDITBOX widgets.
void DrawWidgets() const
Paint all widgets of a window.
void InvalidateData(int data=0, bool gui_scope=true)
Mark this window's data as invalid (in need of re-computing).
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
std::unique_ptr< ViewportData > viewport
Pointer to viewport data, if present.
virtual std::string GetWidgetString(WidgetID widget, StringID stringid) const
Get the raw string for a widget.
void RaiseWidgetWhenLowered(WidgetID widget_index)
Marks a widget as raised and dirty (redraw), when it is marked as lowered.
void DrawSortButtonState(WidgetID widget, SortButtonState state) const
Draw a sort button's up or down arrow symbol.
ResizeInfo resize
Resize information.
void DisableWidget(WidgetID widget_index)
Sets a widget to disabled.
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
bool IsWidgetLowered(WidgetID widget_index) const
Gets the lowered state of a widget.
void RaiseButtons(bool autoraise=false)
Raise the buttons of the window.
bool IsShaded() const
Is window shaded currently?
void SetTimeout()
Set the timeout flag of the window and initiate the timer.
int top
y position of top edge of the window
Window(WindowDesc &desc)
Empty constructor, initialization has been moved to InitNested() called from the constructor of the d...
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
void HandleButtonClick(WidgetID widget)
Do all things to make a button look clicked and mark it to be unclicked in a few ticks.
void InitNested(WindowNumber number=0)
Perform complete initialization of the Window with nested widgets, to allow use.
WindowFlags flags
Window flags.
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
int height
Height of the window (number of pixels down in y direction).
int width
width of the window (number of pixels to the right in x direction)
void ToggleWidgetLoweredState(WidgetID widget_index)
Invert the lowered/raised status of a widget.
WindowNumber window_number
Window number within the window class.
Stuff related to the text buffer GUI.
static bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > > TileIndex
The index/ID of a Tile.
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
@ Clear
A tile without any structures, i.e. grass, rocks, farm fields etc.
Functions related to tile highlights.
void ResetObjectToPlace()
Reset the cursor and mouse mode handling back to default (normal cursor, only clicking in windows).
@ HT_RECT
rectangle (stations, depots, ...)
Definition of Interval and OneShot timers.
Definition of the Window system.
bool ScrollWindowToTile(TileIndex tile, Window *w, bool instant)
Scrolls the viewport in a window to a given location.
bool ScrollMainWindowToTile(TileIndex tile, bool instant)
Scrolls the viewport of the main window to a given location.
Functions related to (drawing on) viewports.
@ ZOOM_IN
Zoom in (get more detailed view).
@ ZOOM_OUT
Zoom out (get helicopter view).
void CloseWindowById(WindowClass cls, WindowNumber number, bool force, int data)
Close a window by its class and window number (if it is open).
Window * FindWindowByClass(WindowClass cls)
Find any window by its class.
Window * BringWindowToFrontById(WindowClass cls, WindowNumber number)
Find a window and make it the relative top-window on the screen.
void InvalidateWindowClassesData(WindowClass cls, int data, bool gui_scope)
Mark window data of all windows of a given class as invalid (in need of re-computing) Note that by de...
Window functions not directly related to making/drawing windows.
@ Construction
This window is used for construction; close it whenever changing company.
Twindow * AllocateWindowDescFront(WindowDesc &desc, WindowNumber window_number, Targs... extra_arguments)
Open a new window.
@ DisableVpScroll
Window does not do autoscroll,.
@ SBS_DOWN
Sort ascending.
@ WDP_AUTO
Find a place automatically.
@ WC_INDUSTRY_DIRECTORY
Industry directory; Window numbers:
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
@ WC_INDUSTRY_CARGOES
Industry cargoes chain; Window numbers:
@ WC_INDUSTRY_PRODUCTION
Industry production history graph; Window numbers:
@ WC_INDUSTRY_VIEW
Industry view; Window numbers:
@ WC_SMALLMAP
Small map; Window numbers:
@ WC_BUILD_INDUSTRY
Build industry; Window numbers:
Functions related to zooming.
ZoomLevel ScaleZoomGUI(ZoomLevel value)
Scale zoom level relative to GUI zoom.
@ Industry
Default zoom level for the industry view.