Project Alice
Loading...
Searching...
No Matches
gui_budget_window.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "color.hpp"
4#include "commands.hpp"
5#include "culture.hpp"
6#include "dcon_generated.hpp"
9#include "nations.hpp"
10#include "system_state.hpp"
11#include "text.hpp"
12
13namespace dcon {
15public:
21 return value;
22 }
23};
25 static dcon::text_key names[5];
26
27public:
29 void set_name(dcon::text_key text) noexcept {
30 names[value] = text;
31 }
32 dcon::text_key get_name() noexcept {
33 switch(value) {
34 case 0: // No needs fulfilled
35 case 1: // Some life needs
36 case 2: // All life needs, some everyday
37 case 3: // All everyday, some luxury
38 case 4: // All luxury
39 return names[value];
40 default:
41 return dcon::text_key{ 0 };
42 }
43 }
44};
45inline pop_satisfaction_wrapper_fat fatten(data_container const& c, pop_satisfaction_wrapper_id id) noexcept {
47}
48} // namespace dcon
49namespace ogl {
50template<>
52 switch(id.value) {
53 case 0: // red
54 return sys::pack_color(1.0f, 0.1f, 0.1f);
55 case 1: // yellow
56 return sys::pack_color(1.0f, 1.0f, 0.1f);
57 case 2: // green
58 return sys::pack_color(0.1f, 1.0f, 0.1f);
59 case 3: // blue
60 return sys::pack_color(0.1f, 0.1f, 1.0f);
61 case 4: // light blue
62 return sys::pack_color(0.1f, 1.0f, 1.0f);
63 }
64 return 0;
65}
66} // namespace ogl
67
68namespace ui {
69
71public:
72 void on_update(sys::state& state) noexcept override {
74 }
75};
76
78public:
79 void on_update(sys::state& state) noexcept override {
81 }
82};
83
85public:
86 void on_update(sys::state& state) noexcept override {
88 }
91 }
92 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
93 auto n = retrieve<dcon::nation_id>(state, parent);
94
95 float w_subsidies_amount =
98
99 if(w_subsidies_amount > 0.0f) {
102 auto box = text::open_layout_box(contents, 0);
103 text::localised_format_box(state, contents, box, "warsubsidies_income", m);
104 text::close_layout_box(contents, box);
105 } else if(w_subsidies_amount < 0.0f) {
108 auto box = text::open_layout_box(contents, 0);
109 text::localised_format_box(state, contents, box, "warsubsidies_expense", m);
110 text::close_layout_box(contents, box);
111 }
112
113 if(reparations_amount > 0.0f) {
116 auto box = text::open_layout_box(contents, 0);
117 text::localised_format_box(state, contents, box, "warindemnities_income", m);
118 text::close_layout_box(contents, box);
119 } else if(reparations_amount < 0.0f) {
122 auto box = text::open_layout_box(contents, 0);
123 text::localised_format_box(state, contents, box, "warindemnities_expense", m);
124 text::close_layout_box(contents, box);
125 }
126
127 auto subjectpayments_income = economy::estimate_subject_payments_received(state, n);
128 auto subjectpayments_expense = economy::estimate_subject_payments_paid(state, n);
129
130 if(subjectpayments_income != 0.0f) {
131 {
134 auto box = text::open_layout_box(contents, 0);
135 text::localised_format_box(state, contents, box, "subjectpayments_income", m);
136 text::close_layout_box(contents, box);
137 }
138
139 for(auto on : state.world.in_nation) {
140 auto rel = state.world.nation_get_overlord_as_subject(on);
141 auto overlord = state.world.overlord_get_ruler(rel);
142
143 if(overlord == n) {
145
149
150 auto box = text::open_layout_box(contents, 1);
151 text::localised_format_box(state, contents, box, "subjectpayments_income_row", m);
152 text::close_layout_box(contents, box);
153 }
154 }
155 }
156 if(subjectpayments_expense != 0.0f) {
159 auto box = text::open_layout_box(contents, 0);
160 text::localised_format_box(state, contents, box, "subjectpayments_expense", m);
161 text::close_layout_box(contents, box);
162 }
163 }
164};
165
167public:
168 void on_update(sys::state& state) noexcept override {
170 }
171};
172
174public:
175 void on_update(sys::state& state) noexcept override {
176 set_text(state, text::format_percentage(state.world.nation_get_administrative_efficiency(state.local_player_nation)));
177 }
180 }
181 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
182 auto n = state.local_player_nation;
183
184 {
187 text::fp_percentage{ 1.0f + state.world.nation_get_modifier_values(n, sys::national_mod_offsets::administrative_efficiency_modifier) });
188 auto box = text::open_layout_box(contents, 0);
189 text::localised_format_box(state, contents, box, "admin_explain_1", m);
190 text::close_layout_box(contents, box);
191 }
192 active_modifiers_description(state, contents, n, 15, sys::national_mod_offsets::administrative_efficiency_modifier,
193 false);
194 {
195 auto non_colonial = state.world.nation_get_non_colonial_population(n);
196 auto total = non_colonial > 0.0f ? state.world.nation_get_non_colonial_bureaucrats(n) / non_colonial : 0.0f;
197
200 auto box = text::open_layout_box(contents, 0);
201 text::localised_format_box(state, contents, box, "admin_explain_2", m);
202 text::close_layout_box(contents, box);
203 }
204 {
205 float issue_sum = 0.0f;
206 for(auto i : state.culture_definitions.social_issues) {
207 issue_sum = issue_sum + state.world.issue_option_get_administrative_multiplier(state.world.nation_get_issues(n, i));
208 }
209 auto from_issues = issue_sum * state.defines.bureaucracy_percentage_increment;
210
212 text::add_to_substitution_map(m, text::variable_type::val, text::fp_percentage{ (from_issues + state.defines.max_bureaucracy_percentage) });
213 text::add_to_substitution_map(m, text::variable_type::x, text::fp_percentage{ state.defines.max_bureaucracy_percentage });
215 auto box = text::open_layout_box(contents, 0);
216 text::localised_format_box(state, contents, box, "admin_explain_3", m);
217 text::close_layout_box(contents, box);
218 }
219 }
220};
221
222template<culture::pop_strata Strata>
224public:
226
227 void on_create(sys::state& state) noexcept override {
228 base_data.position.x -= 25;
229 base_data.size.x *= 2;
230 base_data.size.y *= 2;
231
232 is_coloured = true;
233 }
234
235 void on_update(sys::state& state) noexcept override {
236 if(parent == nullptr)
237 return;
238
239 float min = 0.f;
240
241 float max = 0.f;
242 for(auto prov : state.world.nation_get_province_ownership(state.local_player_nation)) {
243
244 for(auto pop_loc : prov.get_province().get_pop_location()) {
245 auto pop_id = pop_loc.get_pop();
246 auto pop_strata = state.world.pop_type_get_strata(state.world.pop_get_poptype(pop_id));
247 auto pop_size = pop_strata == uint8_t(Strata) ? state.world.pop_get_size(pop_id) : 0.f;
248
249 max += pop_size;
250 }
251 }
252
253 std::vector<float> datapoints(count);
254
255 float integral = 0.f;
256 float total_area = 0.f;
257
258 for(uint32_t i = 0; i < count; ++i) {
259 float cutoff = (float)i / count + 0.01f;
260 float value = 0.f;
261
262 for(auto prov : state.world.nation_get_province_ownership(state.local_player_nation)) {
263
264 for(auto pop_loc : prov.get_province().get_pop_location()) {
265 auto pop_id = pop_loc.get_pop();
266 auto pop_strata = state.world.pop_type_get_strata(state.world.pop_get_poptype(pop_id));
267 auto pop_size = pop_strata == uint8_t(Strata) ? state.world.pop_get_size(pop_id) : 0.f;
268
269 float total =
273
274 if(total / 3.f >= cutoff)
275 value += pop_size;
276
277 integral += total / 3.f * pop_size;
278 total_area += pop_size;
279 }
280 }
281
282 datapoints[i] = value;
283 }
284
285 float area_ratio = integral / (total_area + 0.0001f);
286 if(state.user_settings.color_blind_mode == sys::color_blind_mode::achroma) {
287 r = 0.f;
288 g = 0.f;
289 b = 0.f;
290 } else {
291 r = 1.f - area_ratio * 0.5f;
292 g = std::sqrt(area_ratio);
293 b = std::sqrt(area_ratio) * 0.8f;
294 }
295 set_data_points(state, datapoints, min, max);
296 }
297};
298
299template<culture::pop_strata Strata>
300class pop_satisfaction_piechart : public piechart<dcon::pop_satisfaction_wrapper_id> {
301protected:
302 void on_update(sys::state& state) noexcept override {
303 distribution.clear();
304
305 if(parent == nullptr)
306 return;
307
308 auto total = 0.f;
309 std::array<float, 5> sat_pool = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
310 for(auto prov : state.world.nation_get_province_ownership(state.local_player_nation)) {
311
312 for(auto pop_loc : prov.get_province().get_pop_location()) {
313 auto pop_id = pop_loc.get_pop();
314 auto pop_strata = state.world.pop_type_get_strata(state.world.pop_get_poptype(pop_id));
315 auto pop_size = pop_strata == uint8_t(Strata) ? state.world.pop_get_size(pop_id) : 0.f;
316 // All luxury needs
317 // OR All everyday needs
318 // OR All life needs
319 // OR Some life needs
320 // OR No needs fulfilled...
321 sat_pool[(pop_demographics::get_luxury_needs(state, pop_id) > 0.95f) ? 4
322 : (pop_demographics::get_everyday_needs(state, pop_id) > 0.95f) ? 3
323 : (pop_demographics::get_life_needs(state, pop_id) > 0.95f) ? 2
324 : (pop_demographics::get_life_needs(state, pop_id) > 0.01f) ? 1
325 : 0] += pop_size;
326 }
327 }
328
329 for(uint8_t i = 0; i < 5; i++)
330 distribution.emplace_back(dcon::pop_satisfaction_wrapper_id(i), sat_pool[i]);
331
333 }
334
335public:
336 void on_create(sys::state& state) noexcept override {
337 // Fill-in static information...
338 static bool has_run = false;
339 if(!has_run) {
341 .set_name(text::find_or_add_key(state, "BUDGET_STRATA_NO_NEED", false));
343 .set_name(text::find_or_add_key(state, "BUDGET_STRATA_NEED", false));
345 .set_name(text::find_or_add_key(state, "BUDGET_STRATA_NEED", false));
347 .set_name(text::find_or_add_key(state, "BUDGET_STRATA_NEED", false));
349 .set_name(text::find_or_add_key(state, "BUDGET_STRATA_NEED", false));
350 has_run = true;
351 }
353 }
354
356 text::columnar_layout& contents) noexcept override {
357 static const std::string needs_types[5] = {"no_need", "some_life_needs", "life_needs", "everyday_needs", "luxury_needs"};
358 auto fat_psw = dcon::fatten(state.world, psw);
359 auto box = text::open_layout_box(contents, 0);
360 auto sub = text::substitution_map{};
361 auto needs_type = text::produce_simple_string(state, needs_types[psw.value]);
363 text::add_to_substitution_map(sub, text::variable_type::type, std::string_view(needs_type));
364 text::add_to_layout_box(state, contents, box, fat_psw.get_name(), sub);
365 text::close_layout_box(contents, box);
366 }
367};
368
370 poor_tax,
372 rich_tax,
376 education,
377 admin,
378 social,
379 military,
380 tariffs,
382 raw,
383 //
384 overseas,
387 interest,
388 subsidies,
390 //
392};
393
395 linear,
397};
398
401};
402
405 float amount = 0.f;
406};
407
408template<budget_slider_target SliderTarget, slider_scaling SliderDisplayScaling, slider_update_type SliderUpdateType>
409class budget_slider : public scrollbar {
410public:
411
412 void on_create(sys::state& state) noexcept final {
416 switch(step) {
418 break;
419 case step_size::two:
420 break;
421 case step_size::one:
422 break;
425 break;
428 break;
431 break;
432 }
437
440
441 auto first_child = base_data.data.scrollbar.first_child;
442 auto num_children = base_data.data.scrollbar.num_children;
443
444 if(num_children >= 6) {
445 auto child_tag = dcon::gui_def_id(dcon::gui_def_id::value_base_t(5 + first_child.index()));
446 auto ch_res = make_element_by_type<image_element_base>(state, child_tag);
447 right_limit = ch_res.get();
449 add_child_to_back(std::move(ch_res));
450 }
451 if(num_children >= 5) {
452 auto child_tag = dcon::gui_def_id(dcon::gui_def_id::value_base_t(4 + first_child.index()));
453 auto ch_res = make_element_by_type<image_element_base>(state, child_tag);
454 left_limit = ch_res.get();
456 add_child_to_back(std::move(ch_res));
457 }
458
459 if(num_children >= 4) {
460 {
461 auto child_tag = dcon::gui_def_id(dcon::gui_def_id::value_base_t(2 + first_child.index()));
462 auto ch_res = make_element_by_type<scrollbar_slider>(state, child_tag);
463 slider = ch_res.get();
464 add_child_to_back(std::move(ch_res));
465 }
466 {
467 auto child_tag = dcon::gui_def_id(dcon::gui_def_id::value_base_t(0 + first_child.index()));
468 auto ch_res = make_element_by_type<scrollbar_left>(state, child_tag);
469 left = ch_res.get();
470 add_child_to_back(std::move(ch_res));
471
473 if(step_size::twenty_five == step)
474 left->step_size = 25;
475 else if(step_size::two == step)
476 left->step_size = 2;
477 else
478 left->step_size = 1;
479 }
480 {
481 auto child_tag = dcon::gui_def_id(dcon::gui_def_id::value_base_t(1 + first_child.index()));
482 auto ch_res = make_element_by_type<scrollbar_right>(state, child_tag);
483 //ui::element_base* test = ch_res.get();
484 right = ch_res.get();
485 add_child_to_back(std::move(ch_res));
486
487 if(step_size::twenty_five == step)
488 right->step_size = 25;
489 else if(step_size::two == step)
490 right->step_size = 2;
491 else
492 right->step_size = 1;
493 }
494 {
495 auto child_tag = dcon::gui_def_id(dcon::gui_def_id::value_base_t(3 + first_child.index()));
496 auto ch_res = make_element_by_type<scrollbar_track>(state, child_tag);
497 track = ch_res.get();
498 add_child_to_back(std::move(ch_res));
499
501 }
504 if(settings.vertical) {
508 // track->base_data.position.x = 0;
511 } else {
515 // track->base_data.position.y = 0;
518 }
519 }
520 }
521 }
522 void on_value_change(sys::state& state, int32_t v) noexcept final {
523 if(parent) {
524 float amount = float(v) / 100.0f;
525
526 if constexpr(SliderUpdateType == slider_update_type::manual) {
527 send(state, parent, budget_slider_signal{ SliderTarget, 1.f });
528 } else {
529 switch(SliderDisplayScaling) {
531 break;
533 amount = amount * amount;
534 break;
535 default:
536 break;
537 }
538 send(state, parent, budget_slider_signal{ SliderTarget, amount });
539 }
540 }
541 if(state.ui_state.drag_target != slider)
542 commit_changes(state);
543 }
544
545 void on_update(sys::state& state) noexcept final {
546 switch(SliderTarget) {
548 auto min_tax =
549 int32_t(100.0f * state.world.nation_get_modifier_values(state.local_player_nation, sys::national_mod_offsets::min_tax));
550 auto max_tax =
551 int32_t(100.0f * state.world.nation_get_modifier_values(state.local_player_nation, sys::national_mod_offsets::max_tax));
552 if(max_tax <= 0)
553 max_tax = 100;
554 max_tax = std::max(min_tax, max_tax);
555
556 mutable_scrollbar_settings new_settings;
557 new_settings.lower_value = 0;
558 new_settings.upper_value = 100;
559 new_settings.using_limits = true;
560 new_settings.lower_limit = std::clamp(min_tax, 0, 100);
561 new_settings.upper_limit = std::clamp(max_tax, 0, 100);
562 change_settings(state, new_settings);
563 } break;
565 auto min_tax =
566 int32_t(100.0f * state.world.nation_get_modifier_values(state.local_player_nation, sys::national_mod_offsets::min_tax));
567 auto max_tax =
568 int32_t(100.0f * state.world.nation_get_modifier_values(state.local_player_nation, sys::national_mod_offsets::max_tax));
569 if(max_tax <= 0)
570 max_tax = 100;
571 max_tax = std::max(min_tax, max_tax);
572
573 mutable_scrollbar_settings new_settings;
574 new_settings.lower_value = 0;
575 new_settings.upper_value = 100;
576 new_settings.using_limits = true;
577 new_settings.lower_limit = std::clamp(min_tax, 0, 100);
578 new_settings.upper_limit = std::clamp(max_tax, 0, 100);
579 change_settings(state, new_settings);
580 } break;
582 auto min_tax =
583 int32_t(100.0f * state.world.nation_get_modifier_values(state.local_player_nation, sys::national_mod_offsets::min_tax));
584 auto max_tax =
585 int32_t(100.0f * state.world.nation_get_modifier_values(state.local_player_nation, sys::national_mod_offsets::max_tax));
586 if(max_tax <= 0)
587 max_tax = 100;
588 max_tax = std::max(min_tax, max_tax);
589
590 mutable_scrollbar_settings new_settings;
591 new_settings.lower_value = 0;
592 new_settings.upper_value = 100;
593 new_settings.using_limits = true;
594 new_settings.lower_limit = std::clamp(min_tax, 0, 100);
595 new_settings.upper_limit = std::clamp(max_tax, 0, 100);
596 change_settings(state, new_settings);
597 } break;
599 auto min_spend = int32_t(100.0f * state.world.nation_get_modifier_values(state.local_player_nation,
600 sys::national_mod_offsets::min_social_spending));
601 auto max_spend = int32_t(100.0f * state.world.nation_get_modifier_values(state.local_player_nation,
602 sys::national_mod_offsets::max_social_spending));
603 if(max_spend <= 0)
604 max_spend = 100;
605 max_spend = std::max(min_spend, max_spend);
606
607 mutable_scrollbar_settings new_settings;
608 new_settings.lower_value = 0;
609 new_settings.upper_value = 100;
610 new_settings.using_limits = true;
611 new_settings.lower_limit = std::clamp(min_spend, 0, 100);
612 new_settings.upper_limit = std::clamp(max_spend, 0, 100);
613 change_settings(state, new_settings);
614 } break;
616 auto min_spend = int32_t(100.0f * state.world.nation_get_modifier_values(state.local_player_nation,
617 sys::national_mod_offsets::min_military_spending));
618 auto max_spend = int32_t(100.0f * state.world.nation_get_modifier_values(state.local_player_nation,
619 sys::national_mod_offsets::max_military_spending));
620 if(max_spend <= 0)
621 max_spend = 100;
622 max_spend = std::max(min_spend, max_spend);
623
624 mutable_scrollbar_settings new_settings;
625 new_settings.lower_value = 0;
626 new_settings.upper_value = 100;
627 new_settings.using_limits = true;
628 new_settings.lower_limit = std::clamp(min_spend, 0, 100);
629 new_settings.upper_limit = std::clamp(max_spend, 0, 100);
630 change_settings(state, new_settings);
631 } break;
633 auto min_tariff = int32_t(
634 100.0f * state.world.nation_get_modifier_values(state.local_player_nation, sys::national_mod_offsets::min_tariff));
635 auto max_tariff = int32_t(
636 100.0f * state.world.nation_get_modifier_values(state.local_player_nation, sys::national_mod_offsets::max_tariff));
637 max_tariff = std::max(min_tariff, max_tariff);
638
639 mutable_scrollbar_settings new_settings;
640 new_settings.lower_value = 0;
641 new_settings.upper_value = 100;
642 new_settings.using_limits = true;
643 new_settings.lower_limit = std::clamp(min_tariff, 0, 100);
644 new_settings.upper_limit = std::clamp(max_tariff, 0, 100);
645 change_settings(state, new_settings);
646 } break;
648 {
649 auto min_domestic_investment = int32_t(
650 100.0f * state.world.nation_get_modifier_values(state.local_player_nation, sys::national_mod_offsets::min_domestic_investment));
651 auto max_domestic_investment = int32_t(
652 100.0f * state.world.nation_get_modifier_values(state.local_player_nation, sys::national_mod_offsets::max_domestic_investment));
653 if(max_domestic_investment <= 0)
654 max_domestic_investment = 100;
655 max_domestic_investment = std::max(min_domestic_investment, max_domestic_investment);
656
657 mutable_scrollbar_settings new_settings;
658 new_settings.lower_value = 0;
659 new_settings.upper_value = 100;
660 new_settings.using_limits = true;
661 new_settings.lower_limit = std::clamp(min_domestic_investment, 0, 100);
662 new_settings.upper_limit = std::clamp(max_domestic_investment, 0, 100);
663 change_settings(state, new_settings);
664 } break;
665 default:
666 break;
667 }
668
669 int32_t v = 0;
670 if(state.ui_state.drag_target == slider) {
671 v = int32_t(scaled_value());
672 } else {
675 }
676
677 if(parent) {
678 if constexpr(SliderUpdateType == slider_update_type::manual) {
679 Cyto::Any payload = budget_slider_signal{ SliderTarget, 1.f };
680 parent->impl_set(state, payload);
681 } else {
682 float amount = float(v) / 100.f;
683 switch(SliderDisplayScaling) {
685 break;
687 amount = amount * amount;
688 break;
689 default:
690 break;
691 }
692 Cyto::Any payload = budget_slider_signal{ SliderTarget, amount };
693 parent->impl_set(state, payload);
694 }
695 }
696 }
697
698 virtual int32_t get_true_value(sys::state& state) noexcept {
699 return 0;
700 }
701
702 void on_drag_finish(sys::state& state) noexcept override {
703 commit_changes(state);
704 }
705
706private:
707 void commit_changes(sys::state& state) noexcept {
708 auto budget_settings = command::make_empty_budget_settings();
709 update_budget_settings(budget_settings);
710 command::change_budget_settings(state, state.local_player_nation, budget_settings);
711 }
712
713 void update_budget_settings(command::budget_settings_data& budget_settings) noexcept {
714 auto new_val = int8_t(scaled_value());
715 switch(SliderTarget) {
717 budget_settings.poor_tax = new_val;
718 break;
720 budget_settings.middle_tax = new_val;
721 break;
723 budget_settings.rich_tax = new_val;
724 break;
726 budget_settings.land_spending = new_val;
727 break;
729 budget_settings.naval_spending = new_val;
730 break;
732 budget_settings.construction_spending = new_val;
733 break;
735 budget_settings.education_spending = new_val;
736 break;
738 budget_settings.administrative_spending = new_val;
739 break;
741 budget_settings.social_spending = new_val;
742 break;
744 budget_settings.military_spending = new_val;
745 break;
747 budget_settings.tariffs_import = new_val;
748 break;
750 budget_settings.domestic_investment = new_val;
751 break;
753 budget_settings.overseas = new_val;
754 break;
755 default:
756 break;
757 }
758 }
759};
760
761class budget_poor_tax_slider : public budget_slider<budget_slider_target::poor_tax, slider_scaling::linear, slider_update_type::autoscalerupdate> {
762 int32_t get_true_value(sys::state& state) noexcept override {
763 return int32_t(state.world.nation_get_poor_tax(state.local_player_nation));
764 }
765 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
767 }
768 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
769 auto n = retrieve<dcon::nation_id>(state, parent);
770 auto box = text::open_layout_box(contents, 0);
771 text::localised_single_sub_box(state, contents, box, "alice_budget_setting_percent", text::variable_type::perc, text::int_percentage{ state.world.nation_get_poor_tax(n) });
772 text::close_layout_box(contents, box);
773
774 active_modifiers_description(state, contents, n, 0, sys::national_mod_offsets::tax_efficiency, true);
775 active_modifiers_description(state, contents, n, 0, sys::national_mod_offsets::min_tax, true);
776 active_modifiers_description(state, contents, n, 0, sys::national_mod_offsets::max_tax, true);
777 }
778};
779
780class budget_middle_tax_slider : public budget_slider<budget_slider_target::middle_tax, slider_scaling::linear, slider_update_type::autoscalerupdate> {
781 int32_t get_true_value(sys::state& state) noexcept override {
782 return int32_t(state.world.nation_get_middle_tax(state.local_player_nation));
783 }
784 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
786 }
787 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
788 auto n = retrieve<dcon::nation_id>(state, parent);
789 auto box = text::open_layout_box(contents, 0);
790 text::localised_single_sub_box(state, contents, box, "alice_budget_setting_percent", text::variable_type::perc, text::int_percentage{ state.world.nation_get_middle_tax(n) });
791 text::close_layout_box(contents, box);
792
793 active_modifiers_description(state, contents, n, 0, sys::national_mod_offsets::tax_efficiency, true);
794 active_modifiers_description(state, contents, n, 0, sys::national_mod_offsets::min_tax, true);
795 active_modifiers_description(state, contents, n, 0, sys::national_mod_offsets::max_tax, true);
796 }
797};
798
799class budget_rich_tax_slider : public budget_slider<budget_slider_target::rich_tax, slider_scaling::linear, slider_update_type::autoscalerupdate> {
800 int32_t get_true_value(sys::state& state) noexcept override {
801 return int32_t(state.world.nation_get_rich_tax(state.local_player_nation));
802 }
803 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
805 }
806 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
807 auto n = retrieve<dcon::nation_id>(state, parent);
808 auto box = text::open_layout_box(contents, 0);
809 text::localised_single_sub_box(state, contents, box, "alice_budget_setting_percent", text::variable_type::perc, text::int_percentage{ state.world.nation_get_rich_tax(n) });
810 text::close_layout_box(contents, box);
811
812 active_modifiers_description(state, contents, n, 0, sys::national_mod_offsets::tax_efficiency, true);
813 active_modifiers_description(state, contents, n, 0, sys::national_mod_offsets::min_tax, true);
814 active_modifiers_description(state, contents, n, 0, sys::national_mod_offsets::max_tax, true);
815 }
816};
817
818class budget_army_stockpile_slider : public budget_slider<budget_slider_target::army_stock, slider_scaling::linear, slider_update_type::autoscalerupdate> {
819 int32_t get_true_value(sys::state& state) noexcept override {
820 return int32_t(state.world.nation_get_land_spending(state.local_player_nation));
821 }
822 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
824 }
825 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
826 auto n = retrieve<dcon::nation_id>(state, parent);
827
828 {
829 auto box = text::open_layout_box(contents, 0);
830 text::localised_single_sub_box(state, contents, box, "alice_budget_setting_percent", text::variable_type::perc, text::int_percentage{ state.world.nation_get_land_spending(n) });
831 text::close_layout_box(contents, box);
832 }
833 uint32_t total_commodities = state.world.commodity_size();
834
835 for(uint32_t i = 1; i < total_commodities; ++i) {
836 dcon::commodity_id cid{ dcon::commodity_id::value_base_t(i) };
837 auto cost = 0.f;
838 auto amount = 0.f;
839 state.world.nation_for_each_state_ownership(n, [&](auto soid) {
840 auto local_state = state.world.state_ownership_get_state(soid);
841 auto market = state.world.state_instance_get_market_from_local_market(local_state);
842 amount = amount + state.world.market_get_army_demand(market, cid);
843 cost = cost
844 + economy::price(state, market, cid)
845 * state.world.market_get_army_demand(market, cid);
846 });
847 if(amount > 0.f) {
849 text::add_to_substitution_map(m, text::variable_type::name, state.world.commodity_get_name(cid));
853 auto box = text::open_layout_box(contents, 0);
854
855 std::string padding = cid.index() < 10 ? "0" : "";
856 std::string description = "@$" + padding + std::to_string(cid.index());
857 text::add_unparsed_text_to_layout_box(state, contents, box, description);
858
859 text::localised_format_box(state, contents, box, "alice_spending_commodity", m);
860 text::close_layout_box(contents, box);
861 }
862 }
863 }
864};
865
866class budget_navy_stockpile_slider : public budget_slider<budget_slider_target::navy_stock, slider_scaling::linear, slider_update_type::autoscalerupdate> {
867 int32_t get_true_value(sys::state& state) noexcept override {
868 return int32_t(state.world.nation_get_naval_spending(state.local_player_nation));
869 }
870 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
872 }
873 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
874 auto n = retrieve<dcon::nation_id>(state, parent);
875 {
876 auto box = text::open_layout_box(contents, 0);
877 text::localised_single_sub_box(state, contents, box, "alice_budget_setting_percent", text::variable_type::perc, text::int_percentage{ state.world.nation_get_naval_spending(n) });
878 text::close_layout_box(contents, box);
879 }
880 uint32_t total_commodities = state.world.commodity_size();
881 for(uint32_t i = 1; i < total_commodities; ++i) {
882 dcon::commodity_id cid{ dcon::commodity_id::value_base_t(i) };
883 auto cost = 0.f;
884 auto amount = 0.f;
885 state.world.nation_for_each_state_ownership(n, [&](auto soid) {
886 auto local_state = state.world.state_ownership_get_state(soid);
887 auto market = state.world.state_instance_get_market_from_local_market(local_state);
888 amount = amount + state.world.market_get_navy_demand(market, cid);
889 cost = cost
890 + economy::price(state, market, cid)
891 * state.world.market_get_navy_demand(market, cid);
892 });
893
894 if(amount > 0.f) {
896 text::add_to_substitution_map(m, text::variable_type::name, state.world.commodity_get_name(cid));
900 auto box = text::open_layout_box(contents, 0);
901
902 std::string padding = cid.index() < 10 ? "0" : "";
903 std::string description = "@$" + padding + std::to_string(cid.index());
904 text::add_unparsed_text_to_layout_box(state, contents, box, description);
905
906 text::localised_format_box(state, contents, box, "alice_spending_commodity", m);
907 text::close_layout_box(contents, box);
908 }
909 }
910 }
911};
912
913class budget_construction_stockpile_slider : public budget_slider<budget_slider_target::construction_stock, slider_scaling::linear, slider_update_type::manual> {
914 int32_t get_true_value(sys::state& state) noexcept override {
915 return int32_t(state.world.nation_get_construction_spending(state.local_player_nation));
916 }
917 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
919 }
920 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
921 auto n = retrieve<dcon::nation_id>(state, parent);
922 {
923 auto box = text::open_layout_box(contents, 0);
924 text::localised_single_sub_box(state, contents, box, "alice_budget_setting_percent", text::variable_type::perc, text::int_percentage{ state.world.nation_get_construction_spending(n) });
925 text::close_layout_box(contents, box);
926 }
927 std::vector<float> total;
928 total.resize(size_t(state.world.commodity_size()), 0.0f);
929 std::vector<float> need;
930 need.resize(size_t(state.world.commodity_size()), 0.0f);
931
932 float admin_eff = state.world.nation_get_administrative_efficiency(n);
933 float admin_cost_factor = 2.0f - admin_eff;
934 for(auto lc : state.world.nation_get_province_land_construction(n)) {
935 auto province = state.world.pop_get_province_from_pop_location(state.world.province_land_construction_get_pop(lc));
936 auto s = state.world.province_get_state_membership(province);
937 auto market = state.world.state_instance_get_market_from_local_market(s);
938 if(state.world.province_get_nation_from_province_control(province) == n) {
939 auto& base_cost = state.military_definitions.unit_base_definitions[state.world.province_land_construction_get_type(lc)].build_cost;
940 auto& current_purchased = state.world.province_land_construction_get_purchased_goods(lc);
941 float construction_time = float(state.military_definitions.unit_base_definitions[state.world.province_land_construction_get_type(lc)].build_time);
942 //
943 float total_cost = 0.f;
944 for(uint32_t i = 0; i < economy::commodity_set::set_size; ++i) {
945 if(auto cid = base_cost.commodity_type[i]; cid) {
946 if(current_purchased.commodity_amounts[i] < base_cost.commodity_amounts[i] * admin_cost_factor) {
947 float amount = state.world.market_get_demand_satisfaction(market, cid) * base_cost.commodity_amounts[i] / construction_time;
948 float cost = economy::price(state, market, cid);
949 total_cost += cost * amount;
950 total[base_cost.commodity_type[i].index()] += cost * amount;
951 need[base_cost.commodity_type[i].index()] += amount;
952 }
953 } else {
954 break;
955 }
956 }
960 auto box = text::open_layout_box(contents, 0);
961 text::localised_format_box(state, contents, box, "alice_spending_land_construction", m);
962 text::close_layout_box(contents, box);
963 }
964 }
965 for(auto po : state.world.nation_get_province_ownership(n)) {
966 auto p = po.get_province();
967 auto s = state.world.province_get_state_membership(p);
968 auto market = state.world.state_instance_get_market_from_local_market(s);
969 if(state.world.province_get_nation_from_province_control(p) != n)
970 continue;
971 auto rng = state.world.province_get_province_naval_construction(p);
972 if(rng.begin() != rng.end()) {
973 auto c = *(rng.begin());
974 auto& base_cost = state.military_definitions.unit_base_definitions[c.get_type()].build_cost;
975 auto& current_purchased = c.get_purchased_goods();
976 float construction_time = float(state.military_definitions.unit_base_definitions[c.get_type()].build_time);
977 //
978 float total_cost = 0.f;
979 for(uint32_t i = 0; i < economy::commodity_set::set_size; ++i) {
980 if(auto cid = base_cost.commodity_type[i]; cid) {
981 if(current_purchased.commodity_amounts[i] < base_cost.commodity_amounts[i] * admin_cost_factor) {
982 float amount = state.world.market_get_demand_satisfaction(market, cid) * base_cost.commodity_amounts[i] / construction_time;
983 float cost = economy::price(state, market, cid);
984 total_cost += cost * amount;
985 total[base_cost.commodity_type[i].index()] += cost * amount;
986 need[base_cost.commodity_type[i].index()] += amount;
987 }
988 } else {
989 break;
990 }
991 }
995 auto box = text::open_layout_box(contents, 0);
996 text::localised_format_box(state, contents, box, "alice_spending_naval_construction", m);
997 text::close_layout_box(contents, box);
998 }
999 }
1000 for(auto c : state.world.nation_get_province_building_construction(n)) {
1001 auto p = c.get_province();
1002 auto s = state.world.province_get_state_membership(p);
1003 auto market = state.world.state_instance_get_market_from_local_market(s);
1004 if(n == c.get_province().get_nation_from_province_control() && !c.get_is_pop_project()) {
1005 auto t = economy::province_building_type(c.get_type());
1006 auto& base_cost = state.economy_definitions.building_definitions[int32_t(t)].cost;
1007 auto& current_purchased = c.get_purchased_goods();
1008 float construction_time = float(state.economy_definitions.building_definitions[int32_t(t)].time);
1009 //
1010 float total_cost = 0.f;
1011 for(uint32_t i = 0; i < economy::commodity_set::set_size; ++i) {
1012 if(auto cid = base_cost.commodity_type[i]; cid) {
1013 if(current_purchased.commodity_amounts[i] < base_cost.commodity_amounts[i] * admin_cost_factor) {
1014 float amount = state.world.market_get_demand_satisfaction(market, cid) * base_cost.commodity_amounts[i] / construction_time;
1015 float cost = economy::price(state, market, cid);
1016 total_cost += cost * amount;
1017 total[base_cost.commodity_type[i].index()] += cost * amount;
1018 need[base_cost.commodity_type[i].index()] += amount;
1019 }
1020 } else {
1021 break;
1022 }
1023 }
1027 auto box = text::open_layout_box(contents, 0);
1028 text::localised_format_box(state, contents, box, "alice_spending_building_construction", m);
1029 text::close_layout_box(contents, box);
1030 }
1031 }
1032 float factory_mod = state.world.nation_get_modifier_values(n, sys::national_mod_offsets::factory_cost) + 1.0f;
1033 for(auto c : state.world.nation_get_state_building_construction(n)) {
1034 auto market = state.world.state_instance_get_market_from_local_market(c.get_state());
1035 if(!c.get_is_pop_project()) {
1036 auto& base_cost = c.get_type().get_construction_costs();
1037 auto& current_purchased = c.get_purchased_goods();
1038 float construction_time = float(c.get_type().get_construction_time()) * (c.get_is_upgrade() ? 0.1f : 1.0f);
1039 //
1040 float total_cost = 0.f;
1041 for(uint32_t i = 0; i < economy::commodity_set::set_size; ++i) {
1042 if(auto cid = base_cost.commodity_type[i]; cid) {
1043 if(current_purchased.commodity_amounts[i] < base_cost.commodity_amounts[i] * admin_cost_factor) {
1044 float amount = state.world.market_get_demand_satisfaction(market, cid) * base_cost.commodity_amounts[i] * factory_mod / construction_time;
1045 float cost = economy::price(state, market, cid);
1046 total_cost += cost * amount;
1047 total[base_cost.commodity_type[i].index()] += cost * amount;
1048 need[base_cost.commodity_type[i].index()] += amount;
1049 }
1050 } else {
1051 break;
1052 }
1053 }
1057 auto box = text::open_layout_box(contents, 0);
1058 text::localised_format_box(state, contents, box, "alice_spending_factory_construction", m);
1059 text::close_layout_box(contents, box);
1060 }
1061 }
1062 uint32_t total_commodities = state.world.commodity_size();
1063 bool is_spending = false;
1064 for(uint32_t i = 1; i < total_commodities; ++i) {
1065 is_spending = is_spending || (total[i] > 0.f);
1066 }
1067 if(is_spending) {
1068 text::add_line(state, contents, "alice_spending_total");
1069 for(uint32_t i = 1; i < total_commodities; ++i) {
1070 dcon::commodity_id cid{ dcon::commodity_id::value_base_t(i) };
1071 auto amount = total[i];
1072 auto required = need[i];
1073
1074 if(required > 0.f) {
1076 text::add_to_substitution_map(m, text::variable_type::name, state.world.commodity_get_name(cid));
1080 auto box = text::open_layout_box(contents, 0);
1081
1082 std::string padding = cid.index() < 10 ? "0" : "";
1083 std::string description = "@$" + padding + std::to_string(cid.index());
1084 text::add_unparsed_text_to_layout_box(state, contents, box, description);
1085
1086 text::localised_format_box(state, contents, box, "alice_spending_commodity", m);
1087 text::close_layout_box(contents, box);
1088 }
1089 }
1090 }
1091 }
1092};
1093
1094class budget_education_slider : public budget_slider<budget_slider_target::education, slider_scaling::quadratic, slider_update_type::autoscalerupdate> {
1095 int32_t get_true_value(sys::state& state) noexcept override {
1096 return int32_t(state.world.nation_get_education_spending(state.local_player_nation));
1097 }
1098 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
1100 }
1101 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1102 auto n = retrieve<dcon::nation_id>(state, parent);
1103 auto box = text::open_layout_box(contents, 0);
1104 text::localised_single_sub_box(state, contents, box, "alice_budget_setting_percent", text::variable_type::perc, text::int_percentage{ state.world.nation_get_education_spending(n) });
1105 text::close_layout_box(contents, box);
1106 }
1107};
1108
1109class budget_administration_slider : public budget_slider<budget_slider_target::admin, slider_scaling::quadratic, slider_update_type::autoscalerupdate> {
1110 int32_t get_true_value(sys::state& state) noexcept override {
1111 return int32_t(state.world.nation_get_administrative_spending(state.local_player_nation));
1112 }
1113 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
1115 }
1116 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1117 auto n = retrieve<dcon::nation_id>(state, parent);
1118 auto box = text::open_layout_box(contents, 0);
1119 text::localised_single_sub_box(state, contents, box, "alice_budget_setting_percent", text::variable_type::perc, text::int_percentage{ state.world.nation_get_administrative_spending(n) });
1120 text::close_layout_box(contents, box);
1121 }
1122};
1123
1124class budget_social_spending_slider : public budget_slider<budget_slider_target::social, slider_scaling::linear, slider_update_type::autoscalerupdate> {
1125 int32_t get_true_value(sys::state& state) noexcept override {
1126 return int32_t(state.world.nation_get_social_spending(state.local_player_nation));
1127 }
1128 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
1130 }
1131 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1132 auto n = retrieve<dcon::nation_id>(state, parent);
1133 auto box = text::open_layout_box(contents, 0);
1134 text::localised_single_sub_box(state, contents, box, "alice_budget_setting_percent", text::variable_type::perc, text::int_percentage{ state.world.nation_get_social_spending(n) });
1135 text::close_layout_box(contents, box);
1136 active_modifiers_description(state, contents, n, 0, sys::national_mod_offsets::min_social_spending, true);
1137 active_modifiers_description(state, contents, n, 0, sys::national_mod_offsets::max_social_spending, true);
1138 }
1139};
1140
1141class budget_military_spending_slider : public budget_slider<budget_slider_target::military, slider_scaling::quadratic, slider_update_type::autoscalerupdate> {
1142 int32_t get_true_value(sys::state& state) noexcept override {
1143 return int32_t(state.world.nation_get_military_spending(state.local_player_nation));
1144 }
1145 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
1147 }
1148 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1149 auto n = retrieve<dcon::nation_id>(state, parent);
1150 auto box = text::open_layout_box(contents, 0);
1151 text::localised_single_sub_box(state, contents, box, "alice_budget_setting_percent", text::variable_type::perc, text::int_percentage{ state.world.nation_get_military_spending(n) });
1152 text::close_layout_box(contents, box);
1153 active_modifiers_description(state, contents, n, 0, sys::national_mod_offsets::min_military_spending, true);
1154 active_modifiers_description(state, contents, n, 0, sys::national_mod_offsets::max_military_spending, true);
1155 }
1156};
1157
1158class budget_tariff_slider : public budget_slider<budget_slider_target::tariffs, slider_scaling::linear, slider_update_type::autoscalerupdate> {
1159 int32_t get_true_value(sys::state& state) noexcept override {
1160 return int32_t(state.world.nation_get_tariffs_import(state.local_player_nation));
1161 }
1162 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
1164 }
1165 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1166 auto n = retrieve<dcon::nation_id>(state, parent);
1167 auto box = text::open_layout_box(contents, 0);
1168 text::localised_single_sub_box(state, contents, box, "alice_budget_setting_percent", text::variable_type::perc, text::int_percentage{ state.world.nation_get_tariffs_import(n) });
1169 text::close_layout_box(contents, box);
1170 active_modifiers_description(state, contents, n, 0, sys::national_mod_offsets::tariff_efficiency_modifier, true);
1171 active_modifiers_description(state, contents, n, 0, sys::national_mod_offsets::min_tariff, true);
1172 active_modifiers_description(state, contents, n, 0, sys::national_mod_offsets::max_tariff, true);
1173 }
1174};
1175
1177private:
1178 std::array<float, size_t(budget_slider_target::target_count)> values;
1179 std::array<float, size_t(budget_slider_target::target_count)> multipliers;
1180
1181public:
1182 bool expense = false;
1183
1184 virtual void put_values(sys::state& state, std::array<float, size_t(budget_slider_target::target_count)>& vals) noexcept { }
1185
1186 void on_create(sys::state& state) noexcept override {
1189 for(uint8_t i = 0; i < uint8_t(budget_slider_target::target_count); ++i) {
1190 values[i] = 0.f;
1191 multipliers[i] = 1.f;
1192 }
1193 }
1194
1196 auto total = 0.f;
1198 total += values[i] * multipliers[i];
1199
1200 if(expense)
1201 total = -total;
1202
1203 if(total < 0.0f) {
1205 set_text(state, text::format_money(total)); //automatically adds a - when negative
1206 } else if(total > 0.0f) {
1209 } else {
1212 }
1213 }
1214
1215 void on_update(sys::state& state) noexcept override {
1216 put_values(state, values);
1218 }
1219
1222 }
1223 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1224 auto n = retrieve<dcon::nation_id>(state, parent);
1225 auto box = text::open_layout_box(contents, 0);
1226
1227 float total = 0.f;
1228 float total_exp = 0.f;
1229 float total_inc = 0.f;
1230 for(uint8_t i = 0; i < uint8_t(budget_slider_target::target_count); ++i) {
1231 float v = values[i] * multipliers[i];
1232 if(expense)
1233 v = -v;
1234 if(v < 0.f)
1235 total_exp += v;
1236 else
1237 total_inc += v;
1238 total += v;
1239 }
1240 if(total_inc != 0.f) {
1241 text::localised_single_sub_box(state, contents, box, "alice_budget_scaled_inc", text::variable_type::value, text::fp_currency{ total_inc });
1243 for(uint8_t i = 0; i < uint8_t(budget_slider_target::target_count); ++i) {
1244 float v = values[i] * multipliers[i];
1245 if(expense)
1246 v = -v;
1247 if(v > 0.f) {
1248 switch(budget_slider_target(i)) {
1250 text::localised_single_sub_box(state, contents, box, "alice_budget_scaled_1", text::variable_type::value, text::fp_currency{ v });
1251 break;
1253 text::localised_single_sub_box(state, contents, box, "alice_budget_scaled_2", text::variable_type::value, text::fp_currency{ v });
1254 break;
1256 text::localised_single_sub_box(state, contents, box, "alice_budget_scaled_3", text::variable_type::value, text::fp_currency{ v });
1257 break;
1259 text::localised_single_sub_box(state, contents, box, "alice_budget_scaled_4", text::variable_type::value, text::fp_currency{ v });
1260 break;
1262 text::localised_single_sub_box(state, contents, box, "alice_budget_scaled_17", text::variable_type::value, text::fp_currency{ v });
1263 break;
1265 text::localised_single_sub_box(state, contents, box, "alice_budget_scaled_16", text::variable_type::value, text::fp_currency{ v });
1266 break;
1267 default:
1268 break;
1269 }
1271 }
1272 }
1273 }
1274 if(total_exp != 0.f) {
1275 text::localised_single_sub_box(state, contents, box, "alice_budget_scaled_exp", text::variable_type::value, text::fp_currency{ total_exp });
1277 for(uint8_t i = 0; i < uint8_t(budget_slider_target::target_count); ++i) {
1278 float v = values[i] * multipliers[i];
1279 if(expense)
1280 v = -v;
1281 if(v < 0.f) {
1282 switch(budget_slider_target(i)) {
1284 text::localised_single_sub_box(state, contents, box, "alice_budget_scaled_5", text::variable_type::value, text::fp_currency{ v });
1285 break;
1287 text::localised_single_sub_box(state, contents, box, "alice_budget_scaled_6", text::variable_type::value, text::fp_currency{ v });
1288 break;
1290 text::localised_single_sub_box(state, contents, box, "alice_budget_scaled_7", text::variable_type::value, text::fp_currency{ v });
1291 break;
1293 text::localised_single_sub_box(state, contents, box, "alice_budget_scaled_8", text::variable_type::value, text::fp_currency{ v });
1294 break;
1296 text::localised_single_sub_box(state, contents, box, "alice_budget_scaled_9", text::variable_type::value, text::fp_currency{ v });
1297 break;
1299 text::localised_single_sub_box(state, contents, box, "alice_budget_scaled_10", text::variable_type::value, text::fp_currency{ v });
1300 break;
1302 text::localised_single_sub_box(state, contents, box, "alice_budget_scaled_11", text::variable_type::value, text::fp_currency{ v });
1303 break;
1305 text::localised_single_sub_box(state, contents, box, "alice_budget_scaled_12", text::variable_type::value, text::fp_currency{ v });
1306 break;
1308 text::localised_single_sub_box(state, contents, box, "alice_budget_scaled_13", text::variable_type::value, text::fp_currency{ v });
1309 break;
1311 text::localised_single_sub_box(state, contents, box, "alice_budget_scaled_14", text::variable_type::value, text::fp_currency{ v });
1312 break;
1314 text::localised_single_sub_box(state, contents, box, "alice_budget_scaled_15", text::variable_type::value, text::fp_currency{ v });
1315 break;
1316 default:
1317 break;
1318 }
1320 }
1321 }
1322 }
1323 if(total != 0.f) {
1324 text::localised_single_sub_box(state, contents, box, "alice_budget_scaled_net", text::variable_type::value, text::fp_currency{ total });
1326 }
1327 text::close_layout_box(contents, box);
1328 }
1329
1330 message_result set(sys::state& state, Cyto::Any& payload) noexcept override {
1331 if(payload.holds_type<budget_slider_signal>()) {
1332 auto sig = any_cast<budget_slider_signal>(payload);
1333 multipliers[uint8_t(sig.target)] = sig.amount;
1334 if(values[uint8_t(sig.target)] != 0.f)
1337 }
1339 }
1340};
1341
1343public:
1344 void put_values(sys::state& state, std::array<float, size_t(budget_slider_target::target_count)>& vals) noexcept override {
1347 }
1348};
1349
1351public:
1352 void put_values(sys::state& state, std::array<float, size_t(budget_slider_target::target_count)>& vals) noexcept override {
1357 }
1358};
1359
1361public:
1362 void put_values(sys::state& state, std::array<float, size_t(budget_slider_target::target_count)>& vals) noexcept override {
1365 }
1366};
1367
1369public:
1370 void put_values(sys::state& state, std::array<float, size_t(budget_slider_target::target_count)>& vals) noexcept override {
1373 }
1374};
1375
1377public:
1378 void put_values(sys::state& state, std::array<float, size_t(budget_slider_target::target_count)>& vals) noexcept override {
1380 }
1381};
1382
1383template<culture::pop_strata Strata, budget_slider_target BudgetTarget>
1385 void put_values(sys::state& state, std::array<float, size_t(budget_slider_target::target_count)>& vals) noexcept override {
1386 vals[uint8_t(BudgetTarget)] = economy::estimate_tax_income_by_strata(state, state.local_player_nation, Strata);
1387 }
1388};
1389
1390template<culture::income_type IncomeType, budget_slider_target BudgetTarget>
1392public:
1393 void put_values(sys::state& state, std::array<float, size_t(budget_slider_target::target_count)>& vals) noexcept override {
1394 vals[uint8_t(BudgetTarget)] = economy::estimate_pop_payouts_by_income_type(state, state.local_player_nation, IncomeType);
1395 }
1396};
1397
1399public:
1400 void put_values(sys::state& state, std::array<float, size_t(budget_slider_target::target_count)>& vals) noexcept override {
1402 }
1403};
1404
1406public:
1407 void put_values(sys::state& state, std::array<float, size_t(budget_slider_target::target_count)>& vals) noexcept override {
1415 }
1416};
1417
1419public:
1420 void put_values(sys::state& state, std::array<float, size_t(budget_slider_target::target_count)>& vals) noexcept override {
1437 }
1438};
1439
1441public:
1442 void put_values(sys::state& state, std::array<float, size_t(budget_slider_target::target_count)>& vals) noexcept override {
1443 // income
1451
1452 // spend
1465 // balance
1469 }
1470};
1471
1473public:
1474 void button_action(sys::state& state) noexcept override {
1475 if(parent) {
1476 Cyto::Any payload = element_selection_wrapper<bool>{bool{true}};
1477 parent->impl_get(state, payload);
1478 }
1479 }
1480};
1481
1482// NOTE for simplicity sake we use a payload with bool{true} for taking loan window and a payload with bool{false} for repaying
1483// loan window
1484
1486public:
1487 void button_action(sys::state& state) noexcept override {
1488 if(parent) {
1489 Cyto::Any payload = element_selection_wrapper<bool>{bool{false}};
1490 parent->impl_get(state, payload);
1491 }
1492 }
1493};
1494
1496public:
1497 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1498 if(name == "bg") {
1499 return make_element_by_type<image_element_base>(state, id);
1500 } else if(name == "take_loan_label") {
1501 return make_element_by_type<simple_text_element_base>(state, id);
1502 } else if(name == "ok") {
1503 return make_element_by_type<button_element_base>(state, id);
1504 } else if(name == "cancel") {
1505 return make_element_by_type<generic_close_button>(state, id);
1506 } else if(name == "money_value") {
1507 return make_element_by_type<simple_text_element_base>(state, id);
1508 } /*else if(name == "money_slider") {
1509 return nullptr;
1510 }*/
1511 else {
1512 return nullptr;
1513 }
1514 }
1515};
1516
1518public:
1519 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1520 if(name == "bg") {
1521 return make_element_by_type<image_element_base>(state, id);
1522 } else if(name == "repay_loan_label") {
1523 return make_element_by_type<simple_text_element_base>(state, id);
1524 } else if(name == "ok") {
1525 return make_element_by_type<button_element_base>(state, id);
1526 } else if(name == "cancel") {
1527 return make_element_by_type<generic_close_button>(state, id);
1528 } else if(name == "money_value") {
1529 return make_element_by_type<simple_text_element_base>(state, id);
1530 } /*else if(name == "money_slider") {
1531 return nullptr;
1532 }*/
1533 else {
1534 return nullptr;
1535 }
1536 }
1537};
1538
1540public:
1541 dcon::pop_type_id type{};
1542
1543 void set_type(sys::state& state, dcon::pop_type_id t) {
1544 type = t;
1545 frame = int32_t(state.world.pop_type_get_sprite(t) - 1);
1546 }
1547
1550 }
1551
1552 void on_update(sys::state& state) noexcept override {
1553 auto total_pop = state.world.nation_get_demographics(state.local_player_nation, demographics::to_key(state, type));
1554 disabled = total_pop < 1.0f;
1555 }
1556
1557 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1558 auto total = 0.f;
1559 std::array<float, 5> sat_pool = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
1560 for(auto prov : state.world.nation_get_province_ownership(state.local_player_nation)) {
1561 for(auto pop_loc : prov.get_province().get_pop_location()) {
1562 auto pop_id = pop_loc.get_pop();
1563 if(pop_id.get_poptype() == type) {
1564 auto pop_size = state.world.pop_get_size(pop_id);
1565 sat_pool[(pop_demographics::get_luxury_needs(state, pop_id) > 0.95f) ? 4
1566 : (pop_demographics::get_everyday_needs(state, pop_id) > 0.95f) ? 3
1567 : (pop_demographics::get_life_needs(state, pop_id) > 0.95f) ? 2
1568 : (pop_demographics::get_life_needs(state, pop_id) > 0.01f) ? 1
1569 : 0] += pop_size;
1570 total += pop_size;
1571 }
1572 }
1573 }
1574
1575
1576 if(total > 0.0f) {
1577 auto type_strata = state.world.pop_type_get_strata(type);
1578 float total_pop = 0.0f;
1580 total_pop = state.world.nation_get_demographics(state.local_player_nation, demographics::poor_total);
1581 } else if(culture::pop_strata(type_strata) == culture::pop_strata::middle) {
1582 total_pop = state.world.nation_get_demographics(state.local_player_nation, demographics::middle_total);
1583 } else {
1584 total_pop = state.world.nation_get_demographics(state.local_player_nation, demographics::rich_total);
1585 }
1586
1587 {
1588 auto box = text::open_layout_box(contents, 0);
1589 text::add_to_layout_box(state, contents, box, state.world.pop_type_get_name(type));
1590 text::close_layout_box(contents, box);
1591 }
1592 {
1593 auto box = text::open_layout_box(contents, 0);
1594 text::localised_single_sub_box(state, contents, box, std::string_view("percent_of_pop_strata"), text::variable_type::val, text::fp_percentage{total / total_pop});
1595 text::add_to_layout_box(state, contents, box, std::string("("));
1596 text::add_to_layout_box(state, contents, box, text::prettify(int64_t(total_pop)));
1597 text::add_to_layout_box(state, contents, box, std::string(")"));
1598 text::close_layout_box(contents, box);
1599 //percent_of_pop_strata
1600 }
1602 static const std::string needs_types[5] = {"no_need", "some_life_needs", "life_needs", "everyday_needs", "luxury_needs"};
1603 {
1604 auto box = text::open_layout_box(contents);
1605 auto sub = text::substitution_map{};
1606 auto needs_type = text::produce_simple_string(state, "no_need");
1608 text::add_to_substitution_map(sub, text::variable_type::type, std::string_view(needs_type));
1609 text::localised_format_box(state, contents, box, "budget_strata_no_need", sub);
1610 text::close_layout_box(contents, box);
1611 }
1612 {
1613 auto box = text::open_layout_box(contents);
1614 auto sub = text::substitution_map{};
1615 auto needs_type = text::produce_simple_string(state, "some_life_needs");
1617 text::add_to_substitution_map(sub, text::variable_type::type, std::string_view(needs_type));
1618 text::localised_format_box(state, contents, box, "budget_strata_need", sub);
1619 text::close_layout_box(contents, box);
1620 }
1621 {
1622 auto box = text::open_layout_box(contents);
1623 auto sub = text::substitution_map{};
1624 auto needs_type = text::produce_simple_string(state, "life_needs");
1626 text::add_to_substitution_map(sub, text::variable_type::type, std::string_view(needs_type));
1627 text::localised_format_box(state, contents, box, "budget_strata_need", sub);
1628 text::close_layout_box(contents, box);
1629 }
1630 {
1631 auto box = text::open_layout_box(contents);
1632 auto sub = text::substitution_map{};
1633 auto needs_type = text::produce_simple_string(state, "everyday_needs");
1635 text::add_to_substitution_map(sub, text::variable_type::type, std::string_view(needs_type));
1636 text::localised_format_box(state, contents, box, "budget_strata_need", sub);
1637 text::close_layout_box(contents, box);
1638 }
1639 {
1640 auto box = text::open_layout_box(contents);
1641 auto sub = text::substitution_map{};
1642 auto needs_type = text::produce_simple_string(state, "luxury_needs");
1644 text::add_to_substitution_map(sub, text::variable_type::type, std::string_view(needs_type));
1645 text::localised_format_box(state, contents, box, "budget_strata_need", sub);
1646 text::close_layout_box(contents, box);
1647 }
1648 } else {
1649 {
1650 auto box = text::open_layout_box(contents, 0);
1651 text::add_to_layout_box(state, contents, box, state.world.pop_type_get_name(type));
1652 text::close_layout_box(contents, box);
1653 }
1655 {
1656 auto box = text::open_layout_box(contents, 0);
1657 text::localised_format_box(state, contents, box, std::string_view("no_pops_of_type"));
1658 text::close_layout_box(contents, box);
1659 }
1660 }
1661
1662 }
1663};
1664
1666private:
1668
1669public:
1670 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1671 if(name == "pop") {
1672 auto ptr = make_element_by_type<tax_list_pop_type_icon>(state, id);
1673 pop_type_icon = ptr.get();
1674 return ptr;
1675 } else {
1676 return nullptr;
1677 }
1678 }
1679
1680 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
1681 if(payload.holds_type<wrapped_listbox_row_content<dcon::pop_type_id>>()) {
1682 auto pop_type_id = any_cast<wrapped_listbox_row_content<dcon::pop_type_id>>(payload).content;
1683 pop_type_icon->set_type(state, pop_type_id);
1685 }
1687 }
1688};
1689
1690template<culture::pop_strata Strata>
1691class budget_pop_tax_list : public overlapping_listbox_element_base<budget_pop_list_item, dcon::pop_type_id> {
1692protected:
1693 std::string_view get_row_element_name() override {
1694 return "pop_listitem";
1695 }
1696
1697public:
1698 void on_create(sys::state& state) noexcept override {
1700 state.world.for_each_pop_type([&](dcon::pop_type_id pt) {
1701 if(state.world.pop_type_get_strata(pt) == uint8_t(Strata)) {
1702 row_contents.push_back(pt);
1703 }
1704 });
1705 update(state);
1706 }
1707};
1708
1709template<culture::income_type Income>
1710class budget_pop_income_list : public overlapping_listbox_element_base<budget_pop_list_item, dcon::pop_type_id> {
1711protected:
1712 std::string_view get_row_element_name() override {
1713 return "pop_listitem";
1714 }
1715
1716public:
1717 void on_create(sys::state& state) noexcept override {
1719 state.world.for_each_pop_type([&](dcon::pop_type_id pt) {
1720 if(state.world.pop_type_get_life_needs_income_type(pt) == uint8_t(Income) ||
1721 state.world.pop_type_get_everyday_needs_income_type(pt) == uint8_t(Income) ||
1722 state.world.pop_type_get_luxury_needs_income_type(pt) == uint8_t(Income)) {
1723 row_contents.push_back(pt);
1724 }
1725 });
1726 update(state);
1727 }
1728};
1729
1730template<culture::income_type Income>
1732protected:
1733 std::string_view get_row_element_name() override {
1734 return "pop_listitem_small";
1735 }
1736};
1737
1739public:
1740 message_result set(sys::state& state, Cyto::Any& payload) noexcept override {
1741 if(payload.holds_type<budget_slider_signal>()) {
1742 auto sig = any_cast<budget_slider_signal>(payload);
1743 if(sig.target == budget_slider_target::tariffs) {
1745 }
1747 }
1749 }
1750
1751 void on_update(sys::state& state) noexcept override {
1752 auto nation_id = retrieve<dcon::nation_id>(state, parent);
1753 set_text(state, text::format_percentage(float(state.world.nation_get_tariffs_import(nation_id)) / 100.0f));
1754 }
1755};
1756
1757class debt_piechart : public piechart<dcon::nation_id> {
1758public:
1759 void on_update(sys::state& state) noexcept override {
1760 distribution.clear();
1761 auto t = state.world.nation_get_local_loan(state.local_player_nation);
1762
1763 if(t > 0.0f) {
1764 float share = 10.0f;
1765 distribution.emplace_back(state.local_player_nation, share);
1766 }
1768 }
1769};
1770
1772 dcon::nation_id n;
1773 float amount;
1774
1775 bool operator==(debt_item_data o) const noexcept {
1776 return n == o.n && amount == o.amount;
1777 }
1778 bool operator!=(debt_item_data o) const noexcept {
1779 return !(*this == o);
1780 }
1781};
1782
1784public:
1785 void on_update(sys::state& state) noexcept override {
1786 debt_item_data dat = retrieve< debt_item_data>(state, parent);
1788 }
1789};
1790
1792public:
1793 void on_update(sys::state& state) noexcept override {
1794 debt_item_data dat = retrieve< debt_item_data>(state, parent);
1796 }
1797};
1798
1799
1800class debt_item : public listbox_row_element_base<debt_item_data> {
1801public:
1802 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1803 if(name == "who") {
1804 return make_element_by_type<debtor_name>(state, id);
1805 } else if(name == "debt") {
1806 return make_element_by_type<debtor_amount>(state, id);
1807 } else {
1808 return nullptr;
1809 }
1810 }
1811};
1812
1813class debt_listbox : public listbox_element_base<debt_item, debt_item_data> {
1814protected:
1815 std::string_view get_row_element_name() override {
1816 return "debt_listitem";
1817 }
1818
1819public:
1820 void on_update(sys::state& state) noexcept override {
1821 row_contents.clear();
1822
1823 auto t = state.world.nation_get_local_loan(state.local_player_nation);
1824
1825 if(t > 0.0f) {
1826 row_contents.push_back(debt_item_data{ state.local_player_nation, t });
1827 }
1828
1829 update(state);
1830 }
1831};
1832
1834public:
1835 void on_update(sys::state& state) noexcept override {
1836 frame = state.world.nation_get_is_debt_spending(state.local_player_nation) ? 1 : 0;
1837 disabled = false;
1838
1839 auto last_br = state.world.nation_get_bankrupt_until(state.local_player_nation);
1840 if(last_br && state.current_date < last_br)
1841 disabled = true;
1842 if(economy::max_loan(state, state.local_player_nation) <= 0.0f)
1843 disabled = true;
1844 }
1845 void button_action(sys::state& state) noexcept override {
1846 command::enable_debt(state, state.local_player_nation, !state.world.nation_get_is_debt_spending(state.local_player_nation));
1847 }
1850 }
1851
1852 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1853 auto last_br = state.world.nation_get_bankrupt_until(state.local_player_nation);
1854 if(last_br && state.current_date < last_br) {
1855 text::add_line(state, contents, "alice_currently_bankrupt", text::variable_type::x, last_br);
1856 } else if(economy::max_loan(state, state.local_player_nation) <= 0.0f) {
1857 text::add_line(state, contents, "alice_no_loans_possible");
1858 } else {
1859 text::add_line(state, contents, "alice_debt_spending");
1861 text::add_line(state, contents, "alice_loan_size", text::variable_type::x, text::fp_currency{ economy::max_loan(state, state.local_player_nation) });
1862 }
1863 }
1864};
1865
1866class domestic_investment_slider : public budget_slider<budget_slider_target::domestic_investment, slider_scaling::quadratic, slider_update_type::autoscalerupdate> {
1867 int32_t get_true_value(sys::state& state) noexcept override {
1868 return int32_t(state.world.nation_get_domestic_investment_spending(state.local_player_nation));
1869 }
1870 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
1872 }
1873 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1874 auto n = retrieve<dcon::nation_id>(state, parent);
1875 auto box = text::open_layout_box(contents, 0);
1876 text::localised_single_sub_box(state, contents, box, "alice_budget_setting_percent", text::variable_type::perc, text::int_percentage{ state.world.nation_get_domestic_investment_spending(n) });
1878 text::close_layout_box(contents, box);
1879
1881 state,
1882 contents,
1883 "alice_domestic_investment_pops",
1886 int32_t(
1887 state.world.nation_get_demographics(n,
1888 demographics::to_key(state, state.culture_definitions.capitalists)
1889 ) + state.world.nation_get_demographics(n,
1890 demographics::to_key(state, state.culture_definitions.aristocrat)
1891 )
1892 )
1893 });
1894
1896 state,
1897 contents,
1898 "alice_domestic_investment_needs",
1902 });
1903 }
1904};
1906public:
1907 void on_update(sys::state& state) noexcept override {
1908 float value = state.world.nation_get_domestic_investment_spending(state.local_player_nation) / 100.0f;
1909 set_text(state, text::format_money(economy::estimate_domestic_investment(state, state.local_player_nation) * value * value));
1910 }
1911};
1912
1913// overseas_maintenance
1914
1915
1916class overseas_maintenance_slider : public budget_slider<budget_slider_target::overseas, slider_scaling::linear, slider_update_type::autoscalerupdate> {
1917 int32_t get_true_value(sys::state& state) noexcept override {
1918 return int32_t(state.world.nation_get_overseas_spending(state.local_player_nation));
1919 }
1920 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
1922 }
1923 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1924 auto n = retrieve<dcon::nation_id>(state, parent);
1925 auto box = text::open_layout_box(contents, 0);
1926 text::close_layout_box(contents, box);
1927 }
1928};
1930public:
1931 void on_update(sys::state& state) noexcept override {
1932 float value = state.world.nation_get_overseas_spending(state.local_player_nation) / 100.0f;
1934 }
1935};
1936
1938private:
1939 budget_take_loan_window* budget_take_loan_win = nullptr;
1940 budget_repay_loan_window* budget_repay_loan_win = nullptr;
1941
1942public:
1943 void on_create(sys::state& state) noexcept override {
1945
1946 auto win1337 = make_element_by_type<budget_take_loan_window>(state, state.ui_state.defs_by_name.find(state.lookup_key("take_loan_window"))->second.definition);
1947 budget_take_loan_win = win1337.get();
1948 win1337->base_data.position.y -= 66; // Nudge >w<
1949 win1337->set_visible(state, false);
1950 add_child_to_front(std::move(win1337));
1951
1952 auto win101 = make_element_by_type<budget_repay_loan_window>(state, state.ui_state.defs_by_name.find(state.lookup_key("repay_loan_window"))->second.definition);
1953 budget_repay_loan_win = win101.get();
1954 win101->base_data.position.y -= 66; // Nudge >w<
1955 win101->set_visible(state, false);
1956 add_child_to_front(std::move(win101));
1957
1958 {
1959 auto elm = make_element_by_type<enable_debt_toggle>(state, state.ui_state.defs_by_name.find(state.lookup_key("alice_debt_checkbox"))->second.definition);
1960 add_child_to_front(std::move(elm));
1961 }
1962
1963 {
1964 auto elm = make_element_by_type<domestic_investment_slider>(state, state.ui_state.defs_by_name.find(state.lookup_key("alice_domestic_investment_slider"))->second.definition);
1965 add_child_to_front(std::move(elm));
1966 }
1967 {
1968 auto elm = make_element_by_type<simple_text_element_base>(state, state.ui_state.defs_by_name.find(state.lookup_key("alice_domestic_investment_label"))->second.definition);
1969 add_child_to_front(std::move(elm));
1970 }
1971 {
1972 auto elm = make_element_by_type<domestic_investment_estimated_text>(state, state.ui_state.defs_by_name.find(state.lookup_key("alice_domestic_investment_value"))->second.definition);
1973 add_child_to_front(std::move(elm));
1974 }
1975
1976 {
1977 auto elm = make_element_by_type<overseas_maintenance_slider>(state, state.ui_state.defs_by_name.find(state.lookup_key("alice_overseas_maintenance_slider"))->second.definition);
1978 add_child_to_front(std::move(elm));
1979 }
1980 {
1981 auto elm = make_element_by_type<simple_text_element_base>(state, state.ui_state.defs_by_name.find(state.lookup_key("alice_overseas_maintenance_label"))->second.definition);
1982 add_child_to_front(std::move(elm));
1983 }
1984 {
1985 auto elm = make_element_by_type<overseas_maintenance_estimated_text>(state, state.ui_state.defs_by_name.find(state.lookup_key("alice_overseas_maintenance_value"))->second.definition);
1986 add_child_to_front(std::move(elm));
1987 }
1988
1989 set_visible(state, false);
1990 }
1991
1992 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1993 if(name == "main_bg") {
1994 return make_element_by_type<image_element_base>(state, id);
1995 } else if(name == "bg_budget") {
1996 return make_element_by_type<opaque_element_base>(state, id);
1997 } else if(name == "tariff_mid") {
1998 return make_element_by_type<invisible_element>(state, id);
1999 } else if(name == "close_button") {
2000 return make_element_by_type<generic_close_button>(state, id);
2001 } else if(name == "tariffs_percent") {
2002 auto ptr = make_element_by_type<budget_tariff_percentage_text>(state, id);
2003 ptr->base_data.position.x += int16_t(10); //nudge
2004 return ptr;
2005 } else if(name == "total_funds_val") {
2006 return make_element_by_type<nation_budget_funds_text>(state, id);
2007 } else if(name == "national_bank_val") {
2008 return make_element_by_type<nation_budget_bank_text>(state, id);
2009 } else if(name == "debt_val") {
2010 return make_element_by_type<nation_budget_debt_text>(state, id);
2011 } else if(name == "interest_val") {
2012 return make_element_by_type<nation_budget_interest_text>(state, id);
2013 } else if(name == "tab_takenloans") {
2014 return make_element_by_type<invisible_element>(state, id);
2015 } else if(name == "tab_givenloans") {
2016 return make_element_by_type<invisible_element>(state, id);
2017 } else if(name == "givenloans_text") {
2018 return make_element_by_type<invisible_element>(state, id);
2019 } else if(name == "take_loan") {
2020 return make_element_by_type<invisible_element>(state, id);
2021 } else if(name == "repay_loan") {
2022 return make_element_by_type<invisible_element>(state, id);
2023 } else if(name == "gunboat_alert") {
2024 return make_element_by_type<invisible_element>(state, id);
2025 } else if(name == "chart_debt") {
2026 return make_element_by_type<debt_piechart>(state, id);
2027 } else if(name == "debt_listbox") {
2028 return make_element_by_type<debt_listbox>(state, id);
2029 } else if(name == "chart_0") {
2030 return make_element_by_type<satisfaction_graph<culture::pop_strata::poor>>(state, id);
2031 } else if(name == "chart_1") {
2032 return make_element_by_type<satisfaction_graph<culture::pop_strata::middle>>(state, id);
2033 } else if(name == "chart_2") {
2034 return make_element_by_type<satisfaction_graph<culture::pop_strata::rich>>(state, id);
2035 } else if(name == "overlay_0" || name == "overlay_1" || name == "overlay_2") {
2036 return make_element_by_type<invisible_element>(state, id);
2037 } else if(name == "nat_stock_val") {
2038 auto ptr = make_element_by_type<budget_actual_stockpile_spending_text>(state, id);
2039 ptr->expense = true;
2040 return ptr;
2041 } else if(name == "nat_stock_est") {
2042 auto ptr = make_element_by_type<budget_estimated_stockpile_spending_text>(state, id);
2043 ptr->expense = true;
2044 return ptr;
2045 } else if(name == "mil_cost_val") {
2046 auto ptr = make_element_by_type<budget_military_spending_text>(state, id);
2047 ptr->expense = true;
2048 return ptr;
2049 } else if(name == "overseas_cost_val") {
2050 auto ptr = make_element_by_type<budget_overseas_spending_text>(state, id);
2051 ptr->expense = true;
2052 return ptr;
2053 } else if(name == "tariff_val") {
2054 return make_element_by_type<budget_tariff_income_text>(state, id);
2055 } else if(name == "gold_inc") {
2056 return make_element_by_type<nation_gold_income_text>(state, id);
2057 } else if(name == "tax_0_inc") {
2058 return make_element_by_type<budget_stratified_tax_income_text<culture::pop_strata::poor, budget_slider_target::poor_tax>>( state, id);
2059 } else if(name == "tax_1_inc") {
2060 return make_element_by_type<budget_stratified_tax_income_text<culture::pop_strata::middle, budget_slider_target::middle_tax>>(state, id);
2061 } else if(name == "tax_2_inc") {
2062 return make_element_by_type<budget_stratified_tax_income_text<culture::pop_strata::rich, budget_slider_target::rich_tax>>( state, id);
2063 } else if(name == "exp_val_0") {
2064 auto ptr = make_element_by_type<budget_expenditure_text<culture::income_type::education, budget_slider_target::education>>( state, id);
2065 ptr->expense = true;
2066 return ptr;
2067 } else if(name == "exp_val_1") {
2068 auto ptr = make_element_by_type<budget_expenditure_text<culture::income_type::administration, budget_slider_target::admin>>(state, id);
2069 ptr->expense = true;
2070 return ptr;
2071 } else if(name == "exp_val_2") {
2072 auto ptr = make_element_by_type<budget_social_spending_text>(state, id);
2073 ptr->expense = true;
2074 return ptr;
2075 } else if(name == "exp_val_3") {
2076 auto ptr = make_element_by_type<budget_expenditure_text<culture::income_type::military, budget_slider_target::military>>(state, id);
2077 ptr->expense = true;
2078 return ptr;
2079 } else if(name == "admin_efficiency") {
2080 return make_element_by_type<nation_administrative_efficiency_text>(state, id);
2081 } else if(name == "interest_val") {
2082 return make_element_by_type<nation_loan_spending_text>(state, id);
2083 } else if(name == "ind_sub_val") {
2084 return make_element_by_type<nation_subsidy_spending_text>(state, id);
2085 } else if(name == "diplomatic_balance") {
2086 return make_element_by_type<nation_diplomatic_balance_text>(state, id);
2087 } else if(name == "total_inc") {
2088 return make_element_by_type<budget_income_projection_text>(state, id);
2089 } else if(name == "total_exp") {
2090 auto ptr = make_element_by_type<budget_expenditure_projection_text>(state, id);
2091 ptr->expense = true;
2092 return ptr;
2093 } else if(name == "balance") {
2094 return make_element_by_type<budget_balance_projection_text>(state, id);
2095 } else if(name == "tax_0_slider") {
2096 return make_element_by_type<budget_poor_tax_slider>(state, id);
2097 } else if(name == "tax_1_slider") {
2098 return make_element_by_type<budget_middle_tax_slider>(state, id);
2099 } else if(name == "tax_2_slider") {
2100 return make_element_by_type<budget_rich_tax_slider>(state, id);
2101 } else if(name == "land_stockpile_slider") {
2102 return make_element_by_type<budget_army_stockpile_slider>(state, id);
2103 } else if(name == "naval_stockpile_slider") {
2104 return make_element_by_type<budget_navy_stockpile_slider>(state, id);
2105 } else if(name == "projects_stockpile_slider") {
2106 return make_element_by_type<budget_construction_stockpile_slider>(state, id);
2107 } else if(name == "exp_0_slider") {
2108 return make_element_by_type<budget_education_slider>(state, id);
2109 } else if(name == "exp_1_slider") {
2110 return make_element_by_type<budget_administration_slider>(state, id);
2111 } else if(name == "exp_2_slider") {
2112 return make_element_by_type<budget_social_spending_slider>(state, id);
2113 } else if(name == "exp_3_slider") {
2114 return make_element_by_type<budget_military_spending_slider>(state, id);
2115 } else if(name == "tariff_slider") {
2116 return make_element_by_type<budget_tariff_slider>(state, id);
2117 } else if(name == "take_loan") {
2118 return make_element_by_type<budget_take_loan_button>(state, id);
2119 } else if(name == "repay_loan") {
2120 return make_element_by_type<budget_repay_loan_button>(state, id);
2121 } else if(name == "tax_0_pops") {
2122 return make_element_by_type<budget_pop_tax_list<culture::pop_strata::poor>>(state, id);
2123 } else if(name == "tax_1_pops") {
2124 return make_element_by_type<budget_pop_tax_list<culture::pop_strata::middle>>(state, id);
2125 } else if(name == "tax_2_pops") {
2126 return make_element_by_type<budget_pop_tax_list<culture::pop_strata::rich>>(state, id);
2127 } else if(name == "exp_0_pops") {
2128 return make_element_by_type<budget_small_pop_income_list<culture::income_type::education>>(state, id);
2129 } else if(name == "exp_1_pops") {
2130 return make_element_by_type<budget_small_pop_income_list<culture::income_type::administration>>(state, id);
2131 // } else if(name == "exp_2_pops") { // intentionally unused
2132 // return make_element_by_type<budget_pop_income_list<culture::income_type::reforms>>(state, id);
2133 } else if(name == "exp_3_pops") {
2134 return make_element_by_type<budget_pop_income_list<culture::income_type::military>>(state, id);
2135 } else {
2136 return nullptr;
2137 }
2138 }
2139
2140 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
2141 if(payload.holds_type<dcon::nation_id>()) {
2142 payload.emplace<dcon::nation_id>(state.local_player_nation);
2144 }
2145 //=====================================================================
2146 else if(payload.holds_type<element_selection_wrapper<bool>>()) {
2147 bool type = any_cast<element_selection_wrapper<bool>>(payload).data;
2148 if(type) { // Take Loan Win.
2149 budget_take_loan_win->set_visible(state, true);
2150 move_child_to_front(budget_take_loan_win);
2151 } else { // Repay Loan Win.
2152 budget_repay_loan_win->set_visible(state, true);
2153 move_child_to_front(budget_repay_loan_win);
2154 }
2156 } else if(payload.holds_type<budget_slider_signal>()) {
2157 impl_set(state, payload);
2158 }
2159
2161 }
2162};
2163
2164} // namespace ui
dcon::text_key get_name() noexcept
void set_name(dcon::text_key text) noexcept
void put_values(sys::state &state, std::array< float, size_t(budget_slider_target::target_count)> &vals) noexcept override
void put_values(sys::state &state, std::array< float, size_t(budget_slider_target::target_count)> &vals) noexcept override
void put_values(sys::state &state, std::array< float, size_t(budget_slider_target::target_count)> &vals) noexcept override
void put_values(sys::state &state, std::array< float, size_t(budget_slider_target::target_count)> &vals) noexcept override
void put_values(sys::state &state, std::array< float, size_t(budget_slider_target::target_count)> &vals) noexcept override
void put_values(sys::state &state, std::array< float, size_t(budget_slider_target::target_count)> &vals) noexcept override
void put_values(sys::state &state, std::array< float, size_t(budget_slider_target::target_count)> &vals) noexcept override
void put_values(sys::state &state, std::array< float, size_t(budget_slider_target::target_count)> &vals) noexcept override
void on_create(sys::state &state) noexcept override
std::string_view get_row_element_name() 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
std::string_view get_row_element_name() override
void on_create(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 set(sys::state &state, Cyto::Any &payload) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void on_update(sys::state &state) noexcept override
void on_create(sys::state &state) noexcept override
virtual void put_values(sys::state &state, std::array< float, size_t(budget_slider_target::target_count)> &vals) noexcept
void apply_multipliers(sys::state &state) noexcept
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void on_drag_finish(sys::state &state) noexcept override
void on_create(sys::state &state) noexcept final
virtual int32_t get_true_value(sys::state &state) noexcept
void on_update(sys::state &state) noexcept final
void on_value_change(sys::state &state, int32_t v) noexcept final
std::string_view get_row_element_name() override
void put_values(sys::state &state, std::array< float, size_t(budget_slider_target::target_count)> &vals) 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
void put_values(sys::state &state, std::array< float, size_t(budget_slider_target::target_count)> &vals) noexcept override
void on_update(sys::state &state) noexcept override
message_result set(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
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
void on_create(sys::state &state) noexcept override
message_result impl_set(sys::state &state, Cyto::Any &payload) noexcept final
void add_child_to_back(std::unique_ptr< element_base > child) noexcept final
void add_child_to_front(std::unique_ptr< element_base > child) noexcept final
void move_child_to_front(element_base *child) noexcept final
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_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
virtual message_result impl_set(sys::state &state, Cyto::Any &payload) noexcept
element_base * parent
virtual message_result get(sys::state &state, Cyto::Any &payload) noexcept
message_result impl_get(sys::state &state, Cyto::Any &payload) noexcept
virtual void on_create(sys::state &state) noexcept
element_data base_data
void set_visible(sys::state &state, bool vis)
void on_update(sys::state &state) 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_action(sys::state &state) noexcept override
const uint32_t count
void set_data_points(sys::state &state, std::vector< float > const &datapoints) noexcept
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 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 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_create(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void populate_tooltip(sys::state &state, dcon::pop_satisfaction_wrapper_id psw, float percentage, text::columnar_layout &contents) noexcept override
void on_create(sys::state &state) noexcept override
void on_create(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
image_element_base * right_limit
scrollbar_slider * slider
void change_settings(sys::state &state, mutable_scrollbar_settings const &settings_s)
scrollbar_settings settings
scrollbar_right * right
scrollbar_left * left
scrollbar_track * track
float scaled_value() const
void update_raw_value(sys::state &state, int32_t v)
image_element_base * left_limit
void set_text(sys::state &state, std::string const &new_text)
void on_update(sys::state &state) noexcept override
void set_type(sys::state &state, dcon::pop_type_id t)
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 on_create(sys::state &state) noexcept override
budget_settings_data make_empty_budget_settings()
Definition: commands.hpp:617
void change_budget_settings(sys::state &state, dcon::nation_id source, budget_settings_data const &values)
Definition: commands.cpp:971
pop_satisfaction_wrapper_fat fatten(data_container const &c, pop_satisfaction_wrapper_id id) noexcept
constexpr dcon::demographics_key middle_total(21)
dcon::demographics_key to_key(sys::state const &state, dcon::pop_type_id v)
constexpr dcon::demographics_key rich_total(22)
constexpr dcon::demographics_key poor_total(20)
float estimate_reparations_income(sys::state &state, dcon::nation_id n)
Definition: economy.cpp:8081
float estimate_subsidy_spending(sys::state &state, dcon::nation_id n)
Definition: economy.cpp:8067
float estimate_social_spending(sys::state &state, dcon::nation_id n)
Definition: economy.cpp:7990
float estimate_subject_payments_paid(sys::state &state, dcon::nation_id n)
Definition: economy.cpp:8218
float estimate_diplomatic_balance(sys::state &state, dcon::nation_id n)
Definition: economy.cpp:8126
float estimate_pop_payouts_by_income_type(sys::state &state, dcon::nation_id n, culture::income_type in)
Definition: economy.cpp:8023
float estimate_domestic_investment(sys::state &state, dcon::nation_id n)
Definition: economy.cpp:8147
float estimate_overseas_penalty_spending(sys::state &state, dcon::nation_id n)
Definition: economy.cpp:4041
float max_loan(sys::state &state, dcon::nation_id n)
Definition: economy.cpp:816
float estimate_construction_spending(sys::state &state, dcon::nation_id n)
Definition: economy.cpp:3692
float estimate_war_subsidies_income(sys::state &state, dcon::nation_id n)
Definition: economy.cpp:8071
float estimate_land_spending(sys::state &state, dcon::nation_id n)
Definition: economy.cpp:8177
float price(sys::state const &state, dcon::state_instance_id s, dcon::commodity_id c)
Definition: economy.cpp:150
float estimate_tariff_import_income(sys::state &state, dcon::nation_id n)
Definition: economy.cpp:7958
float estimate_subject_payments_received(sys::state &state, dcon::nation_id o)
Definition: economy.cpp:8242
float estimate_war_subsidies_spending(sys::state &state, dcon::nation_id n)
Definition: economy.cpp:8097
float estimate_reparations_spending(sys::state &state, dcon::nation_id n)
Definition: economy.cpp:8109
float estimate_naval_spending(sys::state &state, dcon::nation_id n)
Definition: economy.cpp:8194
float average_capitalists_luxury_cost(sys::state &state, dcon::nation_id s)
Definition: economy.cpp:432
float estimate_tax_income_by_strata(sys::state &state, dcon::nation_id n, culture::pop_strata ps)
Definition: economy.cpp:8054
float estimate_stockpile_filling_spending(sys::state &state, dcon::nation_id n)
Definition: economy.cpp:4016
province_building_type
Definition: constants.hpp:578
float interest_payment(sys::state &state, dcon::nation_id n)
Definition: economy.cpp:808
float estimate_gold_income(sys::state &state, dcon::nation_id n)
Definition: economy.cpp:7942
uint32_t get_ui_color(sys::state &state, T id)
Definition: color.hpp:585
float get_luxury_needs(sys::state const &state, dcon::pop_id p)
float get_life_needs(sys::state const &state, dcon::pop_id p)
float get_everyday_needs(sys::state const &state, dcon::pop_id p)
Definition: prng.cpp:6
uint32_t pack_color(float r, float g, float b)
Definition: bmfont.cpp:118
void add_line_break_to_layout_box(sys::state &state, layout_base &dest, layout_box &box)
Definition: text.cpp:1147
void add_to_layout_box(sys::state &state, layout_base &dest, layout_box &box, embedded_flag ico)
Definition: text.cpp:1165
std::string format_money(float num)
Definition: text.cpp:1029
layout_box open_layout_box(layout_base &dest, int32_t indent)
Definition: text.cpp:1823
void add_unparsed_text_to_layout_box(sys::state &state, layout_base &dest, layout_box &box, std::string_view sv, substitution_map const &mp)
Definition: text.cpp:1612
void localised_single_sub_box(sys::state &state, layout_base &dest, layout_box &box, std::string_view key, variable_type subkey, substitution value)
Definition: text.cpp:1912
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:1904
std::string prettify(int64_t num)
Definition: text.cpp:762
void add_line(sys::state &state, layout_base &dest, dcon::text_key txt, int32_t indent)
Definition: text.cpp:1923
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:797
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
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:1831
tooltip_behavior
void send(sys::state &state, element_base *parent, T value)
message_result
void active_modifiers_description(sys::state &state, text::layout_base &layout, dcon::nation_id n, int32_t identation, dcon::national_modifier_value nmid, bool header)
uint uint32_t
uchar uint8_t
static constexpr uint32_t set_size
Holds important data about the game world, state, and other data regarding windowing,...
budget_slider_target target
bool operator==(debt_item_data o) const noexcept
bool operator!=(debt_item_data o) const noexcept
element_type get_element_type() const
union ui::element_data::internal_data data
bool is_horizontal() const
step_size get_step_size() const
dcon::gui_def_id first_child
ankerl::unordered_dense::map< dcon::text_key, element_target, hash_text_key > defs_by_name
element_base * drag_target