51 #include "table/strings.h"
57 bool _ignore_restrictions;
104 if (
GB(callback, 0, 8) == 0xFF)
return;
105 if (callback < 0x400) {
116 if (callback == 0x400)
return;
117 if (callback == 0x401) {
121 if (callback < 0x400) {
128 if (callback >= 0x800 && callback < 0xC00) {
141 enum CargoSuffixInOut {
156 template <
typename TC,
typename TS>
159 static_assert(std::tuple_size_v<std::remove_reference_t<decltype(cargoes)>> <=
lengthof(suffixes));
163 for (uint j = 0; j <
lengthof(suffixes); j++) {
166 uint cargotype = local_id << 16 | use_input;
167 GetCargoSuffix(cargotype, cst, ind, ind_type, indspec, suffixes[j]);
169 suffixes[j].text.clear();
175 for (uint j = 0; j <
lengthof(suffixes); j++) {
176 suffixes[j].text.clear();
180 case CARGOSUFFIX_OUT:
215 uint cargotype = local_id << 16 | use_input;
217 }
else if (use_input == CARGOSUFFIX_IN) {
219 }
else if (use_input == CARGOSUFFIX_OUT) {
232 return (r != 0) ? r < 0 : (a < b);
268 static constexpr
NWidgetPart _nested_build_industry_widgets[] = {
279 SetDataTip(STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES, STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_TOOLTIP),
281 SetDataTip(STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES, STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES_TOOLTIP),
285 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),
292 SetDataTip(STR_INDUSTRY_DISPLAY_CHAIN, STR_INDUSTRY_DISPLAY_CHAIN_TOOLTIP),
300 WDP_AUTO,
"build_industry", 170, 212,
303 _nested_build_industry_widgets
309 std::vector<IndustryType>
list;
317 void UpdateAvailability()
342 this->list.push_back(ind);
347 if (this->selected_type ==
INVALID_INDUSTRYTYPE && !this->list.empty()) this->selected_type = this->list[0];
349 this->UpdateAvailability();
351 this->vscroll->
SetCount(this->list.size());
373 std::string
MakeCargoListString(
const std::span<const CargoID> cargolist,
const std::span<const CargoSuffix> cargo_suffix,
StringID prefixstr)
const
375 assert(cargolist.size() == cargo_suffix.size());
377 std::string cargostring;
379 size_t firstcargo = 0;
381 for (
size_t j = 0; j < cargolist.size(); j++) {
396 cargostring =
GetString(prefixstr) + cargostring;
414 if (_game_mode != GM_EDITOR) {
426 this->legend.width = this->legend.height * 9 / 6;
438 for (
const auto &indtype : this->list) {
441 resize.height = std::max<uint>({this->legend.height, d.height, count.height}) + padding.height;
443 d.height = 5 *
resize.height;
450 int height = 2 + (_game_mode == GM_EDITOR ? 0 : 1);
451 uint extra_lines_req = 0;
452 uint extra_lines_prd = 0;
453 uint extra_lines_newgrf = 0;
456 for (
const auto &indtype : this->list) {
464 if (strdim.width > max_minwidth) {
465 extra_lines_req = std::max(extra_lines_req, strdim.width / max_minwidth + 1);
466 strdim.width = max_minwidth;
472 cargostring = this->
MakeCargoListString(indsp->produced_cargo, cargo_suffix, STR_INDUSTRY_VIEW_PRODUCES_N_CARGO);
474 if (strdim.width > max_minwidth) {
475 extra_lines_prd = std::max(extra_lines_prd, strdim.width / max_minwidth + 1);
476 strdim.width = max_minwidth;
482 extra_lines_newgrf = 4;
487 height += extra_lines_prd + extra_lines_req + extra_lines_newgrf;
489 size.width = d.width + padding.width;
497 d.width += padding.width;
498 d.height += padding.height;
505 void SetStringParameters(
WidgetID widget)
const override
511 if (_game_mode == GM_EDITOR) {
513 SetDParam(0, STR_FUND_INDUSTRY_BUILD_NEW_INDUSTRY);
519 SetDParam(0, STR_FUND_INDUSTRY_FUND_NEW_INDUSTRY);
526 void DrawWidget(
const Rect &r,
WidgetID widget)
const override
536 icon.top = r.top + (this->resize.step_height - this->legend.height + 1) / 2;
537 icon.bottom = icon.top + this->legend.height - 1;
540 for (
auto it = first; it != last; ++it) {
541 IndustryType type = *it;
542 bool selected = this->selected_type == type;
552 text = text.
Translate(0, this->resize.step_height);
553 icon = icon.
Translate(0, this->resize.step_height);
568 if (_game_mode != GM_EDITOR) {
570 DrawString(ir, STR_FUND_INDUSTRY_INDUSTRY_BUILD_COST);
583 cargostring = this->
MakeCargoListString(indsp->produced_cargo, cargo_suffix, STR_INDUSTRY_VIEW_PRODUCES_N_CARGO);
590 if (callback_res > 0x400) {
594 if (str != STR_UNDEFINED) {
607 static void AskManyRandomIndustriesCallback(
Window *,
bool confirmed)
609 if (!confirmed)
return;
618 old_generating_world.Restore();
622 static void AskRemoveAllIndustriesCallback(
Window *,
bool confirmed)
624 if (!confirmed)
return;
638 void OnClick([[maybe_unused]]
Point pt,
WidgetID widget, [[maybe_unused]]
int click_count)
override
642 assert(_game_mode == GM_EDITOR);
644 ShowQuery(STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_CAPTION, STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_QUERY,
nullptr, AskManyRandomIndustriesCallback);
649 assert(_game_mode == GM_EDITOR);
651 ShowQuery(STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES_CAPTION, STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES_QUERY,
nullptr, AskRemoveAllIndustriesCallback);
657 if (it != this->list.end()) {
658 this->selected_type = *it;
659 this->UpdateAvailability();
702 void OnPlaceObject([[maybe_unused]]
Point pt,
TileIndex tile)
override
707 uint32_t seed = InteractiveRandom();
708 uint32_t layout_index = InteractiveRandomRange((uint32_t)indsp->
layouts.size());
710 if (_game_mode == GM_EDITOR) {
720 _ignore_restrictions =
true;
724 cur_company.Restore();
725 old_generating_world.Restore();
726 _ignore_restrictions =
false;
736 if (_game_mode == GM_EDITOR)
return;
740 this->UpdateAvailability();
741 if (
enabled != this->enabled) {
762 void OnInvalidateData([[maybe_unused]]
int data = 0, [[maybe_unused]]
bool gui_scope =
true)
override
764 if (!gui_scope)
return;
771 void ShowBuildIndustryWindow()
778 static void UpdateIndustryProduction(
Industry *i);
780 static inline bool IsProductionAlterable(
const Industry *i)
783 bool has_prod = std::any_of(std::begin(is->production_rate), std::end(is->production_rate), [](
auto rate) { return rate != 0; });
821 this->clicked_button = 0;
852 const Rect r = this->GetWidget<NWidgetBase>(
WID_IV_INFO)->GetCurrentRect();
854 if (expected != r.bottom) {
855 this->info_height = expected - r.top + 1;
861 void DrawCargoIcon(
const Rect &r,
CargoID cid)
const
882 bool has_accept =
false;
885 DrawString(ir, STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE);
901 DrawCargoIcon(ir, a.cargo);
916 str = stockpiling ? STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT : STR_INDUSTRY_VIEW_ACCEPT_CARGO;
923 str = STR_INDUSTRY_VIEW_ACCEPT_CARGO;
943 if (this->editable ==
EA_RATE) this->production_offset_y = ir.top;
947 DrawCargoIcon(ir, p.cargo);
953 SetDParam(1, p.history[LAST_MONTH].production);
958 if (this->editable ==
EA_RATE) {
960 p.rate > 0, p.rate < 255);
962 ir.top += line_height;
971 this->production_offset_y = ir.top;
976 ir.top += line_height;
983 if (callback_res > 0x400) {
987 if (message != STR_NULL && message != STR_UNDEFINED) {
1001 if (!i->
text.empty()) {
1004 ir.top =
DrawStringMultiLine(ir.left, ir.right, ir.top, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK);
1011 void SetStringParameters(
WidgetID widget)
const override
1021 void OnClick([[maybe_unused]]
Point pt,
WidgetID widget, [[maybe_unused]]
int click_count)
override
1028 switch (this->editable) {
1036 if (pt.y >= this->production_offset_y) {
1038 for (
auto itp = std::begin(i->
produced); itp != std::end(i->
produced); ++itp) {
1057 switch (this->editable) {
1080 default: NOT_REACHED();
1083 UpdateIndustryProduction(i);
1086 this->clicked_line = line;
1087 this->clicked_button = (decrease ^ rtl) ? 1 : 2;
1090 this->editbox_line = line;
1091 switch (this->editable) {
1102 default: NOT_REACHED();
1133 this->clicked_button = 0;
1147 void OnMouseWheel(
int wheel)
override
1154 void OnQueryTextFinished(std::optional<std::string> str)
override
1156 if (!str.has_value() || str->empty())
return;
1159 uint value = atoi(str->c_str());
1160 switch (this->editbox_line) {
1171 UpdateIndustryProduction(i);
1180 void OnInvalidateData([[maybe_unused]]
int data = 0, [[maybe_unused]]
bool gui_scope =
true)
override
1182 if (!gui_scope)
return;
1184 if (IsProductionAlterable(i)) {
1203 static void UpdateIndustryProduction(
Industry *i)
1242 WDP_AUTO,
"view_industry", 260, 120,
1248 void ShowIndustryViewWindow(
int industry)
1296 auto accepted_cargo = cargoes.first;
1297 auto produced_cargo = cargoes.second;
1299 bool accepted_cargo_matches;
1301 switch (accepted_cargo) {
1303 accepted_cargo_matches =
true;
1307 accepted_cargo_matches = !(*industry)->IsCargoAccepted();
1311 accepted_cargo_matches = (*industry)->IsCargoAccepted(accepted_cargo);
1315 bool produced_cargo_matches;
1317 switch (produced_cargo) {
1319 produced_cargo_matches =
true;
1323 produced_cargo_matches = !(*industry)->IsCargoProduced();
1327 produced_cargo_matches = (*industry)->IsCargoProduced(produced_cargo);
1331 return accepted_cargo_matches && produced_cargo_matches;
1349 static inline const StringID sorter_names[] = {
1352 STR_SORT_BY_PRODUCTION,
1353 STR_SORT_BY_TRANSPORTED,
1355 static const std::initializer_list<GUIIndustryList::SortFunction * const> sorter_funcs;
1357 GUIIndustryList industries{IndustryDirectoryWindow::produced_cargo_filter};
1363 static CargoID produced_cargo_filter;
1382 if (this->produced_cargo_filter_criteria != cid) {
1383 this->produced_cargo_filter_criteria = cid;
1399 if (this->accepted_cargo_filter_criteria != cid) {
1400 this->accepted_cargo_filter_criteria = cid;
1441 for (
const Industry *i : this->industries) {
1451 this->industries.clear();
1455 if (this->string_filter.
IsEmpty()) {
1456 this->industries.push_back(i);
1460 this->string_filter.
AddLine(i->GetCachedName());
1461 if (this->string_filter.
GetState()) this->industries.push_back(i);
1466 auto filter = std::make_pair(this->accepted_cargo_filter_criteria, this->produced_cargo_filter_criteria);
1468 this->industries.
Filter(filter);
1471 this->vscroll->
SetCount(this->industries.size());
1475 this->industries.
Sort();
1501 CargoID filter = IndustryDirectoryWindow::produced_cargo_filter;
1504 int percentage = 0, produced_cargo_count = 0;
1505 for (
const auto &p : i->
produced) {
1508 if (transported != -1) {
1509 produced_cargo_count++;
1510 percentage += transported;
1512 if (produced_cargo_count == 0 && &p == &i->
produced.back() && percentage == 0) {
1515 }
else if (filter == p.cargo) {
1520 if (produced_cargo_count == 0)
return percentage;
1521 return percentage / produced_cargo_count;
1539 int r = it_a - it_b;
1548 uint prod_a = 0, prod_b = 0;
1550 for (
const auto &pa : a->
produced) {
1551 if (
IsValidCargoID(pa.cargo)) prod_a += pa.history[LAST_MONTH].production;
1553 for (
const auto &pb : b->
produced) {
1554 if (
IsValidCargoID(pb.cargo)) prod_b += pb.history[LAST_MONTH].production;
1557 if (
auto ita = a->
GetCargoProduced(filter); ita != std::end(a->
produced)) prod_a = ita->history[LAST_MONTH].production;
1558 if (
auto itb = b->
GetCargoProduced(filter); itb != std::end(b->
produced)) prod_b = itb->history[LAST_MONTH].production;
1560 int r = prod_a - prod_b;
1588 uint16_t production;
1592 CargoInfo(
CargoID cargo_id, uint16_t production, uint transported, std::string &&suffix) : cargo_id(cargo_id), production(production), transported(transported), suffix(std::move(suffix)) {}
1594 std::vector<CargoInfo> cargos;
1596 for (
auto itp = std::begin(i->
produced); itp != std::end(i->
produced); ++itp) {
1600 cargos.emplace_back(itp->cargo, itp->history[LAST_MONTH].production,
ToPercent8(itp->history[LAST_MONTH].PctTransported()), std::move(cargo_suffix.
text));
1608 std::sort(cargos.begin(), cargos.end(), [](
const CargoInfo &a,
const CargoInfo &b) {
1609 if (a.production != b.production) return a.production > b.production;
1610 return a.transported > b.transported;
1616 std::sort(cargos.begin(), cargos.end(), [](
const CargoInfo &a,
const CargoInfo &b) {
1617 if (a.transported != b.transported) return a.transported > b.transported;
1618 return a.production > b.production;
1627 auto filtered_ci = std::find_if(cargos.begin(), cargos.end(), [cid](
const CargoInfo &ci) ->
bool {
1628 return ci.cargo_id == cid;
1630 if (filtered_ci != cargos.end()) {
1631 std::rotate(cargos.begin(), filtered_ci, filtered_ci + 1);
1636 for (
size_t j = 0; j < std::min<size_t>(3, cargos.size()); j++) {
1637 CargoInfo &ci = cargos[j];
1638 SetDParam(p++, STR_INDUSTRY_DIRECTORY_ITEM_INFO);
1649 switch (cargos.size()) {
1650 case 0:
return STR_INDUSTRY_DIRECTORY_ITEM_NOPROD;
1651 case 1:
return STR_INDUSTRY_DIRECTORY_ITEM_PROD1;
1652 case 2:
return STR_INDUSTRY_DIRECTORY_ITEM_PROD2;
1653 case 3:
return STR_INDUSTRY_DIRECTORY_ITEM_PROD3;
1654 default:
return STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE;
1665 this->industries.
SetListing(this->last_sorting);
1666 this->industries.
SetSortFuncs(IndustryDirectoryWindow::sorter_funcs);
1679 this->last_sorting = this->industries.
GetListing();
1687 void SetStringParameters(
WidgetID widget)
const override
1696 SetDParam(0, IndustryDirectoryWindow::sorter_names[this->industries.
SortType()]);
1700 SetDParam(0, this->GetCargoFilterLabel(this->accepted_cargo_filter_criteria));
1704 SetDParam(0, this->GetCargoFilterLabel(this->produced_cargo_filter_criteria));
1709 void DrawWidget(
const Rect &r,
WidgetID widget)
const override
1723 tmp_dpi.left += ir.left;
1724 tmp_dpi.top += ir.top;
1730 if (this->industries.empty()) {
1736 for (
auto it = first; it != last; ++it) {
1746 ir.top += this->resize.step_height;
1759 d.height += padding.height;
1766 d.width += padding.width;
1767 d.height += padding.height;
1774 resize.height = d.height;
1776 d.width += padding.width;
1777 d.height += padding.height;
1796 list.push_back(MakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index()));
1802 void OnClick([[maybe_unused]]
Point pt,
WidgetID widget, [[maybe_unused]]
int click_count)
override
1815 ShowDropDownList(
this, this->BuildCargoDropDownList(), this->accepted_cargo_filter_criteria, widget);
1819 ShowDropDownList(
this, this->BuildCargoDropDownList(), this->produced_cargo_filter_criteria, widget);
1824 if (it != this->industries.end()) {
1836 void OnDropdownSelect(
WidgetID widget,
int index)
override
1840 if (this->industries.
SortType() != index) {
1867 void OnEditboxChanged(
WidgetID wid)
override
1892 void OnInvalidateData([[maybe_unused]]
int data = 0, [[maybe_unused]]
bool gui_scope =
true)
override
1895 case IDIWD_FORCE_REBUILD:
1900 case IDIWD_PRODUCTION_CHANGE:
1923 static inline HotkeyList hotkeys {
"industrydirectory", {
1928 Listing IndustryDirectoryWindow::last_sorting = {
false, 0};
1931 const std::initializer_list<GUIIndustryList::SortFunction * const> IndustryDirectoryWindow::sorter_funcs = {
1932 &IndustryNameSorter,
1933 &IndustryTypeSorter,
1934 &IndustryProductionSorter,
1935 &IndustryTransportedCargoSorter
1943 WDP_AUTO,
"list_industries", 428, 190,
1947 &IndustryDirectoryWindow::hotkeys
1950 void ShowIndustryDirectory()
1970 SetDataTip(STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP, STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP_TOOLTIP),
1973 SetDataTip(STR_INDUSTRY_CARGOES_SELECT_INDUSTRY, STR_INDUSTRY_CARGOES_SELECT_INDUSTRY_TOOLTIP),
1975 SetDataTip(STR_INDUSTRY_CARGOES_SELECT_CARGO, STR_INDUSTRY_CARGOES_SELECT_CARGO_TOOLTIP),
1982 WDP_AUTO,
"industry_cargoes", 300, 210,
2019 using Cargoes = uint16_t;
2020 static_assert(std::numeric_limits<Cargoes>::digits >=
MAX_CARGOES);
2061 this->u.industry.ind_type =
ind_type;
2062 std::fill(std::begin(this->u.industry.other_accepted), std::end(this->u.industry.other_accepted), INVALID_CARGO);
2063 std::fill(std::begin(this->u.industry.other_produced), std::end(this->u.industry.other_produced), INVALID_CARGO);
2079 for (
int i = 0; i < this->u.cargo.num_cargoes; i++) {
2080 if (
cargo == this->u.cargo.vertical_cargoes[i]) {
2085 if (column < 0)
return -1;
2088 assert(!
HasBit(this->u.cargo.supp_cargoes, column));
2089 SetBit(this->u.cargo.supp_cargoes, column);
2091 assert(!
HasBit(this->u.cargo.cust_cargoes, column));
2092 SetBit(this->u.cargo.cust_cargoes, column);
2105 return this->u.cargo.supp_cargoes != 0 || this->u.cargo.cust_cargoes != 0;
2116 assert(std::size(
cargoes) <= std::size(this->u.cargo.vertical_cargoes));
2118 this->u.cargo.num_cargoes =
static_cast<uint8_t
>(std::distance(std::begin(this->u.cargo.vertical_cargoes), insert));
2120 std::sort(std::begin(this->u.cargo.vertical_cargoes), insert, comparator);
2121 std::fill(insert, std::end(this->u.cargo.vertical_cargoes), INVALID_CARGO);
2122 this->u.cargo.top_end =
false;
2123 this->u.cargo.bottom_end =
false;
2124 this->u.cargo.supp_cargoes = 0;
2125 this->u.cargo.cust_cargoes = 0;
2136 assert(std::size(
cargoes) <= std::size(this->u.cargo_label.cargoes));
2137 auto insert = std::copy(std::begin(
cargoes), std::end(
cargoes), std::begin(this->u.cargo_label.cargoes));
2138 std::fill(insert, std::end(this->u.cargo_label.cargoes), INVALID_CARGO);
2149 this->u.header = textid;
2160 int n = this->u.cargo.num_cargoes;
2170 void Draw(
int xpos,
int ypos)
const
2172 switch (this->type) {
2193 int blob_left, blob_right;
2208 std::span<const CargoID> other_right, other_left;
2210 other_right = this->u.industry.other_accepted;
2211 other_left = this->u.industry.other_produced;
2213 other_right = this->u.industry.other_produced;
2214 other_left = this->u.industry.other_accepted;
2239 int colpos = cargo_base;
2240 for (
int i = 0; i < this->u.cargo.num_cargoes; i++) {
2252 Cargoes hor_left, hor_right;
2254 hor_left = this->u.cargo.cust_cargoes;
2255 hor_right = this->u.cargo.supp_cargoes;
2257 hor_left = this->u.cargo.supp_cargoes;
2258 hor_right = this->u.cargo.cust_cargoes;
2262 if (
HasBit(hor_left, i)) {
2266 for (; col > 0; col--) {
2273 if (
HasBit(hor_right, i)) {
2277 for (; col < this->u.cargo.num_cargoes - 1; col++) {
2320 for (col = 0; col < this->u.cargo.num_cargoes; col++) {
2321 if (pt.x < cpos)
break;
2330 if (pt.y < vpos)
return INVALID_CARGO;
2338 if (
HasBit(this->u.cargo.supp_cargoes, row))
return this->u.cargo.vertical_cargoes[row];
2339 if (left !=
nullptr) {
2343 return INVALID_CARGO;
2345 if (col == this->u.cargo.num_cargoes) {
2346 if (
HasBit(this->u.cargo.cust_cargoes, row))
return this->u.cargo.vertical_cargoes[row];
2347 if (right !=
nullptr) {
2351 return INVALID_CARGO;
2358 if (
HasBit(this->u.cargo.supp_cargoes, row))
return this->u.cargo.vertical_cargoes[row];
2359 return INVALID_CARGO;
2362 if (
HasBit(this->u.cargo.cust_cargoes, row))
return this->u.cargo.vertical_cargoes[row];
2363 return INVALID_CARGO;
2378 if (pt.y < vpos)
return INVALID_CARGO;
2383 return this->u.cargo_label.cargoes[row];
2402 static_assert(
MAX_CARGOES >= std::tuple_size_v<decltype(IndustrySpec::produced_cargo)>);
2437 std::fill(std::begin(ind_fld->u.
industry.other_produced), std::end(ind_fld->u.
industry.other_produced), INVALID_CARGO);
2441 int other_count = 0;
2446 int col = cargo_fld->
ConnectCargo(indsp->produced_cargo[i],
true);
2447 if (col < 0) others[other_count++] = indsp->produced_cargo[i];
2451 for (uint i = 0; i < CargoesField::max_cargoes && other_count > 0; i++) {
2452 if (
HasBit(cargo_fld->u.
cargo.supp_cargoes, i)) ind_fld->u.
industry.other_produced[i] = others[--other_count];
2456 for (uint i = 0; i < cargo_fld->u.
cargo.num_cargoes; i++) {
2472 std::fill(std::begin(cargoes), std::end(cargoes), INVALID_CARGO);
2475 CargoesField *cargo_fld = this->columns + (accepting ? column - 1 : column + 1);
2478 for (uint i = 0; i < cargo_fld->u.
cargo.num_cargoes; i++) {
2479 int col = cargo_fld->
ConnectCargo(cargo_fld->u.
cargo.vertical_cargoes[i], !accepting);
2480 if (col >= 0) cargoes[col] = cargo_fld->u.
cargo.vertical_cargoes[i];
2496 std::fill(std::begin(ind_fld->u.
industry.other_accepted), std::end(ind_fld->u.
industry.other_accepted), INVALID_CARGO);
2500 int other_count = 0;
2506 if (col < 0) others[other_count++] = indsp->
accepts_cargo[i];
2510 for (uint i = 0; i < CargoesField::max_cargoes && other_count > 0; i++) {
2511 if (!
HasBit(cargo_fld->u.
cargo.cust_cargoes, i)) ind_fld->u.
industry.other_accepted[i] = others[--other_count];
2515 for (uint i = 0; i < cargo_fld->u.
cargo.num_cargoes; i++) {
2517 if (!hs.enabled)
continue;
2519 for (uint j = 0; j <
lengthof(hs.accepts_cargo); j++) {
2520 if (hs.cargo_acceptance[j] > 0 && cargo_fld->u.
cargo.vertical_cargoes[i] == hs.accepts_cargo[j]) {
2561 typedef std::vector<CargoesRow> Fields;
2611 this->ind_textsize.width = 0;
2612 this->ind_textsize.height = 0;
2616 if (!indsp->
enabled)
continue;
2621 d.width = std::max(d.width, this->ind_textsize.width);
2622 d.height = this->ind_textsize.height;
2626 this->cargo_textsize.width = 0;
2627 this->cargo_textsize.height = 0;
2629 if (!csp->IsValid())
continue;
2632 d =
maxdim(d, this->cargo_textsize);
2657 size.width = std::max(size.width, this->ind_textsize.width + padding.width);
2661 size.width = std::max(size.width, this->cargo_textsize.width + padding.width);
2666 void SetStringParameters(
WidgetID widget)
const override
2685 static bool HasCommonValidCargo(
const std::span<const CargoID> cargoes1,
const std::span<const CargoID> cargoes2)
2687 for (
const CargoID cid1 : cargoes1) {
2689 for (
const CargoID cid2 : cargoes2) {
2690 if (cid1 == cid2)
return true;
2703 for (
const CargoID cid : cargoes) {
2720 case LT_TEMPERATE: climate_mask =
HZ_TEMP;
break;
2723 case LT_TOYLAND: climate_mask =
HZ_TOYLND;
break;
2724 default: NOT_REACHED();
2726 for (
const CargoID cid : cargoes) {
2730 if (!hs.enabled || !(hs.building_availability & climate_mask))
continue;
2732 for (uint j = 0; j <
lengthof(hs.accepts_cargo); j++) {
2733 if (hs.cargo_acceptance[j] > 0 && cid == hs.accepts_cargo[j])
return true;
2750 if (!indsp->
enabled)
continue;
2767 if (!indsp->
enabled)
continue;
2782 while (top < bottom && !this->
fields[
top].columns[column].HasConnection()) {
2783 this->fields[
top].columns[column].MakeEmpty(
CFT_EMPTY);
2786 this->fields[
top].columns[column].u.cargo.top_end =
true;
2788 while (bottom >
top && !this->fields[bottom].columns[column].HasConnection()) {
2789 this->fields[bottom].columns[column].MakeEmpty(
CFT_EMPTY);
2792 this->fields[bottom].columns[column].u.cargo.bottom_end =
true;
2803 assert(this->fields[row].columns[col].type ==
CFT_EMPTY);
2804 this->fields[row].columns[col].MakeIndustry(it);
2806 this->fields[row].ConnectIndustryProduced(col);
2808 this->fields[row].ConnectIndustryAccepted(col);
2830 this->GetWidget<NWidgetCore>(
WID_IC_CAPTION)->widget_data = STR_INDUSTRY_CARGOES_INDUSTRY_CAPTION;
2831 this->ind_cargo = displayed_it;
2835 this->fields.clear();
2836 CargoesRow &first_row = this->fields.emplace_back();
2849 int num_indrows = std::max(3, std::max(num_supp, num_cust));
2850 for (
int i = 0; i < num_indrows; i++) {
2851 CargoesRow &row = this->fields.emplace_back();
2859 int central_row = 1 + num_indrows / 2;
2860 this->fields[central_row].columns[2].MakeIndustry(displayed_it);
2861 this->fields[central_row].ConnectIndustryProduced(2);
2862 this->fields[central_row].ConnectIndustryAccepted(2);
2865 this->fields[central_row - 1].MakeCargoLabel(2,
true);
2866 this->fields[central_row + 1].MakeCargoLabel(2,
false);
2873 if (!indsp->
enabled)
continue;
2876 this->
PlaceIndustry(1 + supp_count * num_indrows / num_supp, 0, it);
2881 this->
PlaceIndustry(1 + cust_count * num_indrows / num_cust, 4, it);
2886 if (houses_supply) {
2890 if (houses_accept) {
2897 this->vscroll->
SetCount(num_indrows);
2908 this->GetWidget<NWidgetCore>(
WID_IC_CAPTION)->widget_data = STR_INDUSTRY_CARGOES_CARGO_CAPTION;
2912 this->fields.clear();
2913 CargoesRow &first_row = this->fields.emplace_back();
2920 auto cargoes = std::span(&cid, 1);
2925 int num_indrows = std::max(num_supp, num_cust);
2926 for (
int i = 0; i < num_indrows; i++) {
2927 CargoesRow &row = this->fields.emplace_back();
2935 this->fields[num_indrows].MakeCargoLabel(0,
false);
2942 if (!indsp->
enabled)
continue;
2945 this->
PlaceIndustry(1 + supp_count * num_indrows / num_supp, 0, it);
2950 this->
PlaceIndustry(1 + cust_count * num_indrows / num_cust, 2, it);
2955 if (houses_supply) {
2959 if (houses_accept) {
2965 this->vscroll->
SetCount(num_indrows);
2977 void OnInvalidateData([[maybe_unused]]
int data = 0, [[maybe_unused]]
bool gui_scope =
true)
override
2979 if (!gui_scope)
return;
2989 void DrawWidget(
const Rect &r,
WidgetID widget)
const override
3005 for (
const auto &field : this->fields) {
3006 if (vpos + row_height >= 0) {
3007 int xpos = left_pos;
3016 while (col >= 0 && col <= last_column) {
3017 field.columns[col].Draw(xpos, vpos);
3023 if (vpos >=
height)
break;
3042 if (pt.y < vpos)
return false;
3045 if (row + 1 >= (
int)this->fields.size())
return false;
3050 if (pt.x < xpos)
return false;
3052 for (column = 0; column <= 5; column++) {
3054 if (pt.x < xpos +
width)
break;
3058 if (column > num_columns)
return false;
3065 fieldxy->x = num_columns - column;
3068 fieldxy->x = column;
3074 void OnClick([[maybe_unused]]
Point pt,
WidgetID widget, [[maybe_unused]]
int click_count)
override
3081 const CargoesField *fld = this->fields[fieldxy.y].columns + fieldxy.x;
3082 switch (fld->
type) {
3088 CargoesField *lft = (fieldxy.x > 0) ? this->fields[fieldxy.y].columns + fieldxy.x - 1 :
nullptr;
3089 CargoesField *rgt = (fieldxy.x < 4) ? this->fields[fieldxy.y].columns + fieldxy.x + 1 :
nullptr;
3122 lst.push_back(MakeDropDownListIconItem(d, cs->GetCargoIcon(), PAL_NONE, cs->name, cs->Index()));
3135 if (!indsp->
enabled)
continue;
3136 lst.push_back(MakeDropDownListStringItem(indsp->
name, ind));
3147 void OnDropdownSelect(
WidgetID widget,
int index)
override
3149 if (index < 0)
return;
3162 bool OnTooltip([[maybe_unused]]
Point pt,
WidgetID widget, TooltipCloseCondition close_cond)
override
3169 const CargoesField *fld = this->fields[fieldxy.y].columns + fieldxy.x;
3171 switch (fld->
type) {
3173 CargoesField *lft = (fieldxy.x > 0) ? this->fields[fieldxy.y].columns + fieldxy.x - 1 :
nullptr;
3174 CargoesField *rgt = (fieldxy.x < 4) ? this->fields[fieldxy.y].columns + fieldxy.x + 1 :
nullptr;
3186 GuiShowTooltips(
this, STR_INDUSTRY_CARGOES_INDUSTRY_TOOLTIP, close_cond);
3196 GuiShowTooltips(
this, STR_INDUSTRY_CARGOES_CARGO_TOOLTIP, close_cond, 1);
Class for backupping variables and making sure they are restored later.
constexpr debug_inline bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
constexpr static debug_inline uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
uint8_t CargoID
Cargo slots to indicate a cargo type within a game.
bool IsValidCargoID(CargoID t)
Test whether cargo type is not INVALID_CARGO.
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.
Build (fund or prospect) a new industry,.
IndustryType selected_type
industry corresponding to the above index
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.
void OnPlaceObjectAbort() override
The user cancelled a tile highlight mode that has been set.
std::string MakeCargoListString(const std::span< const CargoID > cargolist, const std::span< const CargoSuffix > cargo_suffix, StringID prefixstr) const
Build a string of cargo names with suffixes attached.
void OnInvalidateData([[maybe_unused]] int data=0, [[maybe_unused]] 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.
std::vector< IndustryType > list
List of industries.
bool enabled
Availability state of the selected industry.
Common return value for all commands.
bool Succeeded() const
Did this command succeed?
StringID GetErrorMessage() const
Returns the error message of a command.
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.
bool(const const Industry * *, const std::pair< CargoID, CargoID > &) FilterFunction
Signature of filter function.
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.
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.
IntervalTimer< TimerWindow > rebuild_interval
Rebuild the industry list on a regular interval.
void SetProducedCargoFilter(CargoID cid)
Set produced cargo filter for the industry list.
static int GetCargoTransportedSortValue(const Industry *i)
Returns value representing industry's transported cargo percentage for industry sorting.
const int MAX_FILTER_LENGTH
The max length of the filter, in chars.
EventState OnHotkey(int hotkey) override
A hotkey has been pressed.
void SetCargoFilterArray()
Populate the filter list and set the cargo filter criteria.
void OnResize() override
Called after the window got resized.
static int GetCargoTransportedPercentsIfValid(const Industry::ProducedCargo &p)
Returns percents of cargo transported if industry produces this cargo, else -1.
CargoID accepted_cargo_filter_criteria
Selected accepted cargo filter index.
@ 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.
uint GetIndustryListWidth() const
Get the width needed to draw the longest industry line.
static bool IndustryProductionSorter(const Industry *const &a, const Industry *const &b, const CargoID &filter)
Sort industries by production and name.
QueryString industry_editbox
Filter editbox.
StringFilter string_filter
Filter for industries.
void BuildSortIndustriesList()
(Re)Build industries list
static bool IndustryTypeSorter(const Industry *const &a, const Industry *const &b, const CargoID &filter)
Sort industries by type and name.
static bool IndustryNameSorter(const Industry *const &a, const Industry *const &b, const CargoID &)
Sort industries by name.
CargoID produced_cargo_filter_criteria
Selected produced cargo filter index.
void OnInvalidateData([[maybe_unused]] int data=0, [[maybe_unused]] bool gui_scope=true) override
Some data on this window has become invalid.
StringID GetIndustryString(const Industry *i) const
Get the StringID to draw and set the appropriate DParams.
void SetAcceptedCargoFilter(CargoID cid)
Set accepted cargo filter for the industry list.
void OnPaint() override
The window must be repainted.
static bool IndustryTransportedCargoSorter(const Industry *const &a, const Industry *const &b, const CargoID &filter)
Sort industries by transported cargo and name.
void OnInit() override
Notification that the nested widget tree gets initialized.
Editability
Modes for changing production.
@ EA_RATE
Allow changing the production rates.
@ EA_MULTIPLIER
Allow changing the production multiplier.
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.
InfoLine clicked_line
The line of the button that has been clicked.
InfoLine
Specific lines in the info panel.
@ IL_RATE2
Production rate of cargo 2.
@ IL_MULTIPLIER
Production multiplier.
@ IL_RATE1
Production rate of cargo 1.
void OnInvalidateData([[maybe_unused]] int data=0, [[maybe_unused]] 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.
bool IsNewGRFInspectable() const override
Is the data related to this window NewGRF inspectable?
int info_height
Height needed for the WID_IV_INFO panel.
Dimension cargo_icon_size
Largest cargo icon dimension.
void ShowNewGRFInspectWindow() const override
Show the NewGRF inspection window.
void OnInit() override
Notification that the nested widget tree gets initialized.
uint8_t clicked_button
The button that has been clicked (to raise)
int DrawInfo(const Rect &r)
Draw the text in the WID_IV_INFO panel.
InfoLine editbox_line
The line clicked to open the edit box.
static bool UsingWallclockUnits(bool newgame=false)
Check if we are using wallclock units.
Map accessors for 'clear' tiles.
ClearGround GetRawClearGround(Tile t)
Get the type of clear tile but never return CLEAR_SNOW.
void MakeClear(Tile t, ClearGround g, uint density)
Make a clear tile.
Functions related to commands.
Commands
List of 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.
@ 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)
Show a dropdown menu window near a widget of the parent window.
void ShowDropDownList(Window *w, DropDownList &&list, int selected, WidgetID button, uint width, bool instant_close, bool persist)
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.
uint ScaleByCargoScale(uint num, bool town)
Scale a number by the cargo scale setting.
Functions related to errors.
void ShowErrorMessage(StringID summary_msg, int x, int y, CommandCost cc)
Display an error message in a window.
@ WL_INFO
Used for DoCommand-like (and some non-fatal AI GUI) errors/information.
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.
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.
void DrawRectOutline(const Rect &r, int colour, int width, int dash)
Draw the outline of a Rect.
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 GfxFillRect(int left, int top, int right, int bottom, int colour, FillRectMode mode)
Applies a certain FillRectMode-operation to a rectangle [left, right] x [top, bottom] on the screen.
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.
bool FillDrawPixelInfo(DrawPixelInfo *n, int left, int top, int width, int height)
Set up a clipping area for only drawing into a certain area.
int CenterBounds(int min, int max, int size)
Determine where to draw a centred object inside a widget.
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
@ SA_LEFT
Left align the text.
@ SA_RIGHT
Right align the text (must be a single bit).
@ SA_HOR_CENTER
Horizontally center the text.
@ FS_SMALL
Index of the small font in the font tables.
@ FS_NORMAL
Index of the normal font in the font tables.
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.
@ HZ_SUBARTC_BELOW
13 2000 can appear in sub-arctic climate below the snow line
@ HZ_TEMP
12 1000 can appear in temperate climate
@ HZ_TOYLND
15 8000 can appear in toyland climate
@ HZ_SUBTROPIC
14 4000 can appear in subtropical climate
@ HZ_SUBARTC_ABOVE
11 800 can appear in sub-arctic climate above the snow line
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 _industry_directory_desc(WDP_AUTO, "list_industries", 428, 190, WC_INDUSTRY_DIRECTORY, WC_NONE, 0, _nested_industry_directory_widgets, &IndustryDirectoryWindow::hotkeys)
Window definition of the industry directory gui.
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)
static const uint MAX_CARGOES
Maximum number of cargoes carried in a CFT_CARGO field in CargoesField.
CargoesFieldType
Available types of field.
@ CFT_SMALL_EMPTY
Empty small field (for the header).
@ CFT_INDUSTRY
Display industry.
@ CFT_CARGO
Display cargo connections.
@ CFT_CARGO_LABEL
Display cargo labels.
static WindowDesc _industry_view_desc(WDP_AUTO, "view_industry", 260, 120, WC_INDUSTRY_VIEW, WC_NONE, 0, _nested_industry_view_widgets)
Window definition of the view industry gui.
static void GetAllCargoSuffixes(CargoSuffixInOut 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)
IndustryDirectoryHotkeys
Enum referring to the Hotkeys in the industry directory window.
@ IDHK_FOCUS_FILTER_BOX
Focus the filter box.
CargoSuffixType
Cargo suffix type (for which window is it requested)
@ CST_DIR
Industry-directory window.
@ CST_FUND
Fund-industry window.
@ CST_VIEW
View-industry window.
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.
std::array< IndustryType, NUM_INDUSTRYTYPES > _sorted_industry_types
Industry types sorted by name.
static WindowDesc _build_industry_desc(WDP_AUTO, "build_industry", 170, 212, WC_BUILD_INDUSTRY, WC_NONE, WDF_CONSTRUCTION, _nested_build_industry_widgets)
Window definition of the dynamic place industries gui.
static constexpr NWidgetPart _nested_industry_view_widgets[]
Widget definition of the view industry gui.
std::bitset< NUM_INDUSTRYTYPES > _displayed_industries
Communication from the industry chain window to the smallmap window about what industries to display.
static bool CargoFilter(const Industry *const *industry, const std::pair< CargoID, CargoID > &cargoes)
Cargo filter functions.
static void ShowIndustryCargoesWindow(IndustryType id)
Open the industry and cargoes window.
void CcBuildIndustry(Commands, const CommandCost &result, TileIndex tile, IndustryType indtype, uint32_t, bool, uint32_t)
Command callback.
CargoSuffixDisplay
Ways of displaying the cargo.
@ CSD_CARGO_TEXT
Display then cargo and supplied string (cb37 result 800-BFF).
@ CSD_CARGO
Display the cargo without sub-type (cb37 result 401).
@ CSD_CARGO_AMOUNT_TEXT
Display then cargo, amount, and string (cb37 result 000-3FF).
@ CSD_CARGO_AMOUNT
Display the cargo and amount (if useful), but no sub-type (cb37 result 400 or fail).
static constexpr NWidgetPart _nested_industry_directory_widgets[]
Widget definition of the industry directory gui.
static WindowDesc _industry_cargoes_desc(WDP_AUTO, "industry_cargoes", 300, 210, WC_INDUSTRY_CARGOES, WC_NONE, 0, _nested_industry_cargoes_widgets)
Window description for the industry cargoes window.
static constexpr NWidgetPart _nested_industry_cargoes_widgets[]
Widgets of the industry cargoes window.
void SortIndustryTypes()
Initialize the list of sorted industry types.
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 INV...
static const IndustryType INVALID_INDUSTRYTYPE
one above amount is considered invalid
static const int INDUSTRY_ORIGINAL_NUM_OUTPUTS
Original number of produced cargo types.
@ INDUSTRYBEH_CARGOTYPES_UNLIMITED
Allow produced/accepted cargoes callbacks to supply more than 2 and 3 types.
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.
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
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.
void GuiShowTooltips(Window *parent, StringID str, TooltipCloseCondition close_tooltip, uint paramcount)
Shows a tooltip.
void ShowQuery(StringID caption, StringID 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(StringID str, StringID caption, uint maxsize, Window *parent, CharSetFilter afilter, QueryStringFlags flags)
Show a query popup window with a textbox in it.
static constexpr CargoID CF_NONE
Show only items which do not carry cargo (e.g. train engines)
static constexpr CargoID 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.
@ CBM_IND_FUND_MORE_TEXT
additional text in fund window
@ CBM_IND_WINDOW_MORE_TEXT
additional text in industry window
@ CBM_IND_PRODUCTION_CARGO_ARRIVAL
call production callback when cargo arrives at the industry
@ CBM_IND_CARGO_SUFFIX
cargo sub-type display
@ CBM_IND_PRODUCTION_256_TICKS
call production callback every 256 ticks
@ 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.
bool IsNewGRFInspectable(GrfSpecFeature feature, uint index)
Can we inspect the data given a certain feature and index.
bool IndustryTemporarilyRefusesCargo(Industry *ind, CargoID cargo_type)
Check whether an industry temporarily refuses to accept a certain cargo.
uint32_t GetIndustryProbabilityCallback(IndustryType type, IndustryAvailabilityCallType creation_type, uint32_t default_prob)
Check with callback CBID_INDUSTRY_PROBABILITY whether the industry can be built.
uint16_t GetIndustryCallback(CallbackID callback, uint32_t param1, uint32_t param2, Industry *industry, IndustryType type, TileIndex tile)
Perform an industry callback.
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.
void StartTextRefStackUsage(const GRFFile *grffile, uint8_t numEntries, const uint32_t *values)
Start using the TTDP compatible string code parsing.
StringID GetGRFStringID(uint32_t grfid, StringID stringid)
Returns the index for this stringid associated with its grfID.
void StopTextRefStackUsage()
Stop using the TTDP compatible string code parsing.
Header of Action 04 "universal holder" structure and functions.
static const uint8_t PC_WHITE
White palette colour.
static const uint8_t PC_BLACK
Black palette colour.
static const uint8_t PC_YELLOW
Yellow 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.
@ SWS_OFF
Scroll wheel has no effect.
void ShowSmallMap()
Show the smallmap window.
Base types for having sorted lists in GUIs.
Functions related to sound.
@ SND_15_BEEP
19 == 0x13 GUI button click
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.
Functions related to low-level strings.
@ CS_ALPHANUMERAL
Both numeric and alphabetic and spaces and stuff.
Searching and filtering using a stringterm.
void AppendStringInPlace(std::string &result, StringID string)
Resolve the given StringID and append in place into an existing std::string with all the associated D...
void SetDParam(size_t n, uint64_t v)
Set a string parameter v at index n in the global string parameter array.
std::string GetString(StringID string)
Resolve the given StringID into a std::string with all the associated DParam lookups and formatting.
TextDirection _current_text_dir
Text direction of the currently selected language.
void SetDParamStr(size_t n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
void SetDParamMaxDigits(size_t n, uint count, FontSize size)
Set DParam n to some number that is suitable for string size computations.
Functions related to OTTD's strings.
@ TD_RTL
Text is written right-to-left by default.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
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...
Class to backup a specific variable and restore it later.
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...
Comparator to sort CargoID by according to desired order.
Specification of a 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.
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo ID.
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.
Data about a single field in the IndustryCargoesWindow panel.
StringID header
Header text (for CFT_HEADER).
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.
static const int INDUSTRY_LINE_COLOUR
Line colour of the industry type box.
uint8_t top_end
Stop at the top of the vertical cargoes.
Cargoes cust_cargoes
Cargoes in vertical_cargoes leaving to the right.
struct CargoesField::@5::@8 cargo_label
Label data (for CFT_CARGO_LABEL).
struct CargoesField::@5::@7 cargo
Cargo data (for CFT_CARGO).
struct CargoesField::@5::@6 industry
Industry data (for CFT_INDUSTRY).
int GetCargoBase(int xpos) const
For a CFT_CARGO, compute the left position of the left-most vertical cargo connection.
CargoID CargoClickedAt(const CargoesField *left, const CargoesField *right, Point pt) const
Decide which cargo was clicked at in a CFT_CARGO field.
static const int CARGO_LINE_COLOUR
Line colour around the cargo.
CargoID CargoLabelClickedAt(Point pt) const
Decide what cargo the user clicked in the cargo label field.
static int small_height
Height of the header row.
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.
int ConnectCargo(CargoID cargo, bool producer)
Connect a cargo from an industry to the CFT_CARGO column.
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 CFT_CARGO field have a horizontal connection?
CargoID vertical_cargoes[MAX_CARGOES]
Cargoes running from top to bottom (cargo ID or #INVALID_CARGO).
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.
CargoID cargoes[MAX_CARGOES]
Cargoes to display (or #INVALID_CARGO).
IndustryType ind_type
Industry type (NUM_INDUSTRYTYPES means 'houses').
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.
CargoID other_produced[MAX_CARGOES]
Cargoes produced but not used in this figure.
Cargoes supp_cargoes
Cargoes in vertical_cargoes entering from the left.
void MakeCargo(const std::span< const CargoID > cargoes)
Make a piece of cargo column.
void Draw(int xpos, int ypos) const
Draw the field.
void MakeCargoLabel(const std::span< const CargoID > cargoes, bool left_align)
Make a field displaying cargo type names.
CargoID other_accepted[MAX_CARGOES]
Cargoes accepted but not used in this figure.
static int industry_width
Width of an industry field.
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 MakeEmpty(CargoesFieldType type)
Make one of the empty fields (CFT_EMPTY or CFT_SMALL_EMPTY).
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 CFT_CARGO_LABEL field.
bool value
tells if the bool cheat is active or not
Cheat setup_prod
setup raw-material production in game
SoundSettings sound
sound effect settings
GUISettings gui
settings related to the GUI
uint8_t raw_industry_construction
type of (raw) industry construction (none, "normal", prospecting)
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
std::array< uint8_t, NUM_CARGO > cargo_map
Inverse cargo translation table (CargoID -> local ID)
bool persistent_buildingtools
keep the building tools active after usage
uint8_t scrollwheel_scrolling
scrolling using the scroll wheel?
uint8_t landscape
the landscape we're currently in
ConstructionSettings construction
construction of things in-game
GameCreationSettings game_creation
settings used during the creation of a game (map)
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.
static bool HousesCanAccept(const std::span< const CargoID > cargoes)
Can houses be used as customers of the produced cargoes?
void OnInit() override
Notification that the nested widget tree gets initialized.
void OnInvalidateData([[maybe_unused]] int data=0, [[maybe_unused]] bool gui_scope=true) override
Some data on this window has become invalid.
Dimension ind_textsize
Size to hold any industry type text, as well as STR_INDUSTRY_CARGOES_SELECT_INDUSTRY.
void ShortenCargoColumn(int column, int top, int bottom)
Shorten the cargo column to just the part between industries.
void PlaceIndustry(int row, int col, IndustryType it)
Place an industry in the fields.
void OnResize() override
Called after the window got resized.
static bool HousesCanSupply(const std::span< const CargoID > cargoes)
Can houses be used to supply one of the cargoes?
Fields fields
Fields to display in the WID_IC_PANEL.
static bool HasCommonValidCargo(const std::span< const CargoID > cargoes1, const std::span< const CargoID > cargoes2)
Do the two sets of cargoes have a valid cargo in common?
static int CountMatchingProducingIndustries(const std::span< const CargoID > cargoes)
Count how many industries have produced cargoes in common with one of the supplied set.
void ComputeCargoDisplay(CargoID cid)
Compute what and where to display for cargo id cid.
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).
static int CountMatchingAcceptingIndustries(const std::span< const CargoID > cargoes)
Count how many industries have accepted cargoes in common with one of the supplied set.
bool CalculatePositionInWidget(Point pt, Point *fieldxy, Point *xy)
Calculate in which field was clicked, and within the field, at what position.
uint ind_cargo
If less than NUM_INDUSTRYTYPES, an industry type, else a cargo id + NUM_INDUSTRYTYPES.
Defines the data structure for constructing industry.
uint16_t callback_mask
Bitmask of industry callbacks that have to be called.
std::array< CargoID, INDUSTRY_NUM_INPUTS > accepts_cargo
16 accepted cargoes.
bool UsesOriginalEconomy() const
Determines whether this industrytype uses standard/newgrf production changes.
StringID name
Displayed name of the industry.
IndustryBehaviour behaviour
How this industry will behave, and how others entities can use it.
bool IsRawIndustry() const
Is an industry with the spec a raw industry?
GRFFileProps grf_prop
properties related to the grf file
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.
uint8_t map_colour
colour used for the small map
std::array< ProducedHistory, 25 > 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.
uint8_t prod_level
general production level
void RecomputeProductionMultipliers()
Recompute #production_rate for current prod_level.
ProducedCargoes produced
produced cargo slots
AcceptedCargoes accepted
accepted cargo slots
static uint16_t GetIndustryTypeCount(IndustryType type)
Get the count of industries for this type.
std::string text
General text with additional information.
TileArea location
Location of the industry.
bool IsCargoProduced() const
Test if this industry produces any cargo.
ProducedCargoes::iterator GetCargoProduced(CargoID cargo)
Get produced cargo slot for a specific cargo type.
Data structure describing how to show the list (what sort direction and criteria).
static debug_inline uint Size()
Get the size of the map.
TileIndex GetCenterTile() const
Get the center tile.
TileIndex tile
The base tile of the area.
Coordinates of a point in 2D.
Tindex index
Index of this pool item.
static Titem * Get(size_t index)
Returns Titem with given index.
static size_t GetNumItems()
Returns number of valid items in the pool.
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
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.
constexpr uint Horizontal() const
Get total horizontal padding of RectPadding.
constexpr uint Vertical() const
Get total vertical padding of RectPadding.
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 click_beep
Beep on a random selection of buttons.
bool IsEmpty() const
Check whether any filter words were entered.
void SetFilterTerm(const char *str)
Set the term to filter on.
void ResetState()
Reset the matching state to process a new item.
void AddLine(const char *str)
Pass another text line from the current item to the filter.
bool GetState() const
Get the matching state of the current item.
char *const buf
buffer in which text is saved
Window * GetCallbackWnd()
Get the window that started the current highlighting.
High level window description.
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.
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.
ViewportData * viewport
Pointer to viewport data, if present.
bool SetFocusedWidget(WidgetID widget_index)
Set focus within this window to the given widget.
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
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 debug_inline bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
static const uint TILE_SIZE
Tile size in world coordinates.
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
@ MP_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 * BringWindowToFrontById(WindowClass cls, WindowNumber number)
Find a window and make it the relative top-window on the screen.
Window * FindWindowByClass(WindowClass cls)
Find any window by its class.
void SetFocusedWindow(Window *w)
Set the window that has the focus.
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.
@ SBS_DOWN
Sort ascending.
@ WF_DISABLE_VP_SCROLL
Window does not do autoscroll,.
@ WDF_CONSTRUCTION
This window is used for construction; close it whenever changing company.
@ WDP_AUTO
Find a place automatically.
int32_t WindowNumber
Number to differentiate different windows of the same class.
EventState
State of handling an event.
@ ES_HANDLED
The passed event is handled.
@ ES_NOT_HANDLED
The passed event is not handled.
@ 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.
int ScaleGUITrad(int value)
Scale traditional pixel dimensions to GUI zoom level.
ZoomLevel ScaleZoomGUI(ZoomLevel value)
Scale zoom level relative to GUI zoom.
@ ZOOM_LVL_INDUSTRY
Default zoom level for the industry view.