Project Alice
Loading...
Searching...
No Matches
gui_province_window.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "dcon_generated.hpp"
4#include "demographics.hpp"
7#include "gui_graphics.hpp"
9#include "nations.hpp"
10#include "province.hpp"
11#include "system_state.hpp"
12#include "text.hpp"
16#include "nations_templates.hpp"
17
18namespace ui {
19
20
22public:
23 void on_update(sys::state& state) noexcept override {
24 auto p = retrieve<dcon::province_id>(state, parent);
25 frame = (state.world.province_get_land_rally_point(retrieve<dcon::province_id>(state, parent))) ? 1 : 0;
26 disabled = state.world.province_get_nation_from_province_ownership(p) != state.local_player_nation;
27 }
28 void button_action(sys::state& state) noexcept override {
29 auto p = retrieve<dcon::province_id>(state, parent);
30 command::set_rally_point(state, state.local_player_nation, p, false, !state.world.province_get_land_rally_point(p));
31 }
34 }
35 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
36 text::add_line(state, contents, "rally_point_enable_info");
37 }
38};
39
41public:
42 void on_update(sys::state& state) noexcept override {
43 auto p = retrieve<dcon::province_id>(state, parent);
44 frame = state.world.province_get_naval_rally_point(p) ? 1 : 0;
45 disabled = !(state.world.province_get_is_coast(p)) || state.world.province_get_nation_from_province_ownership(p) != state.local_player_nation;
46 }
47 void button_action(sys::state& state) noexcept override {
48 auto p = retrieve<dcon::province_id>(state, parent);
49 command::set_rally_point(state, state.local_player_nation, p, true, !state.world.province_get_naval_rally_point(p));
50 }
53 }
54 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
55 text::add_line(state, contents, "rally_point_enable_info");
56 }
57};
58
60public:
61 void on_create(sys::state& state) noexcept override {
63 disabled = true;
64 }
67 }
68 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
69 text::add_line(state, contents, "alice_merge_rally_point_why");
70 }
71};
72
74public:
75
76 void on_update(sys::state& state) noexcept override {
77 auto prov_id = retrieve<dcon::province_id>(state, parent);
78 progress = state.world.province_get_life_rating(prov_id) / 100.f;
79 }
80
83 }
84
85 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
86 dcon::province_id prov_id = retrieve<dcon::province_id>(state, parent);
87
88 text::add_line(state, contents, "provinceview_liferating", text::variable_type::value, int64_t(state.world.province_get_life_rating(prov_id)));
90 text::add_line(state, contents, "col_liferate_techs");
91 for(auto i : state.world.in_invention) {
92 auto mod = i.get_modifier();
94 if(mod.get_national_values().offsets[j] == sys::national_mod_offsets::colonial_life_rating) {
95 auto box = text::open_layout_box(contents);
96 text::add_to_layout_box(state, contents, box, i.get_name(), state.world.nation_get_active_inventions(state.local_player_nation, i) ? text::text_color::green : text::text_color::red);
97
98 dcon::technology_id containing_tech;
99 auto lim_trigger_k = i.get_limit();
100 trigger::recurse_over_triggers(state.trigger_data.data() + state.trigger_data_indices[lim_trigger_k.index() + 1],
101 [&](uint16_t* tval) {
102 if((tval[0] & trigger::code_mask) == trigger::technology)
103 containing_tech = trigger::payload(tval[1]).tech_id;
104 });
105
106 if(containing_tech) {
107 text::add_to_layout_box(state, contents, box, std::string_view{ " (" });
108 text::add_to_layout_box(state, contents, box, state.world.technology_get_name(containing_tech), state.world.nation_get_active_technologies(state.local_player_nation, containing_tech) ? text::text_color::green : text::text_color::red);
109 text::add_to_layout_box(state, contents, box, std::string_view{ ")" });
110 }
111 text::close_layout_box(contents, box);
112 break;
113 }
114 }
115 }
116 }
117};
118
120public:
123 }
124
125 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
126 auto box = text::open_layout_box(contents, 0);
127 text::localised_format_box(state, contents, box, std::string_view("provinceview_totalpop"));
128 text::close_layout_box(contents, box);
129 }
130};
131
133public:
134 void on_update(sys::state& state) noexcept override {
135 auto fat_id = dcon::fatten(state.world, retrieve<dcon::province_id>(state, parent));
136 frame = fat_id.get_rgo().get_icon();
137 }
138
141 }
142
143 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
144 auto prov = retrieve<dcon::province_id>(state, parent);
145 auto rgo = state.world.province_get_rgo(prov);
146 text::add_line(state, contents, state.world.commodity_get_name(rgo));
147 }
148};
149
151public:
152 void button_action(sys::state& state) noexcept override {
153 state.map_state.set_selected_province(dcon::province_id{});
155 }
156};
157
159public:
160 void button_action(sys::state& state) noexcept override {
161 dcon::province_id province_id = retrieve<dcon::province_id>(state, parent);
162 if(state.ui_state.population_subwindow != nullptr) {
163 Cyto::Any fl_payload = pop_list_filter(province_id);
164 state.ui_state.population_subwindow->impl_set(state, fl_payload);
165 if(state.ui_state.topbar_subwindow != nullptr)
166 state.ui_state.topbar_subwindow->set_visible(state, false);
169 state.ui_state.root->move_child_to_front(state.ui_state.population_subwindow);
170 // ui_state.population_subwindow->impl_get(*this, fl_payload);
171 }
172 }
175 }
176 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
177 dcon::province_id province_id = retrieve<dcon::province_id>(state, parent);
179 text::add_to_substitution_map(sub_map, text::variable_type::loc, state.world.province_get_name(province_id));
180 auto box = text::open_layout_box(contents, 0);
181 text::localised_format_box(state, contents, box, std::string_view("pw_open_popscreen"), sub_map);
182 text::close_layout_box(contents, box);
183 }
184};
185
187public:
188 void on_update(sys::state& state) noexcept override {
189 dcon::province_id province_id = retrieve<dcon::province_id>(state, parent);
190 auto fat_id = dcon::fatten(state.world, province_id);
191 auto terrain_id = fat_id.get_terrain().id;
192 auto terrain_image = state.province_definitions.terrain_to_gfx_map[terrain_id];
194 base_data.data.image.gfx_object = terrain_image;
195 }
196 }
197
200 }
201
202 void update_tooltip(sys::state& state, int32_t x, int32_t t, text::columnar_layout& contents) noexcept override {
203 dcon::province_id province_id = retrieve<dcon::province_id>(state, parent);
204 auto fat_id = dcon::fatten(state.world, province_id);
205 //terrain
206 if(auto name = fat_id.get_terrain().get_name(); name) {
207 auto box = text::open_layout_box(contents, 0);
209 text::close_layout_box(contents, box);
210 }
211 if(auto mod_id = fat_id.get_terrain().id; mod_id) {
212 modifier_description(state, contents, mod_id);
213 }
214 //climate
215 if(auto name = fat_id.get_climate().get_name(); name) {
216 auto box = text::open_layout_box(contents, 0);
218 text::close_layout_box(contents, box);
219 }
220 if(auto mod_id = fat_id.get_climate().id; mod_id) {
221 modifier_description(state, contents, mod_id);
222 }
223 //continent
224 if(auto name = fat_id.get_continent().get_name(); name) {
225 auto box = text::open_layout_box(contents, 0);
227 text::close_layout_box(contents, box);
228 }
229 if(auto mod_id = fat_id.get_continent().id; mod_id) {
230 modifier_description(state, contents, mod_id);
231 }
232 }
233};
234
236public:
237 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
238 auto prov = retrieve<dcon::province_id>(state, parent);
239 if(state.world.state_instance_get_flashpoint_tag(state.world.province_get_state_membership(prov))) {
241 } else {
242 // no flashpoint
243 }
244 }
245
248 }
249
250 void update_tooltip(sys::state& state, int32_t x, int32_t t, text::columnar_layout& contents) noexcept override {
251 dcon::province_id prov = retrieve<dcon::province_id>(state, parent);
252 if(!state.world.state_instance_get_flashpoint_tag(state.world.province_get_state_membership(prov)))
253 return;
254
255 text::substitution_map sub_map{};
256 text::add_to_substitution_map(sub_map, text::variable_type::value, text::fp_two_places{ state.world.state_instance_get_flashpoint_tension(state.world.province_get_state_membership(prov)) });
257 auto box = text::open_layout_box(contents, 0);
258 text::localised_format_box(state, contents, box, std::string_view("flashpoint_tension"), sub_map);
259 text::close_layout_box(contents, box);
260 }
261};
262
264public:
265 dcon::national_identity_id get_current_nation(sys::state& state) noexcept override {
266 if(parent) {
267 dcon::province_id province_id = retrieve<dcon::province_id>(state, parent);
268 auto fat_id = dcon::fatten(state.world, province_id);
269 return state.world.nation_get_identity_from_identity_holder(fat_id.get_province_control_as_province().get_nation().id);
270 }
271 return dcon::national_identity_id{};
272 }
273
274 void on_update(sys::state& state) noexcept override {
276 if(parent) {
277 dcon::province_id province_id = retrieve<dcon::province_id>(state, parent);
278 auto prov_fat = dcon::fatten(state.world, province_id);
279 auto controller = prov_fat.get_province_control_as_province().get_nation();
280 auto rebel_faction = prov_fat.get_province_rebel_control_as_province().get_rebel_faction();
281 if(rebel_faction) {
283 }
284 }
285 }
286
287 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
288 dcon::province_id province_id = retrieve<dcon::province_id>(state, parent);
289 auto prov_fat = dcon::fatten(state.world, province_id);
290 auto controller = prov_fat.get_province_control_as_province().get_nation();
291 auto rebel_faction = prov_fat.get_province_rebel_control_as_province().get_rebel_faction();
292 if(!controller && !rebel_faction)
293 return;
295 }
296
299 }
300
301 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
302 dcon::province_id province_id = retrieve<dcon::province_id>(state, parent);
303 auto prov_fat = dcon::fatten(state.world, province_id);
304 auto controller = prov_fat.get_province_control_as_province().get_nation();
305 auto rebel_faction = prov_fat.get_province_rebel_control_as_province().get_rebel_faction();
306 if(!controller && !rebel_faction)
307 return;
308 auto box = text::open_layout_box(contents, 0);
309 text::localised_format_box(state, contents, box, std::string_view("pv_controller"));
310 text::add_space_to_layout_box(state, contents, box);
311 if(controller) {
312 text::add_to_layout_box(state, contents, box, text::get_name(state, controller));
313 } else {
314 text::add_to_layout_box(state, contents, box, rebel::rebel_name(state, rebel_faction));
315 }
316 text::close_layout_box(contents, box);
317 }
318};
319
321public:
322 int32_t get_icon_frame(sys::state& state) noexcept {
323 auto content = retrieve<dcon::state_instance_id>(state, parent);
324 if(state.world.state_instance_get_nation_from_flashpoint_focus(content) == state.local_player_nation)
325 return state.world.national_focus_get_icon(state.national_definitions.flashpoint_focus) - 1;
326 return bool(state.world.state_instance_get_owner_focus(content).id)
327 ? state.world.state_instance_get_owner_focus(content).get_icon() - 1
328 : 0;
329 }
330
331 void on_update(sys::state& state) noexcept override {
332 auto content = retrieve<dcon::state_instance_id>(state, parent);
333 disabled = true;
334 for(auto nfid : state.world.in_national_focus) {
335 disabled = command::can_set_national_focus(state, state.local_player_nation, content, nfid) ? false : disabled;
336 }
337 if(state.world.state_instance_get_nation_from_flashpoint_focus(content) == state.local_player_nation)
338 disabled = false;
340 }
341
342 void button_action(sys::state& state) noexcept override;
343 void button_right_action(sys::state& state) noexcept override {
344 auto content = retrieve<dcon::state_instance_id>(state, parent);
345 command::set_national_focus(state, state.local_player_nation, content, dcon::national_focus_id{});
346 }
349 }
350
351 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
352 auto box = text::open_layout_box(contents, 0);
353
354 auto sid = retrieve<dcon::state_instance_id>(state, parent);
355 auto fat_si = dcon::fatten(state.world, sid);
356 text::add_to_layout_box(state, contents, box, sid);
358 auto content = state.world.state_instance_get_owner_focus(sid);
359 if(bool(content)) {
360 auto fat_nf = dcon::fatten(state.world, content);
361 text::add_to_layout_box(state, contents, box, state.world.national_focus_get_name(content), text::substitution_map{});
363 auto color = text::text_color::white;
364 if(fat_nf.get_promotion_type()) {
365 //Is the NF not optimal? Recolor it
366 if(fat_nf.get_promotion_type() == state.culture_definitions.clergy) {
367 if((fat_si.get_demographics(demographics::to_key(state, fat_nf.get_promotion_type())) / fat_si.get_demographics(demographics::total)) > state.defines.max_clergy_for_literacy) {
368 color = text::text_color::red;
369 }
370 } else if(fat_nf.get_promotion_type() == state.culture_definitions.bureaucrat) {
371 if(province::state_admin_efficiency(state, fat_si.id) > state.defines.max_bureaucracy_percentage) {
372 color = text::text_color::red;
373 }
374 }
375 auto full_str = text::format_percentage(fat_si.get_demographics(demographics::to_key(state, fat_nf.get_promotion_type())) / fat_si.get_demographics(demographics::total));
376 text::add_to_layout_box(state, contents, box, std::string_view(full_str), color);
377 }
378 }
379 text::close_layout_box(contents, box);
380 if(auto mid = state.world.national_focus_get_modifier(content); mid) {
381 modifier_description(state, contents, mid, 15);
382 }
383 text::add_line(state, contents, "alice_nf_controls");
384 }
385};
386
387
389public:
390 void on_update(sys::state& state) noexcept override {
391 sys::dated_modifier mod = retrieve< sys::dated_modifier>(state, parent);
392 if(mod.mod_id) {
393 frame = state.world.modifier_get_icon(mod.mod_id) - 1;
394 }
395 }
396
399 }
400
401 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
402 sys::dated_modifier mod = retrieve< sys::dated_modifier>(state, parent);
403 if(mod.mod_id) {
404 auto p = retrieve<dcon::province_id>(state, parent);
405 auto n = state.world.province_get_nation_from_province_ownership(p);
406 auto box = text::open_layout_box(contents, 0);
407 text::add_to_layout_box(state, contents, box, state.world.modifier_get_name(mod.mod_id), text::text_color::yellow);
409 if(auto desc = state.world.modifier_get_desc(mod.mod_id); state.key_is_localized(desc)) {
413 text::add_to_substitution_map(sub, text::variable_type::capital, state.world.nation_get_capital(n));
414 text::add_to_substitution_map(sub, text::variable_type::continentname, state.world.modifier_get_name(state.world.province_get_continent(state.world.nation_get_capital(n))));
416 text::add_to_layout_box(state, contents, box, desc, sub);
417 }
418 text::close_layout_box(contents, box);
419 modifier_description(state, contents, mod.mod_id, 15);
420 }
421 if(mod.expiration) {
422 text::add_line(state, contents, "expires_on", text::variable_type::date, mod.expiration);
423 }
424 }
425};
426
428public:
430
431 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
432 if(name == "modifier") {
433 return make_element_by_type<province_modifier_icon>(state, id);
434 } else {
435 return nullptr;
436 }
437 }
438
439 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
440 if(payload.holds_type<sys::dated_modifier>()) {
441 payload.emplace<sys::dated_modifier>(mod);
443 }
445 }
446
447};
448
449class province_modifiers : public overlapping_listbox_element_base<province_modifier_win, sys::dated_modifier> {
450public:
451 std::string_view get_row_element_name() override {
452 return "prov_state_modifier";
453 }
455 subwindow.mod = content;
456 }
457 void on_update(sys::state& state) noexcept override {
458 row_contents.clear();
459
460 auto prov = retrieve<dcon::province_id>(state, parent);
461 if(prov) {
462 for(auto mods : state.world.province_get_current_modifiers(prov)) {
463 row_contents.push_back(mods);
464 }
465 }
466 update(state);
467 }
468};
469
471public:
472 void on_update(sys::state& state) noexcept override {
473 auto p = retrieve<dcon::province_id>(state, parent);
474 disabled = !command::can_move_capital(state, state.local_player_nation, p);
475 }
476
477 void button_action(sys::state& state) noexcept override {
478 auto p = retrieve<dcon::province_id>(state, parent);
479 command::move_capital(state, state.local_player_nation, p);
480 }
481
484 }
485
486 void update_tooltip(sys::state& state, int32_t x, int32_t t, text::columnar_layout& contents) noexcept override {
487 auto source = state.local_player_nation;
488 auto p = retrieve<dcon::province_id>(state, parent);
489 text::add_line(state, contents, "alice_mvcap_1");
490 text::add_line_with_condition(state, contents, "alice_mvcap_2", state.current_crisis_state == sys::crisis_state::inactive);
491 text::add_line_with_condition(state, contents, "alice_mvcap_3", !(state.world.nation_get_is_at_war(source)));
492 text::add_line_with_condition(state, contents, "alice_mvcap_4", !(state.world.nation_get_capital(source) == p));
493 text::add_line_with_condition(state, contents, "alice_mvcap_5", !(state.world.province_get_is_colonial(p)));
494 text::add_line_with_condition(state, contents, "alice_mvcap_6", !(state.world.province_get_continent(state.world.nation_get_capital(source)) != state.world.province_get_continent(p)));
495 text::add_line_with_condition(state, contents, "alice_mvcap_7", !(nations::nation_accepts_culture(state, source, state.world.province_get_dominant_culture(p)) == false));
496 text::add_line_with_condition(state, contents, "alice_mvcap_8", !(state.world.province_get_siege_progress(p) > 0.f));
497 text::add_line_with_condition(state, contents, "alice_mvcap_9", !(state.world.province_get_siege_progress(state.world.nation_get_capital(source)) > 0.f));
498 text::add_line_with_condition(state, contents, "alice_mvcap_10", !(state.world.province_get_nation_from_province_ownership(p) != source));
499 text::add_line_with_condition(state, contents, "alice_mvcap_11", !(state.world.province_get_nation_from_province_control(p) != source));
500 text::add_line_with_condition(state, contents, "alice_mvcap_12", !(state.world.province_get_is_owner_core(p) == false));
501 }
502};
503
505public:
506 void on_update(sys::state& state) noexcept override {
507 if(state.defines.alice_allow_revoke_subject_states == 0.0f) {
508 set_visible(state, false);
509 return;
510 }
511 auto p = retrieve<dcon::province_id>(state, parent);
512 disabled = !command::can_take_province(state, state.local_player_nation, p);
513 }
514
515 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
516 auto p = retrieve<dcon::province_id>(state, parent);
517 auto fid = dcon::fatten(state.world, p);
518 auto owner = fid.get_nation_from_province_ownership();
519
520 if(owner != state.local_player_nation) {
522 } else {
523 // not rendered
524 }
525 }
526
527 void button_action(sys::state& state) noexcept override {
528 auto p = retrieve<dcon::province_id>(state, parent);
529 command::take_province(state, state.local_player_nation, p);
530 }
531
534 }
535
536 void update_tooltip(sys::state& state, int32_t x, int32_t t, text::columnar_layout& contents) noexcept override {
537 auto source = state.local_player_nation;
538 auto p = retrieve<dcon::province_id>(state, parent);
539
540 auto fid = dcon::fatten(state.world, p);
541 auto owner = fid.get_nation_from_province_ownership();
542 auto rel = state.world.nation_get_overlord_as_subject(owner);
543 auto overlord = state.world.overlord_get_ruler(rel);
544
545 text::add_line(state, contents, "alice_take_province_1");
546 {
549 auto box = text::open_layout_box(contents, 0);
550 text::localised_format_box(state, contents, box, "alice_take_province_2", m);
551 text::close_layout_box(contents, box);
552 }
553 {
555 text::add_to_substitution_map(m, text::variable_type::val, text::fp_one_place{ state.defines.alice_take_province_militancy_subject });
556 auto box = text::open_layout_box(contents, 0);
557 text::localised_format_box(state, contents, box, "alice_take_province_3", m);
558 text::close_layout_box(contents, box);
559 }
560 {
562 text::add_to_substitution_map(m, text::variable_type::val, text::fp_one_place{ state.defines.alice_take_province_militancy_all_subjects });
563 auto box = text::open_layout_box(contents, 0);
564 text::localised_format_box(state, contents, box, "alice_take_province_4", m);
565 text::close_layout_box(contents, box);
566 }
567
568 text::add_line_with_condition(state, contents, "alice_take_province_5", !(overlord != source));
569 text::add_line_with_condition(state, contents, "alice_mvcap_2", state.current_crisis_state == sys::crisis_state::inactive);
570 text::add_line_with_condition(state, contents, "alice_mvcap_3", !(state.world.nation_get_is_at_war(source)));
571 text::add_line_with_condition(state, contents, "alice_take_province_6", !(state.world.nation_get_is_at_war(owner)));
572 text::add_line_with_condition(state, contents, "alice_mvcap_8", !(state.world.province_get_siege_progress(p) > 0.f));
573 text::add_line_with_condition(state, contents, "alice_mvcap_9", !(state.world.province_get_siege_progress(state.world.nation_get_capital(owner)) > 0.f));
574 text::add_line_with_condition(state, contents, "alice_take_province_7", !(state.world.province_get_nation_from_province_control(p) != owner));
575 }
576};
577
579public:
580 void on_update(sys::state& state) noexcept override {
581 auto p = retrieve<dcon::province_id>(state, parent);
582 disabled = true;
583 }
584
585 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
586 auto p = retrieve<dcon::province_id>(state, parent);
587 auto fid = dcon::fatten(state.world, p);
588 auto owner = fid.get_nation_from_province_ownership();
589
590 if(owner == state.local_player_nation) {
592 } else {
593 // not rendered
594 }
595 }
596
597 void button_action(sys::state& state) noexcept override {
598 auto p = retrieve<dcon::province_id>(state, parent);
599 command::move_capital(state, state.local_player_nation, p);
600 }
601
604 }
605
606 void update_tooltip(sys::state& state, int32_t x, int32_t t, text::columnar_layout& contents) noexcept override {
607 auto source = state.local_player_nation;
608 auto p = retrieve<dcon::province_id>(state, parent);
609
610 }
611};
612
614private:
615 fixed_pop_type_icon* slave_icon = nullptr;
616 province_colony_button* colony_button = nullptr;
617
618public:
619 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
620 if(name == "state_name") {
621 return make_element_by_type<province_state_name_text>(state, id);
622 } else if(name == "province_name") {
623 return make_element_by_type<generic_name_text<dcon::province_id>>(state, id);
624 } else if(name == "prov_terrain") {
625 return make_element_by_type<province_terrain_image>(state, id);
626 } else if(name == "province_modifiers") {
627 return make_element_by_type<province_modifiers>(state, id);
628 } else if(name == "slave_state_icon") {
629 auto ptr = make_element_by_type<fixed_pop_type_icon>(state, id);
630 slave_icon = ptr.get();
631 ptr->set_type(state, state.culture_definitions.slaves);
632 return ptr;
633 } else if(name == "admin_icon") {
634 auto ptr = make_element_by_type<fixed_pop_type_icon>(state, id);
635 ptr->set_type(state, state.culture_definitions.bureaucrat);
636 return ptr;
637 } else if(name == "owner_icon") {
638 auto ptr = make_element_by_type<fixed_pop_type_icon>(state, id);
639 ptr->set_type(state, state.culture_definitions.aristocrat);
640 return ptr;
641 } else if(name == "controller_flag") {
642 return make_element_by_type<province_controller_flag>(state, id);
643 } else if(name == "flashpoint_indicator") {
644 return make_element_by_type<province_flashpoint_indicator>(state, id);
645 } else if(name == "occupation_progress") {
646 return make_element_by_type<invisible_element>(state, id);
647 } else if(name == "occupation_icon") {
648 return make_element_by_type<invisible_element>(state, id);
649 } else if(name == "occupation_flag") {
650 return make_element_by_type<invisible_element>(state, id);
651 } else if(name == "colony_button") {
652 auto btn = make_element_by_type<province_colony_button>(state, id);
653 colony_button = btn.get();
654 return btn;
655 } else if(name == "alice_move_capital") {
656 return make_element_by_type<province_move_capital_button>(state, id);
657 } else if(name == "alice_take_province") {
658 return make_element_by_type<province_take_province_button>(state, id);
659 } else if(name == "alice_grant_province") {
660 return make_element_by_type<province_grant_province_button>(state, id);
661 } else if(name == "national_focus") {
662 return make_element_by_type<province_national_focus_button>(state, id);
663 } else if(name == "admin_efficiency") {
664 return make_element_by_type<state_admin_efficiency_text>(state, id);
665 } else if(name == "owner_presence") {
666 return make_element_by_type<state_aristocrat_presence_text>(state, id);
667 } else if(name == "liferating") {
668 return make_element_by_type<province_liferating>(state, id);
669 } else {
670 return nullptr;
671 }
672 }
673
674 void on_update(sys::state& state) noexcept override {
675 dcon::province_id prov_id = retrieve<dcon::province_id>(state, parent);
676 dcon::province_fat_id fat_id = dcon::fatten(state.world, prov_id);
677 colony_button->set_visible(state, fat_id.get_is_colonial());
678 slave_icon->set_visible(state, fat_id.get_is_slave());
679 }
680};
681
683public:
684 void button_action(sys::state& state) noexcept override {
685 state.open_diplomacy(retrieve<dcon::nation_id>(state, parent));
686 }
687};
688
690private:
691 void populate(sys::state& state, dcon::province_id prov_id) {
692 row_contents.clear();
693 auto fat_id = dcon::fatten(state.world, prov_id);
694 fat_id.for_each_core_as_province([&](dcon::core_id core_id) {
695 auto core_fat_id = dcon::fatten(state.world, core_id);
696 auto identity = core_fat_id.get_identity();
697 row_contents.push_back(identity.id);
698 });
699 update(state);
700 }
701
702public:
703 void on_update(sys::state& state) noexcept override {
704 populate(state, retrieve<dcon::province_id>(state, parent));
705 }
706};
707
708template<economy::province_building_type Value>
710public:
711 void on_update(sys::state& state) noexcept override {
712 auto prov_id = retrieve<dcon::province_id>(state, parent);
713 auto fat_id = dcon::fatten(state.world, prov_id);
714 frame = fat_id.get_building_level(uint8_t(Value));
715 }
716};
717template<economy::province_building_type Value>
719public:
720 void on_update(sys::state& state) noexcept override {
721 auto content = retrieve<dcon::province_id>(state, parent);
722 disabled = !command::can_begin_province_building_construction(state, state.local_player_nation, content, Value);
723 }
724
725 void button_action(sys::state& state) noexcept override {
726 auto content = retrieve<dcon::province_id>(state, parent);
727 command::begin_province_building_construction(state, state.local_player_nation, content, Value);
728 }
729 virtual void button_shift_action(sys::state& state) noexcept override {
730 if constexpr(Value == economy::province_building_type::naval_base) {
732 } else {
733 auto pid = retrieve<dcon::province_id>(state, parent);
734 auto si = state.world.province_get_state_membership(pid);
735 if(si) {
736 province::for_each_province_in_state_instance(state, si, [&](dcon::province_id p) {
737 if(command::can_begin_province_building_construction(state, state.local_player_nation, p, Value))
738 command::begin_province_building_construction(state, state.local_player_nation, p, Value);
739 });
740 }
741 }
742 }
743 virtual void button_shift_right_action(sys::state& state) noexcept override {
744 auto content = retrieve<dcon::province_id>(state, parent);
745 auto within_nation = state.world.province_get_nation_from_province_ownership(content);
746 for(auto p : state.world.nation_get_province_ownership(within_nation)) {
747 if(command::can_begin_province_building_construction(state, state.local_player_nation, p.get_province(), Value))
748 command::begin_province_building_construction(state, state.local_player_nation, p.get_province(), Value);
749 }
750 }
751
754 }
755
756 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
757 auto id = retrieve<dcon::province_id>(state, parent);
758
759 int32_t current_lvl = state.world.province_get_building_level(id, uint8_t(Value));
760 int32_t max_local_lvl = state.world.nation_get_max_building_level(state.local_player_nation, uint8_t(Value));
761 if constexpr(Value == economy::province_building_type::fort) {
762 text::add_line_with_condition(state, contents, "fort_build_tt_1", state.world.province_get_nation_from_province_control(id) == state.local_player_nation);
764
765 int32_t min_build = int32_t(state.world.province_get_modifier_values(id, sys::provincial_mod_offsets::min_build_fort));
766 text::add_line_with_condition(state, contents, "fort_build_tt_3", (max_local_lvl - current_lvl - min_build > 0), text::variable_type::x, int64_t(current_lvl), text::variable_type::n, int64_t(min_build), text::variable_type::y, int64_t(max_local_lvl));
767
768 } else if constexpr(Value == economy::province_building_type::naval_base) {
769 text::add_line_with_condition(state, contents, "fort_build_tt_1", state.world.province_get_nation_from_province_control(id) == state.local_player_nation);
771 text::add_line_with_condition(state, contents, "nb_build_tt_1", state.world.province_get_is_coast(id));
772
773 int32_t min_build = int32_t(state.world.province_get_modifier_values(id, sys::provincial_mod_offsets::min_build_naval_base));
774
775 auto si = state.world.province_get_state_membership(id);
776 text::add_line_with_condition(state, contents, "nb_build_tt_2", current_lvl > 0 || !si.get_naval_base_is_taken());
777
778 text::add_line_with_condition(state, contents, "fort_build_tt_3", (max_local_lvl - current_lvl - min_build > 0), text::variable_type::x, int64_t(current_lvl), text::variable_type::n, int64_t(min_build), text::variable_type::y, int64_t(max_local_lvl));
779
780 } else {
781 text::add_line_with_condition(state, contents, "fort_build_tt_1", state.world.province_get_nation_from_province_control(id) == state.local_player_nation);
783
784 auto rules = state.world.nation_get_combined_issue_rules(state.local_player_nation);
785 text::add_line_with_condition(state, contents, "rr_build_tt_1", (rules & issue_rule::build_railway) != 0);
786
787 int32_t min_build = 0;
788 if constexpr(Value == economy::province_building_type::railroad) {
789 min_build = int32_t(state.world.province_get_modifier_values(id, sys::provincial_mod_offsets::min_build_railroad));
790 } else if constexpr(Value == economy::province_building_type::bank) {
791 min_build = int32_t(state.world.province_get_modifier_values(id, sys::provincial_mod_offsets::min_build_bank));
792 } else if constexpr(Value == economy::province_building_type::university) {
793 min_build = int32_t(state.world.province_get_modifier_values(id, sys::provincial_mod_offsets::min_build_university));
794 }
795 text::add_line_with_condition(state, contents, "fort_build_tt_3", (max_local_lvl - current_lvl - min_build > 0), text::variable_type::x, int64_t(current_lvl), text::variable_type::n, int64_t(min_build), text::variable_type::y, int64_t(max_local_lvl));
796 }
797 modifier_description(state, contents, state.economy_definitions.building_definitions[uint8_t(Value)].province_modifier);
798 text::add_line(state, contents, "alice_province_building_build");
799 }
800};
801
802template<economy::province_building_type Value>
804public:
805 void on_create(sys::state& state) noexcept override {
807 base_data.position.y -= 2;
808 }
809
810 void on_update(sys::state& state) noexcept override {
811 auto content = retrieve<dcon::province_id>(state, parent);
813 }
814
815
818 }
819
820 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
821 auto prov = retrieve<dcon::province_id>(state, parent);
822
823 for(auto pb_con : state.world.province_get_province_building_construction(prov)) {
824 if(pb_con.get_type() == uint8_t(Value)) {
825 auto& goods = state.economy_definitions.building_definitions[int32_t(Value)].cost;
826 auto& cgoods = pb_con.get_purchased_goods();
827
828 float admin_eff = state.world.nation_get_administrative_efficiency(pb_con.get_nation());
829 float admin_cost_factor = pb_con.get_is_pop_project() ? 1.0f : 2.0f - admin_eff;
830
831 for(uint32_t i = 0; i < economy::commodity_set::set_size; ++i) {
832 if(goods.commodity_type[i]) {
833 auto box = text::open_layout_box(contents, 0);
834
835 auto cid = goods.commodity_type[i];
836 std::string padding = cid.index() < 10 ? "0" : "";
837 std::string description = "@$" + padding + std::to_string(cid.index());
838 text::add_unparsed_text_to_layout_box(state, contents, box, description);
839
840 text::add_to_layout_box(state, contents, box, state.world.commodity_get_name(goods.commodity_type[i]));
841 text::add_to_layout_box(state, contents, box, std::string_view{ ": " });
842 text::add_to_layout_box(state, contents, box, text::fp_one_place{ cgoods.commodity_amounts[i] });
843 text::add_to_layout_box(state, contents, box, std::string_view{ " / " });
844 text::add_to_layout_box(state, contents, box, text::fp_one_place{ goods.commodity_amounts[i] * admin_cost_factor });
845 text::close_layout_box(contents, box);
846 }
847 }
848
849 return;
850 }
851 }
852 }
853};
854
855template<economy::province_building_type Value>
857 button_element_base* expand_button = nullptr;
858 image_element_base* under_construction_icon = nullptr;
859 element_base* building_progress = nullptr;
860 element_base* expanding_text = nullptr;
861
862 std::string get_icon_name() noexcept {
863 switch(Value) {
865 return "build_icon0";
867 return "build_icon1";
869 return "build_icon2";
871 return "build_icon3";
873 return "build_icon4";
874 default:
875 return "build_icon0";
876 }
877 }
878
879 bool is_being_built(sys::state& state, dcon::province_id id) noexcept {
880 for(auto pb : state.world.province_get_province_building_construction(id))
881 if(economy::province_building_type(pb.get_type()) == Value)
882 return true;
883 return false;
884 }
885
886public:
887 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
888 if(name == get_icon_name()) {
889 return make_element_by_type<province_building_icon<Value>>(state, id);
890 } else if(name == "underconstruction_icon") {
891 auto ptr = make_element_by_type<image_element_base>(state, id);
892 under_construction_icon = ptr.get();
893 return ptr;
894 } else if(name == "building_progress") {
895 auto ptr = make_element_by_type<province_building_progress<Value>>(state, id);
896 building_progress = ptr.get();
897 return ptr;
898 } else if(name == "expand_text") {
899 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
900 expanding_text = ptr.get();
901 return ptr;
902 } else if(name == "expand") {
903 auto ptr = make_element_by_type<province_building_expand_button<Value>>(state, id);
904 expand_button = ptr.get();
905 return ptr;
906 } else if(name == "description") {
907 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
909 return ptr;
910 } else if(name.substr(0, 10) == "build_icon") {
911 return make_element_by_type<invisible_element>(state, id);
912 } else {
913 return nullptr;
914 }
915 }
916
917 void on_update(sys::state& state) noexcept override {
918 auto content = retrieve<dcon::province_id>(state, parent);
919 expand_button->set_visible(state, !is_being_built(state, content));
920 under_construction_icon->set_visible(state, is_being_built(state, content));
921 building_progress->set_visible(state, is_being_built(state, content));
922 expanding_text->set_visible(state, is_being_built(state, content));
923 }
924};
925
926//
927// Selector
928//
930public:
931 void on_update(sys::state& state) noexcept override {
932 auto p = retrieve<dcon::province_id>(state, parent);
933 disabled = !command::can_toggle_select_province(state, state.local_player_nation, p);
934
935 bool found = false;
936 for(auto m : state.world.province_get_current_modifiers(p)) {
937 if(m.mod_id == state.economy_definitions.selector_modifier) {
938 found = true;
939 break;
940 }
941 }
942
943 if(found) {
945 } else {
947 }
948 }
949 void button_action(sys::state& state) noexcept override {
950 auto content = retrieve<dcon::province_id>(state, parent);
951 command::toggle_select_province(state, state.local_player_nation, content);
952 }
953 virtual void button_shift_action(sys::state& state) noexcept override {
954 auto pid = retrieve<dcon::province_id>(state, parent);
955 auto si = state.world.province_get_state_membership(pid);
956 if(si) {
957 province::for_each_province_in_state_instance(state, si, [&](dcon::province_id p) {
958 command::toggle_select_province(state, state.local_player_nation, p);
959 });
960 }
961 }
962};
964public:
965 void on_update(sys::state& state) noexcept override {
966 auto p = retrieve<dcon::province_id>(state, parent);
967 frame = 0;
968 for(auto m : state.world.province_get_current_modifiers(p)) {
969 if(m.mod_id == state.economy_definitions.selector_modifier) {
970 frame = 1;
971 break;
972 }
973 }
974 }
975};
977public:
978 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
979 if(name == "underconstruction_icon"
980 || name == "building_progress"
981 || name == "expand_text") {
982 return make_element_by_type<invisible_element>(state, id);
983 } else if(name == "expand") {
984 return make_element_by_type<province_selector_button>(state, id);
985 } else if(name == "description") {
986 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
987 ptr->set_text(state, text::produce_simple_string(state, "province_selector"));
988 return ptr;
989 } else if(name.substr(0, 10) == "build_icon") {
990 int32_t value = name[10] - '0';
991 int32_t num_buildings = 0;
992 for(auto& def : state.economy_definitions.building_definitions) {
993 if(def.defined)
994 num_buildings++;
995 }
996 if(value == num_buildings) {
997 return make_element_by_type<province_selector_image>(state, id);
998 }
999 return make_element_by_type<invisible_element>(state, id);
1000 } else {
1001 return nullptr;
1002 }
1003 }
1004};
1005
1006//
1007// Immigrator
1008//
1010public:
1011 void on_update(sys::state& state) noexcept override {
1012 auto p = retrieve<dcon::province_id>(state, parent);
1013 disabled = !command::can_toggle_immigrator_province(state, state.local_player_nation, p);
1014
1015 bool found = false;
1016 for(auto m : state.world.province_get_current_modifiers(p)) {
1017 if(m.mod_id == state.economy_definitions.immigrator_modifier) {
1018 found = true;
1019 break;
1020 }
1021 }
1022
1023 if(found) {
1025 } else {
1027 }
1028 }
1029 void button_action(sys::state& state) noexcept override {
1030 auto content = retrieve<dcon::province_id>(state, parent);
1031 command::toggle_immigrator_province(state, state.local_player_nation, content);
1032 }
1033 virtual void button_shift_action(sys::state& state) noexcept override {
1034 auto pid = retrieve<dcon::province_id>(state, parent);
1035 auto si = state.world.province_get_state_membership(pid);
1036 if(si) {
1037 province::for_each_province_in_state_instance(state, si, [&](dcon::province_id p) {
1038 command::toggle_immigrator_province(state, state.local_player_nation, p);
1039 });
1040 }
1041 }
1042};
1044public:
1045 void on_update(sys::state& state) noexcept override {
1046 auto p = retrieve<dcon::province_id>(state, parent);
1047 frame = 0;
1048 for(auto m : state.world.province_get_current_modifiers(p)) {
1049 if(m.mod_id == state.economy_definitions.immigrator_modifier) {
1050 frame = 1;
1051 break;
1052 }
1053 }
1054 }
1055};
1057public:
1058 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1059 if(name == "underconstruction_icon"
1060 || name == "building_progress"
1061 || name == "expand_text") {
1062 return make_element_by_type<invisible_element>(state, id);
1063 } else if(name == "expand") {
1064 return make_element_by_type<province_immigrator_button>(state, id);
1065 } else if(name == "description") {
1066 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1067 ptr->set_text(state, text::produce_simple_string(state, "province_immigrator"));
1068 return ptr;
1069 } else if(name.substr(0, 10) == "build_icon") {
1070 int32_t value = name[10] - '0';
1071 int32_t num_buildings = 0;
1072 for(auto& def : state.economy_definitions.building_definitions) {
1073 if(def.defined)
1074 num_buildings++;
1075 }
1076 if(value == num_buildings + 1) {
1077 return make_element_by_type<province_immigrator_image>(state, id);
1078 }
1079 return make_element_by_type<invisible_element>(state, id);
1080 } else {
1081 return nullptr;
1082 }
1083 }
1084};
1085
1087public:
1088 void button_action(sys::state& state) noexcept override {
1089 auto content = retrieve<dcon::province_id>(state, parent);
1091 }
1092 virtual void button_shift_action(sys::state& state) noexcept override {
1093 auto pid = retrieve<dcon::province_id>(state, parent);
1094 auto si = state.world.province_get_state_membership(pid);
1095 if(si) {
1096 province::for_each_province_in_state_instance(state, si, [&](dcon::province_id p) {
1098 });
1099 }
1100 }
1101 virtual void button_shift_right_action(sys::state& state) noexcept override {
1102 auto pid = retrieve<dcon::province_id>(state, parent);
1103 auto n = state.world.province_get_nation_from_province_ownership(pid);
1104 for(auto p : state.world.nation_get_province_ownership(n)) {
1106 }
1107 }
1108 void on_update(sys::state& state) noexcept override {
1109 auto content = retrieve<dcon::province_id>(state, parent);
1112 }
1113};
1114
1116public:
1119 }
1120};
1121
1122template<economy::province_building_type Value>
1124public:
1127 }
1128 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1129 auto box = text::open_layout_box(contents, 0);
1130 switch(Value) {
1132 text::localised_format_box(state, contents, box, std::string_view("pv_railroad"));
1133 break;
1135 text::localised_format_box(state, contents, box, std::string_view("pv_fort"));
1136 break;
1138 text::localised_format_box(state, contents, box, std::string_view("pv_navalbase"));
1139 break;
1141 text::localised_format_box(state, contents, box, std::string_view("pv_bank"));
1142 break;
1144 text::localised_format_box(state, contents, box, std::string_view("pv_university"));
1145 break;
1146 default:
1147 break;
1148 }
1149 text::close_layout_box(contents, box);
1150 }
1151};
1152
1154public:
1155 void button_action(sys::state& state) noexcept override {
1156 auto content = retrieve<dcon::province_id>(state, parent);
1157 if(content) {
1158 open_build_foreign_factory(state, state.world.province_get_state_membership(content));
1159 }
1160
1161 }
1162
1163 void on_update(sys::state& state) noexcept override {
1164 auto content = retrieve<dcon::province_id>(state, parent);
1165 disabled = true;
1166
1167 if(!content)
1168 return;
1169
1170 for(auto ft : state.world.in_factory_type) {
1172 state.world.province_get_state_membership(content), ft, false)) {
1173
1174 disabled = false;
1175 return;
1176 }
1177 }
1178 }
1179};
1180
1182public:
1183 void on_update(sys::state& state) noexcept override {
1184 auto province_id = retrieve<dcon::province_id>(state, parent);
1185 auto supply = int32_t(military::peacetime_attrition_limit(state, state.local_player_nation, province_id));
1186 set_text(state, std::to_string(supply));
1187 }
1188
1189 // TODO: needs an explanation of where the value comes from
1190};
1191
1193public:
1194 void on_update(sys::state& state) noexcept override {
1195 auto prov = retrieve<dcon::province_id>(state, parent);
1197 }
1198};
1199
1201public:
1202 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1203 if(name == "building_progress") {
1204 return make_element_by_type<rr_investment_progress>(state, id);
1205 } else {
1206 return nullptr;
1207 }
1208 }
1209 void impl_render(sys::state& state, int32_t x, int32_t y) noexcept override {
1210 auto prov = retrieve<dcon::province_id>(state, parent);
1213 }
1214 }
1215 message_result test_mouse(sys::state& state, int32_t x, int32_t y, mouse_probe_type type) noexcept override {
1216 auto prov = retrieve<dcon::province_id>(state, parent);
1220 }
1221};
1222
1224private:
1225 province_country_flag_button* country_flag_button = nullptr;
1226 culture_piechart<dcon::province_id>* culture_chart = nullptr;
1227 ideology_piechart<dcon::province_id>* ideology_chart = nullptr;
1228 workforce_piechart<dcon::province_id>* workforce_chart = nullptr;
1229
1230public:
1231 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1232 if(name == "country_name") {
1233 return make_element_by_type<generic_name_text<dcon::nation_id>>(state, id);
1234 } else if(name == "country_flag") {
1235 auto ptr = make_element_by_type<province_country_flag_button>(state, id);
1236 country_flag_button = ptr.get();
1237 return ptr;
1238 } else if(name == "country_gov") {
1239 return make_element_by_type<nation_government_type_text>(state, id);
1240 } else if(name == "country_party") {
1241 return make_element_by_type<nation_ruling_party_text>(state, id);
1242 } else if(name == "country_prestige") {
1243 return make_element_by_type<nation_prestige_text>(state, id);
1244 } else if(name == "country_economic") {
1245 return make_element_by_type<nation_industry_score_text>(state, id);
1246 } else if(name == "country_military") {
1247 return make_element_by_type<nation_military_score_text>(state, id);
1248 } else if(name == "country_total") {
1249 return make_element_by_type<nation_total_score_text>(state, id);
1250 } else if(name == "selected_prestige_rank") {
1251 return make_element_by_type<nation_prestige_rank_text>(state, id);
1252 } else if(name == "selected_industry_rank") {
1253 return make_element_by_type<nation_industry_rank_text>(state, id);
1254 } else if(name == "selected_military_rank") {
1255 return make_element_by_type<nation_military_rank_text>(state, id);
1256 } else if(name == "selected_total_rank") {
1257 return make_element_by_type<nation_rank_text>(state, id);
1258 } else if(name == "country_status") {
1259 return make_element_by_type<nation_status_text>(state, id);
1260 } else if(name == "country_flag_overlay") {
1261 return make_element_by_type<nation_flag_frame>(state, id);
1262 } else if(name == "total_population") {
1263 return make_element_by_type<province_population>(state, id);
1264 } else if(name == "sphere_label") {
1265 return make_element_by_type<nation_sphere_list_label>(state, id);
1266 } else if(name == "puppet_label") {
1267 return make_element_by_type<nation_puppet_list_label>(state, id);
1268 } else if(name == "our_relation") {
1269 return make_element_by_type<nation_player_relations_text>(state, id);
1270 } else if(name == "workforce_chart") {
1271 auto ptr = make_element_by_type<workforce_piechart<dcon::province_id>>(state, id);
1272 workforce_chart = ptr.get();
1273 return ptr;
1274 } else if(name == "ideology_chart") {
1275 auto ptr = make_element_by_type<ideology_piechart<dcon::province_id>>(state, id);
1276 ideology_chart = ptr.get();
1277 return ptr;
1278 } else if(name == "culture_chart") {
1279 auto ptr = make_element_by_type<culture_piechart<dcon::province_id>>(state, id);
1280 culture_chart = ptr.get();
1281 return ptr;
1282 } else if(name == "goods_type") {
1283 return make_element_by_type<province_rgo>(state, id);
1284 } else if(name == "build_icon_fort") {
1285 return make_element_by_type<province_view_foreign_building_icon<economy::province_building_type::fort>>(state, id);
1286 } else if(name == "build_icon_navalbase") {
1287 return make_element_by_type<province_view_foreign_building_icon<economy::province_building_type::naval_base>>(state, id);
1288 } else if(name == "build_icon_infra") {
1289 return make_element_by_type<province_view_foreign_building_icon<economy::province_building_type::railroad>>(state, id);
1290 } else if(name == "build_icon_bank") {
1291 return make_element_by_type<province_view_foreign_building_icon<economy::province_building_type::bank>>(state, id);
1292 } else if(name == "build_icon_university") {
1293 return make_element_by_type<province_view_foreign_building_icon<economy::province_building_type::university>>(state, id);
1294 } else if(name == "infra_progress_win") {
1295 return make_element_by_type<rr_invest_inwdow>(state, id);
1296 } else if(name == "invest_build_infra") {
1297 return make_element_by_type<province_invest_railroad_button>(state, id);
1298 } else if(name == "invest_factory_button") {
1299 return make_element_by_type<province_invest_factory_button>(state, id);
1300 } else if(name == "sphere_targets") {
1301 return make_element_by_type<overlapping_sphere_flags>(state, id);
1302 } else if(name == "puppet_targets") {
1303 return make_element_by_type<overlapping_puppet_flags>(state, id);
1304 } else if(name == "allied_targets") {
1305 return make_element_by_type<overlapping_ally_flags>(state, id);
1306 } else if(name == "war_targets") {
1307 return make_element_by_type<overlapping_enemy_flags>(state, id);
1308 } else if(name == "send_diplomat") {
1309 return make_element_by_type<province_send_diplomat_button>(state, id);
1310 } else if(name == "core_icons") {
1311 return make_element_by_type<province_core_flags>(state, id);
1312 } else if(name == "supply_limit") {
1313 return make_element_by_type<province_supply_limit_text>(state, id);
1314 } else if (name == "selected_military_icon") {
1315 auto ptr = make_element_by_type<military_score_icon>(state, id);
1316 return ptr;
1317 } else if(name == "rallypoint_checkbox") {
1318 return make_element_by_type<land_rally_point>(state, id);
1319 } else if(name == "rallypoint_checkbox_naval") {
1320 return make_element_by_type<naval_rally_point>(state, id);
1321 } else if(name == "rallypoint_merge_checkbox" || name == "rallypoint_merge_checkbox_naval") {
1322 return make_element_by_type<merge_rally_point>(state, id);
1323 } else {
1324 return nullptr;
1325 }
1326 }
1327
1328 void on_update(sys::state& state) noexcept override {
1329 auto prov_id = retrieve<dcon::province_id>(state, parent);
1330 dcon::province_fat_id fat_id = dcon::fatten(state.world, prov_id);
1331 auto nation_id = fat_id.get_nation_from_province_ownership();
1332 if(!bool(nation_id) || nation_id.id == state.local_player_nation) {
1333 set_visible(state, false);
1334 } else {
1335 country_flag_button->impl_on_update(state);
1336 culture_chart->impl_on_update(state);
1337 workforce_chart->impl_on_update(state);
1338 ideology_chart->impl_on_update(state);
1339 set_visible(state, true);
1340 }
1341 }
1342};
1343
1344void province_owner_rgo_draw_tooltip(sys::state& state, text::columnar_layout& contents, dcon::province_id prov_id) noexcept;
1345
1347public:
1350 }
1351 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1352 auto prov_id = retrieve<dcon::province_id>(state, parent);
1353 province_owner_rgo_draw_tooltip(state, contents, prov_id);
1354 }
1355};
1356
1358public:
1361 }
1362 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1363 auto prov_id = retrieve<dcon::province_id>(state, parent);
1364 province_owner_rgo_draw_tooltip(state, contents, prov_id);
1365 }
1366};
1367
1369public:
1372 }
1373 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1374 auto prov_id = retrieve<dcon::province_id>(state, parent);
1375 province_owner_rgo_draw_tooltip(state, contents, prov_id);
1376 }
1377};
1378
1380public:
1381 void on_update(sys::state& state) noexcept override {
1382 auto province = retrieve<dcon::province_id>(state, parent);
1384 auto employment_ratio = province::land_employment(state, province) / (max_emp + 1.f);
1385 frame = int32_t(10.f * employment_ratio);
1386 }
1389 }
1390 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1391 auto prov_id = retrieve<dcon::province_id>(state, parent);
1392 auto owner = state.world.province_get_nation_from_province_ownership(prov_id);
1393 auto max_emp = province::land_maximum_employment(state, prov_id);
1394 auto employment_ratio = province::land_employment(state, prov_id) / (max_emp + 1.f);
1395
1396 auto box = text::open_layout_box(contents);
1397 text::add_to_layout_box(state, contents, box, int64_t(std::ceil(employment_ratio * max_emp)));
1398 text::add_to_layout_box(state, contents, box, std::string_view{" / "});
1399 text::add_to_layout_box(state, contents, box, int64_t(std::ceil(max_emp)));
1400
1401 text::close_layout_box(contents, box);
1402 }
1403};
1404
1406public:
1409 }
1410 void on_update(sys::state& state) noexcept override {
1411 auto prov_id = retrieve<dcon::province_id>(state, parent);
1412 auto fat_id = dcon::fatten(state.world, prov_id);
1413 frame = fat_id.get_crime().index() + 1;
1414 }
1415 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1416 auto province = retrieve<dcon::province_id>(state, parent);
1417 auto crime = state.world.province_get_crime(province);
1418 if(crime) {
1419 modifier_description(state, contents, state.culture_definitions.crimes[crime].modifier);
1420 }
1421 }
1422};
1423
1425public:
1426 void on_update(sys::state& state) noexcept override {
1427 auto province_id = retrieve<dcon::province_id>(state, parent);
1428 auto fat_id = dcon::fatten(state.world, province_id);
1429 auto crime_id = fat_id.get_crime();
1430 if(crime_id) {
1431 set_text(state, text::produce_simple_string(state, state.culture_definitions.crimes[crime_id].name));
1432 } else {
1433 set_text(state, "");
1434 }
1435 }
1436
1439 }
1440 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1441 auto province = retrieve<dcon::province_id>(state, parent);
1442 auto crime = state.world.province_get_crime(province);
1443 if(crime) {
1444 modifier_description(state, contents, state.culture_definitions.crimes[crime].modifier);
1445 }
1446 }
1447};
1448
1450public:
1451 void on_update(sys::state& state) noexcept override {
1452 auto province_id = retrieve<dcon::province_id>(state, parent);
1454 }
1455
1456 /*
1457 // TODO: explain where the value comes from
1458 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
1459 return tooltip_behavior::variable_tooltip;
1460 }
1461
1462 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1463 auto content = retrieve<dcon::province_id>(state, parent);
1464 auto box = text::open_layout_box(contents, 0);
1465 text::localised_single_sub_box(state, contents, box, std::string_view("provinceview_crimefight"), text::variable_type::value, text::fp_one_place{province::crime_fighting_efficiency(state, content) * 100});
1466 text::close_layout_box(contents, box);
1467 }
1468 */
1469
1472 }
1473 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1474 auto content = retrieve<dcon::province_id>(state, parent);
1475 ui::active_modifiers_description(state, contents, state.world.province_control_get_nation(state.world.province_get_province_control_as_province(content)), 0, sys::national_mod_offsets::administrative_efficiency_modifier, true);
1476 }
1477};
1478
1480public:
1481 void on_update(sys::state& state) noexcept override {
1482 auto province_id = retrieve<dcon::province_id>(state, parent);
1484 }
1487 }
1488 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1489 auto content = retrieve<dcon::province_id>(state, parent);
1491 ui::active_modifiers_description(state, contents, state.world.province_control_get_nation(state.world.province_get_province_control_as_province(content)), 0, sys::national_mod_offsets::core_pop_militancy_modifier, true);
1492 ui::active_modifiers_description(state, contents, state.world.province_control_get_nation(state.world.province_get_province_control_as_province(content)), 0, sys::national_mod_offsets::global_pop_militancy_modifier, true);
1493 ui::active_modifiers_description(state, contents, state.world.province_control_get_nation(state.world.province_get_province_control_as_province(content)), 0, sys::national_mod_offsets::non_accepted_pop_militancy_modifier, true);
1494 }
1495};
1496
1498public:
1499 void on_update(sys::state& state) noexcept override {
1500 auto province_id = retrieve<dcon::province_id>(state, parent);
1501 set_text(state, text::format_percentage(state.world.province_get_rgo_employment(province_id), 1));
1502 }
1505 }
1506 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1507 auto content = retrieve<dcon::province_id>(state, parent);
1508 ui::active_modifiers_description(state, contents, content, 0, sys::provincial_mod_offsets::farm_rgo_eff, true);
1509 ui::active_modifiers_description(state, contents, content, 0, sys::provincial_mod_offsets::farm_rgo_size, true);
1510 ui::active_modifiers_description(state, contents, content, 0, sys::provincial_mod_offsets::mine_rgo_eff, true);
1511 ui::active_modifiers_description(state, contents, content, 0, sys::provincial_mod_offsets::mine_rgo_size, true);
1512 ui::active_modifiers_description(state, contents, content, 0, sys::provincial_mod_offsets::local_rgo_input, true);
1513 ui::active_modifiers_description(state, contents, content, 0, sys::provincial_mod_offsets::local_rgo_output, true);
1514 ui::active_modifiers_description(state, contents, content, 0, sys::provincial_mod_offsets::local_rgo_throughput, true);
1515 ui::active_modifiers_description(state, contents, state.world.province_control_get_nation(state.world.province_get_province_control_as_province(content)), 0, sys::national_mod_offsets::rgo_input, true);
1516 ui::active_modifiers_description(state, contents, state.world.province_control_get_nation(state.world.province_get_province_control_as_province(content)), 0, sys::national_mod_offsets::rgo_output, true);
1517 ui::active_modifiers_description(state, contents, state.world.province_control_get_nation(state.world.province_get_province_control_as_province(content)), 0, sys::national_mod_offsets::rgo_throughput, true);
1518 ui::active_modifiers_description(state, contents, state.world.province_control_get_nation(state.world.province_get_province_control_as_province(content)), 0, sys::national_mod_offsets::farm_rgo_eff, true);
1519 ui::active_modifiers_description(state, contents, state.world.province_control_get_nation(state.world.province_get_province_control_as_province(content)), 0, sys::national_mod_offsets::farm_rgo_size, true);
1520 ui::active_modifiers_description(state, contents, state.world.province_control_get_nation(state.world.province_get_province_control_as_province(content)), 0, sys::national_mod_offsets::mine_rgo_eff, true);
1521 ui::active_modifiers_description(state, contents, state.world.province_control_get_nation(state.world.province_get_province_control_as_province(content)), 0, sys::national_mod_offsets::mine_rgo_size, true);
1522 }
1523};
1524
1526public:
1527 void on_update(sys::state& state) noexcept override {
1528 auto province_id = retrieve<dcon::province_id>(state, parent);
1529 auto migration = state.world.province_get_daily_net_migration(province_id);
1530 auto immigration = state.world.province_get_daily_net_immigration(province_id);
1531 set_text(state, text::prettify(int32_t(migration - immigration)));
1532 }
1535 }
1536 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1537 auto content = retrieve<dcon::province_id>(state, parent);
1538 ui::active_modifiers_description(state, contents, content, 0, sys::provincial_mod_offsets::immigrant_attract, true);
1539 ui::active_modifiers_description(state, contents, content, 0, sys::provincial_mod_offsets::immigrant_push, true);
1540 if(state.world.province_get_is_colonial(content)) {
1541 ui::active_modifiers_description(state, contents, state.world.province_control_get_nation(state.world.province_get_province_control_as_province(content)), 0, sys::national_mod_offsets::colonial_migration, true);
1542 }
1543 ui::active_modifiers_description(state, contents, state.world.province_control_get_nation(state.world.province_get_province_control_as_province(content)), 0, sys::national_mod_offsets::global_immigrant_attract, true);
1544 }
1545};
1546
1548public:
1549 void on_update(sys::state& state) noexcept override {
1550 auto province_id = retrieve<dcon::province_id>(state, parent);
1552 }
1555 }
1556 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1557 auto content = retrieve<dcon::province_id>(state, parent);
1558 ui::active_modifiers_description(state, contents, content, 0, sys::provincial_mod_offsets::population_growth, true);
1559 ui::active_modifiers_description(state, contents, state.world.province_control_get_nation(state.world.province_get_province_control_as_province(content)), 0, sys::national_mod_offsets::pop_growth, true);
1560 }
1561};
1562
1564public:
1565 void on_update(sys::state& state) noexcept override {
1566 auto province_id = retrieve<dcon::province_id>(state, parent);
1567 auto built = military::regiments_created_from_province(state, province_id);
1568 auto max_possible = military::regiments_max_possible_from_province(state, province_id);
1569 set_text(state, text::format_ratio(built, max_possible));
1570 }
1571};
1572
1574private:
1575 culture_piechart<dcon::province_id>* culture_chart = nullptr;
1576 ideology_piechart<dcon::province_id>* ideology_chart = nullptr;
1577 workforce_piechart<dcon::province_id>* workforce_chart = nullptr;
1578
1579public:
1580 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1581 if(name == "goods_type") {
1582 return make_element_by_type<province_owner_rgo>(state, id);
1583 } else if(name == "open_popscreen") {
1584 return make_element_by_type<province_pop_button>(state, id);
1585 } else if(name == "total_population") {
1586 return make_element_by_type<province_population>(state, id);
1587 } else if(name == "workforce_chart") {
1588 auto ptr = make_element_by_type<workforce_piechart<dcon::province_id>>(state, id);
1589 workforce_chart = ptr.get();
1590 return ptr;
1591 } else if(name == "ideology_chart") {
1592 auto ptr = make_element_by_type<ideology_piechart<dcon::province_id>>(state, id);
1593 ideology_chart = ptr.get();
1594 return ptr;
1595 } else if(name == "culture_chart") {
1596 auto ptr = make_element_by_type<culture_piechart<dcon::province_id>>(state, id);
1597 culture_chart = ptr.get();
1598 return ptr;
1599 } else if(name == "core_icons") {
1600 return make_element_by_type<province_core_flags>(state, id);
1601 } else if(name == "supply_limit") {
1602 return make_element_by_type<province_supply_limit_text>(state, id);
1603 } else if(name == "crime_icon") {
1604 return make_element_by_type<province_crime_icon>(state, id);
1605 } else if(name == "crime_name") {
1606 return make_element_by_type<province_crime_name_text>(state, id);
1607 } else if(name == "crimefight_percent") {
1608 return make_element_by_type<province_crime_fighting_text>(state, id);
1609 } else if(name == "rebel_percent") {
1610 return make_element_by_type<province_rebel_percent_text>(state, id);
1611 } else if(name == "employment_ratio") {
1612 return make_element_by_type<province_rgo_employment_progress_icon>(state, id);
1613 } else if(name == "rgo_population") {
1614 return make_element_by_type<province_rgo_workers_text>(state, id);
1615 } else if(name == "rgo_percent") {
1616 return make_element_by_type<province_rgo_employment_percent_text>(state, id);
1617 } else if(name == "produced") {
1618 return make_element_by_type<province_owner_goods_produced_text>(state, id);
1619 } else if(name == "income") {
1620 return make_element_by_type<province_owner_income_text>(state, id);
1621 } else if(name == "growth") {
1622 return make_element_by_type<province_pop_growth_text>(state, id);
1623 } else if(name == "migration") {
1624 return make_element_by_type<province_migration_text>(state, id);
1625 } else if(name == "build_factory_button") {
1626 return make_element_by_type<province_build_new_factory>(state, id);
1627 } else {
1628 return nullptr;
1629 }
1630 }
1631
1632 void on_update(sys::state& state) noexcept override {
1633 auto prov_id = retrieve<dcon::province_id>(state, parent);
1634 dcon::province_fat_id fat_id = dcon::fatten(state.world, prov_id);
1635 auto nation_id = fat_id.get_nation_from_province_ownership();
1636 if(bool(nation_id) && nation_id.id == state.local_player_nation) {
1637 culture_chart->impl_on_update(state);
1638 workforce_chart->impl_on_update(state);
1639 ideology_chart->impl_on_update(state);
1640 set_visible(state, true);
1641 } else {
1642 set_visible(state, false);
1643 }
1644 }
1645};
1646
1648public:
1649 void on_update(sys::state& state) noexcept override {
1650 progress = 0.f;
1651 float amount = 0.f;
1652 float total = 0.f;
1653 auto p = retrieve<dcon::province_id>(state, parent);
1654 for(auto pop : dcon::fatten(state.world, p).get_pop_location()) {
1655 if(pop.get_pop().get_poptype() == state.culture_definitions.soldiers) {
1656 auto lcs = pop.get_pop().get_province_land_construction();
1657 for(const auto lc : lcs) {
1658 auto& base_cost = state.military_definitions.unit_base_definitions[lc.get_type()].build_cost;
1659 auto& current_purchased = lc.get_purchased_goods();
1660 for(uint32_t i = 0; i < economy::commodity_set::set_size; ++i) {
1661 if(base_cost.commodity_type[i]) {
1662 amount += current_purchased.commodity_amounts[i];
1663 total += base_cost.commodity_amounts[i];
1664 } else {
1665 break;
1666 }
1667 }
1668 }
1669 }
1670 }
1671 if(total > 0.f) {
1672 progress = amount / total;
1673 }
1674 }
1675};
1677public:
1678 void on_update(sys::state& state) noexcept override {
1679 progress = 0.f;
1680 float amount = 0.f;
1681 float total = 0.f;
1682 auto p = retrieve<dcon::province_id>(state, parent);
1683 auto ncs = state.world.province_get_province_naval_construction(p);
1684 for(auto nc : ncs) {
1685 auto& base_cost = state.military_definitions.unit_base_definitions[nc.get_type()].build_cost;
1686 auto& current_purchased = nc.get_purchased_goods();
1687 for(uint32_t i = 0; i < economy::commodity_set::set_size; ++i) {
1688 if(base_cost.commodity_type[i]) {
1689 amount += current_purchased.commodity_amounts[i];
1690 total += base_cost.commodity_amounts[i];
1691 } else {
1692 break;
1693 }
1694 }
1695 }
1696 if(total > 0.f) {
1697 progress = amount / total;
1698 }
1699 }
1700};
1701
1703public:
1704 void on_update(sys::state& state) noexcept override {
1705 float amount = 0.f;
1706 float total = 0.f;
1707 auto p = retrieve<dcon::province_id>(state, parent);
1708 for(auto pop : dcon::fatten(state.world, p).get_pop_location()) {
1709 if(pop.get_pop().get_poptype() == state.culture_definitions.soldiers) {
1710 auto lcs = pop.get_pop().get_province_land_construction();
1711 for(const auto lc : lcs) {
1712 auto& base_cost = state.military_definitions.unit_base_definitions[lc.get_type()].build_cost;
1713 auto& current_purchased = lc.get_purchased_goods();
1714 for(uint32_t i = 0; i < economy::commodity_set::set_size; ++i) {
1715 if(base_cost.commodity_type[i]) {
1716 amount += current_purchased.commodity_amounts[i];
1717 total += base_cost.commodity_amounts[i];
1718 } else {
1719 break;
1720 }
1721 }
1722 }
1723 }
1724 }
1725 set_text(state, text::format_percentage(total > 0.f ? amount / total : 0.f));
1726 }
1727};
1729public:
1730 void on_update(sys::state& state) noexcept override {
1731 float amount = 0.f;
1732 float total = 0.f;
1733 auto p = retrieve<dcon::province_id>(state, parent);
1734 auto ncs = state.world.province_get_province_naval_construction(p);
1735 for(auto nc : ncs) {
1736 auto& base_cost = state.military_definitions.unit_base_definitions[nc.get_type()].build_cost;
1737 auto& current_purchased = nc.get_purchased_goods();
1738 for(uint32_t i = 0; i < economy::commodity_set::set_size; ++i) {
1739 if(base_cost.commodity_type[i]) {
1740 amount += current_purchased.commodity_amounts[i];
1741 total += base_cost.commodity_amounts[i];
1742 } else {
1743 break;
1744 }
1745 }
1746 }
1747 set_text(state, text::format_percentage(total > 0.f ? amount / total : 0.f));
1748 }
1749};
1750
1751
1752template<typename T>
1754public:
1755 void on_update(sys::state& state) noexcept override {
1756 disabled = true;
1757 //
1758 auto p = retrieve<dcon::province_id>(state, parent);
1759 for(uint8_t i = 2; i < state.military_definitions.unit_base_definitions.size(); i++) {
1760 auto utid = dcon::unit_type_id(i);
1761 auto const& def = state.military_definitions.unit_base_definitions[utid];
1762 if(!def.active && !state.world.nation_get_active_unit(state.local_player_nation, utid))
1763 continue;
1764 if(def.is_land != std::is_same_v<T, dcon::army_id>)
1765 continue;
1766 if constexpr(std::is_same_v<T, dcon::army_id>) {
1767 for(const auto c : state.world.in_culture) {
1768 if(command::can_start_land_unit_construction(state, state.local_player_nation, p, c, utid)) {
1769 for(auto pl : state.world.province_get_pop_location_as_province(p)) {
1770 if(pl.get_pop().get_culture() == c) {
1771 if(pl.get_pop().get_poptype() == state.culture_definitions.soldiers && state.world.pop_get_size(pl.get_pop()) >= state.defines.pop_min_size_for_regiment) {
1772 disabled = false;
1773 break;
1774 }
1775 }
1776 }
1777 } else {
1778 //not disabled when there are constructions
1779 for(auto pl : state.world.province_get_pop_location_as_province(p)) {
1780 auto lc = pl.get_pop().get_province_land_construction();
1781 if(lc.begin() != lc.end()) {
1782 disabled = false;
1783 break;
1784 }
1785 }
1786 }
1787 if(!disabled)
1788 break;
1789 }
1790 } else {
1791 disabled = !command::can_start_naval_unit_construction(state, state.local_player_nation, p, utid);
1792 }
1793 if(!disabled)
1794 break;
1795 }
1796 }
1797
1798 void button_action(sys::state& state) noexcept override {
1799 if(state.ui_state.build_province_unit_window) {
1801 Cyto::Any payload = Cyto::any_cast<T>(T{});
1802 state.ui_state.build_province_unit_window->impl_get(state, payload);
1803 }
1804 }
1805};
1806
1808public:
1809 void on_create(sys::state& state) noexcept override {
1811 int16_t y_offset = 1;
1812 {
1813 auto ptr = make_element_by_type<province_building_window<economy::province_building_type::fort>>(state, "building");
1814 ptr->base_data.position.y = y_offset;
1815 y_offset += 35;
1816 add_child_to_front(std::move(ptr));
1817 }
1818 {
1819 auto ptr = make_element_by_type<province_building_window<economy::province_building_type::naval_base>>(state, "building");
1820 ptr->base_data.position.y = y_offset;
1821 y_offset += 35;
1822 add_child_to_front(std::move(ptr));
1823 }
1824 {
1825 auto ptr = make_element_by_type<province_building_window<economy::province_building_type::railroad>>(state, "building");
1826 ptr->base_data.position.y = y_offset;
1827 y_offset += 35;
1828 add_child_to_front(std::move(ptr));
1829 }
1830 if(state.economy_definitions.building_definitions[int32_t(economy::province_building_type::bank)].defined) {
1831 auto ptr = make_element_by_type<province_building_window<economy::province_building_type::bank>>(state, "building");
1832 ptr->base_data.position.y = y_offset;
1833 y_offset += 35;
1834 add_child_to_front(std::move(ptr));
1835 }
1836 if(state.economy_definitions.building_definitions[int32_t(economy::province_building_type::university)].defined) {
1837 auto ptr = make_element_by_type<province_building_window<economy::province_building_type::university>>(state, "building");
1838 ptr->base_data.position.y = y_offset;
1839 y_offset += 35;
1840 add_child_to_front(std::move(ptr));
1841 }
1842 if(bool(state.economy_definitions.selector_modifier)) {
1843 auto ptr = make_element_by_type<province_selector_window>(state, "building");
1844 ptr->base_data.position.y = y_offset;
1845 y_offset += 35;
1846 add_child_to_front(std::move(ptr));
1847 }
1848 if(bool(state.economy_definitions.immigrator_modifier)) {
1849 auto ptr = make_element_by_type<province_immigrator_window>(state, "building");
1850 ptr->base_data.position.y = y_offset;
1851 y_offset += 35;
1852 add_child_to_front(std::move(ptr));
1853 }
1854 }
1855
1856 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1857 if(name == "army_size") {
1858 return make_element_by_type<province_army_size_text>(state, id);
1859 } else if(name == "army_progress") {
1860 return make_element_by_type<province_army_progress>(state, id);
1861 } else if(name == "navy_progress") {
1862 return make_element_by_type<province_navy_progress>(state, id);
1863 } else if(name == "rallypoint_checkbox") {
1864 return make_element_by_type<land_rally_point>(state, id);
1865 } else if(name == "rallypoint_checkbox_naval") {
1866 return make_element_by_type<naval_rally_point>(state, id);
1867 } else if(name == "rallypoint_merge_checkbox" || name == "rallypoint_merge_checkbox_naval") {
1868 return make_element_by_type<merge_rally_point>(state, id);
1869 } else if(name == "build_army") {
1870 return make_element_by_type<province_build_unit<dcon::army_id>>(state, id);
1871 } else if(name == "build_navy") {
1872 return make_element_by_type<province_build_unit<dcon::navy_id>>(state, id);
1873 } else if(name == "army_text") {
1874 return make_element_by_type<province_army_progress_text>(state, id);
1875 } else if(name == "navy_text") {
1876 return make_element_by_type<province_navy_progress_text>(state, id);
1877 } else {
1878 return nullptr;
1879 }
1880 }
1881
1882 void on_update(sys::state& state) noexcept override {
1883 auto prov_id = retrieve<dcon::province_id>(state, parent);
1884 dcon::province_fat_id fat_id = dcon::fatten(state.world, prov_id);
1885 auto nation_id = fat_id.get_nation_from_province_ownership();
1886 if(bool(nation_id) && nation_id.id == state.local_player_nation) {
1887 set_visible(state, true);
1888 } else {
1889 set_visible(state, false);
1890 }
1891 }
1892};
1893
1895public:
1896 void button_action(sys::state& state) noexcept override {
1897 auto content = retrieve<dcon::province_id>(state, parent);
1898 command::finish_colonization(state, state.local_player_nation, content);
1899 state.ui_state.province_window->set_visible(state, false);
1900 state.map_state.set_selected_province(dcon::province_id{});
1901 }
1902
1903 void on_update(sys::state& state) noexcept override {
1904 auto content = retrieve<dcon::province_id>(state, parent);
1905 disabled = !command::can_finish_colonization(state, state.local_player_nation, content);
1906 }
1907};
1908
1910public:
1911 void button_action(sys::state& state) noexcept override {
1912 auto content = retrieve<dcon::province_id>(state, parent);
1913 command::abandon_colony(state, state.local_player_nation, content);
1914 }
1915
1916 void on_update(sys::state& state) noexcept override {
1917 auto content = retrieve<dcon::province_id>(state, parent);
1918 disabled = !command::can_abandon_colony(state, state.local_player_nation, content);
1919 }
1920};
1921
1923public:
1924 void button_action(sys::state& state) noexcept override {
1925 auto content = retrieve<dcon::province_id>(state, parent);
1926 command::invest_in_colony(state, state.local_player_nation, content);
1927 }
1928
1929 void on_update(sys::state& state) noexcept override {
1930 auto content = retrieve<dcon::province_id>(state, parent);
1931 disabled = !command::can_invest_in_colony(state, state.local_player_nation, content);
1932 }
1933
1936 }
1937
1938 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1939 auto province = retrieve<dcon::province_id>(state, parent);
1940 auto sdef = state.world.province_get_state_from_abstract_state_membership(province);
1941 auto col = retrieve<dcon::colonization_id>(state, parent);
1942
1943 if(!province::is_colonizing(state, state.local_player_nation, sdef)) {
1944 text::add_line(state, contents, "col_start_title");
1946
1947 auto first_wg = state.crisis_attacker_wargoals.at(0);
1948
1949 text::add_line_with_condition(state, contents, "col_start_1", state.world.state_definition_get_colonization_stage(sdef) <= uint8_t(1));
1950 text::add_line_with_condition(state, contents, "col_start_2", state.world.nation_get_rank(state.local_player_nation) <= uint16_t(state.defines.colonial_rank), text::variable_type::x, uint16_t(state.defines.colonial_rank));
1951 text::add_line_with_condition(state, contents, "col_start_3", first_wg.state != sdef);
1952
1953 bool war_participant = false;
1954 for(auto par : state.world.war_get_war_participant(state.crisis_war)) {
1955 if(par.get_nation() == state.local_player_nation)
1956 war_participant = true;
1957 }
1958 text::add_line_with_condition(state, contents, "col_start_4", !war_participant);
1959
1960 float max_life_rating = -1.0f;
1961 for(auto p : state.world.state_definition_get_abstract_state_membership(sdef)) {
1962 if(!p.get_province().get_nation_from_province_ownership()) {
1963 max_life_rating = std::max(max_life_rating, float(p.get_province().get_life_rating()));
1964 }
1965 }
1966
1967 text::add_line_with_condition(state, contents, "col_start_5",
1968 state.defines.colonial_liferating + state.world.nation_get_modifier_values(state.local_player_nation, sys::national_mod_offsets::colonial_life_rating) <= max_life_rating,
1969 text::variable_type::x, int64_t(state.defines.colonial_liferating + state.world.nation_get_modifier_values(state.local_player_nation, sys::national_mod_offsets::colonial_life_rating)),
1970 text::variable_type::y, int64_t(max_life_rating));
1971 text::add_line(state, contents, "col_start_6", text::variable_type::x, int64_t(state.defines.colonial_liferating), 15);
1972 active_modifiers_description(state, contents, state.local_player_nation, 15, sys::national_mod_offsets::colonial_life_rating, false);
1973
1974 auto colonizers = state.world.state_definition_get_colonization(sdef);
1975 auto num_colonizers = colonizers.end() - colonizers.begin();
1976
1977 text::add_line_with_condition(state, contents, "col_start_7", num_colonizers < 4);
1978
1979 bool adjacent = [&]() {
1980 for(auto p : state.world.state_definition_get_abstract_state_membership(sdef)) {
1981 if(!p.get_province().get_nation_from_province_ownership()) {
1982 for(auto adj : p.get_province().get_province_adjacency()) {
1983 auto indx = adj.get_connected_provinces(0) != p.get_province() ? 0 : 1;
1984 auto o = adj.get_connected_provinces(indx).get_nation_from_province_ownership();
1985 if(o == state.local_player_nation)
1986 return true;
1987 if(o.get_overlord_as_subject().get_ruler() == state.local_player_nation)
1988 return true;
1989 }
1990 }
1991 }
1992 return false;
1993 }();
1994
1995 bool reachable_by_sea = false;
1996
1997 dcon::province_id coastal_target = [&]() {
1998 for(auto p : state.world.state_definition_get_abstract_state_membership(sdef)) {
1999 if(!p.get_province().get_nation_from_province_ownership()) {
2000 if(p.get_province().get_is_coast())
2001 return p.get_province().id;
2002 }
2003 }
2004 return dcon::province_id{};
2005 }();
2006
2007 if(!adjacent && coastal_target && state.world.nation_get_central_ports(state.local_player_nation) != 0) {
2008 for(auto p : state.world.nation_get_province_ownership(state.local_player_nation)) {
2009 if(auto nb_level = p.get_province().get_building_level(uint8_t(economy::province_building_type::naval_base)); nb_level > 0 && p.get_province().get_nation_from_province_control() == state.local_player_nation) {
2010 if(province::direct_distance(state, p.get_province(), coastal_target) <= province::world_circumference * 0.075f * nb_level) {
2011 reachable_by_sea = true;
2012 break;
2013 }
2014 }
2015 }
2016 }
2017
2018 text::add_line_with_condition(state, contents, "col_start_8", adjacent || reachable_by_sea);
2019
2020 auto free_points = nations::free_colonial_points(state, state.local_player_nation);
2021 auto required_points = int32_t(state.defines.colonization_interest_cost_initial + (adjacent ? state.defines.colonization_interest_cost_neighbor_modifier : 0.0f));
2022
2023 text::add_line_with_condition(state, contents, "col_start_9", free_points > required_points, text::variable_type::x, required_points);
2024 } else {
2025 text::add_line(state, contents, "col_invest_title");
2027
2028 text::add_line_with_condition(state, contents, "col_invest_1", state.world.nation_get_rank(state.local_player_nation) <= uint16_t(state.defines.colonial_rank), text::variable_type::x, uint16_t(state.defines.colonial_rank));
2029 auto first_wg = state.crisis_attacker_wargoals.at(0);
2030 text::add_line_with_condition(state, contents, "col_invest_2", first_wg.state != sdef);
2031
2032 bool war_participant = false;
2033 for(auto par : state.world.war_get_war_participant(state.crisis_war)) {
2034 if(par.get_nation() == state.local_player_nation)
2035 war_participant = true;
2036 }
2037 text::add_line_with_condition(state, contents, "col_invest_3", !war_participant);
2038
2039 auto crange = state.world.state_definition_get_colonization(sdef);
2040 auto last_investment = state.world.colonization_get_last_investment(col);
2041
2042 if(crange.end() - crange.begin() <= 1) { // no competition
2044 text::add_line(state, contents, "col_invest_4", text::variable_type::x, last_investment + int32_t(state.defines.colonization_days_for_initial_investment));
2045 } else {
2046 text::add_line_with_condition(state, contents, "col_invest_5", last_investment + int32_t(state.defines.colonization_days_between_investment) <= state.current_date,
2047 text::variable_type::x, int32_t(state.defines.colonization_days_between_investment),
2048 text::variable_type::y, last_investment + int32_t(state.defines.colonization_days_between_investment));
2049
2050 auto free_points = nations::free_colonial_points(state, state.local_player_nation);
2051 int32_t point_cost = 0;
2052 if(state.world.state_definition_get_colonization_stage(sdef) == 1) {
2053 point_cost = int32_t(state.defines.colonization_interest_cost);
2054 } else if(state.world.colonization_get_level(col) <= 4) {
2055 point_cost = int32_t(state.defines.colonization_influence_cost);
2056 } else {
2057 point_cost = int32_t(state.defines.colonization_extra_guard_cost * (state.world.colonization_get_level(col) - 4) + state.defines.colonization_influence_cost);
2058 }
2059
2060 text::add_line_with_condition(state, contents, "col_invest_6", free_points >= point_cost, text::variable_type::x, point_cost);
2061 }
2062 }
2063 }
2064};
2065
2067private:
2068 image_element_base* progressicon = nullptr;
2069 button_element_base* investbutton = nullptr;
2070public:
2071 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2072 if(name == "progress_icon") {
2073 auto ptr = make_element_by_type<image_element_base>(state, id);
2074 progressicon = ptr.get();
2075 return ptr;
2076 } else if(name == "progress_button") {
2077 auto ptr = make_element_by_type<colony_invest_button>(state, id);
2078 investbutton = ptr.get();
2079 return ptr;
2080 } else {
2081 return nullptr;
2082 }
2083 }
2084
2085 void on_update(sys::state& state) noexcept override {
2086 if(content >= 0) {
2087 progressicon->frame = content;
2088 investbutton->set_visible(state, false);
2089 progressicon->set_visible(state, true);
2090 } else {
2091 investbutton->frame = -(content + 1);
2092 investbutton->set_visible(state, true);
2093 progressicon->set_visible(state, false);
2094 }
2095 }
2096};
2097
2098class colonisation_listbox : public overlapping_listbox_element_base<level_entry, int8_t> {
2099protected:
2100 std::string_view get_row_element_name() override {
2101 return "level_entry";
2102 }
2103
2104public:
2105 void on_update(sys::state& state) noexcept override {
2106 auto content = retrieve<dcon::colonization_id>(state, parent);
2107
2108 row_contents.clear();
2109
2110 if(!content) {
2111 row_contents.push_back(int8_t(-1));
2112 } else {
2113 auto province = retrieve<dcon::province_id>(state, parent);
2114 auto stage = state.world.state_definition_get_colonization_stage(state.world.province_get_state_from_abstract_state_membership(province));
2115
2116 auto fat_colony = dcon::fatten(state.world, content);
2117
2118 if(stage == 3) {
2119 row_contents.push_back(int8_t(0));
2120 row_contents.push_back(int8_t(1));
2121 row_contents.push_back(int8_t(2));
2122 row_contents.push_back(int8_t(3));
2123 row_contents.push_back(int8_t(4));
2124 } else if(fat_colony.get_colonizer() == state.local_player_nation) {
2125 int8_t i = 0;
2126 for(; i < 4 && i < int32_t(fat_colony.get_level()); ++i) {
2127 row_contents.push_back(i);
2128 }
2129 row_contents.push_back(int8_t(-(i + 1)));
2130 } else {
2131 for(int8_t i = 0; i < 5 && i < int32_t(fat_colony.get_level()); ++i) {
2132 row_contents.push_back(i);
2133 }
2134 }
2135 }
2136 update(state);
2137 }
2138};
2139
2141public:
2142 void on_update(sys::state& state) noexcept override {
2143 auto col = retrieve<dcon::colonization_id>(state, parent);
2144 auto level = state.world.colonization_get_level(col);
2145 if(level < 5)
2146 set_text(state, "");
2147 else
2148 set_text(state, std::to_string(level - 4));
2149 }
2150};
2151
2152class colonist_entry : public listbox_row_element_base<dcon::colonization_id> {
2153public:
2154 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2155 if(name == "controller_flag") {
2156 return make_element_by_type<flag_button>(state, id);
2157 } else if(name == "levels") {
2158 return make_element_by_type<colonisation_listbox>(state, id);
2159 } else if(name == "progress_counter") {
2160 return make_element_by_type<colonization_level_number>(state, id);
2161 } else {
2162 return nullptr;
2163 }
2164 }
2165
2166 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
2167 if(payload.holds_type<dcon::national_identity_id>()) {
2168 if(content)
2169 payload.emplace<dcon::national_identity_id>(dcon::fatten(state.world, content).get_colonizer().get_identity_from_identity_holder().id);
2170 else
2171 payload.emplace<dcon::national_identity_id>(state.world.nation_get_identity_from_identity_holder(state.local_player_nation));
2173 }
2175 }
2176};
2177
2178class colonist_listbox : public listbox_element_base<colonist_entry, dcon::colonization_id> {
2179protected:
2180 std::string_view get_row_element_name() override {
2181 return "colonist_item";
2182 }
2183
2184public:
2185 void on_update(sys::state& state) noexcept override {
2186
2187 auto prov = retrieve<dcon::province_id>(state, parent);
2188 auto fat_def = dcon::fatten(state.world, state.world.province_get_state_from_abstract_state_membership(prov));
2189
2190 row_contents.clear();
2191
2192 bool found_player = false;
2193 int32_t existing_colonizers = 0;
2194 for(auto colony : fat_def.get_colonization()) {
2195 if(colony.get_colonizer().id == state.local_player_nation) {
2196 found_player = true;
2197 }
2198 row_contents.push_back(colony.id);
2199 ++existing_colonizers;
2200 }
2201
2202 if(!found_player && (existing_colonizers == 0 || (fat_def.get_colonization_stage() == 1 && existing_colonizers < 4))) {
2203 row_contents.push_back(dcon::colonization_id{});
2204 }
2205
2206 update(state);
2207 }
2208};
2209
2211public:
2212 void on_update(sys::state& state) noexcept override {
2213 auto content = retrieve<dcon::state_instance_id>(state, parent);
2214 progress = dcon::fatten(state.world, content).get_definition().get_colonization_temperature();
2215 }
2216};
2217
2219private:
2220 simple_text_element_base* population_box = nullptr;
2221 culture_piechart<dcon::province_id>* culture_chart = nullptr;
2222
2223public:
2224 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2225 if(name == "total_population") {
2226 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
2227 population_box = ptr.get();
2228 return ptr;
2229 } else if(name == "culture_chart") {
2230 auto ptr = make_element_by_type<culture_piechart<dcon::province_id>>(state, id);
2231 culture_chart = ptr.get();
2232 return ptr;
2233 } else if(name == "goods_type") {
2234 return make_element_by_type<province_rgo>(state, id);
2235 } else if(name == "colonize_button") {
2236 return make_element_by_type<province_protectorate_button>(state, id);
2237 } else if(name == "withdraw_button") {
2238 return make_element_by_type<province_withdraw_button>(state, id);
2239 } else if(name == "colonist_list") {
2240 return make_element_by_type<colonist_listbox>(state, id);
2241 } else if(name == "crisis_temperature") {
2242 return make_element_by_type<province_colonisation_temperature>(state, id);
2243 } else if(name == "rallypoint_checkbox") {
2244 return make_element_by_type<land_rally_point>(state, id);
2245 } else if(name == "rallypoint_checkbox_naval") {
2246 return make_element_by_type<naval_rally_point>(state, id);
2247 } else if(name == "rallypoint_merge_checkbox" || name == "rallypoint_merge_checkbox_naval") {
2248 return make_element_by_type<merge_rally_point>(state, id);
2249 } else {
2250 return nullptr;
2251 }
2252 }
2253
2254 void on_update(sys::state& state) noexcept override {
2255 auto prov_id = retrieve<dcon::province_id>(state, parent);
2256 dcon::province_fat_id fat_id = dcon::fatten(state.world, prov_id);
2257 auto nation_id = fat_id.get_nation_from_province_ownership();
2258 if(bool(nation_id)) {
2259 set_visible(state, false);
2260 } else {
2261 auto total_pop = state.world.province_get_demographics(prov_id, demographics::total);
2262 population_box->set_text(state, text::prettify(int32_t(total_pop)));
2263 culture_chart->on_update(state);
2264 set_visible(state, true);
2265 }
2266 }
2267};
2268
2269
2271 .sortable = true,
2272 .header = "route_origin",
2273 .compare = [](sys::state& state, element_base* container, dcon::trade_route_id a, dcon::trade_route_id b) {
2274 return a.index() < b.index();
2275 },
2276 .view = [](sys::state& state, element_base* container, dcon::trade_route_id item) {
2277
2278 auto sid = retrieve<dcon::state_instance_id>(state, container);
2279 auto nid = state.world.state_instance_get_nation_from_state_ownership(sid);
2280 auto niid = state.world.nation_get_identity_from_identity_holder(nid);
2281 auto ii = state.world.national_identity_get_identifying_int(niid);
2282 auto tag = nations::int_to_tag(ii);
2283 auto prefix = "@" + tag;
2284
2285 return prefix + text::get_name_as_string(
2286 state,
2287 state.world.state_instance_get_capital(sid)
2288 );
2289 },
2290 .cell_definition_string = "thin_cell_name",
2291 .header_definition_string = "thin_cell_name"
2292};
2293
2295 .sortable = true,
2296 .header = "route_target",
2297 .compare = [](sys::state& state, element_base* container, dcon::trade_route_id a, dcon::trade_route_id b) {
2298
2299 auto local_market = retrieve<dcon::market_id>(state, container);
2300 int32_t index_a = 0;
2301 if(local_market == dcon::fatten(state.world, a).get_connected_markets(index_a)) {
2302 index_a = 1;
2303 }
2304 int32_t index_b = 0;
2305 if(local_market == dcon::fatten(state.world, b).get_connected_markets(index_b)) {
2306 index_b = 1;
2307 }
2308
2309 auto value_a = text::get_name_as_string(
2310 state,
2311 dcon::fatten(state.world, a).get_connected_markets(index_a).get_zone_from_local_market().get_capital()
2312 );
2313 auto value_b = text::get_name_as_string(
2314 state,
2315 dcon::fatten(state.world, b).get_connected_markets(index_b).get_zone_from_local_market().get_capital()
2316 );
2317
2318 if(value_a != value_b)
2319 return value_a > value_b;
2320 else
2321 return a.index() < b.index();
2322 },
2323 .view = [](sys::state& state, element_base* container, dcon::trade_route_id item) {
2324 auto local_market = retrieve<dcon::market_id>(state, container);
2325 int32_t index = 0;
2326 if(local_market == dcon::fatten(state.world, item).get_connected_markets(index)) {
2327 index = 1;
2328 }
2329
2330 auto sid = dcon::fatten(state.world, item).get_connected_markets(index).get_zone_from_local_market();
2331 auto nid = state.world.state_instance_get_nation_from_state_ownership(sid);
2332 auto niid = state.world.nation_get_identity_from_identity_holder(nid);
2333 auto ii = state.world.national_identity_get_identifying_int(niid);
2334 auto tag = nations::int_to_tag(ii);
2335 auto prefix = "@" + tag;
2336
2337 return prefix + text::get_name_as_string(
2338 state,
2339 sid.get_capital()
2340 );
2341 },
2342 .cell_definition_string = "thin_cell_name",
2343 .header_definition_string = "thin_cell_name"
2344};
2345
2347 .sortable = true,
2348 .header = "price_origin",
2349 .compare = [](sys::state& state, element_base* container, dcon::trade_route_id a, dcon::trade_route_id b) {
2350 return a.index() < b.index();
2351 },
2352 .view = [](sys::state& state, element_base* container, dcon::trade_route_id item) {
2353 return text::format_money(
2354 dcon::fatten(state.world, retrieve<dcon::market_id>(state, container))
2355 .get_price(retrieve<dcon::commodity_id>(state, container))
2356 );
2357 }
2358};
2359
2361 .sortable = true,
2362 .header = "price_target",
2363 .compare = [](sys::state& state, element_base* container, dcon::trade_route_id a, dcon::trade_route_id b) {
2364 auto local_market = retrieve<dcon::market_id>(state, container);
2365 int32_t index_a = 0;
2366 if(local_market == dcon::fatten(state.world, a).get_connected_markets(index_a)) {
2367 index_a = 1;
2368 }
2369 int32_t index_b = 0;
2370 if(local_market == dcon::fatten(state.world, b).get_connected_markets(index_b)) {
2371 index_b = 1;
2372 }
2373
2374 auto value_a = dcon::fatten(state.world, a).get_connected_markets(index_a).get_price(retrieve<dcon::commodity_id>(state, container));
2375 auto value_b = dcon::fatten(state.world, b).get_connected_markets(index_b).get_price(retrieve<dcon::commodity_id>(state, container));
2376
2377 if(value_a != value_b)
2378 return value_a > value_b;
2379 else
2380 return a.index() < b.index();
2381 },
2382 .view = [](sys::state& state, element_base* container, dcon::trade_route_id item) {
2383 auto local_market = retrieve<dcon::market_id>(state, container);
2384 int32_t index = 0;
2385 if(local_market == dcon::fatten(state.world, item).get_connected_markets(index)) {
2386 index = 1;
2387 }
2388
2389 return text::format_money(
2390 dcon::fatten(state.world, item)
2391 .get_connected_markets(index).get_price(retrieve<dcon::commodity_id>(state, container))
2392 );
2393 }
2394};
2395
2397 .sortable = true,
2398 .header = "trade_distance",
2399 .compare = [](sys::state& state, element_base* container, dcon::trade_route_id a, dcon::trade_route_id b) {
2400 auto value_a = dcon::fatten(state.world, a).get_distance();
2401 auto value_b = dcon::fatten(state.world, b).get_distance();
2402
2403 if(value_a != value_b)
2404 return value_a > value_b;
2405 else
2406 return a.index() < b.index();
2407 },
2408 .view = [](sys::state& state, element_base* container, dcon::trade_route_id item) {
2409 return text::format_float(dcon::fatten(state.world, item).get_distance());
2410 }
2411};
2412
2414 .sortable = true,
2415 .header = "desired_volume",
2416 .compare = [](sys::state& state, element_base* container, dcon::trade_route_id a, dcon::trade_route_id b) {
2417 auto local_market = retrieve<dcon::market_id>(state, container);
2418 int32_t index_a = 0;
2419 if(local_market == dcon::fatten(state.world, a).get_connected_markets(index_a)) {
2420 index_a = 1;
2421 }
2422 int32_t index_b = 0;
2423 if(local_market == dcon::fatten(state.world, b).get_connected_markets(index_b)) {
2424 index_b = 1;
2425 }
2426
2427
2428 auto value_a = dcon::fatten(state.world, a).get_volume(retrieve<dcon::commodity_id>(state, container)) * ((float)index_a - 0.5f);
2429 auto value_b = dcon::fatten(state.world, b).get_volume(retrieve<dcon::commodity_id>(state, container)) * ((float)index_b - 0.5f);
2430
2431 if(value_a != value_b)
2432 return value_a > value_b;
2433 else
2434 return a.index() < b.index();
2435 },
2436 .view = [](sys::state& state, element_base* container, dcon::trade_route_id item) {
2437 auto local_market = retrieve<dcon::market_id>(state, container);
2438 int32_t index = 0;
2439 if(local_market == dcon::fatten(state.world, item).get_connected_markets(index)) {
2440 index = 1;
2441 }
2442
2443 return text::format_float(dcon::fatten(state.world, item).get_volume(retrieve<dcon::commodity_id>(state, container)) * (float(index) - 0.5f) * 2.f);
2444 }
2445};
2446
2448 .sortable = true,
2449 .header = "max_throughput",
2450 .compare = [](sys::state& state, element_base* container, dcon::trade_route_id a, dcon::trade_route_id b) {
2451 auto value_a = std::min(
2452 dcon::fatten(state.world, a).get_connected_markets(0).get_max_throughput(),
2453 dcon::fatten(state.world, a).get_connected_markets(1).get_max_throughput()
2454 );
2455 auto value_b = std::min(
2456 dcon::fatten(state.world, b).get_connected_markets(0).get_max_throughput(),
2457 dcon::fatten(state.world, b).get_connected_markets(1).get_max_throughput()
2458 );
2459
2460 if(value_a != value_b)
2461 return value_a > value_b;
2462 else
2463 return a.index() < b.index();
2464 },
2465 .view = [](sys::state& state, element_base* container, dcon::trade_route_id item) {
2466 return text::format_float(std::min(
2467 dcon::fatten(state.world, item).get_connected_markets(0).get_max_throughput(),
2468 dcon::fatten(state.world, item).get_connected_markets(1).get_max_throughput()
2469 ));
2470 },
2471 .update_tooltip = [](
2473 element_base* container,
2474 text::columnar_layout& contents,
2475 const dcon::trade_route_id& a,
2476 std::string fallback
2477 ) {
2478 auto local_market = retrieve<dcon::market_id>(state, container);
2479 float total = 0.f;
2480 state.world.for_each_commodity([&](auto commodity) {
2481 state.world.market_for_each_trade_route(local_market, [&](auto trade_route) {
2482 total += std::abs(state.world.trade_route_get_volume(trade_route, commodity));
2483 });
2484 });
2485 float max = state.world.market_get_max_throughput(local_market);
2486
2487 auto box = text::open_layout_box(contents, 0);
2488 text::add_to_layout_box(state, contents, box, text::fp_two_places{ total });
2489 text::add_to_layout_box(state, contents, box, std::string("/"));
2490 text::add_to_layout_box(state, contents, box, text::fp_two_places{ max });
2491 text::close_layout_box(contents, box);
2492 },
2493 .has_tooltip = true,
2494};
2495
2496float trade_route_profit(sys::state& state, dcon::trade_route_id route, dcon::commodity_id c);
2497
2499 .sortable = true,
2500 .header = "trade_margin",
2501 .compare = [](sys::state& state, element_base* container, dcon::trade_route_id a, dcon::trade_route_id b) {
2502 auto local_market = retrieve<dcon::market_id>(state, container);
2503
2504 auto value_a = trade_route_profit(state, a, retrieve<dcon::commodity_id>(state, container));
2505 auto value_b = trade_route_profit(state, b, retrieve<dcon::commodity_id>(state, container));
2506
2507 if(value_a != value_b)
2508 return value_a > value_b;
2509 else
2510 return a.index() < b.index();
2511 },
2512 .view = [](sys::state& state, element_base* container, dcon::trade_route_id item) {
2513 auto local_market = retrieve<dcon::market_id>(state, container);
2514 return text::format_percentage(trade_route_profit(state, item, retrieve<dcon::commodity_id>(state, container)));
2515 }
2516};
2517
2519 .sortable = true,
2520 .header = "trade_good_name_header",
2521 .compare = [](sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
2522 auto value_a = text::get_name_as_string(
2523 state,
2524 dcon::fatten(state.world, a)
2525 );
2526 auto value_b = text::get_name_as_string(
2527 state,
2528 dcon::fatten(state.world, b)
2529 );
2530
2531 if(value_a != value_b)
2532 return value_a > value_b;
2533 else
2534 return a.index() < b.index();
2535 },
2536 .view = [](sys::state& state, element_base* container, dcon::commodity_id item) {
2537 std::string padding = item.index() < 10 ? "0" : "";
2538 std::string description = "@$" + padding + std::to_string(item.index());
2539
2540 return description + text::get_name_as_string(
2541 state,
2542 dcon::fatten(state.world, item)
2543 );
2544 },
2545 .cell_definition_string = "thin_cell_name",
2546 .header_definition_string = "thin_cell_name"
2547};
2548
2550 .sortable = true,
2551 .header = "price",
2552 .compare = [](sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
2553 auto si = retrieve<dcon::state_instance_id>(state, container);
2554 auto m = state.world.state_instance_get_market_from_local_market(si);
2555
2556 auto av = economy::price(state, m, a);
2557 auto bv = economy::price(state, m, b);
2558 if(av != bv)
2559 return av > bv;
2560 else
2561 return a.index() < b.index();
2562 },
2563 .view = [](sys::state& state, element_base* container, dcon::commodity_id id) {
2564 auto si = retrieve<dcon::state_instance_id>(state, container);
2565 auto m = state.world.state_instance_get_market_from_local_market(si);
2566
2567 auto value = economy::price(state, m, id);
2568 return text::format_money(value);
2569 }
2570};
2571
2573 .sortable = true,
2574 .header = "rgo_output",
2575 .compare = [](sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
2576 auto p = retrieve<dcon::province_id>(state, container);
2577 auto si = retrieve<dcon::state_instance_id>(state, container);
2578 auto m = state.world.state_instance_get_market_from_local_market(si);
2579
2580 auto av = state.world.province_get_rgo_actual_production_per_good(p, a);
2581 auto bv = state.world.province_get_rgo_actual_production_per_good(p, b);
2582 if(av != bv)
2583 return av > bv;
2584 else
2585 return a.index() < b.index();
2586 },
2587 .view = [](sys::state& state, element_base* container, dcon::commodity_id id) {
2588 auto p = retrieve<dcon::province_id>(state, container);
2589 auto si = retrieve<dcon::state_instance_id>(state, container);
2590 auto m = state.world.state_instance_get_market_from_local_market(si);
2591
2592 auto value = state.world.province_get_rgo_actual_production_per_good(p, id);
2593 return text::format_float(value);
2594 }
2595};
2596
2598 .sortable = true,
2599 .header = "rgo_profit",
2600 .compare = [](sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
2601 auto p = retrieve<dcon::province_id>(state, container);
2602 auto si = retrieve<dcon::state_instance_id>(state, container);
2603 auto m = state.world.state_instance_get_market_from_local_market(si);
2604
2605 auto av = state.world.province_get_rgo_profit_per_good(p, a);
2606 auto bv = state.world.province_get_rgo_profit_per_good(p, b);
2607 if(av != bv)
2608 return av > bv;
2609 else
2610 return a.index() < b.index();
2611 },
2612 .view = [](sys::state& state, element_base* container, dcon::commodity_id id) {
2613 auto p = retrieve<dcon::province_id>(state, container);
2614 auto si = retrieve<dcon::state_instance_id>(state, container);
2615 auto m = state.world.state_instance_get_market_from_local_market(si);
2616
2617 auto value = state.world.province_get_rgo_profit_per_good(p, id);
2618 return text::format_money(value);
2619 }
2620};
2621
2623 .sortable = true,
2624 .header = "rgo_expected_profit",
2625 .compare = [](sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
2626 auto p = retrieve<dcon::province_id>(state, container);
2627 auto n = state.world.province_get_nation_from_province_ownership(p);
2628 auto si = retrieve<dcon::state_instance_id>(state, container);
2629 auto m = state.world.state_instance_get_market_from_local_market(si);
2630
2631 auto av = economy::rgo_expected_worker_norm_profit(state, p, m, n, a);
2632 auto bv = economy::rgo_expected_worker_norm_profit(state, p, m, n, b);
2633 if(av != bv)
2634 return av > bv;
2635 else
2636 return a.index() < b.index();
2637 },
2638 .view = [](sys::state& state, element_base* container, dcon::commodity_id id) {
2639 auto p = retrieve<dcon::province_id>(state, container);
2640 auto n = state.world.province_get_nation_from_province_ownership(p);
2641 auto si = retrieve<dcon::state_instance_id>(state, container);
2642 auto m = state.world.state_instance_get_market_from_local_market(si);
2643
2644 auto value = economy::rgo_expected_worker_norm_profit(state, p, m, n, id)
2645 * state.defines.alice_rgo_per_size_employment;
2646 return text::format_money(value);
2647 }
2648};
2649
2651 .sortable = true,
2652 .header = "rgo_desired_profit",
2653 .compare = [](sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
2654 return a.index() < b.index();
2655 },
2656 .view = [](sys::state& state, element_base* container, dcon::commodity_id id) {
2657 auto p = retrieve<dcon::province_id>(state, container);
2658 auto n = state.world.province_get_nation_from_province_ownership(p);
2659 auto si = retrieve<dcon::state_instance_id>(state, container);
2660 auto m = state.world.state_instance_get_market_from_local_market(si);
2661 auto pops = economy::rgo_relevant_population(state, p, n);
2662 auto min_wage_factor = economy::pop_min_wage_factor(state, n);
2663 auto pop_farmer_min_wage = economy::farmer_min_wage(state, m, min_wage_factor);
2664 auto pop_laborer_min_wage = economy::laborer_min_wage(state, m, min_wage_factor);
2665 bool is_mine = state.world.commodity_get_is_mine(state.world.province_get_rgo(p));
2667 state, p, m, n,
2668 is_mine ? pop_laborer_min_wage : pop_farmer_min_wage,
2669 pops.total);
2670
2671 auto value = v * state.defines.alice_rgo_per_size_employment;
2672 return text::format_money(value);
2673 }
2674};
2675
2677 .sortable = true,
2678 .header = "rgo_employment",
2679 .compare = [](sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
2680 auto p = retrieve<dcon::province_id>(state, container);
2681 auto n = state.world.province_get_nation_from_province_ownership(p);
2682 auto si = retrieve<dcon::state_instance_id>(state, container);
2683 auto m = state.world.state_instance_get_market_from_local_market(si);
2684
2685 auto av = state.world.province_get_rgo_employment_per_good(p, a);
2686 auto bv = state.world.province_get_rgo_employment_per_good(p, b);
2687 if(av != bv)
2688 return av > bv;
2689 else
2690 return a.index() < b.index();
2691 },
2692 .view = [](sys::state& state, element_base* container, dcon::commodity_id id) {
2693 auto p = retrieve<dcon::province_id>(state, container);
2694 auto n = state.world.province_get_nation_from_province_ownership(p);
2695 auto si = retrieve<dcon::state_instance_id>(state, container);
2696 auto m = state.world.state_instance_get_market_from_local_market(si);
2697
2698 auto value = state.world.province_get_rgo_employment_per_good(p, id);
2699 return text::format_wholenum(int32_t(value));
2700 }
2701};
2702
2704 .sortable = true,
2705 .header = "rgo_max_employment",
2706 .compare = [](sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
2707 auto p = retrieve<dcon::province_id>(state, container);
2708 auto n = state.world.province_get_nation_from_province_ownership(p);
2709 auto si = retrieve<dcon::state_instance_id>(state, container);
2710 auto m = state.world.state_instance_get_market_from_local_market(si);
2711
2712 auto av = economy::rgo_max_employment(state, n, p, a);
2713 auto bv = economy::rgo_max_employment(state, n, p, b);
2714 if(av != bv)
2715 return av > bv;
2716 else
2717 return a.index() < b.index();
2718 },
2719 .view = [](sys::state& state, element_base* container, dcon::commodity_id id) {
2720 auto p = retrieve<dcon::province_id>(state, container);
2721 auto n = state.world.province_get_nation_from_province_ownership(p);
2722 auto si = retrieve<dcon::state_instance_id>(state, container);
2723 auto m = state.world.state_instance_get_market_from_local_market(si);
2724
2725 auto value = economy::rgo_max_employment(state, n, p, id);
2726 return text::format_wholenum(int32_t(value));
2727 }
2728};
2729
2731 .sortable = true,
2732 .header = "rgo_saturation",
2733 .compare = [](sys::state& state, element_base* container, dcon::commodity_id a, dcon::commodity_id b) {
2734 auto p = retrieve<dcon::province_id>(state, container);
2735 auto n = state.world.province_get_nation_from_province_ownership(p);
2736 auto si = retrieve<dcon::state_instance_id>(state, container);
2737 auto m = state.world.state_instance_get_market_from_local_market(si);
2738
2739 auto ae = economy::rgo_max_employment(state, n, p, a);
2740 auto be = economy::rgo_max_employment(state, n, p, b);
2741
2742 auto av = state.world.province_get_rgo_employment_per_good(p, a);
2743 auto bv = state.world.province_get_rgo_employment_per_good(p, b);
2744
2745 auto ar = ae > 0.f ? av / ae : 0.f;
2746 auto br = be > 0.f ? bv / be : 0.f;
2747
2748 if(ar != br)
2749 return ar > br;
2750 else
2751 return a.index() < b.index();
2752 },
2753 .view = [](sys::state& state, element_base* container, dcon::commodity_id id) {
2754 auto p = retrieve<dcon::province_id>(state, container);
2755 auto n = state.world.province_get_nation_from_province_ownership(p);
2756 auto si = retrieve<dcon::state_instance_id>(state, container);
2757 auto m = state.world.state_instance_get_market_from_local_market(si);
2758
2759 auto e = economy::rgo_max_employment(state, n, p, id);
2760 auto v = state.world.province_get_rgo_employment_per_good(p, id);
2761 auto r = e > 0.f ? v / e : 0.f;
2762
2763 return text::format_percentage(r);
2764 }
2765};
2766
2768
2770public:
2771 void button_action(sys::state& state) noexcept override {
2772 send<province_economy_toggle_signal>(state, parent, { });
2773 }
2774};
2775
2777
2778public:
2784
2785 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2786 if(name == "toggle-economy-province") {
2787 return make_element_by_type<economy_data_toggle>(state, id);
2788 }else if(name == "table_rgo_data") {
2789 std::vector<table::column<dcon::commodity_id>> columns = {
2792 };
2793 auto ptr = make_element_by_type<table::display<dcon::commodity_id>>(
2794 state,
2795 id,
2796 std::string("table_body"),
2797 columns
2798 );
2799
2800 rgo_table = ptr.get();
2801 rgo_table->row_callback = [](sys::state& state, ui::element_base* container, const dcon::commodity_id a) {
2802 if(state.selected_trade_good == a) {
2803 state.selected_trade_good = { };
2804 } else {
2805 state.selected_trade_good = a;
2806 }
2807 state.update_trade_flow.store(true, std::memory_order::release);
2808 if(state.ui_state.province_window) {
2810 }
2811 };
2812 state.world.for_each_commodity([&](dcon::commodity_id id) {
2813 rgo_table->content.data.push_back(id);
2814 });
2815 rgo_table->set_visible(state, true);
2816 return ptr;
2817 } else if(name == "table_trade_route_data") {
2818 std::vector<table::column<dcon::trade_route_id>> columns = {
2822 };
2823
2824 auto ptr = make_element_by_type<table::display<dcon::trade_route_id>>(
2825 state,
2826 id,
2827 std::string("table_body"),
2828 columns
2829 );
2830
2831 trade_table = ptr.get();
2833
2834 // On click - change selected province to the target of the row
2835 trade_table->row_callback = [](sys::state& state, ui::element_base* container, const dcon::trade_route_id t) {
2836 auto origin = state.world.trade_route_get_connected_markets(t, 0);
2837 auto target = state.world.trade_route_get_connected_markets(t, 1);
2838
2839 auto s_origin = state.world.market_get_zone_from_local_market(origin);
2840 auto s_target = state.world.market_get_zone_from_local_market(target);
2841
2842 auto p_origin = state.world.state_instance_get_capital(s_origin);
2843 auto p_target = state.world.state_instance_get_capital(s_target);
2844
2845 auto selected_province = state.map_state.get_selected_province();
2846 if(selected_province) {
2847 auto selected_province_state = state.world.province_get_state_membership(selected_province);
2848
2849 if(selected_province_state != s_origin) {
2850 state.map_state.set_selected_province(p_origin);
2851 }
2852 else if(selected_province_state != s_target) {
2853 state.map_state.set_selected_province(p_target);
2854 }
2855 }
2856
2857 state.map_state.center_map_on_province(state, state.map_state.get_selected_province());
2858
2859 state.update_trade_flow.store(true, std::memory_order::release);
2860
2861 if(state.ui_state.province_window) {
2863 }
2864 };
2865 return ptr;
2866 } else if(name == "trade_route_background") {
2867 auto ptr = make_element_by_type<image_element_base>(state, id);
2868 trade_routes_bg = ptr.get();
2870 return ptr;
2871 } else if(name == "background") {
2872 auto ptr = make_element_by_type<image_element_base>(state, id);
2873 rgo_bg = ptr.get();
2874 rgo_bg->set_visible(state, true);
2875 return ptr;
2876 } else if(name == "table_rgo_headers") {
2877 auto ptr = make_element_by_type<window_element_base>(state, id);
2878 rgo_headers = ptr.get();
2880 return ptr;
2881 }
2882 return nullptr;
2883 }
2884
2885 void on_update(sys::state& state) noexcept override {
2886 auto p = retrieve<dcon::province_id>(state, parent);
2887 auto n = state.world.province_get_nation_from_province_ownership(p);
2888 auto si = retrieve<dcon::state_instance_id>(state, parent);
2889 auto m = state.world.state_instance_get_market_from_local_market(si);
2890 trade_table->content.data.clear();
2891
2892 if(state.selected_trade_good) {
2893 state.world.market_for_each_trade_route_as_connected_markets(m, [&](auto route) {
2894 trade_table->content.data.push_back(route);
2895 });
2898 } else {
2899 trade_table->set_visible(state, false);
2901 }
2902 }
2903
2904 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
2905 if(payload.holds_type<province_economy_toggle_signal>()) {
2906 if(rgo_bg->is_visible()) {
2907 trade_table->set_visible(state, false);
2909 rgo_table->set_visible(state, false);
2910 rgo_bg->set_visible(state, false);
2911 rgo_headers->set_visible(state, false);
2912 } else {
2913 rgo_table->set_visible(state, true);
2914 rgo_bg->set_visible(state, true);
2916 }
2918 }
2920 }
2921};
2922
2924private:
2925 dcon::province_id active_province{};
2926 province_window_header* header_window = nullptr;
2927 province_view_foreign_details* foreign_details_window = nullptr;
2928 province_view_statistics* local_details_window = nullptr;
2929 province_view_buildings* local_buildings_window = nullptr;
2930 province_window_colony* colony_window = nullptr;
2931 province_economy_window* economy_window = nullptr;
2932 element_base* nf_win = nullptr;
2933
2934public:
2935 void on_create(sys::state& state) noexcept override {
2937 state.ui_state.province_window = this;
2938 set_visible(state, false);
2939 //
2940 auto ptr = make_element_by_type<build_unit_province_window>(state, "build_unit_view");
2941 state.ui_state.build_province_unit_window = ptr.get();
2942 add_child_to_front(std::move(ptr));
2943 }
2944
2945 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2946 if(name == "close_button") {
2947 return make_element_by_type<province_close_button>(state, id);
2948 } else if(name == "background") {
2949 return make_element_by_type<draggable_target>(state, id);
2950 } else if(name == "province_view_header") {
2951 auto ptr = make_element_by_type<province_window_header>(state, id);
2952 header_window = ptr.get();
2953 return ptr;
2954 } else if(name == "province_other") {
2955 auto ptr = make_element_by_type<province_view_foreign_details>(state, id);
2956 ptr->set_visible(state, false);
2957 foreign_details_window = ptr.get();
2958 return ptr;
2959 } else if(name == "province_colony") {
2960 auto ptr = make_element_by_type<province_window_colony>(state, id);
2961 ptr->set_visible(state, false);
2962 colony_window = ptr.get();
2963 return ptr;
2964 } else if(name == "province_statistics") {
2965 auto ptr = make_element_by_type<province_view_statistics>(state, id);
2966 local_details_window = ptr.get();
2967 ptr->set_visible(state, false);
2968 return ptr;
2969 } else if(name == "province_buildings") {
2970 auto ptr = make_element_by_type<province_view_buildings>(state, id);
2971 local_buildings_window = ptr.get();
2972 ptr->set_visible(state, false);
2973 return ptr;
2974 } else if(name == "national_focus_window") {
2975 auto ptr = make_element_by_type<national_focus_window>(state, id);
2976 ptr->set_visible(state, false);
2977 nf_win = ptr.get();
2978 return ptr;
2979 } else if(name == "local_economy_view") {
2980 auto ptr = make_element_by_type<province_economy_window>(state, id);
2981 economy_window = ptr.get();
2982 return ptr;
2983 } else {
2984 return nullptr;
2985 }
2986 }
2987
2988 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
2989 if(payload.holds_type<dcon::province_id>()) {
2990 payload.emplace<dcon::province_id>(active_province);
2992 } else if(payload.holds_type<dcon::nation_id>()) {
2993 dcon::nation_id nid = dcon::fatten(state.world, active_province).get_nation_from_province_ownership();
2994 payload.emplace<dcon::nation_id>(nid);
2996 } else if(payload.holds_type<dcon::state_instance_id>()) {
2997 dcon::state_instance_id sid = dcon::fatten(state.world, active_province).get_state_membership();
2998 payload.emplace<dcon::state_instance_id>(sid);
3000 } else if(payload.holds_type<dcon::commodity_id>()) {
3001 payload.emplace<dcon::commodity_id>(state.selected_trade_good);
3003 } else if(payload.holds_type<dcon::market_id>()) {
3004 dcon::market_id mid = dcon::fatten(state.world, active_province).get_state_membership().get_market_from_local_market();
3005 payload.emplace<dcon::market_id>(mid);
3007 }
3009 }
3010
3011 void set_active_province(sys::state& state, dcon::province_id map_province) {
3012 if(bool(map_province)) {
3013 active_province = map_province;
3014 state.map_state.set_selected_province(map_province);
3015 if(!is_visible())
3016 set_visible(state, true);
3017 else
3019 } else {
3020 set_visible(state, false);
3021 }
3022 }
3023
3024 void on_update(sys::state& state) noexcept override {
3025 header_window->impl_on_update(state);
3026 foreign_details_window->impl_on_update(state);
3027 local_details_window->impl_on_update(state);
3028 local_buildings_window->impl_on_update(state);
3029 colony_window->impl_on_update(state);
3030 economy_window->impl_on_update(state);
3031
3032 active_province = state.map_state.get_selected_province();
3033
3034 //Hide unit builder if not our province
3035 auto n = state.world.province_get_nation_from_province_ownership(active_province);
3036 if(state.ui_state.build_province_unit_window && state.ui_state.build_province_unit_window->is_visible() && n != state.local_player_nation) {
3038 }
3039 }
3040
3042};
3043
3044} // namespace ui
ui::message_result get(sys::state &state, Cyto::Any &payload) noexcept override
Definition: table.hpp:427
std::function< void(sys::state &state, ui::element_base *container, const item_type &a)> row_callback
Definition: table.hpp:354
data< item_type > content
Definition: table.hpp:346
void set_button_text(sys::state &state, std::string const &new_text)
void render(sys::state &state, int32_t x, int32_t y) noexcept override
void on_create(sys::state &state) noexcept override
void on_update(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_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void button_action(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
void button_action(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
virtual void impl_on_update(sys::state &state) noexcept
virtual void impl_render(sys::state &state, int32_t x, int32_t y) noexcept
bool is_visible() const
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 render(sys::state &state, int32_t x, int32_t y) noexcept override
virtual void set_current_nation(sys::state &state, dcon::national_identity_id identity) noexcept
void button_action(sys::state &state) noexcept override
void render(sys::state &state, int32_t x, int32_t y) 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 button_action(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
message_result get(sys::state &state, Cyto::Any &payload) 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 on_create(sys::state &state) noexcept override
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
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 button_action(sys::state &state) noexcept override
virtual void button_shift_right_action(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
virtual void button_shift_action(sys::state &state) 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 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
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 button_action(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
dcon::national_identity_id get_current_nation(sys::state &state) noexcept override
void on_update(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 on_update(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
tooltip_behavior has_tooltip(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_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 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
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
table::display< dcon::trade_route_id > * trade_table
image_element_base * trade_routes_bg
table::display< dcon::commodity_id > * rgo_table
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 update_tooltip(sys::state &state, int32_t x, int32_t t, text::columnar_layout &contents) 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 button_action(sys::state &state) noexcept override
void on_update(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 update_tooltip(sys::state &state, int32_t x, int32_t t, text::columnar_layout &contents) noexcept override
virtual void button_shift_action(sys::state &state) 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
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
void button_action(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
virtual void button_shift_action(sys::state &state) noexcept override
virtual void button_shift_right_action(sys::state &state) 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 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 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
tooltip_behavior has_tooltip(sys::state &state) noexcept override
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
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
std::string_view get_row_element_name() override
void update_subwindow(sys::state &state, province_modifier_win &subwindow, sys::dated_modifier content) override
void button_action(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t t, text::columnar_layout &contents) noexcept override
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
int32_t get_icon_frame(sys::state &state) noexcept
void on_update(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) 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
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 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
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
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
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
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 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
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
tooltip_behavior has_tooltip(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 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 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
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void button_action(sys::state &state) noexcept override
virtual void button_shift_action(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 button_action(sys::state &state) noexcept override
void on_update(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 on_update(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t t, text::columnar_layout &contents) noexcept override
void button_action(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t t, text::columnar_layout &contents) 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 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
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) 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_create(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
void set_active_province(sys::state &state, dcon::province_id map_province)
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
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
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 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 test_mouse(sys::state &state, int32_t x, int32_t y, mouse_probe_type type) noexcept override
void impl_render(sys::state &state, int32_t x, int32_t y) noexcept override
void on_update(sys::state &state) noexcept override
void set_text(sys::state &state, std::string const &new_text)
message_result test_mouse(sys::state &state, int32_t x, int32_t y, mouse_probe_type type) noexcept override
void on_create(sys::state &state) noexcept override
bool can_begin_factory_building_construction(sys::state &state, dcon::nation_id source, dcon::state_instance_id location, dcon::factory_type_id type, bool is_upgrade)
Definition: commands.cpp:512
bool can_begin_province_building_construction(sys::state &state, dcon::nation_id source, dcon::province_id p, economy::province_building_type type)
Definition: commands.cpp:423
bool can_set_national_focus(sys::state &state, dcon::nation_id source, dcon::state_instance_id target_state, dcon::national_focus_id focus)
Definition: commands.cpp:122
bool can_abandon_colony(sys::state &state, dcon::nation_id source, dcon::province_id pr)
Definition: commands.cpp:1637
bool can_move_capital(sys::state &state, dcon::nation_id source, dcon::province_id p)
Definition: commands.cpp:4713
void set_national_focus(sys::state &state, dcon::nation_id source, dcon::state_instance_id target_state, dcon::national_focus_id focus)
Definition: commands.cpp:111
bool can_toggle_select_province(sys::state &state, dcon::nation_id source, dcon::province_id prov)
Definition: commands.cpp:4004
bool can_start_land_unit_construction(sys::state &state, dcon::nation_id source, dcon::province_id location, dcon::culture_id soldier_culture, dcon::unit_type_id type, dcon::province_id template_province)
Definition: commands.cpp:705
bool can_invest_in_colony(sys::state &state, dcon::nation_id source, dcon::province_id p)
Definition: commands.cpp:1591
bool can_take_province(sys::state &state, dcon::nation_id source, dcon::province_id p)
Definition: commands.cpp:4752
bool can_finish_colonization(sys::state &state, dcon::nation_id source, dcon::province_id p)
Definition: commands.cpp:1660
bool can_toggle_immigrator_province(sys::state &state, dcon::nation_id source, dcon::province_id prov)
Definition: commands.cpp:4023
bool can_start_naval_unit_construction(sys::state &state, dcon::nation_id source, dcon::province_id location, dcon::unit_type_id type, dcon::province_id template_province)
Definition: commands.cpp:646
pop_satisfaction_wrapper_fat fatten(data_container const &c, pop_satisfaction_wrapper_id id) noexcept
constexpr dcon::demographics_key total(0)
dcon::demographics_key to_key(sys::state const &state, dcon::pop_type_id v)
float get_monthly_pop_increase(sys::state &state, dcon::pop_id ids)
construction_status province_building_construction(sys::state &state, dcon::province_id p, province_building_type t)
Definition: economy.cpp:8268
std::string_view province_building_type_get_name(economy::province_building_type v)
Definition: economy.hpp:57
rgo_workers_breakdown rgo_relevant_population(sys::state &state, dcon::province_id p, dcon::nation_id n)
Definition: economy.cpp:2682
float farmer_min_wage(sys::state &state, dcon::market_id m, float min_wage_factor)
Definition: economy.cpp:65
float price(sys::state const &state, dcon::state_instance_id s, dcon::commodity_id c)
Definition: economy.cpp:150
float laborer_min_wage(sys::state &state, dcon::market_id m, float min_wage_factor)
Definition: economy.cpp:70
float rgo_expected_worker_norm_profit(sys::state &state, dcon::province_id p, dcon::market_id m, dcon::nation_id n, dcon::commodity_id c)
Definition: economy.cpp:2764
float rgo_desired_worker_norm_profit(sys::state &state, dcon::province_id p, dcon::market_id m, dcon::nation_id n, float min_wage, float total_relevant_population)
Definition: economy.cpp:2698
float rgo_max_employment(sys::state &state, dcon::nation_id n, dcon::province_id p, dcon::commodity_id c)
Definition: economy.cpp:1822
float pop_min_wage_factor(sys::state &state, dcon::nation_id n)
Definition: economy.cpp:16
province_building_type
Definition: constants.hpp:578
constexpr uint32_t build_railway
Definition: culture.hpp:38
bool province_is_under_siege(sys::state const &state, dcon::province_id ids)
Definition: military.cpp:603
int32_t regiments_created_from_province(sys::state &state, dcon::province_id p)
Definition: military.cpp:823
int32_t regiments_max_possible_from_province(sys::state &state, dcon::province_id p)
Definition: military.cpp:885
float peacetime_attrition_limit(sys::state &state, dcon::nation_id n, dcon::province_id prov)
Definition: military.cpp:5344
int32_t free_colonial_points(sys::state &state, dcon::nation_id n)
Definition: nations.cpp:1304
std::string int_to_tag(uint32_t v)
Definition: nations.hpp:14
auto nation_accepts_culture(sys::state const &state, T ids, U cul_ids)
GLuint get_rebel_flag_handle(sys::state &state, dcon::rebel_faction_id faction)
Definition: texture.cpp:1010
float direct_distance(sys::state &state, dcon::province_id a, dcon::province_id b)
Definition: province.cpp:1745
bool is_colonizing(sys::state &state, dcon::nation_id n, dcon::state_definition_id d)
Definition: province.cpp:1170
void for_each_province_in_state_instance(sys::state &state, dcon::state_instance_id s, F const &func)
float crime_fighting_efficiency(sys::state &state, dcon::province_id id)
Definition: province.cpp:586
bool has_railroads_being_built(sys::state &state, dcon::province_id id)
Definition: province.cpp:359
float land_maximum_employment(sys::state &state, dcon::province_id id)
Definition: province.cpp:505
float land_employment(sys::state &state, dcon::province_id id)
Definition: province.cpp:509
constexpr float world_circumference
Definition: province.hpp:8
float revolt_risk(sys::state &state, dcon::province_id id)
Definition: province.cpp:611
float state_admin_efficiency(sys::state &state, dcon::state_instance_id id)
Definition: province.cpp:553
std::string rebel_name(sys::state &state, dcon::rebel_faction_id reb)
Definition: rebels.cpp:1276
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
std::string get_name_as_string(sys::state &state, T t)
Definition: text.hpp:957
std::string format_ratio(int32_t left, int32_t right)
Definition: text.cpp:1064
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_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
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:1923
void add_line_with_condition(sys::state &state, layout_base &dest, std::string_view key, bool condition_met, int32_t indent)
Definition: text.cpp:1979
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
dcon::text_key get_adjective(sys::state &state, dcon::nation_id id)
Definition: text.cpp:890
std::string format_wholenum(int32_t num)
Definition: text.cpp:1033
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
void add_space_to_layout_box(sys::state &state, layout_base &dest, layout_box &box)
Definition: text.cpp:1812
void close_layout_box(columnar_layout &dest, layout_box &box)
Definition: text.cpp:1831
uint16_t * recurse_over_triggers(uint16_t *source, T const &f)
void modifier_description(sys::state &state, text::layout_base &layout, dcon::modifier_id mid, int32_t indentation=0)
table::column< dcon::commodity_id > rgo_profit
table::column< dcon::commodity_id > rgo_expected_profit
table::column< dcon::commodity_id > rgo_name
table::column< dcon::commodity_id > rgo_amount
table::column< dcon::trade_route_id > trade_route_7
table::column< dcon::trade_route_id > trade_route_0
table::column< dcon::commodity_id > rgo_desired_profit
table::column< dcon::trade_route_id > trade_route_6
table::column< dcon::commodity_id > rgo_saturation
table::column< dcon::commodity_id > rgo_employment
tooltip_behavior
std::variant< std::monostate, dcon::nation_id, dcon::state_instance_id, dcon::province_id > pop_list_filter
message_result
float trade_route_profit(sys::state &state, dcon::trade_route_id route, dcon::commodity_id c)
table::column< dcon::trade_route_id > trade_route_4
table::column< dcon::trade_route_id > trade_route_5
table::column< dcon::trade_route_id > trade_route_1
table::column< dcon::commodity_id > rgo_price
table::column< dcon::commodity_id > rgo_max_employment
void open_build_foreign_factory(sys::state &state, dcon::state_instance_id st)
table::column< dcon::trade_route_id > trade_route_2
void province_owner_rgo_draw_tooltip(sys::state &state, text::columnar_layout &contents, dcon::province_id prov_id) noexcept
table::column< dcon::trade_route_id > trade_route_3
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
sys::date expiration
Definition: modifiers.hpp:321
dcon::modifier_id mod_id
Definition: modifiers.hpp:322
static constexpr uint32_t modifier_definition_size
Definition: modifiers.hpp:231
Holds important data about the game world, state, and other data regarding windowing,...
std::vector< item_type > data
Definition: table.hpp:70
element_type get_element_type() const
union ui::element_data::internal_data data
dcon::gfx_object_id gfx_object
element_base * topbar_subwindow
std::unique_ptr< element_base > root
element_base * province_window
element_base * population_subwindow
element_base * build_province_unit_window