Project Alice
Loading...
Searching...
No Matches
gui_trade_window.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "dcon_generated.hpp"
4#include "economy.hpp"
7#include "widgets/table.hpp"
8
9namespace ui {
10
12public:
13 void on_update(sys::state& state) noexcept override {
14 auto commodity_id = retrieve<dcon::commodity_id>(state, parent);
15 set_text(state, text::format_money(state.world.commodity_get_current_price(commodity_id)));
16 }
17};
18
20public:
21 void on_update(sys::state& state) noexcept override {
22 auto n = retrieve<dcon::nation_id>(state, parent);
23 auto c = retrieve<dcon::commodity_id>(state, parent);
24 set_text(state, text::format_money(state.world.nation_get_effective_prices(n, c)));
25 }
26};
27
29public:
30 void on_update(sys::state& state) noexcept override {
31 auto commodity_id = retrieve<dcon::commodity_id>(state, parent);
32 if(commodity_id)
33 set_text(state, text::format_float(state.world.nation_get_demand_satisfaction(state.local_player_nation, commodity_id), 2));
34 }
35};
36
38public:
39 void on_update(sys::state& state) noexcept override {
40 auto commodity_id = retrieve<dcon::commodity_id>(state, parent);
41 if(commodity_id)
42 set_text(state, text::format_float(state.world.nation_get_real_demand(state.local_player_nation, commodity_id), 1));
43 }
44};
45
47public:
48 void on_update(sys::state& state) noexcept override {
49 auto commodity_id = retrieve<dcon::commodity_id>(state, parent);
50 if(commodity_id)
51 set_text(state, text::format_float(state.world.nation_get_stockpiles(state.local_player_nation, commodity_id), 2));
52 }
53};
54
56public:
57 void on_update(sys::state& state) noexcept override {
58 auto commodity_id = retrieve<dcon::commodity_id>(state, parent);
59 float amount = economy::stockpile_commodity_daily_increase(state, commodity_id, state.local_player_nation);
60 auto txt = std::string(amount >= 0.f ? "+" : "") + text::format_float(amount, 2);
61 set_text(state, txt);
62 }
63};
64
66public:
67 void on_update(sys::state& state) noexcept override {
68 auto commodity_id = retrieve<dcon::commodity_id>(state, parent);
69 float amount = economy::global_market_commodity_daily_increase(state, commodity_id);
70 auto txt = std::string("(") + text::format_float(amount, 0) + ")";
71 set_text(state, txt);
72 }
73};
74
76public:
77 void on_update(sys::state& state) noexcept override {
78 auto commodity_id = retrieve<dcon::commodity_id>(state, parent);
79 set_text(state, text::format_float(state.world.commodity_get_global_market_pool(commodity_id), 2));
80 }
81};
82
84public:
85 void on_update(sys::state& state) noexcept override {
86 auto commodity_id = retrieve<dcon::commodity_id>(state, parent);
87 if(commodity_id)
88 set_text(state, text::format_float(commodity_id ? state.world.nation_get_domestic_market_pool(state.local_player_nation, commodity_id) : 0.0f, 2));
89 }
90};
91
93public:
94 void on_update(sys::state& state) noexcept override {
95 auto commodity_id = retrieve<dcon::commodity_id>(state, parent);
96 if(commodity_id)
97 set_text(state, text::format_float(commodity_id ? economy::nation_factory_consumption(state, state.local_player_nation, commodity_id) : 0.0f, 2));
98 }
99};
100
102public:
103 void on_update(sys::state& state) noexcept override {
104 auto commodity_id = retrieve<dcon::commodity_id>(state, parent);
105 if(commodity_id)
106 set_text(state, text::format_float(commodity_id ? economy::nation_pop_consumption(state, state.local_player_nation, commodity_id) : 0.0f, 2));
107 }
108};
109
111public:
112 void on_update(sys::state& state) noexcept override {
113 auto commodity_id = retrieve<dcon::commodity_id>(state, parent);
114 if(commodity_id)
115 set_text(state, text::format_float(commodity_id ? economy::government_consumption(state, state.local_player_nation, commodity_id) : 0.0f, 2));
116 }
117};
118
119enum class trade_sort : uint8_t {
120 commodity,
121 stockpile,
123 price,
125 needs,
126 market,
130};
133 stockpile,
138};
142};
143
144template<trade_sort Sort, trade_sort_assoc Assoc>
146public:
147 void button_action(sys::state& state) noexcept override {
148 send(state, parent, trade_sort_data{ Sort, Assoc });
149 }
152 }
153 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
154 /*auto box = text::open_layout_box(contents);
155 text::localised_format_box(state, contents, box, "sort_by");
156 text::add_space_to_layout_box(state, contents, box);
157 text::localised_format_box(state, contents, box, "trait_speed");
158 text::close_layout_box(contents, box);*/
159 }
160};
161
162class trade_market_activity_entry : public listbox_row_element_base<dcon::commodity_id> {
163public:
164 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
165 if(name == "goods_type") {
166 return make_element_by_type<commodity_image>(state, id);
167 } else if(name == "cost") {
168 return make_element_by_type<commodity_price_text>(state, id);
169 } else if(name == "activity") {
170 return make_element_by_type<commodity_player_availability_text>(state, id);
171 } else {
172 return nullptr;
173 }
174 }
175};
176class trade_market_activity_listbox : public listbox_element_base<trade_market_activity_entry, dcon::commodity_id> {
177protected:
178 std::string_view get_row_element_name() override {
179 return "market_activity_entry";
180 }
181
182public:
184 bool sort_ascend = false;
185 void on_create(sys::state& state) noexcept override {
188 }
189 void on_update(sys::state& state) noexcept override {
190 row_contents.clear();
191 state.world.for_each_commodity([&](dcon::commodity_id id) {
192 if(id != economy::money) {
193 row_contents.push_back(id);
194 }
195 });
196 switch(sort) {
198 std::sort(row_contents.begin(), row_contents.end(), [&](dcon::commodity_id a, dcon::commodity_id b) {
199 return a.index() < b.index();
200 });
201 break;
203 std::sort(row_contents.begin(), row_contents.end(), [&](dcon::commodity_id a, dcon::commodity_id b) {
204 auto av = state.world.commodity_get_current_price(a);
205 auto bv = state.world.commodity_get_current_price(b);
206 if(av != bv)
207 return av > bv;
208 else
209 return a.index() < b.index();
210 });
211 break;
213 std::sort(row_contents.begin(), row_contents.end(), [&](dcon::commodity_id a, dcon::commodity_id b) {
214 auto av = state.world.nation_get_demand_satisfaction(state.local_player_nation, a);
215 auto bv = state.world.nation_get_demand_satisfaction(state.local_player_nation, b);
216 if(av != bv)
217 return av > bv;
218 else
219 return a.index() < b.index();
220 });
221 break;
222 default:
223 break;
224 }
225 if(!sort_ascend) {
226 std::reverse(row_contents.begin(), row_contents.end());
227 }
228 update(state);
229 }
230};
231
232class trade_stockpile_entry : public listbox_row_element_base<dcon::commodity_id> {
233public:
234 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
235 if(name == "goods_type") {
236 return make_element_by_type<commodity_image>(state, id);
237 } else if(name == "value") {
238 return make_element_by_type<commodity_national_player_stockpile_text>(state, id);
239 } else if(name == "change") {
240 return make_element_by_type<commodity_player_stockpile_increase_text>(state, id);
241 } else {
242 return nullptr;
243 }
244 }
245};
246class trade_stockpile_listbox : public listbox_element_base<trade_stockpile_entry, dcon::commodity_id> {
247protected:
248 std::string_view get_row_element_name() override {
249 return "stockpile_entry";
250 }
251
252public:
254 bool sort_ascend = false;
255 void on_create(sys::state& state) noexcept override {
258 }
259 void on_update(sys::state& state) noexcept override {
260 row_contents.clear();
261 state.world.for_each_commodity([&](dcon::commodity_id id) {
262 if(id != economy::money && state.world.nation_get_stockpiles(state.local_player_nation, id) > 0.0f) {
263 row_contents.push_back(id);
264 }
265 });
266 switch(sort) {
268 std::sort(row_contents.begin(), row_contents.end(), [&](dcon::commodity_id a, dcon::commodity_id b) {
269 return a.index() < b.index();
270 });
271 break;
273 std::sort(row_contents.begin(), row_contents.end(), [&](dcon::commodity_id a, dcon::commodity_id b) {
274 auto av = state.world.nation_get_stockpiles(state.local_player_nation, a);
275 auto bv = state.world.nation_get_stockpiles(state.local_player_nation, b);
276 if(av != bv)
277 return av > bv;
278 else
279 return a.index() < b.index();
280 });
281 break;
283 std::sort(row_contents.begin(), row_contents.end(), [&](dcon::commodity_id a, dcon::commodity_id b) {
284 auto av = economy::stockpile_commodity_daily_increase(state, a, state.local_player_nation);
285 auto bv = economy::stockpile_commodity_daily_increase(state, b, state.local_player_nation);
286 if(av != bv)
287 return av > bv;
288 else
289 return a.index() < b.index();
290 });
291 break;
292 default:
293 break;
294 }
295 if(!sort_ascend) {
296 std::reverse(row_contents.begin(), row_contents.end());
297 }
298 update(state);
299 }
300};
301
302class trade_common_market_entry : public listbox_row_element_base<dcon::commodity_id> {
303public:
304 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
305 if(name == "goods_type") {
306 return make_element_by_type<commodity_image>(state, id);
307 } else if(name == "total") {
308 return make_element_by_type<commodity_global_market_text>(state, id);
309 } else if(name == "produce_change") {
310 return make_element_by_type<commodity_player_real_demand_text>(state, id);
311 } else if(name == "exported") {
312 return make_element_by_type<commodity_player_domestic_market_text>(state, id);
313 } else {
314 return nullptr;
315 }
316 }
317};
318class trade_common_market_listbox : public listbox_element_base<trade_common_market_entry, dcon::commodity_id> {
319protected:
320 std::string_view get_row_element_name() override {
321 return "common_market_entry";
322 }
323public:
325 bool sort_ascend = false;
326 void on_create(sys::state& state) noexcept override {
329 }
330 void on_update(sys::state& state) noexcept override {
331 row_contents.clear();
332 state.world.for_each_commodity([&](dcon::commodity_id id) {
333 if(id != economy::money) {
334 row_contents.push_back(id);
335 }
336 });
337 switch(sort) {
339 std::sort(row_contents.begin(), row_contents.end(), [&](dcon::commodity_id a, dcon::commodity_id b) {
340 return a.index() < b.index();
341 });
342 break;
344 std::sort(row_contents.begin(), row_contents.end(), [&](dcon::commodity_id a, dcon::commodity_id b) {
345 auto av = state.world.commodity_get_global_market_pool(a);
346 auto bv = state.world.commodity_get_global_market_pool(b);
347 if(av != bv)
348 return av > bv;
349 else
350 return a.index() < b.index();
351 });
352 break;
354 std::sort(row_contents.begin(), row_contents.end(), [&](dcon::commodity_id a, dcon::commodity_id b) {
355 auto av = state.world.nation_get_real_demand(state.local_player_nation, a);
356 auto bv = state.world.nation_get_real_demand(state.local_player_nation, b);
357 if(av != bv)
358 return av > bv;
359 else
360 return a.index() < b.index();
361 });
362 break;
364 std::sort(row_contents.begin(), row_contents.end(), [&](dcon::commodity_id a, dcon::commodity_id b) {
365 auto av = state.world.nation_get_domestic_market_pool(state.local_player_nation, a);
366 auto bv = state.world.nation_get_domestic_market_pool(state.local_player_nation, b);
367 if(av != bv)
368 return av > bv;
369 else
370 return a.index() < b.index();
371 });
372 break;
373 default:
374 break;
375 }
376 if(!sort_ascend) {
377 std::reverse(row_contents.begin(), row_contents.end());
378 }
379 update(state);
380 }
381};
382
383template<class T>
384class trade_goods_needs_entry : public listbox_row_element_base<dcon::commodity_id> {
385public:
386 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
387 if(name == "goods_type") {
388 return make_element_by_type<commodity_image>(state, id);
389 } else if(name == "value") {
390 return make_element_by_type<T>(state, id);
391 } else {
392 return nullptr;
393 }
394 }
395};
396
397class trade_government_needs_listbox : public listbox_element_base<trade_goods_needs_entry<commodity_player_government_needs_text>, dcon::commodity_id> {
398protected:
399 std::string_view get_row_element_name() override {
400 return "goods_needs_entry";
401 }
402public:
404 bool sort_ascend = false;
405 void on_create(sys::state& state) noexcept override {
408 }
409 void on_update(sys::state& state) noexcept override {
410 row_contents.clear();
411 state.world.for_each_commodity([&](dcon::commodity_id id) {
412 if(id != economy::money && economy::government_consumption(state, state.local_player_nation, id) > 0.f) {
413 row_contents.push_back(id);
414 }
415 });
416 switch(sort) {
418 std::sort(row_contents.begin(), row_contents.end(), [&](dcon::commodity_id a, dcon::commodity_id b) {
419 return a.index() < b.index();
420 });
421 break;
423 std::sort(row_contents.begin(), row_contents.end(), [&](dcon::commodity_id a, dcon::commodity_id b) {
424 auto av = economy::government_consumption(state, state.local_player_nation, a);
425 auto bv = economy::government_consumption(state, state.local_player_nation, b);
426 if(av != bv)
427 return av > bv;
428 else
429 return a.index() < b.index();
430 });
431 break;
432 default:
433 break;
434 }
435 if(!sort_ascend) {
436 std::reverse(row_contents.begin(), row_contents.end());
437 }
438 update(state);
439 }
440};
441
442class trade_factory_needs_listbox : public listbox_element_base<trade_goods_needs_entry<commodity_player_factory_needs_text>, dcon::commodity_id> {
443protected:
444 std::string_view get_row_element_name() override {
445 return "goods_needs_entry";
446 }
447public:
449 bool sort_ascend = false;
450 void on_create(sys::state& state) noexcept override {
453 }
454 void on_update(sys::state& state) noexcept override {
455 row_contents.clear();
456 state.world.for_each_commodity([&](dcon::commodity_id id) {
457 if(id != economy::money && economy::nation_factory_consumption(state, state.local_player_nation, id) > 0.f) {
458 row_contents.push_back(id);
459 }
460 });
461 switch(sort) {
463 std::sort(row_contents.begin(), row_contents.end(), [&](dcon::commodity_id a, dcon::commodity_id b) {
464 return a.index() < b.index();
465 });
466 break;
468 std::sort(row_contents.begin(), row_contents.end(), [&](dcon::commodity_id a, dcon::commodity_id b) {
469 auto av = economy::nation_factory_consumption(state, state.local_player_nation, a);
470 auto bv = economy::nation_factory_consumption(state, state.local_player_nation, b);
471 if(av != bv)
472 return av > bv;
473 else
474 return a.index() < b.index();
475 });
476 break;
477 default:
478 break;
479 }
480 if(!sort_ascend) {
481 std::reverse(row_contents.begin(), row_contents.end());
482 }
483 update(state);
484 }
485};
486
487class trade_pop_needs_listbox : public listbox_element_base<trade_goods_needs_entry<commodity_player_pop_needs_text>, dcon::commodity_id> {
488protected:
489 std::string_view get_row_element_name() override {
490 return "goods_needs_entry";
491 }
492public:
494 bool sort_ascend = false;
495 void on_create(sys::state& state) noexcept override {
498 }
499 void on_update(sys::state& state) noexcept override {
500 row_contents.clear();
501 state.world.for_each_commodity([&](dcon::commodity_id id) {
502 if(id != economy::money && economy::nation_pop_consumption(state, state.local_player_nation, id) > 0.f) {
503 row_contents.push_back(id);
504 }
505 });
506 switch(sort) {
508 std::sort(row_contents.begin(), row_contents.end(), [&](dcon::commodity_id a, dcon::commodity_id b) {
509 return a.index() < b.index();
510 });
511 break;
513 std::sort(row_contents.begin(), row_contents.end(), [&](dcon::commodity_id a, dcon::commodity_id b) {
514 auto av = economy::nation_pop_consumption(state, state.local_player_nation, a);
515 auto bv = economy::nation_pop_consumption(state, state.local_player_nation, b);
516 if(av != bv)
517 return av > bv;
518 else
519 return a.index() < b.index();
520 });
521 break;
522 default:
523 break;
524 }
525 if(!sort_ascend) {
526 std::reverse(row_contents.begin(), row_contents.end());
527 }
528 update(state);
529 }
530};
531
533 dcon::commodity_id commodity_id{};
534};
536 dcon::commodity_id commodity_id{};
537};
538
540public:
541 void on_update(sys::state& state) noexcept override {
542 auto com = retrieve<dcon::commodity_id>(state, parent);
543 auto sat = state.world.nation_get_demand_satisfaction(state.local_player_nation, com);
544 if(sat < 0.5f) { // shortage
545 color = sys::pack_color(255, 196, 196);
546 if(state.user_settings.color_blind_mode == sys::color_blind_mode::deutan || state.user_settings.color_blind_mode == sys::color_blind_mode::protan) {
547 color = sys::pack_color(255, 100, 255); //remap to blue
548 } else if(state.user_settings.color_blind_mode == sys::color_blind_mode::achroma) {
549 color = sys::pack_color(196, 196, 196);
550 }
551 } else if(sat >= 1.f) { // full fulfillment
552 color = sys::pack_color(196, 255, 196);
553 if(state.user_settings.color_blind_mode == sys::color_blind_mode::deutan || state.user_settings.color_blind_mode == sys::color_blind_mode::protan) {
554 color = sys::pack_color(114, 150, 77); //remap to yellow
555 } else if(state.user_settings.color_blind_mode == sys::color_blind_mode::achroma) {
556 color = sys::pack_color(128, 128, 128);
557 }
558 } else {
559 color = sys::pack_color(255, 255, 255);
560 }
561 }
562
563 void button_action(sys::state& state) noexcept override {
564 trade_details_select_commodity payload{retrieve<dcon::commodity_id>(state, parent)};
565 send<trade_details_select_commodity>(state, state.ui_state.trade_subwindow, payload);
566 }
567
568 void button_right_action(sys::state& state) noexcept override {
569 trade_details_select_commodity payload{ retrieve<dcon::commodity_id>(state, parent) };
570 send<trade_details_select_commodity>(state, state.ui_state.trade_subwindow, payload);
571 Cyto::Any dt_payload = trade_details_open_window{ retrieve<dcon::commodity_id>(state, parent) };
572 state.ui_state.trade_subwindow->impl_get(state, dt_payload);
573 }
574
577 }
578
579 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
580 auto com = retrieve<dcon::commodity_id>(state, parent);
581
582 struct tagged_value {
583 float v = 0.0f;
584 dcon::nation_id n;
585 };
586 static std::vector<tagged_value> producers;
587
588 producers.clear();
589 for(auto n : state.world.in_nation) {
590 if(n.get_domestic_market_pool(com) >= 0.05f) {
591 producers.push_back(tagged_value{ n.get_domestic_market_pool(com), n.id });
592 }
593 }
594 if(producers.size() > 0) {
595 std::sort(producers.begin(), producers.end(), [](auto const& a, auto const& b) { return a.v > b.v; });
596 {
597 auto box = text::open_layout_box(contents, 0);
599 text::add_to_substitution_map(sub, text::variable_type::value, std::min(int32_t(state.defines.great_nations_count), int32_t(producers.size())));
600 text::localised_format_box(state, contents, box, "alice_trade_top_producers", sub);
601 text::close_layout_box(contents, box);
602 }
603 for(uint32_t i = 0; i < producers.size() && i < state.defines.great_nations_count; ++i) {
604 auto box = text::open_layout_box(contents, 15);
605 auto ident = state.world.nation_get_identity_from_identity_holder(producers[i].n);
606 text::add_to_layout_box(state, contents, box, text::embedded_flag{ ident ? ident : state.national_definitions.rebel_id });
607 text::add_space_to_layout_box(state, contents, box);
608 text::add_to_layout_box(state, contents, box, text::get_name(state, producers[i].n));
609 text::add_space_to_layout_box(state, contents, box);
610 text::add_to_layout_box(state, contents, box, text::fp_one_place{ producers[i].v });
611 text::close_layout_box(contents, box);
612 }
614 float r_total = 0.0f;
615
616 } else {
617 text::add_line(state, contents, "alice_trade_no_producers");
618 }
619 }
620};
621
623public:
624 void on_update(sys::state& state) noexcept override {
625 auto com = retrieve<dcon::commodity_id>(state, parent);
626 if(state.world.nation_get_drawing_on_stockpiles(state.local_player_nation, com)) {
627 if(state.world.nation_get_stockpiles(state.local_player_nation, com) > 0)
628 frame = 2;
629 else
630 frame = 0;
631 } else if(state.world.nation_get_stockpiles(state.local_player_nation, com) < state.world.nation_get_stockpile_targets(state.local_player_nation, com)) {
632 frame = 1;
633 } else {
634 frame = 0;
635 }
636 }
637
639 auto com = retrieve<dcon::commodity_id>(state, parent);
640 if(state.world.nation_get_drawing_on_stockpiles(state.local_player_nation, com)) {
642 } else if(state.world.nation_get_stockpiles(state.local_player_nation, com) < state.world.nation_get_stockpile_targets(state.local_player_nation, com)) {
644 } else {
646 }
647
648 }
649
650 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
651 auto com = retrieve<dcon::commodity_id>(state, parent);
652 if(state.world.nation_get_drawing_on_stockpiles(state.local_player_nation, com)) {
653 if(state.world.nation_get_stockpiles(state.local_player_nation, com) > 0)
654 text::add_line(state, contents, "trade_setting_drawing");
655 } else if(state.world.nation_get_stockpiles(state.local_player_nation, com) < state.world.nation_get_stockpile_targets(state.local_player_nation, com)) {
656 text::add_line(state, contents, "trade_setting_filling");
657 } else {
658
659 }
660 }
661};
662
664public:
665 void on_update(sys::state& state) noexcept override {
666 auto com = retrieve<dcon::commodity_id>(state, parent);
667 auto current_price = state.world.commodity_get_price_record(com, (state.ui_date.value >> 4) % economy::price_history_length);
668 auto previous_price = state.world.commodity_get_price_record(com, ((state.ui_date.value >> 4) + economy::price_history_length - 1) % economy::price_history_length);
669 if(current_price > previous_price) {
670 frame = 0;
671 } else if(current_price < previous_price) {
672 frame = 2;
673 } else {
674 frame = 1;
675 }
676 }
677};
678
680public:
681 dcon::commodity_id commodity_id{};
682 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
683 if(name == "entry_button") {
684 return make_element_by_type<trade_commodity_entry_button>(state, id);
685 } else if(name == "goods_type") {
686 return make_element_by_type<commodity_image>(state, id);
687 } else if(name == "price") {
688 auto ptr = make_element_by_type<commodity_effective_price_text>(state, id);
689 ptr->base_data.position.y += ptr->base_data.size.y / 2;
690 add_child_to_front(std::move(ptr));
691 return make_element_by_type<commodity_price_text>(state, id);
692 } else if(name == "trend_indicator") {
693 return make_element_by_type<commodity_price_trend>(state, id);
694 } else if(name == "selling_indicator") {
695 return make_element_by_type<commodity_stockpile_indicator>(state, id);
696 } else if(name == "automation_indicator") {
697 return make_element_by_type<invisible_element>(state, id);
698 } else {
699 return nullptr;
700 }
701 }
702
703 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
704 if(payload.holds_type<dcon::commodity_id>()) {
705 payload.emplace<dcon::commodity_id>(commodity_id);
707 }
709 }
710};
711
713public:
714 dcon::commodity_id trade_good;
715 enum class type : uint8_t {
716 factory,
717 province,
718 pop,
721 } type{};
723 union {
724 dcon::factory_id factory_id; // factory
725 dcon::province_id province_id; // province
726 dcon::province_id pop_province_id; // pop
727 dcon::army_id army_id; // army
728 dcon::navy_id navy_id; // navy
729 } data{};
730
731 bool operator==(trade_flow_data const& o) const {
732 if(value_type != o.value_type)
733 return false;
734
735 switch(type) {
736 case type::factory:
737 if(o.type != type::factory)
738 return false;
739 return data.factory_id == o.data.factory_id;
740 case type::province:
741 if(o.type != type::province)
742 return false;
743 return data.province_id == o.data.province_id;
744 case type::pop:
745 if(o.type != type::pop)
746 return false;
747 return data.pop_province_id == o.data.pop_province_id;
750 return false;
751 return data.army_id == o.data.army_id;
754 return false;
755 return data.navy_id == o.data.navy_id;
756 default:
757 return true;
758 }
759 }
760 bool operator!=(trade_flow_data const& o) const {
761 return !(*this == o);
762 }
763};
764class trade_flow_entry : public listbox_row_element_base<trade_flow_data> {
765 image_element_base* icon = nullptr;
766 simple_text_element_base* title = nullptr;
767 simple_text_element_base* value = nullptr;
768 image_element_base* output_icon = nullptr;
769
770public:
771 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
772 if(name == "icon") {
773 auto ptr = make_element_by_type<image_element_base>(state, id);
774 icon = ptr.get();
775 return ptr;
776 } else if(name == "title") {
777 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
778 title = ptr.get();
779 return ptr;
780 } else if(name == "value") {
781 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
782 value = ptr.get();
783 return ptr;
784 } else if(name == "output_icon") {
785 auto ptr = make_element_by_type<image_element_base>(state, id);
786 output_icon = ptr.get();
787 return ptr;
788 } else {
789 return nullptr;
790 }
791 }
792
793 void on_update(sys::state& state) noexcept override {
794 auto commodity_id = retrieve<dcon::commodity_id>(state, parent);
795
796 icon->frame = int32_t(content.type);
799
802 float amount = 0.f;
803 switch(content.type) {
805 auto fid = content.data.factory_id;
806 auto ftid = state.world.factory_get_building_type(fid);
807 switch(content.value_type) {
809 amount += state.world.factory_get_actual_production(fid);
810 } break;
812 auto& inputs = state.world.factory_type_get_inputs(ftid);
813 for(uint32_t i = 0; i < inputs.set_size; ++i)
814 if(inputs.commodity_type[i] == commodity_id)
815 amount += inputs.commodity_amounts[i];
816 output_icon->frame = state.world.commodity_get_icon(state.world.factory_type_get_output(ftid));
817 } break;
819 output_icon->frame = state.world.commodity_get_icon(state.world.factory_type_get_output(ftid));
820 break;
821 default:
822 break;
823 }
824 auto name = state.world.factory_type_get_name(ftid);
825 title->set_text(state, text::produce_simple_string(state, name));
826 } break;
828 auto pid = content.data.province_id;
829 switch(content.value_type) {
831 amount += state.world.province_get_rgo_actual_production_per_good(pid, content.trade_good);
832 } break;
835 default:
836 break;
837 }
838 auto name = state.world.province_get_name(pid);
839 title->set_text(state, text::produce_simple_string(state, name));
840 } break;
842 break;
844 break;
846 break;
847 default:
848 break;
849 }
850 if(value->is_visible())
851 value->set_text(state, text::format_float(amount, 2));
852 }
853};
854class trade_flow_listbox_base : public listbox_element_base<trade_flow_entry, trade_flow_data> {
855protected:
856 std::string_view get_row_element_name() override {
857 return "trade_flow_entry";
858 }
859
860 template<typename F>
861 void populate_rows(sys::state& state, F&& factory_func, enum trade_flow_data::value_type vt) {
862 auto commodity_id = retrieve<dcon::commodity_id>(state, parent);
863 for(auto const fat_stown_id : state.world.nation_get_state_ownership(state.local_player_nation)) {
864 province::for_each_province_in_state_instance(state, fat_stown_id.get_state(), [&](dcon::province_id pid) {
865 auto fat_id = dcon::fatten(state.world, pid);
866 fat_id.for_each_factory_location_as_province([&](dcon::factory_location_id flid) {
867 auto fid = state.world.factory_location_get_factory(flid);
868 if(factory_func(fid)) {
869 trade_flow_data td{};
870 td.type = trade_flow_data::type::factory;
871 td.value_type = vt;
872 td.data.factory_id = fid;
873 td.trade_good = commodity_id;
874 row_contents.push_back(td);
875 }
876 });
878 if(state.world.province_get_rgo_actual_production_per_good(pid, commodity_id) > 0.f) {
879 trade_flow_data td{};
881 td.value_type = vt;
882 td.data.province_id = pid;
883 td.trade_good = commodity_id;
884 row_contents.push_back(td);
885 }
886 });
887 }
888 }
889};
890
892public:
893 void on_update(sys::state& state) noexcept override {
894 auto commodity_id = retrieve<dcon::commodity_id>(state, parent);
895
896 row_contents.clear();
897 populate_rows(
898 state,
899 [&](dcon::factory_id fid) -> bool {
900 auto ftid = state.world.factory_get_building_type(fid);
901 return state.world.factory_type_get_output(ftid) == commodity_id;
902 },
903 trade_flow_data::value_type::produced_by);
904 update(state);
905 }
906};
908public:
909 void on_update(sys::state& state) noexcept override {
910 auto commodity_id = retrieve<dcon::commodity_id>(state, parent);
911
912 row_contents.clear();
913 populate_rows(
914 state,
915 [&](dcon::factory_id fid) -> bool {
916 auto ftid = state.world.factory_get_building_type(fid);
917 auto& inputs = state.world.factory_type_get_inputs(ftid);
918 for(uint32_t i = 0; i < inputs.set_size; ++i)
919 if(inputs.commodity_type[i] == commodity_id)
920 return inputs.commodity_amounts[i] > 0.f; // Some inputs taken
921 return false;
922 },
923 trade_flow_data::value_type::used_by);
924 update(state);
925 }
926};
928public:
929 void on_update(sys::state& state) noexcept override {
930 auto commodity_id = retrieve<dcon::commodity_id>(state, parent);
931
932 row_contents.clear();
933 populate_rows(
934 state,
935 [&](dcon::factory_id fid) -> bool {
936 auto ftid = state.world.factory_get_building_type(fid);
937 auto& inputs = state.world.factory_type_get_inputs(ftid);
938 for(uint32_t i = 0; i < inputs.set_size; ++i)
939 if(inputs.commodity_type[i] == commodity_id)
940 return inputs.commodity_amounts[i] == 0.f; // No inputs intaken
941 return false;
942 },
943 trade_flow_data::value_type::may_be_used_by);
944 update(state);
945 }
946};
947
948class trade_flow_producers_piechart : public piechart<dcon::nation_id> {
949public:
950 void on_update(sys::state& state) noexcept override {
951 auto com = retrieve<dcon::commodity_id>(state, parent);
952 distribution.clear();
953 for(auto n : state.world.in_nation)
954 if(n.get_owned_province_count() != 0)
955 distribution.emplace_back(n.id, n.get_domestic_market_pool(com));
956 update_chart(state);
957 }
958};
959
960class trade_flow_consumers_piechart : public piechart<dcon::nation_id> {
961public:
962 void on_update(sys::state& state) noexcept override {
963 auto com = retrieve<dcon::commodity_id>(state, parent);
964 distribution.clear();
965 for(auto n : state.world.in_nation)
966 if(n.get_owned_province_count() != 0)
967 distribution.emplace_back(n.id, n.get_real_demand(com));
968 update_chart(state);
969 }
970};
971
972
973class trade_flow_workers_piechart : public piechart<dcon::pop_type_id> {
974public:
975 void on_update(sys::state& state) noexcept override {
976 auto com = retrieve<dcon::commodity_id>(state, parent);
977 distribution.clear();
978 float total = 0.f;
979 {
980 float amount = 0.f;
981 for(const auto pc : state.world.nation_get_province_control(state.local_player_nation)) {
982 for(const auto fl : pc.get_province().get_factory_location()) {
983 if(fl.get_factory().get_building_type().get_output() == com)
984 amount += fl.get_factory().get_actual_production();
985 }
986 }
987 total += amount;
988 distribution.emplace_back(state.culture_definitions.capitalists, amount);
989 }
990 {
991 float amount = 0.f;
992 for(const auto pc : state.world.nation_get_province_control(state.local_player_nation)) {
993 amount += pc.get_province().get_rgo_actual_production_per_good(com);
994 }
995 total += amount;
996 distribution.emplace_back(state.culture_definitions.aristocrat, amount);
997 }
998 {
999 auto amount = state.world.nation_get_artisan_actual_production(state.local_player_nation, com);
1000 total += amount;
1001 distribution.emplace_back(state.culture_definitions.artisans, amount);
1002 }
1003 // remaining
1004 auto produced = state.world.nation_get_domestic_market_pool(state.local_player_nation, com);
1005 if(produced >= total) {
1006 distribution.emplace_back(state.culture_definitions.laborers, total - produced);
1007 }
1008 update_chart(state);
1009 }
1010};
1011
1013public:
1014 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1015 if(name == "current_price_label") {
1016 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1017 ptr->set_text(state, text::produce_simple_string(state, "alice_trade_flow_label"));
1018 ptr->base_data.size.x *= 2; // Nudge
1019 return ptr;
1020 } else if(name == "current_price_value"
1021 || name == "price_linechart"
1022 || name == "price_chart_low"
1023 || name == "price_chart_time") {
1024 return make_element_by_type<invisible_element>(state, id);
1025 } else if(name == "price_chart_high") {
1026 auto ptr = make_element_by_type<invisible_element>(state, id);
1027 {
1028 auto ov_elm = make_element_by_type<image_element_base>(state, "generic_piechart_overlay");
1029 ov_elm->base_data.position.x = ptr->base_data.position.x;
1030 ov_elm->base_data.position.y = ptr->base_data.position.y;
1031 auto pc_elm = make_element_by_type<trade_flow_producers_piechart>(state, "generic_piechart");
1032 pc_elm->base_data.position.x += ov_elm->base_data.position.x;
1033 pc_elm->base_data.position.y += ov_elm->base_data.position.y;
1034 auto lg_elm = make_element_by_type<simple_text_element_base>(state, id);
1035 lg_elm->set_text(state, text::produce_simple_string(state, "alice_trade_flow_piechart_producers"));
1036 lg_elm->base_data.position.x = ptr->base_data.position.x;
1037 lg_elm->base_data.position.y = ptr->base_data.position.y - 8;
1038 add_child_to_front(std::move(lg_elm));
1039 add_child_to_front(std::move(pc_elm));
1040 add_child_to_front(std::move(ov_elm));
1041 }
1042 {
1043 auto ov_elm = make_element_by_type<image_element_base>(state, "generic_piechart_overlay");
1044 ov_elm->base_data.position.x = ptr->base_data.position.x + (ov_elm->base_data.size.x + 20) * 1;
1045 ov_elm->base_data.position.y = ptr->base_data.position.y;
1046 auto pc_elm = make_element_by_type<trade_flow_consumers_piechart>(state, "generic_piechart");
1047 pc_elm->base_data.position.x += ov_elm->base_data.position.x;
1048 pc_elm->base_data.position.y += ov_elm->base_data.position.y;
1049 auto lg_elm = make_element_by_type<simple_text_element_base>(state, id);
1050 lg_elm->set_text(state, text::produce_simple_string(state, "alice_trade_flow_piechart_consumers"));
1051 lg_elm->base_data.position.x = ptr->base_data.position.x + (ov_elm->base_data.size.x + 20) * 1;
1052 lg_elm->base_data.position.y = ptr->base_data.position.y - 8;
1053 add_child_to_front(std::move(lg_elm));
1054 add_child_to_front(std::move(pc_elm));
1055 add_child_to_front(std::move(ov_elm));
1056 }
1057 {
1058 auto ov_elm = make_element_by_type<image_element_base>(state, "generic_piechart_overlay");
1059 ov_elm->base_data.position.x = ptr->base_data.position.x + (ov_elm->base_data.size.x + 20) * 2;
1060 ov_elm->base_data.position.y = ptr->base_data.position.y;
1061 auto pc_elm = make_element_by_type<trade_flow_workers_piechart>(state, "generic_piechart");
1062 pc_elm->base_data.position.x += ov_elm->base_data.position.x;
1063 pc_elm->base_data.position.y += ov_elm->base_data.position.y;
1064 auto lg_elm = make_element_by_type<simple_text_element_base>(state, id);
1065 lg_elm->set_text(state, text::produce_simple_string(state, "alice_trade_flow_piechart_workforce"));
1066 lg_elm->base_data.position.x = ptr->base_data.position.x + (ov_elm->base_data.size.x + 20) * 2;
1067 lg_elm->base_data.position.y = ptr->base_data.position.y - 8;
1068 add_child_to_front(std::move(lg_elm));
1069 add_child_to_front(std::move(pc_elm));
1070 add_child_to_front(std::move(ov_elm));
1071 }
1072 return ptr;
1073 } else {
1074 return nullptr;
1075 }
1076 }
1077};
1078
1080public:
1081 void on_update(sys::state& state) noexcept override {
1082 auto commodity_id = retrieve<dcon::commodity_id>(state, parent);
1083
1084 auto amount = 0.f;
1085 for(auto const fat_stown_id : state.world.nation_get_state_ownership(state.local_player_nation)) {
1086 province::for_each_province_in_state_instance(state, fat_stown_id.get_state(), [&](dcon::province_id pid) {
1087 auto fat_id = dcon::fatten(state.world, pid);
1088 fat_id.for_each_factory_location_as_province([&](dcon::factory_location_id flid) {
1089 auto fid = state.world.factory_location_get_factory(flid);
1090 auto ftid = state.world.factory_get_building_type(fid);
1091 if(state.world.factory_type_get_output(ftid) == commodity_id)
1092 amount += state.world.factory_get_actual_production(fid);
1093 });
1094 if(state.world.province_get_rgo(pid) == commodity_id)
1095 amount += state.world.province_get_rgo_actual_production_per_good(pid, commodity_id);
1096 });
1097 }
1098
1099 set_text(state, text::format_float(amount, 2));
1100 }
1101};
1103public:
1104 void on_update(sys::state& state) noexcept override {
1105 auto commodity_id = retrieve<dcon::commodity_id>(state, parent);
1106 set_text(state, text::format_float(economy::nation_factory_consumption(state, state.local_player_nation, commodity_id), 2));
1107 }
1108};
1109
1111public:
1112 void on_create(sys::state& state) noexcept override {
1113 window_element_base::on_create(state);
1114 set_visible(state, false);
1115 }
1116
1117 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1118 if(name == "close_button") {
1119 return make_element_by_type<generic_close_button>(state, id);
1120 } else if(name == "trade_flow_bg") {
1121 return make_element_by_type<draggable_target>(state, id);
1122 } else if(name == "material_name") {
1123 return make_element_by_type<generic_name_text<dcon::commodity_id>>(state, id);
1124 } else if(name == "material_icon_big") {
1125 return make_element_by_type<commodity_image>(state, id);
1126 } else if(name == "header_produced_by") {
1127 auto ptr = make_element_by_type<single_multiline_text_element_base>(state, id);
1128 ptr->text_id = text::find_or_add_key(state, "alice_trade_flow_produced", true);
1129 return ptr;
1130 } else if(name == "header_used_by") {
1131 auto ptr = make_element_by_type<single_multiline_text_element_base>(state, id);
1132 ptr->text_id = text::find_or_add_key(state, "alice_trade_flow_consumed", true);
1133 return ptr;
1134 } else if(name == "header_may_be_used_by") {
1135 auto ptr = make_element_by_type<single_multiline_text_element_base>(state, id);
1136 ptr->text_id = text::find_or_add_key(state, "trade_flow_may_be_used", true);
1137 return ptr;
1138 } else if(name == "total_produced_text") {
1139 auto ptr = make_element_by_type<single_multiline_text_element_base>(state, id);
1140 ptr->text_id = text::find_or_add_key(state, "trade_flow_total_produced", true);
1141 ptr->base_data.position.x += 48; // Nudge
1142 return ptr;
1143 } else if(name == "total_used_text") {
1144 auto ptr = make_element_by_type<single_multiline_text_element_base>(state, id);
1145 ptr->text_id = text::find_or_add_key(state, "trade_flow_total_used", true);
1146 ptr->base_data.position.x += 48; // Nudge
1147 return ptr;
1148 } else if(name == "total_produced_value") {
1149 return make_element_by_type<trade_flow_total_produced_text>(state, id);
1150 } else if(name == "total_used_value") {
1151 return make_element_by_type<trade_flow_total_used_text>(state, id);
1152 } else if(name == "price_graph") {
1153 return make_element_by_type<trade_flow_price_graph_window>(state, id);
1154 } else if(name == "produced_by_listbox") {
1155 return make_element_by_type<trade_flow_produced_by_listbox>(state, id);
1156 } else if(name == "used_by_listbox") {
1157 return make_element_by_type<trade_flow_used_by_listbox>(state, id);
1158 } else if(name == "may_be_used_by_listbox") {
1159 return make_element_by_type<trade_flow_may_be_used_by_listbox>(state, id);
1160 } else {
1161 return nullptr;
1162 }
1163 }
1164};
1165
1166template<sys::commodity_group Group>
1168public:
1169 void on_create(sys::state& state) noexcept override {
1170 window_element_base::on_create(state);
1171 xy_pair cell_size = state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("goods_entry_offset"))->second.definition].position;
1172 xy_pair offset{0, 0};
1173 state.world.for_each_commodity([&](dcon::commodity_id id) {
1174 if(sys::commodity_group(state.world.commodity_get_commodity_group(id)) != Group)
1175 return;
1176 auto ptr = make_element_by_type<trade_commodity_entry>(state, state.ui_state.defs_by_name.find(state.lookup_key("goods_entry"))->second.definition);
1177 ptr->commodity_id = id;
1178 ptr->base_data.position = offset;
1179 offset.x += cell_size.x;
1180 if(offset.x + cell_size.x - 1 >= base_data.size.x) {
1181 offset.x = 0;
1182 offset.y += cell_size.y;
1183 if(offset.y + cell_size.y >= base_data.size.y) {
1184 offset.x += cell_size.x;
1185 offset.y = 0;
1186 }
1187 }
1188 add_child_to_front(std::move(ptr));
1189 });
1190 }
1191};
1192
1193std::string name_view_commodity_id(sys::state& state, element_base* container, dcon::commodity_id item) {
1195 state,
1196 dcon::fatten(state.world, item)
1197 );
1198};
1199
1200bool compare_price(sys::state& state, element_base* container, const dcon::commodity_id a, const dcon::commodity_id b) {
1201 auto price_a = state.world.commodity_get_current_price(a);
1202 auto price_b = state.world.commodity_get_current_price(b);
1203 return price_a < price_b;
1204}
1205
1206std::string price_view_commodity_id(sys::state& state, element_base* container, dcon::commodity_id item) {
1207 return text::format_money(state.world.commodity_get_current_price(item));
1208};
1209std::string supply_view_commodity_id(sys::state& state, element_base* container, dcon::commodity_id item) {
1210 return text::format_float(state.world.commodity_get_total_production(item));
1211};
1212std::string demand_view_commodity_id(sys::state& state, element_base* container, dcon::commodity_id item) {
1213 return text::format_float(state.world.commodity_get_total_real_demand(item));
1214};
1215std::string balance_view_commodity_id(sys::state& state, element_base* container, dcon::commodity_id item) {
1216 auto supply = state.world.commodity_get_total_production(item);
1217 auto demand = state.world.commodity_get_total_real_demand(item);
1218 auto balance = supply - demand;
1220};
1221std::string stockpile_market_view_commodity_id(sys::state& state, element_base* container, dcon::commodity_id item) {
1222 return text::format_float(state.world.commodity_get_global_market_pool(item));
1223};
1224std::string stockpile_player_view_commodity_id(sys::state& state, element_base* container, dcon::commodity_id item) {
1225 return text::format_float(state.world.nation_get_stockpiles(state.local_player_nation, item));
1226};
1227std::string stockpile_target_player_view_commodity_id(sys::state& state, element_base* container, dcon::commodity_id item) {
1228 return text::format_float(state.world.nation_get_stockpile_targets(state.local_player_nation, item));
1229};
1230
1231bool compare_name(sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
1232 auto value_a = text::get_name_as_string(
1233 state,
1234 dcon::fatten(state.world, a)
1235 );
1236 auto value_b = text::get_name_as_string(
1237 state,
1238 dcon::fatten(state.world, b)
1239 );
1240 return value_a < value_b;
1241}
1242bool compare_supply(sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
1243 auto value_a = state.world.commodity_get_total_production(a);
1244 auto value_b = state.world.commodity_get_total_production(b);
1245 return value_a < value_b;
1246}
1247bool compare_demand(sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
1248 auto value_a = state.world.commodity_get_total_real_demand(a);
1249 auto value_b = state.world.commodity_get_total_real_demand(b);
1250 return value_a < value_b;
1251}
1252bool compare_balance(sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
1253 auto supply_a = state.world.commodity_get_total_production(a);
1254 auto demand_a = state.world.commodity_get_total_real_demand(a);
1255 auto balance_a = supply_a - demand_a;
1256
1257 auto supply_b = state.world.commodity_get_total_production(b);
1258 auto demand_b = state.world.commodity_get_total_real_demand(b);
1259 auto balance_b = supply_b - demand_b;
1260
1261 return balance_a < balance_b;
1262}
1263bool compare_stockpile_market(sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
1264 auto value_a = state.world.commodity_get_global_market_pool(a);
1265 auto value_b = state.world.commodity_get_global_market_pool(b);
1266 return value_a < value_b;
1267}
1268bool compare_stockpile_player(sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
1269 auto value_a = state.world.nation_get_stockpiles(state.local_player_nation, a);
1270 auto value_b = state.world.nation_get_stockpiles(state.local_player_nation, b);
1271 return value_a < value_b;
1272}
1273
1275 .sortable = true,
1276 .header = "trade_good_name_header",
1277 .compare = compare_name,
1278 .view = name_view_commodity_id,
1279 .cell_definition_string = "thin_cell_name",
1280 .header_definition_string = "thin_cell_name"
1281};
1283 .sortable = true,
1284 .header = "price",
1285 .compare = compare_price,
1287 .cell_definition_string = "thin_cell_number"
1288};
1289
1291 .sortable = true,
1292 .header = "supply",
1293 .compare = compare_supply,
1295 .cell_definition_string = "thin_cell_number"
1296};
1298 .sortable = true,
1299 .header = "demand",
1300 .compare = compare_demand,
1302 .cell_definition_string = "thin_cell_number"
1303};
1305 .sortable = true,
1306 .header = "balance",
1307 .compare = compare_balance,
1309 .cell_definition_string = "thin_cell_number"
1310};
1312 .sortable = true,
1313 .header = "market_stockpiles",
1314 .compare = compare_stockpile_market,
1316 .cell_definition_string = "thin_cell_number"
1317};
1319 .sortable = true,
1320 .header = "national_stockpile",
1321 .compare = compare_stockpile_player,
1323 .cell_definition_string = "thin_cell_number"
1324};
1325
1326
1328 .sortable = true,
1329 .header = "government_need",
1330 .compare = [](sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
1331 auto av = economy::government_consumption(state, state.local_player_nation, a);
1332 auto bv = economy::government_consumption(state, state.local_player_nation, b);
1333 if(av != bv)
1334 return av > bv;
1335 else
1336 return a.index() < b.index();
1337 },
1338 .view = [](sys::state& state, element_base* container, dcon::commodity_id id) {
1339 auto value = economy::government_consumption(state, state.local_player_nation, id);
1340 return text::format_float(value);
1341 }
1342};
1343
1345 .sortable = true,
1346 .header = "factory_need",
1347 .compare = [](sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
1348 auto av = economy::nation_factory_consumption(state, state.local_player_nation, a);
1349 auto bv = economy::nation_factory_consumption(state, state.local_player_nation, b);
1350 if(av != bv)
1351 return av > bv;
1352 else
1353 return a.index() < b.index();
1354 },
1355 .view = [](sys::state& state, element_base* container, dcon::commodity_id id) {
1356 auto value = economy::nation_factory_consumption(state, state.local_player_nation, id);
1357 return text::format_float(value);
1358 }
1359};
1360
1362 .sortable = true,
1363 .header = "pop_need",
1364 .compare = [](sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
1365 auto av = economy::nation_pop_consumption(state, state.local_player_nation, a);
1366 auto bv = economy::nation_pop_consumption(state, state.local_player_nation, b);
1367 if(av != bv)
1368 return av > bv;
1369 else
1370 return a.index() < b.index();
1371 },
1372 .view = [](sys::state& state, element_base* container, dcon::commodity_id id) {
1373 auto value = economy::nation_pop_consumption(state, state.local_player_nation, id);
1374 return text::format_float(value);
1375 }
1376};
1377
1379 .sortable = true,
1380 .header = "rgo_production",
1381 .compare = [](sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
1382 auto av = 0.f;
1383 auto bv = 0.f;
1384 for(auto p : state.world.in_province) {
1385 if(p.get_nation_from_province_ownership()) {
1386 av += p.get_rgo_actual_production_per_good(a);
1387 }
1388 }
1389 for(auto p : state.world.in_province) {
1390 if(p.get_nation_from_province_ownership()) {
1391 bv += p.get_rgo_actual_production_per_good(b);
1392 }
1393 }
1394 if(av != bv)
1395 return av > bv;
1396 else
1397 return a.index() < b.index();
1398 },
1399 .view = [](sys::state& state, element_base* container, dcon::commodity_id id) {
1400 auto value = 0.f;
1401 for(auto p : state.world.in_province) {
1402 if(p.get_nation_from_province_ownership()) {
1403 value += p.get_rgo_actual_production_per_good(id);
1404 }
1405 }
1406 return text::format_float(value);
1407 }
1408};
1409
1411 .sortable = true,
1412 .header = "artisan_production",
1413 .compare = [](sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
1414 auto av = 0.f;
1415 auto bv = 0.f;
1416 for(auto n : state.world.in_nation) {
1417 av += state.world.nation_get_artisan_actual_production(n, a);
1418 }
1419 for(auto n : state.world.in_nation) {
1420 bv += state.world.nation_get_artisan_actual_production(n, b);
1421 }
1422 if(av != bv)
1423 return av > bv;
1424 else
1425 return a.index() < b.index();
1426 },
1427 .view = [](sys::state& state, element_base* container, dcon::commodity_id id) {
1428 auto value = 0.f;
1429 for(auto n : state.world.in_nation) {
1430 value += state.world.nation_get_artisan_actual_production(n, id);
1431 }
1432 return text::format_float(value);
1433 }
1434};
1435
1437 .sortable = true,
1438 .header = "factory_production",
1439 .compare = [](sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
1440 auto av = 0.f;
1441 auto bv = 0.f;
1442 for(auto f : state.world.in_factory) {
1443 if(f.get_building_type().get_output() == a)
1444 av += f.get_actual_production();
1445 }
1446 for(auto f : state.world.in_factory) {
1447 if(f.get_building_type().get_output() == b)
1448 bv += f.get_actual_production();
1449 }
1450 if(av != bv)
1451 return av > bv;
1452 else
1453 return a.index() < b.index();
1454 },
1455 .view = [](sys::state& state, element_base* container, dcon::commodity_id id) {
1456 auto value = 0.f;
1457 for(auto f : state.world.in_factory) {
1458 if(f.get_building_type().get_output() == id)
1459 value += f.get_actual_production();
1460 }
1461 return text::format_float(value);
1462 }
1463};
1464
1466 .sortable = true,
1467 .header = "artisan_distribution",
1468 .compare = [](sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
1469 auto av = economy::get_artisan_distribution_slow(state, state.local_player_nation, a);
1470 auto bv = economy::get_artisan_distribution_slow(state, state.local_player_nation, b);
1471 if(av != bv)
1472 return av > bv;
1473 else
1474 return a.index() < b.index();
1475 },
1476 .view = [](sys::state& state, element_base* container, dcon::commodity_id id) {
1477 auto value = economy::get_artisan_distribution_slow(state, state.local_player_nation, id) * 1000.f;
1478 return text::format_float(value, 4);
1479 }
1480};
1481
1483 .sortable = true,
1484 .header = "artisan_distribution",
1485 .compare = [](sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
1486 auto av = state.world.nation_get_demand_satisfaction(state.local_player_nation, a);
1487 auto bv = state.world.nation_get_demand_satisfaction(state.local_player_nation, b);
1488 if(av != bv)
1489 return av > bv;
1490 else
1491 return a.index() < b.index();
1492 },
1493 .view = [](sys::state& state, element_base* container, dcon::commodity_id id) {
1494 auto value = state.world.nation_get_demand_satisfaction(state.local_player_nation, id);
1495 return text::format_percentage(value, 1);
1496 }
1497};
1498
1500 .sortable = true,
1501 .header = "produced_nation",
1502 .compare = [](sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
1503 auto av = state.world.nation_get_domestic_market_pool(state.local_player_nation, a);
1504 auto bv = state.world.nation_get_domestic_market_pool(state.local_player_nation, b);
1505 if(av != bv)
1506 return av > bv;
1507 else
1508 return a.index() < b.index();
1509 },
1510 .view = [](sys::state& state, element_base* container, dcon::commodity_id id) {
1511 auto value = state.world.nation_get_domestic_market_pool(state.local_player_nation, id);
1512 return text::format_float(value, 1);
1513 }
1514};
1515
1517 .sortable = true,
1518 .header = "consumed_nation",
1519 .compare = [](sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
1520 auto av = state.world.nation_get_real_demand(state.local_player_nation, a)
1521 * state.world.nation_get_demand_satisfaction(state.local_player_nation, a);
1522 auto bv = state.world.nation_get_real_demand(state.local_player_nation, b)
1523 * state.world.nation_get_demand_satisfaction(state.local_player_nation, b);
1524 if(av != bv)
1525 return av > bv;
1526 else
1527 return a.index() < b.index();
1528 },
1529 .view = [](sys::state& state, element_base* container, dcon::commodity_id id) {
1530 auto value = state.world.nation_get_real_demand(state.local_player_nation, id) *
1531 state.world.nation_get_demand_satisfaction(state.local_player_nation, id);
1532 return text::format_float(value, 1);
1533 }
1534};
1535
1537 .sortable = true,
1538 .header = "nation_name",
1539 .compare = [](sys::state& state, element_base* container, dcon::nation_id a, dcon::nation_id b) {
1542 if(av != bv)
1543 return av > bv;
1544 else
1545 return a.index() < b.index();
1546 },
1547 .view = [](sys::state& state, element_base* container, dcon::nation_id id) {
1549 return value;
1550 },
1551 .cell_definition_string = "thin_cell_name",
1552 .header_definition_string = "thin_cell_name"
1553};
1554
1556 .sortable = true,
1557 .header = "produced_nation",
1558 .compare = [](sys::state& state, element_base* container, dcon::nation_id a, dcon::nation_id b) {
1559 dcon::commodity_id good = retrieve<dcon::commodity_id>(state, container);
1560 auto av = state.world.nation_get_domestic_market_pool(a, good);
1561 auto bv = state.world.nation_get_domestic_market_pool(b, good);
1562 if(av != bv)
1563 return av > bv;
1564 else
1565 return a.index() < b.index();
1566 },
1567 .view = [](sys::state& state, element_base* container, dcon::nation_id id) {
1568 dcon::commodity_id good = retrieve<dcon::commodity_id>(state, container);
1569 auto value = state.world.nation_get_domestic_market_pool(id, good);
1570 return text::format_float(value, 1);
1571 }
1572};
1573
1575 .sortable = true,
1576 .header = "demanded_nation",
1577 .compare = [](sys::state& state, element_base* container, dcon::nation_id a, dcon::nation_id b) {
1578 dcon::commodity_id good = retrieve<dcon::commodity_id>(state, container);
1579 auto av = state.world.nation_get_real_demand(a, good);
1580 auto bv = state.world.nation_get_real_demand(b, good);
1581 if(av != bv)
1582 return av > bv;
1583 else
1584 return a.index() < b.index();
1585 },
1586 .view = [](sys::state& state, element_base* container, dcon::nation_id id) {
1587 dcon::commodity_id good = retrieve<dcon::commodity_id>(state, container);
1588 auto value = state.world.nation_get_real_demand(id, good);
1589 return text::format_float(value, 1);
1590 }
1591};
1592
1594 .sortable = true,
1595 .header = "consumed_nation",
1596 .compare = [](sys::state& state, element_base* container, dcon::nation_id a, dcon::nation_id b) {
1597 dcon::commodity_id good = retrieve<dcon::commodity_id>(state, container);
1598 auto av = state.world.nation_get_real_demand(a, good)
1599 * state.world.nation_get_demand_satisfaction(a, good);
1600 auto bv = state.world.nation_get_real_demand(b, good)
1601 * state.world.nation_get_demand_satisfaction(b, good);
1602 if(av != bv)
1603 return av > bv;
1604 else
1605 return a.index() < b.index();
1606 },
1607 .view = [](sys::state& state, element_base* container, dcon::nation_id id) {
1608 dcon::commodity_id good = retrieve<dcon::commodity_id>(state, container);
1609 auto value = state.world.nation_get_real_demand(id, good)
1610 * state.world.nation_get_demand_satisfaction(id, good);
1611 return text::format_float(value, 1);
1612 }
1613};
1614
1615/*
1616* MOVE TO PRODUCTION METHODS TABLE
1617text::add_line(state, contents, "w_artisan_profit", text::variable_type::x, text::fp_one_place{ economy::base_artisan_profit(state, state.local_player_nation, com) * economy::artisan_scale_limit(state, state.local_player_nation, com) });
1618*/
1619
1621public:
1622 void button_action(sys::state& state) noexcept override {
1623 auto commodity_id = retrieve<dcon::commodity_id>(state, parent);
1624 Cyto::Any dt_payload = trade_details_open_window{commodity_id};
1625 state.ui_state.trade_subwindow->impl_get(state, dt_payload);
1626 }
1627};
1628
1630public:
1631 void button_action(sys::state& state) noexcept override {
1632 // TODO: change stockpile settings option?
1633 //float famount = retrieve<float>(state, parent);
1634 //auto cid = retrieve<dcon::commodity_id>(state, parent);
1635 //command::change_stockpile_settings(state, state.local_player_nation, cid, famount, false);
1636 }
1637};
1638
1640public:
1642 : line_graph(32) { }
1643
1644 void on_create(sys::state& state) noexcept override {
1645 line_graph::on_create(state);
1646 }
1647
1648 void on_update(sys::state& state) noexcept override {
1649 auto com = retrieve<dcon::commodity_id>(state, parent);
1650
1652
1653 std::vector<float> datapoints(32);
1655 for(uint32_t i = 0; i < 32; ++i) {
1656 datapoints[i] = state.world.commodity_get_price_record(com, (newest_index + i + economy::price_history_length - 32) % economy::price_history_length);
1657 }
1658 set_data_points(state, datapoints);
1659 }
1660 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
1661 auto com = retrieve<dcon::commodity_id>(state, parent);
1662 line_graph::render(state, x, y);
1663 }
1664};
1665
1667public:
1668 void on_update(sys::state& state) noexcept override {
1669 auto com = retrieve<dcon::commodity_id>(state, parent);
1670
1672 float max_price = state.world.commodity_get_price_record(com, newest_index);
1673
1674 for(int32_t i = 1; i < 32; ++i) {
1675 max_price = std::max(state.world.commodity_get_price_record(com, (newest_index + i + economy::price_history_length - 32) % economy::price_history_length), max_price);
1676 }
1677 set_text(state, text::format_money(max_price));
1678 }
1679};
1680
1682public:
1683 void on_update(sys::state& state) noexcept override {
1684 auto com = retrieve<dcon::commodity_id>(state, parent);
1685
1687 float min_price = state.world.commodity_get_price_record(com, newest_index);
1688
1689 for(int32_t i = 1; i < 32; ++i) {
1690 min_price = std::min(state.world.commodity_get_price_record(com, (newest_index + i + economy::price_history_length - 32) % economy::price_history_length), min_price);
1691 }
1692 set_text(state, text::format_money(min_price));
1693 }
1694};
1695
1697public:
1698 void on_update(sys::state& state) noexcept override {
1699 auto com = retrieve<dcon::commodity_id>(state, parent);
1700 if(state.world.nation_get_drawing_on_stockpiles(state.local_player_nation, com)) {
1701 frame = 1;
1702 } else {
1703 frame = 0;
1704 }
1705 }
1706
1707 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
1708 auto com = retrieve<dcon::commodity_id>(state, parent);
1709 button_element_base::render(state, x, y);
1710 }
1711
1712 void button_action(sys::state& state) noexcept override {
1713 auto com = retrieve<dcon::commodity_id>(state, parent);
1714 command::change_stockpile_settings(state, state.local_player_nation, com, state.world.nation_get_stockpile_targets(state.local_player_nation, com), !state.world.nation_get_drawing_on_stockpiles(state.local_player_nation, com));
1715 }
1716};
1717
1719public:
1720 void on_update(sys::state& state) noexcept override {
1721 auto com = retrieve<dcon::commodity_id>(state, parent);
1722 set_text(state, text::produce_simple_string(state, state.world.nation_get_drawing_on_stockpiles(state.local_player_nation, com) ? "trade_use" : "trade_fill"));
1723 }
1724};
1725
1727public:
1728 void on_create(sys::state& state) noexcept override {
1729 set_text(state, text::produce_simple_string(state, "trade_stockpile_target"));
1730 }
1731 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
1732 auto com = retrieve<dcon::commodity_id>(state, parent);
1733 simple_text_element_base::render(state, x, y);
1734 }
1735};
1736
1738public:
1739 void on_create(sys::state& state) noexcept override {
1740
1741 }
1742 void on_update(sys::state& state) noexcept override {
1743 auto com = retrieve<dcon::commodity_id>(state, parent);
1744 set_text(state, text::produce_simple_string(state, "trade_stockpile_current") + text::format_float(state.world.nation_get_stockpiles(state.local_player_nation, com), 1));
1745 }
1746};
1747
1749public:
1750 void on_update(sys::state& state) noexcept override {
1751 auto com = retrieve<dcon::commodity_id>(state, parent);
1753 text::add_to_substitution_map(m, text::variable_type::val, text::pretty_integer{int64_t(state.world.nation_get_domestic_market_pool(state.local_player_nation, com))});
1754 set_text(state, text::resolve_string_substitution(state, "produced_detail_remove", m));
1755 }
1756};
1757
1759 float value;
1760};
1762 float value;
1763};
1764
1765class trade_slider : public scrollbar {
1766public:
1767 void on_value_change(sys::state& state, int32_t v) noexcept final {
1768 float a = std::pow(10.0f, float(v) * (6.0f / 2000.0f)) - 1.0f;
1769 send(state, parent, stockpile_target_change{a});
1770 if(state.ui_state.drag_target != slider)
1771 commit_changes(state);
1772 }
1773
1774 void on_update(sys::state& state) noexcept final {
1775 auto com = retrieve<dcon::commodity_id>(state, parent);
1776 if(!com)
1777 return;
1778
1779 if(state.ui_state.drag_target == slider) {
1780
1781 } else {
1782 auto value = state.world.nation_get_stockpile_targets(state.local_player_nation, com);
1783 auto a = std::log10(value + 1.0f);
1784 auto b = a * (2000.0f / 6.0f);
1785 update_raw_value(state, int32_t(b));
1786
1787 send(state, parent, stockpile_target_change{value});
1788 }
1789 }
1790 void impl_render(sys::state& state, int32_t x, int32_t y) noexcept override {
1791 auto com = retrieve<dcon::commodity_id>(state, parent);
1792 scrollbar::impl_render(state, x, y);
1793 }
1794 void on_drag_finish(sys::state& state) noexcept override {
1795 commit_changes(state);
1796 }
1798 auto com = retrieve<dcon::commodity_id>(state, parent);
1799 float v = std::pow(10.0f, float(raw_value()) * (6.0f / 2000.0f)) - 1.0f;
1800 command::change_stockpile_settings(state, state.local_player_nation, com, v, state.world.nation_get_drawing_on_stockpiles(state.local_player_nation, com));
1801 }
1802};
1803
1805public:
1806 void on_update(sys::state& state) noexcept override {
1807 auto com = retrieve<dcon::commodity_id>(state, parent);
1808 auto val = retrieve<get_stockpile_target>(state, parent);
1809 set_text(state, text::prettify(int64_t(val.value)));
1810 }
1811};
1812
1813
1815 simple_text_element_base* slider_value_display = nullptr;
1816
1817public:
1818 float trade_amount = 0.0f;
1819
1820 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1821 if(name == "trade_flow_bg") {
1822 return make_element_by_type<image_element_base>(state, id);
1823 } else if(name == "goods_icon") {
1824 return make_element_by_type<commodity_image>(state, id);
1825 } else if(name == "goods_title") {
1826 return make_element_by_type<generic_name_text<dcon::commodity_id>>(state, id);
1827 } else if(name == "goods_price") {
1828 return make_element_by_type<commodity_price_text>(state, id);
1829 } else if(name == "automate_label") {
1830 return make_element_by_type<invisible_element>(state, id);
1831 } else if(name == "automate") {
1832 return make_element_by_type<invisible_element>(state, id);
1833 } else if(name == "price_linechart") {
1834 return make_element_by_type<prices_line_graph>(state, id);
1835 } else if(name == "price_chart_low") {
1836 return make_element_by_type<price_chart_low>(state, id);
1837 } else if(name == "price_chart_high") {
1838 return make_element_by_type<price_chart_high>(state, id);
1839 } else if(name == "price_chart_time") {
1840 return make_element_by_type<invisible_element>(state, id);
1841 } else if(name == "sell_stockpile") {
1842 return make_element_by_type<stockpile_sell_button>(state, id);
1843 } else if(name == "sell_stockpile_label") {
1844 return make_element_by_type<stockpile_sell_label>(state, id);
1845 } else if(name == "sell_slidier_desc") {
1846 return make_element_by_type<stockpile_slider_label>(state, id);
1847 } else if(name == "sell_slider") {
1848 return make_element_by_type<trade_slider>(state, id);
1849 } else if(name == "slider_value") {
1850 auto ptr = make_element_by_type<trade_slider_amount>(state, id);
1851 slider_value_display = ptr.get();
1852 return ptr;
1853 } else if(name == "confirm_trade") {
1854 return make_element_by_type<stockpile_amount_label>(state, id);
1855 } else if(name == "goods_details") {
1856 return make_element_by_type<trade_details_button>(state, id);
1857 } else if(name == "goods_need_gov_desc") {
1858 return make_element_by_type<invisible_element>(state, id);
1859 } else if(name == "goods_need_factory_desc") {
1860 return make_element_by_type<invisible_element>(state, id);
1861 } else if(name == "produced_detail_desc") {
1862 return make_element_by_type<detail_domestic_production>(state, id);
1863 } else if(name == "goods_need_pop_desc") {
1864 return make_element_by_type<invisible_element>(state, id);
1865 } else {
1866 return nullptr;
1867 }
1868 }
1869
1870 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
1871 if(payload.holds_type<get_stockpile_target>()) {
1872 payload = get_stockpile_target{trade_amount};
1873 return message_result::consumed;
1874 } else if(payload.holds_type<stockpile_target_change>()) {
1875 trade_amount = any_cast<stockpile_target_change>(payload).value;
1876 slider_value_display->impl_on_update(state);
1877 return message_result::consumed;
1878 }
1879
1880 return message_result::unseen;
1881 }
1882};
1883
1885 uint8_t index = 0;
1886 uint8_t subindex = 0;
1887 uint8_t click_amount = 0;
1888public:
1889 void on_create(sys::state& state) noexcept override {
1890 button_element_base::on_create(state);
1891 subindex = 0;
1892 if(state.network_mode != sys::network_mode_type::single_player) {
1893 index = 3;
1894 } else {
1895 index = uint8_t(state.game_seed % 3);
1896 }
1897 }
1898
1899 void on_update(sys::state& state) noexcept override {
1900
1901 }
1902
1903 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
1904 if(index == 1 && subindex == 2) {
1905 return; //no render
1906 }
1907 button_element_base::render(state, x, y);
1908 }
1909
1910 void button_action(sys::state& state) noexcept override {
1911 if(index == 1) {
1912 click_amount++;
1913 if(click_amount >= 10)
1914 subindex = 1;
1915 if(click_amount >= 15)
1916 subindex = 2;
1917 }
1918 }
1919
1921 return tooltip_behavior::variable_tooltip;
1922 }
1923
1924 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1925 std::string key = "alice_stockpile_button_" + std::to_string(index) + "_" + std::to_string(subindex);
1926 text::add_line(state, contents, key);
1927 }
1928};
1929
1933
1935 void button_action(sys::state& state) noexcept override {
1936 signal_global_table signal{};
1937 send<signal_global_table>(state, parent, signal);
1938 }
1939};
1940
1942 void button_action(sys::state& state) noexcept override {
1943 signal_nation_table signal{};
1944 send<signal_nation_table>(state, parent, signal);
1945 }
1946};
1947
1949 void button_action(sys::state& state) noexcept override {
1950 signal_trade_good_table signal{};
1951 send<signal_trade_good_table>(state, parent, signal);
1952 }
1953};
1954
1956 trade_flow_window* trade_flow_win = nullptr;
1957 trade_details_window* details_win = nullptr;
1958 dcon::commodity_id commodity_id{1};
1959
1960 trade_market_activity_listbox* list_ma = nullptr;
1961 trade_stockpile_listbox* list_sp = nullptr;
1962 trade_common_market_listbox* list_cm = nullptr;
1963 trade_government_needs_listbox* list_gn = nullptr;
1964 trade_factory_needs_listbox* list_fn = nullptr;
1965 trade_pop_needs_listbox* list_pn = nullptr;
1966
1967 table::display<dcon::commodity_id>* table_nation = nullptr;
1968 table::display<dcon::commodity_id>* table_global = nullptr;
1969 table::display<dcon::nation_id>* table_trade_good_stats = nullptr;
1970
1971public:
1972 void on_create(sys::state& state) noexcept override {
1973 window_element_base::on_create(state);
1974
1975 auto ptr = make_element_by_type<trade_flow_window>(state, state.ui_state.defs_by_name.find(state.lookup_key("trade_flow"))->second.definition);
1976 trade_flow_win = ptr.get();
1977 add_child_to_front(std::move(ptr));
1978
1979 set_visible(state, false);
1980 }
1981
1982 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1983 if(name == "main_bg") {
1984 return make_element_by_type<image_element_base>(state, id);
1985 } else if(name == "bg_trade") {
1986 return make_element_by_type<opaque_element_base>(state, id);
1987 } else if(name == "close_button") {
1988 return make_element_by_type<generic_close_button>(state, id);
1989 } else if(name == "market_activity_list") {
1990 auto ptr = make_element_by_type<trade_market_activity_listbox>(state, id);
1991 list_ma = ptr.get();
1992 return ptr;
1993 } else if(name == "common_market_list") {
1994 auto ptr = make_element_by_type<trade_common_market_listbox>(state, id);
1995 list_cm = ptr.get();
1996 return ptr;
1997 } else if(name == "stockpile_list") {
1998 auto ptr = make_element_by_type<trade_stockpile_listbox>(state, id);
1999 list_sp = ptr.get();
2000 return ptr;
2001 } else if(name == "commodity_table_nation") {
2002 std::vector<table::column<dcon::commodity_id>> columns = {
2012 };
2013 auto ptr = make_element_by_type<table::display<dcon::commodity_id>>(
2014 state,
2015 id,
2016 std::string("commodity_table_body"),
2017 columns
2018 );
2019 table_nation = ptr.get();
2020 table_nation->row_callback = [](sys::state& state, ui::element_base* container, const dcon::commodity_id& a) {
2021 trade_details_select_commodity payload{ a };
2022 send<trade_details_select_commodity>(state, container, payload);
2023 };
2024 state.world.for_each_commodity([&](dcon::commodity_id id) {
2025 table_nation->content.data.push_back(id);
2026 });
2027 table_nation->set_visible(state, false);
2028 return ptr;
2029 } else if(name == "commodity_table_global") {
2030 std::vector<table::column<dcon::commodity_id>> columns = {
2040 };
2041 auto ptr = make_element_by_type<table::display<dcon::commodity_id>>(
2042 state,
2043 id,
2044 std::string("commodity_table_body"),
2045 columns
2046 );
2047 table_global = ptr.get();
2048 table_global->row_callback = [](sys::state& state, ui::element_base* container, const dcon::commodity_id& a) {
2049 trade_details_select_commodity payload{ a };
2050 send<trade_details_select_commodity>(state, container, payload);
2051 };
2052 state.world.for_each_commodity([&](dcon::commodity_id id) {
2053 table_global->content.data.push_back(id);
2054 });
2055 return ptr;
2056 } else if(name == "trade_good_global_stats") {
2057 std::vector<table::column<dcon::nation_id>> columns = {
2059 };
2060 auto ptr = make_element_by_type<table::display<dcon::nation_id>>(
2061 state,
2062 id,
2063 std::string("commodity_table_body"),
2064 columns
2065 );
2066 table_trade_good_stats = ptr.get();
2067 table_trade_good_stats->set_visible(state, false);
2068 state.world.for_each_nation([&](dcon::nation_id id) {
2069 table_trade_good_stats->content.data.push_back(id);
2070 });
2071 return ptr;
2072 } else if(name == "market_table_global") {
2073 return make_element_by_type<switch_to_global_button>(state, id);
2074 } else if(name == "market_table_nation") {
2075 return make_element_by_type<switch_to_nation_button>(state, id);
2076 } else if(name == "market_table_trade_good_global") {
2077 return make_element_by_type<switch_to_trade_good_button>(state, id);
2078 /* } else if(name == "group_raw_material_goods") {
2079 return make_element_by_type<trade_commodity_group_window<sys::commodity_group::raw_material_goods>>(state, id);
2080 } else if(name == "group_industrial_goods") {
2081 return make_element_by_type<trade_commodity_group_window<sys::commodity_group::industrial_goods>>(state, id);
2082 } else if(name == "group_consumer_goods") {
2083 return make_element_by_type<trade_commodity_group_window<sys::commodity_group::consumer_goods>>(state, id);
2084 } else if(name == "group_military_goods") {
2085 return make_element_by_type<trade_commodity_group_window<sys::commodity_group::military_goods>>(state, id);
2086 } else if(name == "government_needs_list") {
2087 auto ptr = make_element_by_type<trade_government_needs_listbox>(state, id);
2088 list_gn = ptr.get();
2089 return ptr;
2090 } else if(name == "factory_needs_list") {
2091 auto ptr = make_element_by_type<trade_factory_needs_listbox>(state, id);
2092 list_fn = ptr.get();
2093 return ptr;
2094 } else if(name == "pop_needs_list") {
2095 auto ptr = make_element_by_type<trade_pop_needs_listbox>(state, id);
2096 list_pn = ptr.get();
2097 return ptr;
2098 */
2099 } else if(name == "trade_details") {
2100 auto ptr = make_element_by_type<trade_details_window>(state, id);
2101 details_win = ptr.get();
2102 return ptr;
2103 } else if(name == "market_activity_sort_by_goods") {
2104 return make_element_by_type<trade_sort_button<trade_sort::commodity, trade_sort_assoc::market_activity>>(state, id);
2105 } else if(name == "market_activity_sort_by_activity") {
2106 return make_element_by_type<trade_sort_button<trade_sort::demand_satisfaction, trade_sort_assoc::market_activity>>(state, id);
2107 } else if(name == "market_activity_sort_by_cost") {
2108 return make_element_by_type<trade_sort_button<trade_sort::price, trade_sort_assoc::market_activity>>(state, id);
2109 } else if(name == "stockpile_sort_by_goods") {
2110 return make_element_by_type<trade_sort_button<trade_sort::commodity, trade_sort_assoc::stockpile>>(state, id);
2111 } else if(name == "stockpile_sort_by_value") {
2112 return make_element_by_type<trade_sort_button<trade_sort::stockpile, trade_sort_assoc::stockpile>>(state, id);
2113 } else if(name == "stockpile_sort_by_change") {
2114 return make_element_by_type<trade_sort_button<trade_sort::stockpile_change, trade_sort_assoc::stockpile>>(state, id);
2115 } else if(name == "common_market_sort_by_goods") {
2116 return make_element_by_type<trade_sort_button<trade_sort::commodity, trade_sort_assoc::common_market>>(state, id);
2117 } else if(name == "common_market_sort_by_produced") {
2118 return make_element_by_type<trade_sort_button<trade_sort::global_market_pool, trade_sort_assoc::common_market>>(state, id);
2119 } else if(name == "common_market_sort_by_diff") {
2120 return make_element_by_type<trade_sort_button<trade_sort::real_demand, trade_sort_assoc::common_market>>(state, id);
2121 } else if(name == "common_market_sort_by_exported") {
2122 return make_element_by_type<trade_sort_button<trade_sort::domestic_market, trade_sort_assoc::common_market>>(state, id);
2123 } else if(name == "needs_government_sort_by_goods") {
2124 return make_element_by_type<trade_sort_button<trade_sort::commodity, trade_sort_assoc::needs_government>>(state, id);
2125 } else if(name == "needs_government_sort_by_value") {
2126 return make_element_by_type<trade_sort_button<trade_sort::needs, trade_sort_assoc::needs_government>>(state, id);
2127 } else if(name == "needs_factories_sort_by_goods") {
2128 return make_element_by_type<trade_sort_button<trade_sort::commodity, trade_sort_assoc::needs_factories>>(state, id);
2129 } else if(name == "needs_factories_sort_by_value") {
2130 return make_element_by_type<trade_sort_button<trade_sort::needs, trade_sort_assoc::needs_factories>>(state, id);
2131 } else if(name == "needs_pops_sort_by_goods") {
2132 return make_element_by_type<trade_sort_button<trade_sort::commodity, trade_sort_assoc::needs_pops>>(state, id);
2133 } else if(name == "needs_pops_sort_by_value") {
2134 return make_element_by_type<trade_sort_button<trade_sort::needs, trade_sort_assoc::needs_pops>>(state, id);
2135 // Non-vanila
2136 } else if(name == "group_industrial_and_consumer_goods") {
2137 return make_element_by_type<trade_commodity_group_window<sys::commodity_group::industrial_and_consumer_goods>>(state, id);
2138 } else {
2139 return nullptr;
2140 }
2141 }
2142
2143 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
2144 // Special message rebroadcasted by the details button from the hierarchy
2145 if(payload.holds_type<signal_nation_table>()) {
2146 table_global->set_visible(state, false);
2147 table_nation->set_visible(state, true);
2148 table_trade_good_stats->set_visible(state, false);
2149 } else if(payload.holds_type<signal_global_table>()) {
2150 table_nation->set_visible(state, false);
2151 table_global->set_visible(state, true);
2152 table_trade_good_stats->set_visible(state, false);
2153 } else if(payload.holds_type<signal_trade_good_table>()) {
2154 table_nation->set_visible(state, false);
2155 table_global->set_visible(state, false);
2156 table_trade_good_stats->set_visible(state, true);
2157 } else if(payload.holds_type<dcon::commodity_id>()) {
2158 payload.emplace<dcon::commodity_id>(commodity_id);
2159 return message_result::consumed;
2160 } else if(payload.holds_type<trade_details_open_window>()) {
2161 commodity_id = any_cast<trade_details_open_window>(payload).commodity_id;
2162 trade_flow_win->set_visible(state, true);
2163 trade_flow_win->impl_on_update(state);
2164 return message_result::consumed;
2165 } else if(payload.holds_type<trade_details_select_commodity>()) {
2166 commodity_id = any_cast<trade_details_select_commodity>(payload).commodity_id;
2167 if(commodity_id)
2168 details_win->trade_amount = state.world.nation_get_stockpile_targets(state.local_player_nation, commodity_id);
2169 details_win->impl_on_update(state);
2170 return message_result::consumed;
2171 } else if(payload.holds_type<dcon::nation_id>()) {
2172 payload.emplace<dcon::nation_id>(state.local_player_nation);
2173 return message_result::consumed;
2174 } else if(payload.holds_type<trade_sort_data>()) {
2175 auto d = any_cast<trade_sort_data>(payload);
2176 switch(d.assoc) {
2177 case trade_sort_assoc::market_activity:
2178 if(list_ma->sort == d.sort)
2179 list_ma->sort_ascend = !list_ma->sort_ascend;
2180 else
2181 list_ma->sort_ascend = false;
2182 list_ma->sort = d.sort;
2183 list_ma->impl_on_update(state);
2184 break;
2185 case trade_sort_assoc::stockpile:
2186 if(list_sp->sort == d.sort)
2187 list_sp->sort_ascend = !list_sp->sort_ascend;
2188 else
2189 list_sp->sort_ascend = false;
2190 list_sp->sort = d.sort;
2191 list_sp->impl_on_update(state);
2192 break;
2193 case trade_sort_assoc::common_market:
2194 if(list_cm->sort == d.sort)
2195 list_cm->sort_ascend = !list_cm->sort_ascend;
2196 else
2197 list_cm->sort_ascend = false;
2198 list_cm->sort = d.sort;
2199 list_cm->impl_on_update(state);
2200 break;
2201 case trade_sort_assoc::needs_government:
2202 if(list_gn->sort == d.sort)
2203 list_gn->sort_ascend = !list_gn->sort_ascend;
2204 else
2205 list_gn->sort_ascend = false;
2206 list_gn->sort = d.sort;
2207 list_gn->impl_on_update(state);
2208 break;
2209 case trade_sort_assoc::needs_factories:
2210 if(list_fn->sort == d.sort)
2211 list_fn->sort_ascend = !list_fn->sort_ascend;
2212 else
2213 list_fn->sort_ascend = false;
2214 list_fn->sort = d.sort;
2215 list_fn->impl_on_update(state);
2216 break;
2217 case trade_sort_assoc::needs_pops:
2218 if(list_pn->sort == d.sort)
2219 list_pn->sort_ascend = !list_pn->sort_ascend;
2220 else
2221 list_pn->sort_ascend = false;
2222 list_pn->sort = d.sort;
2223 list_pn->impl_on_update(state);
2224 break;
2225 default:
2226 break;
2227 }
2228 return message_result::consumed;
2229 }
2230 return message_result::unseen;
2231 }
2232};
2233
2234} // namespace ui
ui::message_result get(sys::state &state, Cyto::Any &payload) noexcept override
Definition: table.hpp:426
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void add_child_to_front(std::unique_ptr< element_base > child) noexcept final
void impl_on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
element_base * parent
virtual message_result get(sys::state &state, Cyto::Any &payload) noexcept
virtual void impl_on_update(sys::state &state) noexcept
message_result impl_get(sys::state &state, Cyto::Any &payload) noexcept
void set_visible(sys::state &state, bool vis)
void on_create(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_create(sys::state &state) noexcept override
void render(sys::state &state, int32_t x, int32_t y) noexcept override
void set_text(sys::state &state, std::string const &new_text)
void on_update(sys::state &state) noexcept override
void on_create(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void on_create(sys::state &state) noexcept override
void render(sys::state &state, int32_t x, int32_t y) noexcept override
void button_action(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void render(sys::state &state, int32_t x, int32_t y) noexcept override
void button_action(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_create(sys::state &state) noexcept override
void render(sys::state &state, int32_t x, int32_t y) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void button_right_action(sys::state &state) noexcept override
void button_action(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
dcon::commodity_id commodity_id
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
void on_create(sys::state &state) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
std::string_view get_row_element_name() override
void on_update(sys::state &state) noexcept override
void on_create(sys::state &state) noexcept override
void button_action(sys::state &state) noexcept override
void button_action(sys::state &state) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
void on_update(sys::state &state) noexcept override
void on_create(sys::state &state) noexcept override
std::string_view get_row_element_name() override
void on_update(sys::state &state) noexcept override
bool operator==(trade_flow_data const &o) const
bool operator!=(trade_flow_data const &o) const
dcon::province_id province_id
union ui::trade_flow_data::@4 data
dcon::commodity_id trade_good
dcon::factory_id factory_id
dcon::province_id pop_province_id
void on_update(sys::state &state) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
std::string_view get_row_element_name() override
void populate_rows(sys::state &state, F &&factory_func, enum trade_flow_data::value_type vt)
void on_update(sys::state &state) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
void on_create(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
std::string_view get_row_element_name() override
void on_update(sys::state &state) noexcept override
void on_create(sys::state &state) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
void on_create(sys::state &state) noexcept override
std::string_view get_row_element_name() override
void on_update(sys::state &state) noexcept override
std::string_view get_row_element_name() override
void on_create(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void commit_changes(sys::state &state) noexcept
void impl_render(sys::state &state, int32_t x, int32_t y) noexcept override
void on_update(sys::state &state) noexcept final
void on_drag_finish(sys::state &state) noexcept override
void on_value_change(sys::state &state, int32_t v) noexcept final
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void button_action(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
void on_create(sys::state &state) noexcept override
std::string_view get_row_element_name() override
void on_update(sys::state &state) noexcept override
void on_create(sys::state &state) noexcept override
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
#define assert(condition)
Definition: debug.h:74
pop_satisfaction_wrapper_fat fatten(data_container const &c, pop_satisfaction_wrapper_id id) noexcept
float global_market_commodity_daily_increase(sys::state &state, dcon::commodity_id c)
Definition: economy.cpp:123
float government_consumption(sys::state &state, dcon::nation_id n, dcon::commodity_id c)
Definition: economy.cpp:4361
float nation_factory_consumption(sys::state &state, dcon::nation_id n, dcon::commodity_id c)
Definition: economy.cpp:4416
constexpr uint32_t price_history_length
Definition: economy.hpp:122
constexpr dcon::commodity_id money(0)
int32_t most_recent_price_record_index(sys::state &state)
Definition: economy.cpp:82
float stockpile_commodity_daily_increase(sys::state &state, dcon::commodity_id c, dcon::nation_id n)
Definition: economy.cpp:118
float get_artisan_distribution_slow(sys::state &state, dcon::nation_id n, dcon::commodity_id c)
Definition: economy.cpp:546
float nation_pop_consumption(sys::state &state, dcon::nation_id n, dcon::commodity_id c)
Definition: economy.cpp:4495
void for_each_province_in_state_instance(sys::state &state, dcon::state_instance_id s, F const &func)
uint32_t pack_color(float r, float g, float b)
commodity_group
Definition: constants.hpp:223
void add_to_layout_box(sys::state &state, layout_base &dest, layout_box &box, embedded_flag ico)
Definition: text.cpp:1165
std::string resolve_string_substitution(sys::state &state, dcon::text_key source_text, substitution_map const &mp)
Definition: text.cpp:2113
std::string format_money(float num)
Definition: text.cpp:1029
std::string get_name_as_string(sys::state &state, T t)
Definition: text.hpp:954
layout_box open_layout_box(layout_base &dest, int32_t indent)
Definition: text.cpp:1799
void localised_format_box(sys::state &state, layout_base &dest, layout_box &box, std::string_view key, text::substitution_map const &sub)
Definition: text.cpp:1880
std::string prettify(int64_t num)
Definition: text.cpp:762
std::string format_float(float num, size_t digits)
Definition: text.cpp:981
void add_line(sys::state &state, layout_base &dest, dcon::text_key txt, int32_t indent)
Definition: text.cpp:1899
void add_line_break_to_layout(sys::state &state, columnar_layout &dest)
Definition: text.cpp:1152
void add_to_substitution_map(substitution_map &mp, variable_type key, substitution value)
Definition: text.cpp:1068
ankerl::unordered_dense::map< uint32_t, substitution > substitution_map
Definition: text.hpp:794
std::string produce_simple_string(sys::state const &state, dcon::text_key id)
Definition: text.cpp:617
dcon::text_key get_name(sys::state &state, dcon::nation_id id)
Definition: text.cpp:880
std::string format_percentage(float num, size_t digits)
Definition: text.cpp:977
void add_space_to_layout_box(sys::state &state, layout_base &dest, layout_box &box)
Definition: text.cpp:1788
dcon::text_key find_or_add_key(sys::state &state, std::string_view key, bool as_unicode)
Definition: text.cpp:695
void close_layout_box(columnar_layout &dest, layout_box &box)
Definition: text.cpp:1807
table::column< dcon::commodity_id > trade_good_consumed_nation
std::string stockpile_target_player_view_commodity_id(sys::state &state, element_base *container, dcon::commodity_id item)
table::column< dcon::commodity_id > trade_good_satisfaction
table::column< dcon::commodity_id > trade_good_production_artisan
bool compare_stockpile_market(sys::state &state, element_base *container, dcon::commodity_id a, dcon::commodity_id b)
std::string price_view_commodity_id(sys::state &state, element_base *container, dcon::commodity_id item)
table::column< dcon::commodity_id > trade_good_production_factory
std::string stockpile_player_view_commodity_id(sys::state &state, element_base *container, dcon::commodity_id item)
bool compare_name(sys::state &state, element_base *container, dcon::commodity_id a, dcon::commodity_id b)
table::column< dcon::nation_id > nation_name
bool compare_stockpile_player(sys::state &state, element_base *container, dcon::commodity_id a, dcon::commodity_id b)
std::string supply_view_commodity_id(sys::state &state, element_base *container, dcon::commodity_id item)
bool compare_balance(sys::state &state, element_base *container, dcon::commodity_id a, dcon::commodity_id b)
table::column< dcon::commodity_id > trade_good_demand_column
bool compare_demand(sys::state &state, element_base *container, dcon::commodity_id a, dcon::commodity_id b)
table::column< dcon::commodity_id > trade_good_artisan_distribution
bool compare_supply(sys::state &state, element_base *container, dcon::commodity_id a, dcon::commodity_id b)
table::column< dcon::nation_id > nation_consumption
table::column< dcon::commodity_id > trade_good_player_gov_needs
table::column< dcon::nation_id > nation_demand
tooltip_behavior
void send(sys::state &state, element_base *parent, T value)
std::string stockpile_market_view_commodity_id(sys::state &state, element_base *container, dcon::commodity_id item)
std::string demand_view_commodity_id(sys::state &state, element_base *container, dcon::commodity_id item)
table::column< dcon::commodity_id > trade_good_player_pop_needs
message_result
std::string name_view_commodity_id(sys::state &state, element_base *container, dcon::commodity_id item)
table::column< dcon::commodity_id > trade_good_market_stockpile_column
table::column< dcon::commodity_id > trade_good_name_column
bool compare_price(sys::state &state, element_base *container, const dcon::commodity_id a, const dcon::commodity_id b)
table::column< dcon::commodity_id > trade_good_production_rgo
table::column< dcon::commodity_id > trade_good_produced_nation
table::column< dcon::commodity_id > trade_good_player_stockpile_column
table::column< dcon::commodity_id > trade_good_player_factory_needs
table::column< dcon::nation_id > nation_production
table::column< dcon::commodity_id > trade_good_price_column
std::string balance_view_commodity_id(sys::state &state, element_base *container, dcon::commodity_id item)
table::column< dcon::commodity_id > trade_good_supply_column
table::column< dcon::commodity_id > trade_good_balance_column
uint uint32_t
uchar uint8_t
@ ident
element_base * trade_subwindow
ankerl::unordered_dense::map< dcon::text_key, element_target, hash_text_key > defs_by_name
element_base * drag_target
trade_sort_assoc assoc