Project Alice
Loading...
Searching...
No Matches
gui_unit_panel.hpp
Go to the documentation of this file.
1#pragma once
2
6#include "text.hpp"
7#include "prng.hpp"
10#include "gui_unit_grid_box.hpp"
11
12namespace ui {
13
15
17public:
18 void button_action(sys::state& state) noexcept override {
20 }
21
24 }
25
26 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
27 text::add_line(state, contents, "deselect_unit");
28 }
29};
30
31template<class T>
33public:
34 void button_action(sys::state& state) noexcept override {
35 // No selected Regiments or Ships
36 if(!state.selected_regiments[0] && !state.selected_ships[0]) {
38 }
39 else {
40 auto content = retrieve<T>(state, parent);
41 if constexpr(std::is_same_v<T, dcon::army_id>) {
42 std::array<dcon::regiment_id, command::num_packed_units> tosplit{};
43 for(size_t i = 0; i < state.selected_regiments.size(); i++) {
44 if(state.selected_regiments[i]) {
45 tosplit[i % command::num_packed_units] = state.selected_regiments[i];
46 } else {
47 break;
48 }
50 command::mark_regiments_to_split(state, state.local_player_nation, tosplit);
51 tosplit = {};
52 }
53 }
54
55 command::mark_regiments_to_split(state, state.local_player_nation, tosplit);
56 command::split_army(state, state.local_player_nation, content);
58 } else if constexpr(std::is_same_v<T, dcon::navy_id>) {
59 std::array<dcon::ship_id, command::num_packed_units> tosplit{};
60 for(size_t i = 0; i < state.selected_ships.size(); i++) {
61 if(state.selected_ships[i]) {
62 tosplit[i % command::num_packed_units] = state.selected_ships[i];
63 }
64 else {
65 break;
66 }
68 command::mark_ships_to_split(state, state.local_player_nation, tosplit);
69 tosplit = {};
70 }
71 }
72
73 command::mark_ships_to_split(state, state.local_player_nation, tosplit);
74 command::split_navy(state, state.local_player_nation, content);
76 }
77 }
78 }
79
82 }
83
84 void on_update(sys::state& state) noexcept override {
85 auto content = retrieve<T>(state, parent);
86 if constexpr(std::is_same_v<T, dcon::army_id>) {
87 disabled = !command::can_split_army(state, state.local_player_nation, content);
88 } else if constexpr(std::is_same_v<T, dcon::navy_id>) {
89 disabled = !command::can_split_navy(state, state.local_player_nation, content);
90 }
91 }
92
93 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
94 text::add_line(state, contents, "new_unit");
95 }
96};
97
98template<class T>
100public:
101 void button_action(sys::state& state) noexcept override {
102 auto content = retrieve<T>(state, parent);
103 if constexpr(std::is_same_v<T, dcon::army_id>) {
104 command::evenly_split_army(state, state.local_player_nation, content);
105 } else {
106 command::evenly_split_navy(state, state.local_player_nation, content);
107 }
108 state.select(content); //deselect original
109 }
110
111 void on_update(sys::state& state) noexcept override {
112 auto content = retrieve<T>(state, parent);
113 if constexpr(std::is_same_v<T, dcon::army_id>) {
114 disabled = !command::can_evenly_split_army(state, state.local_player_nation, content);
115 } else {
116 disabled = !command::can_evenly_split_navy(state, state.local_player_nation, content);
117 }
118 }
119
122 }
123
124 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
125 text::add_line(state, contents, "splitinhalf");
126 }
127};
128
129template<class T>
131public:
132 void button_action(sys::state& state) noexcept override {
133 auto content = retrieve<T>(state, parent);
134 if constexpr(std::is_same_v<T, dcon::army_id>) {
135 command::delete_army(state, state.local_player_nation, content);
136 } else {
137 command::delete_navy(state, state.local_player_nation, content);
138 }
140 }
141
142 void on_update(sys::state& state) noexcept override {
143 auto content = retrieve<T>(state, parent);
144 if constexpr(std::is_same_v<T, dcon::army_id>) {
145 disabled = !command::can_delete_army(state, state.local_player_nation, content);
146 } else {
147 disabled = !command::can_delete_navy(state, state.local_player_nation, content);
148 }
149 }
150
153 }
154
155 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
156 text::add_line(state, contents, "disband_unit");
157 }
158};
159
161public:
162 void on_update(sys::state& state) noexcept override {
163 disabled = !command::can_disband_undermanned_regiments(state, state.local_player_nation, retrieve<dcon::army_id>(state, parent));
164 color = sys::pack_color(255, 196, 196);
165 if(state.user_settings.color_blind_mode == sys::color_blind_mode::deutan || state.user_settings.color_blind_mode == sys::color_blind_mode::protan) {
166 color = sys::pack_color(255, 255, 255); //remap to blue
167 }
168 }
169 void button_action(sys::state& state) noexcept override {
170 command::disband_undermanned_regiments(state, state.local_player_nation, retrieve<dcon::army_id>(state, parent));
171 }
174 }
175 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
176 text::add_line(state, contents, "disband_too_small_unit");
177 }
178};
179
181public:
182 void on_update(sys::state& state) noexcept override {
183 disabled = !(state.selected_regiments[0] || state.selected_ships[0]);
184 }
185 void button_action(sys::state& state) noexcept override {
187 }
190 }
191 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
192 text::add_line(state, contents, "unit_upgrade_button");
193 }
194};
195
196template<typename T>
198public:
199 void on_update(sys::state& state) noexcept override {
200 auto content = retrieve<T>(state, parent);
201 set_text(state, std::string(state.to_string_view(dcon::fatten(state.world, content).get_name())));
202 }
203};
204
205template<typename T>
207 void on_update(sys::state& state) noexcept override {
208 auto content = retrieve<T>(state, parent);
209 if constexpr(std::is_same_v<T, dcon::army_id>) {
210 auto fat = dcon::fatten(state.world, content);
211 set_text(state, std::string(state.to_string_view(fat.get_general_from_army_leadership().get_name())));
212 } else {
213 auto fat = dcon::fatten(state.world, content);
214 set_text(state, std::string(state.to_string_view(fat.get_admiral_from_navy_leadership().get_name())));
215 }
216 }
217};
218
219template<class T>
221public:
222
225 }
226
227 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
228 auto unit = retrieve<T>(state, parent);
229 dcon::leader_id lid;
230 if constexpr(std::is_same_v<T, dcon::army_id>) {
231 lid = state.world.army_get_general_from_army_leadership(unit);
232 } else {
233 lid = state.world.navy_get_admiral_from_navy_leadership(unit);
234 }
235 if(lid)
236 display_leader_full(state, lid, contents, 0);
237 }
238
239
240 void button_action(sys::state& state) noexcept override {
241 auto unit = retrieve<T>(state, parent);
243 if constexpr(std::is_same_v<T, dcon::army_id>) {
244 if(command::can_change_general(state, state.local_player_nation, unit, dcon::leader_id{}))
245 open_leader_selection(state, unit, dcon::navy_id{}, location.x, location.y);
246 } else {
247 if(command::can_change_admiral(state, state.local_player_nation, unit, dcon::leader_id{}))
248 open_leader_selection(state, dcon::army_id{}, unit, location.x, location.y);
249 }
250 }
251};
252
253template<class T>
255public:
256 dcon::gfx_object_id default_img;
257
258 void on_update(sys::state& state) noexcept override {
259 if(!default_img) {
264 }
265
266 auto unit = retrieve<T>(state, parent);
267 dcon::leader_id lid;
268 if constexpr(std::is_same_v<T, dcon::army_id>) {
269 lid = state.world.army_get_general_from_army_leadership(unit);
270 disabled = !command::can_change_general(state, state.local_player_nation, unit, dcon::leader_id{});
271 } else {
272 lid = state.world.navy_get_admiral_from_navy_leadership(unit);
273 disabled = !command::can_change_admiral(state, state.local_player_nation, unit, dcon::leader_id{});
274 }
275
276 auto pculture = state.world.nation_get_primary_culture(state.local_player_nation);
277 auto ltype = pculture.get_group_from_culture_group_membership().get_leader();
278
279 if(ltype && lid) {
280 auto admiral = state.world.leader_get_is_admiral(lid);
281 if(admiral) {
282 auto arange = ltype.get_admirals();
283 if(arange.size() > 0) {
284 auto rval = rng::get_random(state, uint32_t(state.world.leader_get_since(lid).value), uint32_t(lid.value));
285 auto in_range = rng::reduce(uint32_t(rval), arange.size());
287 base_data.data.image.gfx_object = arange[in_range];
289 base_data.data.button.button_image = arange[in_range];
290 }
291 } else {
292 auto grange = ltype.get_generals();
293 if(grange.size() > 0) {
294 auto rval = rng::get_random(state, uint32_t(state.world.leader_get_since(lid).value), uint32_t(lid.value));
295 auto in_range = rng::reduce(uint32_t(rval), grange.size());
297 base_data.data.image.gfx_object = grange[in_range];
299 base_data.data.button.button_image = grange[in_range];
300 }
301 }
302 } else {
307 }
308 }
309
312 }
313
314 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
315 auto unit = retrieve<T>(state, parent);
316 dcon::leader_id lid;
317 if constexpr(std::is_same_v<T, dcon::army_id>) {
318 lid = state.world.army_get_general_from_army_leadership(unit);
319 } else {
320 lid = state.world.navy_get_admiral_from_navy_leadership(unit);
321 }
322 if(lid)
323 display_leader_full(state, lid, contents, 0);
324 }
325
326
327 void button_action(sys::state& state) noexcept override {
328 auto unit = retrieve<T>(state, parent);
330 if constexpr(std::is_same_v<T, dcon::army_id>) {
331 open_leader_selection(state, unit, dcon::navy_id{}, location.x + base_data.size.x, location.y);
332 } else {
333 open_leader_selection(state, dcon::army_id{}, unit, location.x + base_data.size.x, location.y);
334 }
335 }
336};
337
338template<class T>
340public:
341 void on_update(sys::state& state) noexcept override {
342 auto content = retrieve<T>(state, parent);
343 if constexpr(std::is_same_v<T, dcon::army_id>) {
344 set_text(state, text::produce_simple_string(state, dcon::fatten(state.world, content).get_location_from_army_location().get_name()));
345 } else {
346 set_text(state, text::produce_simple_string(state, dcon::fatten(state.world, content).get_location_from_navy_location().get_name()));
347 }
348 }
349};
350template<class T>
352public:
355 }
356 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
357 text::add_line(state, contents, "uw_loc_iro");
358 }
359 void button_action(sys::state& state) noexcept override {
360 auto content = retrieve<T>(state, parent);
361 if constexpr(std::is_same_v<T, dcon::army_id>) {
362 auto p = dcon::fatten(state.world, content).get_location_from_army_location();
363 state.map_state.center_map_on_province(state, p);
364 } else {
365 auto p = dcon::fatten(state.world, content).get_location_from_navy_location();
366 state.map_state.center_map_on_province(state, p);
367 }
368 }
369};
370
371template<class T>
373public:
374 void on_update(sys::state& state) noexcept override {
375 auto content = retrieve<T>(state, parent);
376
377 float total_strength = 0.0f;
378 int32_t unit_count = 0;
379 if constexpr(std::is_same_v<T, dcon::army_id>) {
380 state.world.army_for_each_army_membership_as_army(content, [&](dcon::army_membership_id nmid) {
381 auto regiment = dcon::fatten(state.world, state.world.army_membership_get_regiment(nmid));
382 total_strength += regiment.get_strength();
383 ++unit_count;
384 });
385 } else {
386 state.world.navy_for_each_navy_membership_as_navy(content, [&](dcon::navy_membership_id nmid) {
387 auto ship = dcon::fatten(state.world, state.world.navy_membership_get_ship(nmid));
388 total_strength += ship.get_strength();
389 ++unit_count;
390 });
391 }
392 total_strength /= static_cast<float>(unit_count);
393 progress = total_strength;
394 }
395
398 }
399
400 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
401 auto content = retrieve<T>(state, parent);
402 float total_strength = 0.0f;
403 int32_t unit_count = 0;
404 if constexpr(std::is_same_v<T, dcon::army_id>) {
405 state.world.army_for_each_army_membership_as_army(content, [&](dcon::army_membership_id nmid) {
406 auto regiment = dcon::fatten(state.world, state.world.army_membership_get_regiment(nmid));
407 total_strength += regiment.get_strength();
408 ++unit_count;
409 });
410 } else {
411 state.world.navy_for_each_navy_membership_as_navy(content, [&](dcon::navy_membership_id nmid) {
412 auto ship = dcon::fatten(state.world, state.world.navy_membership_get_ship(nmid));
413 total_strength += ship.get_strength();
414 ++unit_count;
415 });
416 }
417 total_strength /= static_cast<float>(unit_count);
418
419 auto box = text::open_layout_box(contents, 0);
420 text::localised_format_box(state, contents, box, std::string_view("curr_comb_str"));
422 text::close_layout_box(contents, box);
423 }
424};
425
426template<class T>
428public:
429 void on_update(sys::state& state) noexcept override {
430 auto content = retrieve<T>(state, parent);
431
432 float total_org = 0.0f;
433 int32_t unit_count = 0;
434 if constexpr(std::is_same_v<T, dcon::army_id>) {
435 state.world.army_for_each_army_membership_as_army(content, [&](dcon::army_membership_id nmid) {
436 auto regiment = dcon::fatten(state.world, state.world.army_membership_get_regiment(nmid));
437 total_org += regiment.get_org();
438 ++unit_count;
439 });
440 } else {
441 state.world.navy_for_each_navy_membership_as_navy(content, [&](dcon::navy_membership_id nmid) {
442 auto ship = dcon::fatten(state.world, state.world.navy_membership_get_ship(nmid));
443 total_org += ship.get_org();
444 ++unit_count;
445 });
446 }
447 total_org /= static_cast<float>(unit_count);
448 progress = total_org;
449 }
450
453 }
454
455 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
456 auto content = retrieve<T>(state, parent);
457 float total_org = 0.0f;
458 int32_t unit_count = 0;
459 if constexpr(std::is_same_v<T, dcon::army_id>) {
460 state.world.army_for_each_army_membership_as_army(content, [&](dcon::army_membership_id nmid) {
461 auto regiment = dcon::fatten(state.world, state.world.army_membership_get_regiment(nmid));
462 total_org += regiment.get_org();
463 ++unit_count;
464 });
465 } else {
466 state.world.navy_for_each_navy_membership_as_navy(content, [&](dcon::navy_membership_id nmid) {
467 auto ship = dcon::fatten(state.world, state.world.navy_membership_get_ship(nmid));
468 total_org += ship.get_org();
469 ++unit_count;
470 });
471 }
472 total_org /= static_cast<float>(unit_count);
473
474 auto box = text::open_layout_box(contents, 0);
475 text::localised_format_box(state, contents, box, std::string_view("curr_comb_org"));
477 text::close_layout_box(contents, box);
478
479 if constexpr(std::is_same_v<T, dcon::army_id>) {
480 ui::active_modifiers_description(state, contents, state.local_player_nation, 0, sys::national_mod_offsets::land_organisation, true);
481 } else {
482 ui::active_modifiers_description(state, contents, state.local_player_nation, 0, sys::national_mod_offsets::naval_organisation, true);
483 }
484 }
485};
486
487template<class T>
489public:
490 void on_update(sys::state& state) noexcept override {
491 if constexpr(std::is_same_v<T, dcon::regiment_id>) {
492 auto regiment = retrieve<dcon::regiment_id>(state, parent);
493 frame = int(state.world.regiment_get_experience(regiment) * 10);
494 } else {
495 auto ship = retrieve<dcon::ship_id>(state, parent);
496 frame = int(state.world.ship_get_experience(ship) * 10);
497 }
498 }
499
500 void on_create(sys::state& state) noexcept override {
501 if constexpr(std::is_same_v<T, dcon::regiment_id>) {
502 auto regiment = retrieve<dcon::regiment_id>(state, parent);
503 frame = int(state.world.regiment_get_experience(regiment) * 10);
504 } else {
505 auto ship = retrieve<dcon::ship_id>(state, parent);
506 frame = int(state.world.ship_get_experience(ship) * 10);
507 }
508 }
509
512 }
513
514 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
515 if constexpr(std::is_same_v<T, dcon::regiment_id>) {
516 auto regiment = retrieve<dcon::regiment_id>(state, parent);
517 auto exp = state.world.regiment_get_experience(regiment);
518 auto box = text::open_layout_box(contents);
519 text::localised_format_box(state, contents, box, "unit_experience");
520 text::add_space_to_layout_box(state, contents, box);
522 text::close_layout_box(contents, box);
523 } else {
524 auto ship = retrieve<dcon::ship_id>(state, parent);
525 auto exp = state.world.ship_get_experience(ship);
526 auto box = text::open_layout_box(contents);
527 text::localised_format_box(state, contents, box, "unit_experience");
528 text::add_space_to_layout_box(state, contents, box);
530 text::close_layout_box(contents, box);
531 }
532 }
533};
534
535template<class T>
537 void on_update(sys::state& state) noexcept override {
538 auto content = retrieve<T>(state, parent);
539
540 int32_t total_strength = 0;
541 if constexpr(std::is_same_v<T, dcon::army_id>) {
542 state.world.army_for_each_army_membership_as_army(content, [&](dcon::army_membership_id nmid) {
543 auto regiment = dcon::fatten(state.world, state.world.army_membership_get_regiment(nmid));
544 total_strength += int32_t(regiment.get_strength() * state.defines.pop_size_per_regiment);
545 });
546 } else {
547 state.world.navy_for_each_navy_membership_as_navy(content, [&](dcon::navy_membership_id nmid) {
548 auto ship = dcon::fatten(state.world, state.world.navy_membership_get_ship(nmid));
549 ++total_strength;
550 });
551 }
552
553 set_text(state, text::prettify(total_strength));
554 }
555};
556
557template<class T>
559public:
560 bool visible = false;
561 void on_update(sys::state& state) noexcept override {
562 auto content = retrieve<T>(state, parent);
564 }
565 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
566 if(visible)
568 }
569};
570
571template<class T>
573public:
574 void on_update(sys::state& state) noexcept override {
575 auto content = retrieve<T>(state, parent);
576 auto amount = military::attrition_amount(state, content);
577 if(amount > 0)
579 else
580 set_text(state, "");
581 }
582};
583
584template<class T>
586public:
588
589 void on_update(sys::state& state) noexcept override {
590 auto content = retrieve<T>(state, parent);
591 if constexpr(std::is_same_v<T, dcon::army_id>) {
592 if(state.world.army_get_controller_from_army_control(content) == state.local_player_nation) {
593 color = sys::pack_color(210, 255, 210);
594 } else {
595 color = sys::pack_color(170, 190, 170);
596 }
597 } else {
598 if(state.world.navy_get_controller_from_navy_control(content) == state.local_player_nation) {
599 color = sys::pack_color(210, 210, 255);
600 } else {
601 color = sys::pack_color(170, 170, 190);
602 }
603 }
604 }
605
606 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
607 dcon::gfx_object_id gid;
612 }
613 if(gid) {
614 auto const& gfx_def = state.ui_defs.gfx[gid];
615 if(gfx_def.primary_texture_handle) {
616 if(gfx_def.number_of_frames > 1) {
618 gfx_def.number_of_frames, float(x), float(y), float(base_data.size.x), float(base_data.size.y),
620 ogl::get_texture_handle(state, gfx_def.primary_texture_handle, gfx_def.is_partially_transparent()),
621 base_data.get_rotation(), gfx_def.is_vertically_flipped(),
622 state.world.locale_get_native_rtl(state.font_collection.get_current_locale()));
623 } else {
624 ogl::render_tinted_textured_rect(state, float(x), float(y), float(base_data.size.x), float(base_data.size.y),
626 ogl::get_texture_handle(state, gfx_def.primary_texture_handle, gfx_def.is_partially_transparent()),
627 base_data.get_rotation(), gfx_def.is_vertically_flipped(),
628 state.world.locale_get_native_rtl(state.font_collection.get_current_locale()));
629 }
630 }
631 }
632 }
633};
634
635template<class T>
637 dcon::gfx_object_id disband_gfx{};
638 unit_selection_disband_too_small_button* disband_too_small_btn = nullptr;
639public:
642
643 void on_create(sys::state& state) noexcept override {
644 {
645 if constexpr(std::is_same_v<T, dcon::army_id>) {
646 auto win2 = make_element_by_type<unit_reorg_window<T, dcon::regiment_id>>(state, state.ui_state.defs_by_name.find(state.lookup_key("reorg_window"))->second.definition);
647 win2->base_data.position.y = base_data.position.y - 29;
648 win2->set_visible(state, false);
649 reorg_window = win2.get();
650 add_child_to_front(std::move(win2));
651 } else {
652 auto win2 = make_element_by_type<unit_reorg_window<T, dcon::ship_id>>(state, state.ui_state.defs_by_name.find(state.lookup_key("reorg_window"))->second.definition);
653 win2->base_data.position.y = base_data.position.y - 29;
654 win2->set_visible(state, false);
655 reorg_window = win2.get();
656 add_child_to_front(std::move(win2));
657 }
658 }
660 if(disband_too_small_btn && disband_gfx) {
661 disband_too_small_btn->base_data.data.button.button_image = disband_gfx;
662 }
663 }
664
665 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
666 if(name == "unitpanel_bg") {
667 return make_element_by_type<unit_panel_dynamic_tinted_bg<T>>(state, id);
668 } else if(name == "leader_prestige_icon") {
669 return make_element_by_type<invisible_element>(state, id);
670 } else if(name == "leader_prestige_bar") {
671 return make_element_by_type<leader_prestige_progress_bar<T>>(state, id);
672 } else if(name == "prestige_bar_frame") {
673 return make_element_by_type<image_element_base>(state, id);
674 } else if(name == "unitname") {
675 auto ptr = make_element_by_type<unit_selection_unit_name_text<T>>(state, id);
676 ptr->base_data.position.x += 9;
677 ptr->base_data.position.y += 4;
678 return ptr;
679 } else if(name == "only_unit_from_selection_button") {
680 return make_element_by_type<invisible_element>(state, id);
681 } else if(name == "remove_unit_from_selection_button") {
682 return make_element_by_type<unit_selection_close_button>(state, id);
683 } else if(name == "newunitbutton") {
684 return make_element_by_type<unit_selection_new_unit_button<T>>(state, id);
685 } else if(name == "splitinhalf") {
686 return make_element_by_type<unit_selection_split_in_half_button<T>>(state, id);
687 } else if(name == "disbandbutton") {
688 auto ptr = make_element_by_type<unit_selection_disband_button<T>>(state, id);
689 disband_gfx = ptr->base_data.data.button.button_image;
690 return ptr;
691 } else if(name == "disbandtoosmallbutton") {
692 if constexpr(std::is_same_v<T, dcon::army_id>) {
693 auto ptr = make_element_by_type<unit_selection_disband_too_small_button>(state, id);
694 disband_too_small_btn = ptr.get();
695 return ptr;
696 } else {
697 return make_element_by_type<invisible_element>(state, id);
698 }
699 } else if(name == "str_bar") {
700 return make_element_by_type<unit_selection_str_bar<T>>(state, id);
701 } else if(name == "org_bar") {
702 return make_element_by_type<unit_selection_org_bar<T>>(state, id);
703 } else if(name == "unitattrition_icon") {
704 return make_element_by_type<unit_selection_attrition_icon<T>>(state, id);
705 } else if(name == "unitattrition") {
706 return make_element_by_type<unit_selection_attrition_amount<T>>(state, id);
707 } else if(name == "unitstrength") {
708 return make_element_by_type<unit_selection_total_str_text<T>>(state, id);
709 } else if(name == "unitlocation") {
710 return make_element_by_type<unit_selection_unit_location_text<T>>(state, id);
711 } else if(name == "unit_location_button") {
712 return make_element_by_type<unit_selection_unit_location_button<T>>(state, id);
713 } else if(name == "unitleader") {
714 return make_element_by_type<unit_selection_leader_name<T>>(state, id);
715 } else if(name == "leader_button") {
716 return make_element_by_type<unit_selection_change_leader_button<T>>(state, id);
717 } else if(name == "unit_activity") {
718 return make_element_by_type<image_element_base>(state, id);
719 } else if(name == "leader_photo") {
720 return make_element_by_type<unit_selection_leader_image<T>>(state, id);
721 } else if(name == "unit_upgrade_button") {
722 auto ptr = make_element_by_type<unit_selection_unit_upgrade_button>(state, id);
723 move_child_to_front(ptr.get());
724 return ptr;
725 } else {
726 return nullptr;
727 }
728 }
729
730 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
731 if(payload.holds_type<element_selection_wrapper<unitpanel_action>>()) {
732 auto action = any_cast<element_selection_wrapper<unitpanel_action>>(payload).data;
733 switch(action) {
735 // Bucket Carry, we dont handle this, but the parent does
736 parent->impl_get(state, payload);
737 // Tell reorg window to clean up after itself
739 reorg_window->impl_get(state, cpayload);
740 break;
744 break;
746 break;
748 {
750 }
751 default: {
752 break;
753 }
754 }
756 }
758 }
759};
760
761template<std::size_t N>
763private:
764 simple_text_element_base* unitamount_text = nullptr;
765 simple_text_element_base* unitstrength_text = nullptr;
766public:
767 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
768 if(name == "unit_amount") {
769 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
770 unitamount_text = ptr.get();
771 return ptr;
772 } else if(name == "unit_strength") {
773 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
774 unitstrength_text = ptr.get();
775 return ptr;
776 } else if(name == "unit_icon") {
777 auto ptr = make_element_by_type<image_element_base>(state, id);
778 ptr->frame = N;
779 return ptr;
780 } else {
781 return nullptr;
782 }
783 }
784
785 void on_update(sys::state& state) noexcept override {
786 if(parent) {
787 uint16_t totalunits = 0;
788 uint32_t totalpops = 0;
789
790 if(state.selected_army_group) {
791 auto group = fatten(state.world, state.selected_army_group);
792 for(auto regiment_membership : group.get_automated_army_group_membership_regiment()) {
793 auto fat = regiment_membership.get_regiment().get_regiment_from_automation();
794 auto strenght = fat.get_strength() * state.defines.pop_size_per_regiment;
795 unitstrength_text->set_visible(state, true);
796
797 dcon::unit_type_id utid = fat.get_type();
798 auto result = utid ? state.military_definitions.unit_base_definitions[utid].type : military::unit_type::infantry;
799 if constexpr(N == 0) {
800 if(result == military::unit_type::infantry) {
801 totalunits++;
802 totalpops += uint32_t(strenght);
803 }
804 } else if constexpr(N == 1) {
805 if(result == military::unit_type::cavalry) {
806 totalunits++;
807 totalpops += uint32_t(strenght);
808 }
809 } else if constexpr(N == 2) {
811 totalunits++;
812 totalpops += uint32_t(strenght);
813 }
814 }
815 }
816 }
817 unitamount_text->set_text(state, text::format_float(totalunits, 0));
818 unitstrength_text->set_text(state, text::format_wholenum(totalpops));
819 }
820 }
821};
822
823template<std::size_t N>
825private:
826 simple_text_element_base* unitamount_text = nullptr;
827 simple_text_element_base* unitstrength_text = nullptr;
828public:
829 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
830 if(name == "unit_amount") {
831 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
832 unitamount_text = ptr.get();
833 return ptr;
834 } else if(name == "unit_strength") {
835 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
836 unitstrength_text = ptr.get();
837 return ptr;
838 } else if(name == "unit_icon") {
839 auto ptr = make_element_by_type<image_element_base>(state, id);
840 ptr->frame = 3 + N;
841 return ptr;
842 } else {
843 return nullptr;
844 }
845 }
846
847 void on_update(sys::state& state) noexcept override {
848 if(parent) {
849 unitstrength_text->set_visible(state, false);
850 uint16_t total = 0;
851
852 if(state.selected_army_group) {
853 auto army_group = fatten(state.world, state.selected_army_group);
854
855 for(auto navy_membership : army_group.get_automated_army_group_membership_navy()) {
856 auto fat = navy_membership.get_navy();
857
858 for(auto n : fat.get_navy_membership()) {
859 dcon::unit_type_id utid = n.get_ship().get_type();
860 auto result = utid ? state.military_definitions.unit_base_definitions[utid].type : military::unit_type::infantry;
861 if constexpr(N == 0) {
862 if(result == military::unit_type::big_ship) {
863 total++;
864 }
865 } else if constexpr(N == 1) {
866 if(result == military::unit_type::light_ship) {
867 total++;
868 }
869 } else if constexpr(N == 2) {
870 if(result == military::unit_type::transport) {
871 total++;
872 }
873 }
874 }
875 }
876 }
877
878 unitamount_text->set_text(state, text::format_float(total, 0));
879 }
880 }
881};
882
883template<class T, std::size_t N>
885private:
886 simple_text_element_base* unitamount_text = nullptr;
887 simple_text_element_base* unitstrength_text = nullptr;
888public:
889 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
890 if(name == "unit_amount") {
891 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
892 unitamount_text = ptr.get();
893 return ptr;
894 } else if(name == "unit_strength") {
895 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
896 unitstrength_text = ptr.get();
897 return ptr;
898 } else if(name == "unit_icon") {
899 auto ptr = make_element_by_type<image_element_base>(state, id);
900 if constexpr(std::is_same_v<T, dcon::army_id>) {
901 ptr->frame = N;
902 } else {
903 ptr->frame = 3 + N;
904 }
905 return ptr;
906 } else {
907 return nullptr;
908 }
909 }
910
911 void on_update(sys::state& state) noexcept override {
912 if(parent) {
913 Cyto::Any payload = T{};
914 parent->impl_get(state, payload);
915 auto content = any_cast<T>(payload);
916 auto fat = dcon::fatten(state.world, content);
917
918 if constexpr(std::is_same_v<T, dcon::army_id>) {
919 unitstrength_text->set_visible(state, true);
920
921 uint16_t totalunits = 0;
922 uint32_t totalpops = 0;
923 for(auto n : fat.get_army_membership()) {
924 dcon::unit_type_id utid = n.get_regiment().get_type();
925 auto result = utid ? state.military_definitions.unit_base_definitions[utid].type : military::unit_type::infantry;
926 if constexpr(N == 0) {
927 if(result == military::unit_type::infantry) {
928 totalunits++;
929 totalpops += uint32_t(state.world.regiment_get_strength(n.get_regiment().id) * state.defines.pop_size_per_regiment);
930 }
931 } else if constexpr(N == 1) {
932 if(result == military::unit_type::cavalry) {
933 totalunits++;
934 totalpops += uint32_t(state.world.regiment_get_strength(n.get_regiment().id) * state.defines.pop_size_per_regiment);
935 }
936 } else if constexpr(N == 2) {
938 totalunits++;
939 totalpops += uint32_t(state.world.regiment_get_strength(n.get_regiment().id) * state.defines.pop_size_per_regiment);
940 }
941 }
942 }
943 unitamount_text->set_text(state, text::format_float(totalunits, 0));
944 unitstrength_text->set_text(state, text::format_wholenum(totalpops));
945 } else {
946 unitstrength_text->set_visible(state, false);
947 uint16_t total = 0;
948 for(auto n : fat.get_navy_membership()) {
949 dcon::unit_type_id utid = n.get_ship().get_type();
950 auto result = utid ? state.military_definitions.unit_base_definitions[utid].type : military::unit_type::infantry;
951 if constexpr(N == 0) {
952 if(result == military::unit_type::big_ship) {
953 total++;
954 }
955 } else if constexpr(N == 1) {
956 if(result == military::unit_type::light_ship) {
957 total++;
958 }
959 } else if constexpr(N == 2) {
960 if(result == military::unit_type::transport) {
961 total++;
962 }
963 }
964 }
965 unitamount_text->set_text(state, text::format_float(total, 0));
966 }
967 }
968 }
969};
970
971template<class T>
973public:
974 void on_update(sys::state& state) noexcept override {
975 if(parent) {
976 Cyto::Any payload = T{};
977 parent->impl_get(state, payload);
978 T content = any_cast<T>(payload);
979 dcon::unit_type_id utid = dcon::fatten(state.world, content).get_type();
980 if(utid)
981 frame = state.military_definitions.unit_base_definitions[utid].icon - 1;
982
983 if constexpr(std::is_same_v<T, dcon::regiment_id>) {
984 dcon::regiment_id reg = any_cast<dcon::regiment_id>(payload);
985
986 if(std::find(state.selected_regiments.begin(), state.selected_regiments.end(), reg) != state.selected_regiments.end()) {
987 color = sys::pack_color(255, 200, 200);
988 } else {
989 color = sys::pack_color(255, 255, 255);
990 }
991 }
992 else if constexpr(std::is_same_v<T, dcon::ship_id>) {
993 dcon::ship_id sh = any_cast<dcon::ship_id>(payload);
994
995 if(std::find(state.selected_ships.begin(), state.selected_ships.end(), sh) != state.selected_ships.end()) {
996 color = sys::pack_color(255, 200, 200);
997 } else {
998 color = sys::pack_color(255, 255, 255);
999 }
1000 }
1001 }
1002 }
1003
1004 message_result on_lbutton_down(sys::state& state, int32_t x, int32_t y, sys::key_modifiers mods) noexcept override {
1005 if constexpr(std::is_same_v<T, dcon::regiment_id>) {
1006 if(parent) {
1007 Cyto::Any payload = dcon::regiment_id{};
1008 parent->impl_get(state, payload);
1009 dcon::regiment_id reg = any_cast<dcon::regiment_id>(payload);
1010
1015 } else {
1020 }
1021 }
1022 }
1023 else if constexpr(std::is_same_v<T, dcon::ship_id>) {
1024 if(parent) {
1025 Cyto::Any payload = dcon::ship_id{};
1026 parent->impl_get(state, payload);
1027 dcon::ship_id reg = any_cast<dcon::ship_id>(payload);
1028
1033 } else {
1038 }
1039 }
1040 }
1041
1043 }
1044
1045 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
1046 dcon::gfx_object_id gid;
1051 }
1052 if(gid) {
1053 auto const& gfx_def = state.ui_defs.gfx[gid];
1054 if(gfx_def.primary_texture_handle) {
1055 if(gfx_def.number_of_frames > 1) {
1057 gfx_def.number_of_frames, float(x), float(y), float(base_data.size.x), float(base_data.size.y),
1059 ogl::get_texture_handle(state, gfx_def.primary_texture_handle, gfx_def.is_partially_transparent()),
1060 base_data.get_rotation(), gfx_def.is_vertically_flipped(),
1061 state.world.locale_get_native_rtl(state.font_collection.get_current_locale()));
1062 } else {
1063 ogl::render_tinted_textured_rect(state, float(x), float(y), float(base_data.size.x), float(base_data.size.y),
1065 ogl::get_texture_handle(state, gfx_def.primary_texture_handle, gfx_def.is_partially_transparent()),
1066 base_data.get_rotation(), gfx_def.is_vertically_flipped(),
1067 state.world.locale_get_native_rtl(state.font_collection.get_current_locale()));
1068 }
1069 }
1070 }
1071 }
1072};
1073
1075public:
1076 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1077 if(name == "select") {
1078 return make_element_by_type<subunit_entry_bg<dcon::regiment_id>>(state, id);
1079 } else if(name == "select_naval") {
1080 return make_element_by_type<invisible_element>(state, id);
1081 } else if(name == "sunit_icon") {
1082 return make_element_by_type<subunit_details_type_icon<dcon::regiment_id>>(state, id);
1083 } else if(name == "subunit_name") {
1084 return make_element_by_type<subunit_details_name<dcon::regiment_id>>(state, id);
1085 } else if(name == "subunit_type") {
1086 return make_element_by_type<subunit_details_type_text<dcon::regiment_id>>(state, id);
1087 } else if(name == "subunit_amount") {
1088 return make_element_by_type<subunit_details_regiment_amount>(state, id);
1089 } else if(name == "subunit_amount_naval") {
1090 return make_element_by_type<invisible_element>(state, id);
1091 } else if(name == "connected_pop") {
1092 return make_element_by_type<regiment_pop_icon>(state, id);
1093 } else if(name == "rebel_faction") {
1094 return make_element_by_type<invisible_element>(state, id);
1095 } else if(name == "unit_experience") {
1096 return make_element_by_type<unit_experience_bar<dcon::regiment_id>>(state, id);
1097 } else if(name == "org_bar") {
1098 return make_element_by_type<subunit_organisation_progress_bar<dcon::regiment_id>>(state, id);
1099 } else if(name == "str_bar") {
1100 return make_element_by_type<subunit_strength_progress_bar<dcon::regiment_id>>(state, id);
1101 } else {
1102 return nullptr;
1103 }
1104 }
1105};
1106
1108public:
1109 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1110 if(name == "select") {
1111 return make_element_by_type<invisible_element>(state, id);
1112 } else if(name == "select_naval") {
1113 return make_element_by_type<subunit_entry_bg<dcon::ship_id>>(state, id);
1114 } else if(name == "sunit_icon") {
1115 return make_element_by_type<subunit_details_type_icon<dcon::ship_id>>(state, id);
1116 } else if(name == "subunit_name") {
1117 return make_element_by_type<subunit_details_name<dcon::ship_id>>(state, id);
1118 } else if(name == "subunit_type") {
1119 return make_element_by_type<subunit_details_type_text<dcon::ship_id>>(state, id);
1120 } else if(name == "subunit_amount") {
1121 return make_element_by_type<invisible_element>(state, id);
1122 } else if(name == "subunit_amount_naval") {
1123 return make_element_by_type<subunit_details_ship_amount>(state, id);
1124 } else if(name == "connected_pop") {
1125 return make_element_by_type<invisible_element>(state, id);
1126 } else if(name == "rebel_faction") {
1127 return make_element_by_type<invisible_element>(state, id);
1128 } else if(name == "unit_experience") {
1129 return make_element_by_type<unit_experience_bar<dcon::ship_id>>(state, id);
1130 } else if(name == "org_bar") {
1131 return make_element_by_type<subunit_organisation_progress_bar<dcon::ship_id>>(state, id);
1132 } else if(name == "str_bar") {
1133 return make_element_by_type<subunit_strength_progress_bar<dcon::ship_id>>(state, id);
1134 } else {
1135 return nullptr;
1136 }
1137 }
1138};
1139
1140class unit_details_army_listbox : public listbox_element_base<subunit_details_entry_regiment, dcon::regiment_id> {
1141protected:
1142 std::string_view get_row_element_name() override {
1143 return "subunit_entry";
1144 }
1145
1146 dcon::army_id cached_id;
1147
1148public:
1149 void on_create(sys::state& state) noexcept override {
1150 base_data.size.y += state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("subunit_entry"))->second.definition].size.y; //nudge - allows for the extra element in the lb
1152 }
1153
1154 void on_update(sys::state& state) noexcept override {
1155 auto content = retrieve<dcon::army_id>(state, parent);
1156
1157 if(content != cached_id) {
1158 cached_id = content;
1160 }
1161
1162 row_contents.clear();
1163 state.world.army_for_each_army_membership_as_army(content, [&](dcon::army_membership_id amid) {
1164 auto rid = state.world.army_membership_get_regiment(amid);
1165 row_contents.push_back(rid);
1166 });
1167 std::sort(row_contents.begin(), row_contents.end(), [&](dcon::regiment_id a, dcon::regiment_id b) {
1168 auto av = state.world.regiment_get_type(a).index();
1169 auto bv = state.world.regiment_get_type(b).index();
1170 if(av != bv)
1171 return av > bv;
1172 else
1173 return a.index() < b.index();
1174 });
1175 update(state);
1176 }
1177};
1178class unit_details_navy_listbox : public listbox_element_base<subunit_details_entry_ship, dcon::ship_id> {
1179protected:
1180 std::string_view get_row_element_name() override {
1181 return "subunit_entry";
1182 }
1183
1184public:
1185 void on_create(sys::state& state) noexcept override {
1186 base_data.size.y += state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("subunit_entry"))->second.definition].size.y; //nudge - allows for the extra element in the lb
1188 }
1189
1190 void on_update(sys::state& state) noexcept override {
1191 auto content = retrieve<dcon::navy_id>(state, parent);
1192 row_contents.clear();
1193 state.world.navy_for_each_navy_membership_as_navy(content, [&](dcon::navy_membership_id nmid) {
1194 auto sid = state.world.navy_membership_get_ship(nmid);
1195 row_contents.push_back(sid);
1196 });
1197 std::sort(row_contents.begin(), row_contents.end(), [&](dcon::ship_id a, dcon::ship_id b) {
1198 auto av = state.world.ship_get_type(a).index();
1199 auto bv = state.world.ship_get_type(b).index();
1200 if(av != bv)
1201 return av > bv;
1202 else
1203 return a.index() < b.index();
1204 });
1205 update(state);
1206 }
1207};
1208
1210public:
1211 bool visible = false;
1212
1213 void button_action(sys::state& state) noexcept override {
1214 auto a = retrieve<dcon::army_id>(state, parent);
1215 auto p = state.world.army_get_location_from_army_location(a);
1216 int32_t max_cap = 0;
1217 for(auto n : state.world.province_get_navy_location(p)) {
1218 if(n.get_navy().get_controller_from_navy_control() == state.local_player_nation &&
1219 !bool(n.get_navy().get_battle_from_navy_battle_participation())) {
1220 max_cap = std::max(military::free_transport_capacity(state, n.get_navy()), max_cap);
1221 }
1222 }
1223 if(!military::can_embark_onto_sea_tile(state, state.local_player_nation, p, a)
1224 && max_cap > 0) { //require splitting
1225 auto regs = state.world.army_get_army_membership(a);
1226 int32_t army_cap = int32_t(regs.end() - regs.begin());
1227 int32_t to_split = army_cap - max_cap;
1228 //can mark 10 regiments to be split at a time
1229 std::array<dcon::regiment_id, command::num_packed_units> data;
1230 int32_t i = 0;
1231 data.fill(dcon::regiment_id{});
1232 for(auto reg : state.world.army_get_army_membership(a)) {
1233 if(to_split == 0)
1234 break;
1235 //
1236 data[i] = reg.get_regiment();
1237 ++i;
1238 if(i >= int32_t(command::num_packed_units)) { //reached max allowed
1239 command::mark_regiments_to_split(state, state.local_player_nation, data);
1240 data.fill(dcon::regiment_id{});
1241 i = 0;
1242 }
1243 //
1244 --to_split;
1245 }
1246 if(i > 0) { //leftovers
1247 command::mark_regiments_to_split(state, state.local_player_nation, data);
1248 }
1249 command::split_army(state, state.local_player_nation, a);
1250 command::embark_army(state, state.local_player_nation, a);
1251 } else { //no split
1252 command::embark_army(state, state.local_player_nation, a);
1253 }
1254 }
1255 void on_update(sys::state& state) noexcept override {
1256 auto a = retrieve<dcon::army_id>(state, parent);
1257 auto p = state.world.army_get_location_from_army_location(a);
1258 visible = !bool(state.world.army_get_navy_from_army_transport(a)); //not already in ship
1259 disabled = true;
1260 frame = 0;
1261 if(visible) {
1262 int32_t max_cap = 0;
1263 for(auto n : state.world.province_get_navy_location(p)) {
1264 if(n.get_navy().get_controller_from_navy_control() == state.local_player_nation &&
1265 !bool(n.get_navy().get_battle_from_navy_battle_participation())) {
1266 max_cap = std::max(military::free_transport_capacity(state, n.get_navy()), max_cap);
1267 }
1268 }
1269 disabled = max_cap <= 0;
1270 //require splitting
1271 if(!military::can_embark_onto_sea_tile(state, state.local_player_nation, p, a)
1272 && max_cap > 0) {
1273 frame = 1;
1274 }
1275 }
1276 }
1279 }
1280
1281 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1282 auto n = retrieve<dcon::army_id>(state, parent);
1283 auto loc = state.world.army_get_location_from_army_location(n);
1284
1285 text::add_line(state, contents, "uw_load_is_valid");
1286 text::add_line_with_condition(state, contents, "alice_load_unload_1", military::can_embark_onto_sea_tile(state, state.local_player_nation, loc, n));
1287 }
1288 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
1289 if(visible)
1291 }
1292 message_result test_mouse(sys::state& state, int32_t x, int32_t y, mouse_probe_type t) noexcept override {
1293 if(visible)
1294 return button_element_base::test_mouse(state, x, y, t);
1296 }
1297};
1299public:
1300 bool visible = false;
1301
1302 void button_action(sys::state& state) noexcept override {
1303 auto n = retrieve<dcon::army_id>(state, parent);
1304 command::embark_army(state, state.local_player_nation, n);
1305 }
1306 void on_update(sys::state& state) noexcept override {
1307 auto n = retrieve<dcon::army_id>(state, parent);
1308 auto tprted = state.world.army_get_navy_from_army_transport(n);
1309 auto loc = state.world.army_get_location_from_army_location(n);
1310
1311 visible = bool(tprted);
1312
1313 if(loc.index() >= state.province_definitions.first_sea_province.index()) {
1314 disabled = true;
1315 } else {
1316 disabled = false;
1317 }
1318 }
1321 }
1322
1323 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1324 auto n = retrieve<dcon::army_id>(state, parent);
1325 auto tprted = state.world.army_get_navy_from_army_transport(n);
1326 auto loc = state.world.army_get_location_from_army_location(n);
1327
1328 text::add_line(state, contents, "uw_unload_valid");
1329 text::add_line_with_condition(state, contents, "alice_load_unload_2", bool(tprted));
1330 text::add_line_with_condition(state, contents, "alice_load_unload_3", loc.index() < state.province_definitions.first_sea_province.index());
1331 }
1332 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
1333 if(visible)
1335 }
1336 message_result test_mouse(sys::state& state, int32_t x, int32_t y, mouse_probe_type t) noexcept override {
1337 if(visible)
1338 return button_element_base::test_mouse(state, x, y, t);
1340 }
1341};
1343public:
1344 void button_action(sys::state& state) noexcept override {
1345 auto n = retrieve<dcon::navy_id>(state, parent);
1346 auto tprted = state.world.navy_get_army_transport(n);
1347 std::vector<dcon::army_id> tmp;
1348 for(auto t : tprted)
1349 tmp.push_back(t.get_army());
1350 for(auto a : tmp)
1351 command::embark_army(state, state.local_player_nation, a);
1352 }
1353
1354 void on_update(sys::state& state) noexcept override {
1355 auto n = retrieve<dcon::navy_id>(state, parent);
1356 auto tprted = state.world.navy_get_army_transport(n);
1357 auto loc = state.world.navy_get_location_from_navy_location(n);
1358
1359 if(tprted.begin() == tprted.end() || loc.index() >= state.province_definitions.first_sea_province.index()) {
1360 disabled = true;
1361 } else {
1362 disabled = false;
1363 }
1364 }
1365
1368 }
1369
1370 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1371 auto n = retrieve<dcon::navy_id>(state, parent);
1372 auto tprted = state.world.navy_get_army_transport(n);
1373 auto loc = state.world.navy_get_location_from_navy_location(n);
1374
1375 text::add_line(state, contents, "alice_unload_fleet");
1376 text::add_line_with_condition(state, contents, "alice_load_unload_4", tprted.begin() != tprted.end());
1377 text::add_line_with_condition(state, contents, "alice_load_unload_5", loc.index() < state.province_definitions.first_sea_province.index());
1378 }
1379};
1380
1382public:
1383 void on_create(sys::state& state) noexcept override {
1384 base_data.position.x -= int16_t(50);
1386 }
1387 void on_update(sys::state& state) noexcept override {
1388 auto n = retrieve<dcon::navy_id>(state, parent);
1389
1390 auto tcap = military::transport_capacity(state, n);
1393 if(tcap != tfree) {
1394 auto txt = std::to_string(tfree) + " (" + std::to_string(tcap) + ")";
1395 text::add_to_substitution_map(sub, text::variable_type::num, std::string_view(txt));
1396 set_text(state, text::resolve_string_substitution(state, std::string_view("load_capacity_label"), sub));
1397 } else {
1399 set_text(state, text::resolve_string_substitution(state, std::string_view("load_capacity_label"), sub));
1400 }
1401 }
1402
1403};
1404
1406public:
1407 bool visible = false;
1408 void on_update(sys::state& state) noexcept override {
1409 auto a = retrieve<dcon::army_id>(state, parent);
1410 visible = !state.world.army_get_is_rebel_hunter(a) && state.world.army_get_controller_from_army_control(a) == state.local_player_nation;
1411 }
1412 message_result test_mouse(sys::state& state, int32_t x, int32_t y, mouse_probe_type type) noexcept override {
1413 if(visible)
1416 }
1419 }
1420 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1421 text::add_line(state, contents, "unit_enable_rebel_hunt");
1422 }
1423 void button_action(sys::state& state) noexcept override {
1424 command::toggle_rebel_hunting(state, state.local_player_nation, retrieve<dcon::army_id>(state, parent));
1425 }
1426 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
1427 if(visible)
1429 }
1430};
1432public:
1433 bool visible = false;
1434 void on_update(sys::state& state) noexcept override {
1435 auto a = retrieve<dcon::army_id>(state, parent);
1436 visible = state.world.army_get_is_rebel_hunter(a) && state.world.army_get_controller_from_army_control(a) == state.local_player_nation;
1437 }
1438 message_result test_mouse(sys::state& state, int32_t x, int32_t y, mouse_probe_type type) noexcept override {
1439 if(visible)
1442 }
1445 }
1446 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1447 text::add_line(state, contents, "alice_unit_disable_rebel_hunt");
1448 }
1449 void button_action(sys::state& state) noexcept override {
1450 command::toggle_rebel_hunting(state, state.local_player_nation, retrieve<dcon::army_id>(state, parent));
1451 }
1452 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
1453 if(visible)
1455 }
1456};
1458public:
1459 bool is_active(sys::state& state) noexcept override {
1460 return state.world.army_get_is_ai_controlled(retrieve<dcon::army_id>(state, parent));
1461 }
1464 }
1465 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1466 text::add_line(state, contents, "alice_ai_controlled_unit");
1467 }
1468 void button_action(sys::state& state) noexcept override {
1469 auto a = retrieve<dcon::army_id>(state, parent);
1470 command::toggle_unit_ai_control(state, state.local_player_nation, a);
1471 }
1472 void on_update(sys::state& state) noexcept override {
1473 auto a = retrieve<dcon::army_id>(state, parent);
1474 disabled = state.world.army_get_controller_from_army_control(a) != state.local_player_nation;
1475 }
1476};
1477
1479public:
1480 void on_update(sys::state& state) noexcept override {
1481 auto army = retrieve<dcon::army_id>(state, parent);
1482 auto navy = retrieve<dcon::navy_id>(state, parent);
1483
1484 economy::commodity_set commodities;
1485
1486 auto owner = state.local_player_nation;
1487 auto capital = state.world.nation_get_capital(owner);
1488 auto s = state.world.province_get_state_membership(capital);
1489 auto m = state.world.state_instance_get_market_from_local_market(s);
1490
1491 float spending_level = .0f;
1492
1493 if(army) {
1494 commodities = military::get_required_supply(state, state.local_player_nation, army);
1495 spending_level = float(state.world.nation_get_land_spending(owner)) / 100.0f;
1496 } else if(navy) {
1497 commodities = military::get_required_supply(state, state.local_player_nation, navy);
1498 spending_level = float(state.world.nation_get_naval_spending(owner)) / 100.0f;
1499 }
1500
1501
1502 uint32_t total_commodities = state.world.commodity_size();
1503
1504 float max_supply = 0.0f;
1505 float actual_supply = 0.0f;
1506
1507
1508 auto nations_commodity_spending = state.world.nation_get_spending_level(owner);
1509
1510 for(uint32_t i = 0; i < total_commodities; ++i) {
1511 if(!commodities.commodity_type[i]) {
1512 break;
1513 }
1514
1515 dcon::commodity_id c{ dcon::commodity_id::value_base_t(i) };
1516
1517 auto satisfaction = state.world.market_get_demand_satisfaction(m, c);
1518 auto val = commodities.commodity_type[i];
1519
1520 max_supply += commodities.commodity_amounts[i];
1521 actual_supply += commodities.commodity_amounts[i] * satisfaction * nations_commodity_spending * spending_level;
1522 }
1523
1524 float median_supply = max_supply > 0.0f ? actual_supply / max_supply : 0.0f;
1525
1526 progress = median_supply;
1527 }
1528
1531 }
1532
1533 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1534 auto army = retrieve<dcon::army_id>(state, parent);
1535 auto navy = retrieve<dcon::navy_id>(state, parent);
1536 economy::commodity_set commodities;
1537
1538 float spending_level = .0f;
1539 auto owner = state.local_player_nation;
1540 auto capital = state.world.nation_get_capital(owner);
1541 auto s = state.world.province_get_state_membership(capital);
1542 auto m = state.world.state_instance_get_market_from_local_market(s);
1543
1544 if(army) {
1545 commodities = military::get_required_supply(state, state.local_player_nation, army);
1546 spending_level = float(state.world.nation_get_land_spending(owner)) / 100.0f;
1547 } else if(navy) {
1548 commodities = military::get_required_supply(state, state.local_player_nation, navy);
1549 spending_level = float(state.world.nation_get_naval_spending(owner)) / 100.0f;
1550 }
1551
1552
1553 uint32_t total_commodities = state.world.commodity_size();
1554
1555 float max_supply = 0.0f;
1556 float actual_supply = 0.0f;
1557
1558 auto nations_commodity_spending = state.world.nation_get_spending_level(owner);
1559 for(uint32_t i = 0; i < total_commodities; ++i) {
1560 if(!commodities.commodity_type[i]) {
1561 break;
1562 }
1563 dcon::commodity_id c{ dcon::commodity_id::value_base_t(i) };
1564
1565 auto satisfaction = state.world.market_get_demand_satisfaction(m, c);
1566 auto val = commodities.commodity_type[i];
1567
1568 max_supply += commodities.commodity_amounts[i];
1569 actual_supply += commodities.commodity_amounts[i] * satisfaction * nations_commodity_spending * spending_level;
1570 }
1571
1572 float median_supply = max_supply > 0.0f ? actual_supply / max_supply : 0.0f;
1573 text::add_line(state, contents, "unit_current_supply", text::variable_type::val, int16_t(median_supply * 100.f));
1575 for(uint32_t i = 0; i < economy::commodity_set::set_size; ++i) {
1576 if(commodities.commodity_type[i] && commodities.commodity_amounts[i] > 0) {
1577 dcon::commodity_id c{ dcon::commodity_id::value_base_t(i) };
1578 float satisfaction = state.world.market_get_demand_satisfaction(m, c);
1579 float wanted_commodity = commodities.commodity_amounts[i];
1580 float actual_commodity = commodities.commodity_amounts[i] * satisfaction * nations_commodity_spending * spending_level;
1581
1582 int32_t display_satisfaction = int32_t(satisfaction * 100);
1583
1584 if(satisfaction == 1 || satisfaction >= 0.95) {
1585 text::add_line(state, contents, "unit_current_supply_high", text::variable_type::what, state.world.commodity_get_name(commodities.commodity_type[i]), text::variable_type::val, text::fp_three_places{ actual_commodity }, text::variable_type::value, text::fp_three_places{ wanted_commodity }, text::variable_type::total, display_satisfaction);
1586 } else if (satisfaction < 0.95 && satisfaction >= 0.5) {
1587 text::add_line(state, contents, "unit_current_supply_mid", text::variable_type::what, state.world.commodity_get_name(commodities.commodity_type[i]), text::variable_type::val, text::fp_three_places{ actual_commodity }, text::variable_type::value, text::fp_three_places{ wanted_commodity }, text::variable_type::total, display_satisfaction);
1588 } else {
1589 text::add_line(state, contents, "unit_current_supply_low", text::variable_type::what, state.world.commodity_get_name(commodities.commodity_type[i]), text::variable_type::val, text::fp_three_places{ actual_commodity }, text::variable_type::value, text::fp_three_places{ wanted_commodity }, text::variable_type::total, display_satisfaction);
1590 }
1591 }
1592 }
1593 }
1594};
1595
1597public:
1598 void on_update(sys::state& state) noexcept override {
1599 auto contents = text::create_endless_layout(
1600 state,
1603 0,
1604 0,
1605 static_cast<int16_t>(base_data.size.x),
1606 static_cast<int16_t>(base_data.size.y),
1608 0,
1611 true
1612 });
1613
1614 auto box = text::open_layout_box(contents);
1615
1616 for(dcon::unit_type_id::value_base_t i = 0; i < state.military_definitions.unit_base_definitions.size(); i++) {
1617 auto amount = state.ui_state.current_template == -1 ? uint8_t(0) : state.ui_state.templates[state.ui_state.current_template].amounts[i];
1618
1619 if(amount < 1) {
1620 continue;
1621 }
1622
1623 auto const utid = dcon::unit_type_id(i);
1624
1625 std::string padding = i < 10 ? "0" : "";
1626
1627 text::add_to_layout_box(state, contents, box, text::int_wholenum{ amount });
1628
1629 std::string description = "@*" + padding + std::to_string(i);
1630
1631 text::add_unparsed_text_to_layout_box(state, contents, box, description);
1632 }
1633
1634 text::close_layout_box(contents, box);
1635 }
1636
1639 }
1640
1641 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1642 text::add_line(state, contents, "unit_macro_template_tooltip");
1643 }
1644};
1645
1647 std::vector<dcon::province_id> provinces;
1648public:
1649 void on_create(sys::state& state) noexcept override {
1651 }
1652 void on_update(sys::state& state) noexcept override {
1653 disabled = false;
1654 }
1655 void button_action(sys::state& state) noexcept override {
1656 if(state.ui_state.current_template == -1)
1657 return;
1658
1659 auto army = retrieve<dcon::army_id>(state, parent);
1660 auto army_location = state.world.army_get_location_from_army_location(army);
1661
1662 state.fill_vector_of_connected_provinces(army_location, true, provinces);
1663 if(provinces.empty())
1664 return;
1665
1666 std::array<uint8_t, sys::macro_builder_template::max_types> current_distribution;
1667 current_distribution.fill(0);
1668
1669 for(auto reg : state.world.army_get_army_membership(army)) {
1670 current_distribution[reg.get_regiment().get_type().index()] += 1;
1671 }
1672
1673 state.build_up_to_template_land(
1674 state.ui_state.templates[state.ui_state.current_template],
1675 army_location,
1676 provinces,
1677 current_distribution
1678 );
1679 }
1680};
1681
1683 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1684 if(name == "composition") {
1685 return make_element_by_type<main_template_composition_label>(state, id);
1686 } else if(name == "background") {
1687 return make_element_by_type< apply_template_to_army_location_button>(state, id);
1688 } else {
1689 return nullptr;
1690 }
1691 }
1692};
1693
1694template<class T>
1696private:
1697 simple_text_element_base* navytransport_text = nullptr;
1698public:
1699 void on_create(sys::state& state) noexcept override {
1701 if constexpr(std::is_same_v<T, dcon::army_id>) {
1702 auto ptr = make_element_by_type<unit_details_ai_controlled>(state, "alice_enable_ai_controlled");
1703 add_child_to_front(std::move(ptr));
1704 }
1705 }
1706
1707 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1708 if(name == "load_button" && std::is_same_v<T, dcon::army_id>) {
1709 if constexpr(std::is_same_v<T, dcon::army_id>) {
1710 return make_element_by_type<unit_details_load_army_button>(state, id);
1711 } else {
1712 return make_element_by_type<invisible_element>(state, id);
1713 }
1714 } else if(name == "unload_button") {
1715 if constexpr(std::is_same_v<T, dcon::army_id>) {
1716 return make_element_by_type<unit_details_unload_army_button>(state, id);
1717 } else {
1718 return make_element_by_type<unit_details_unload_navy_button>(state, id);
1719 }
1720 } else if(name == "enable_rebel_button") {
1721 if constexpr(std::is_same_v<T, dcon::army_id>) {
1722 return make_element_by_type<unit_details_hunt_rebels>(state, id);
1723 } else {
1724 return make_element_by_type<invisible_element>(state, id);
1725 }
1726 } else if(name == "disable_rebel_button") {
1727 if constexpr(std::is_same_v<T, dcon::army_id>) {
1728 return make_element_by_type<unit_details_dont_hunt_rebels>(state, id);
1729 } else {
1730 return make_element_by_type<invisible_element>(state, id);
1731 }
1732 } else if(name == "attach_unit_button"
1733 || name == "detach_unit_button"
1734 || name == "select_land") {
1735
1736 return make_element_by_type<invisible_element>(state, id);
1737 } else if(name == "header") {
1738 if constexpr(std::is_same_v<T, dcon::army_id>) {
1739 return make_element_by_type<invisible_element>(state, id);
1740 } else {
1741 return make_element_by_type< navy_transport_text>(state, id);
1742 }
1743 } else if(name == "alice_build_up_to_template_window") {
1744 if constexpr(std::is_same_v<T, dcon::army_id>) {
1745 return make_element_by_type<apply_template_container>(state, id);
1746 } else {
1747 return make_element_by_type<invisible_element>(state, id);
1748 }
1749 } else {
1750 return nullptr;
1751 }
1752 }
1753};
1754
1756 void on_update(sys::state& state) noexcept override {
1757 auto regiment_type = retrieve<dcon::unit_type_id>(state, parent);
1758
1759 if(regiment_type) {
1760 frame = state.military_definitions.unit_base_definitions[regiment_type].icon - 1;
1761 }
1762 }
1763};
1764
1766 void on_update(sys::state& state) noexcept override {
1767 auto regiment_type = retrieve<dcon::unit_type_id>(state, parent);
1768
1769 if(regiment_type) {
1770 auto name_string_def = state.military_definitions.unit_base_definitions[regiment_type].name;
1772 }
1773
1774 auto const& ut = state.military_definitions.unit_base_definitions[regiment_type];
1775 if(!ut.active && !state.world.nation_get_active_unit(state.local_player_nation, regiment_type)) {
1776 disabled = true;
1777 return;
1778 }
1779
1780 dcon::regiment_id regs[command::num_packed_units];
1781 dcon::ship_id ships[command::num_packed_units];
1782 auto allowed_transition = true;
1783
1784 for(unsigned i = 0; i < state.selected_regiments.size(); i++) {
1785 if(state.selected_regiments[i]) {
1786 regs[i % command::num_packed_units] = state.selected_regiments[i];
1787 }
1788 if(state.selected_ships[i]) {
1789 ships[i % command::num_packed_units] = state.selected_ships[i];
1790 }
1791
1792 if(i % command::num_packed_units == 0) {
1793 allowed_transition = command::can_change_unit_type(state, state.local_player_nation, regs, ships, regiment_type);
1794 if(!allowed_transition) {
1795 disabled = true; return;
1796 }
1797 }
1798
1799 if(!state.selected_regiments[i] && !state.selected_ships[i]) {
1800 break;
1801 }
1802 }
1803
1804 allowed_transition = command::can_change_unit_type(state, state.local_player_nation, regs, ships, regiment_type);
1805 if(!allowed_transition) {
1806 disabled = true;
1807 return;
1808 }
1809
1810 disabled = false;
1811 }
1812
1813 void button_action(sys::state& state) noexcept override {
1814 auto regiment_type = retrieve<dcon::unit_type_id>(state, parent);
1815 dcon::regiment_id regs[command::num_packed_units];
1816 dcon::ship_id ships[command::num_packed_units];
1817
1818 for(unsigned i = 0; i < state.selected_regiments.size(); i++) {
1819 if(state.selected_regiments[i]) {
1820 regs[i % command::num_packed_units] = state.selected_regiments[i];
1821 }
1822 if(state.selected_ships[i]) {
1823 ships[i % command::num_packed_units] = state.selected_ships[i];
1824 }
1825
1826 if(i % command::num_packed_units == 0) {
1827 command::change_unit_type(state, state.local_player_nation, regs, ships, regiment_type);
1828 }
1829
1830 if(!state.selected_regiments[i] && !state.selected_ships[i]) {
1831 break;
1832 }
1833 }
1834
1835 command::change_unit_type(state, state.local_player_nation, regs, ships, regiment_type);
1838 }
1839
1840 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
1842 }
1843
1844 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1845 text::add_line(state, contents, "unit_upgrade_desc", text::variable_type::days, int64_t(state.defines.discredit_days));
1847
1848 auto new_type = retrieve<dcon::unit_type_id>(state, parent);
1849 auto const& ut = state.military_definitions.unit_base_definitions[new_type];
1850
1851 text::add_line_with_condition(state, contents, "unit_upgrade_explain_1", !state.selected_regiments[0] || !state.selected_ships[0]);
1852 text::add_line_with_condition(state, contents, "unit_upgrade_explain_2", ut.active || state.world.nation_get_active_unit(state.local_player_nation, new_type));
1853
1854 if(!ut.is_land && ut.type == military::unit_type::big_ship) {
1855 auto any_non_big_ship = false;
1856 for(unsigned i = 0; i < state.selected_ships.size(); i++) {
1857 if(!state.selected_ships[i]) {
1858 break;
1859 }
1860 auto shiptype = state.world.ship_get_type(state.selected_ships[i]);
1861 auto st = state.military_definitions.unit_base_definitions[shiptype];
1862 if(st.type != military::unit_type::big_ship) {
1863 any_non_big_ship = true;
1864 }
1865 }
1866
1867 text::add_line_with_condition(state, contents, "unit_upgrade_explain_3", !any_non_big_ship);
1868 }
1869
1870 if(ut.is_land) {
1871 auto any_breaking_army_check = false;
1872 for(unsigned i = 0; i < state.selected_regiments.size(); i++) {
1873 if(!state.selected_regiments[i]) {
1874 break;
1875 }
1876 auto a = state.world.regiment_get_army_from_army_membership(state.selected_regiments[i]);
1877
1878 if(state.world.army_get_controller_from_army_control(a) != state.local_player_nation || state.world.army_get_is_retreating(a) || state.world.army_get_navy_from_army_transport(a) ||
1879 bool(state.world.army_get_battle_from_army_battle_participation(a))) {
1880 any_breaking_army_check = true;
1881 }
1882 }
1883
1884 text::add_line_with_condition(state, contents, "unit_upgrade_explain_4", !any_breaking_army_check);
1885 }
1886
1887 if(!ut.is_land) {
1888 auto any_breaking_navy_check = false;
1889 auto any_breaking_navy_base_check = false;
1890 // Navy-level checks
1891 for(unsigned i = 0; i < state.selected_ships.size(); i++) {
1892 if(!state.selected_ships[i]) {
1893 break;
1894 }
1895 auto n = state.world.ship_get_navy_from_navy_membership(state.selected_ships[i]);
1896 auto embarked = state.world.navy_get_army_transport(n);
1897 if(state.world.navy_get_controller_from_navy_control(n) != state.local_player_nation || state.world.navy_get_is_retreating(n) ||
1898 bool(state.world.navy_get_battle_from_navy_battle_participation(n)) || embarked.begin() != embarked.end()) {
1899 any_breaking_navy_check = true;
1900 }
1901
1902 if(ut.min_port_level) {
1903 auto fnid = dcon::fatten(state.world, n);
1904
1905 auto loc = fnid.get_location_from_navy_location();
1906
1907 // Ship requires naval base level for construction but province location doesn't have one
1908 if(loc.get_building_level(uint8_t(economy::province_building_type::naval_base)) < ut.min_port_level) {
1909 any_breaking_navy_base_check = true;
1910 }
1911 }
1912 }
1913
1914 text::add_line_with_condition(state, contents, "unit_upgrade_explain_5", !any_breaking_navy_check);
1915 text::add_line_with_condition(state, contents, "unit_upgrade_explain_6", !any_breaking_navy_base_check);
1916 }
1917 }
1918};
1919
1920class unit_type_listbox_entry : public listbox_row_element_base<dcon::unit_type_id> {
1921 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1922 if(name == "unit_type_icon") {
1923 return make_element_by_type<unit_type_listbox_entry_image>(state, id);
1924 } else if(name == "unit_type_select") {
1925 return make_element_by_type<unit_type_listbox_entry_label>(state, id);
1926 } else {
1927 return nullptr;
1928 }
1929 }
1930};
1931
1932template<class T>
1933class unit_type_listbox : public listbox_element_base<unit_type_listbox_entry, dcon::unit_type_id> {
1934protected:
1935 std::string_view get_row_element_name() override {
1936 return "unit_type_item";
1937 }
1938
1939public:
1940 void on_update(sys::state& state) noexcept override {
1941 row_contents.clear();
1942
1943 auto is_land = true;
1944
1945 if constexpr(std::is_same_v<T, dcon::army_id>) {
1946 if(parent) {
1947
1948 }
1949 } else if constexpr(std::is_same_v<T, dcon::navy_id>) {
1950 if(parent) {
1951 is_land = false;
1952 }
1953 }
1954
1955 for(dcon::unit_type_id::value_base_t i = 2; i < state.military_definitions.unit_base_definitions.size(); i++) {
1956 auto const utid = dcon::unit_type_id(i);
1957 auto const& ut = state.military_definitions.unit_base_definitions[utid];
1958 if(ut.is_land == is_land) {
1959 row_contents.push_back(utid);
1960 }
1961 }
1962
1963 update(state);
1964 }
1965};
1966
1967template<class T>
1969public:
1970 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1971 if(name == "unit_type_list") {
1972 return make_element_by_type<unit_type_listbox<T>>(state, id);
1973 } else {
1974 return nullptr;
1975 }
1976 }
1977
1978 void on_update(sys::state& state) noexcept override {
1979 if(!state.selected_regiments.at(0) && !state.selected_ships.at(0)) {
1980 set_visible(state, false);
1981 return;
1982 }
1983 }
1984};
1985
1986template<class T>
1988 simple_text_element_base* unitspeed_text = nullptr;
1989 image_element_base* unitrecon_icon = nullptr;
1990 simple_text_element_base* unitrecon_text = nullptr;
1991 image_element_base* unitengineer_icon = nullptr;
1992 simple_text_element_base* unitengineer_text = nullptr;
1993 progress_bar* unitsupply_bar = nullptr;
1994 image_element_base* unitdugin_icon = nullptr;
1995 unit_selection_panel<T>* unit_selection_win = nullptr;
1996
1997 unit_upgrade_window<T>* unit_upgrade_win = nullptr;
1998
1999public:
2001
2002 void on_create(sys::state& state) noexcept override {
2004 base_data.position.y = 250;
2005
2006 xy_pair base_position = {20,
2007 0}; // state.ui_defs.gui[state.ui_state.defs_by_name.find("unittype_item_start")->second.definition].position;
2008 xy_pair base_offset = state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("unittype_item_offset"))->second.definition].position;
2009
2010 {
2011 auto win = make_element_by_type<unit_details_type_item<T, 0>>(state,
2012 state.ui_state.defs_by_name.find(state.lookup_key("unittype_item"))->second.definition);
2013 win->base_data.position.x = base_position.x + (0 * base_offset.x); // Flexnudge
2014 win->base_data.position.y = base_position.y + (0 * base_offset.y); // Flexnudge
2015 add_child_to_front(std::move(win));
2016 }
2017 {
2018 auto win = make_element_by_type<unit_details_type_item<T, 1>>(state,
2019 state.ui_state.defs_by_name.find(state.lookup_key("unittype_item"))->second.definition);
2020 win->base_data.position.x = base_position.x + (1 * base_offset.x); // Flexnudge
2021 win->base_data.position.y = base_position.y + (1 * base_offset.y); // Flexnudge
2022 add_child_to_front(std::move(win));
2023 }
2024 {
2025 auto win = make_element_by_type<unit_details_type_item<T, 2>>(state,
2026 state.ui_state.defs_by_name.find(state.lookup_key("unittype_item"))->second.definition);
2027 win->base_data.position.x = base_position.x + (2 * base_offset.x); // Flexnudge
2028 win->base_data.position.y = base_position.y + (2 * base_offset.y); // Flexnudge
2029 add_child_to_front(std::move(win));
2030 }
2031
2032 const xy_pair item_offset = state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("unittype_item"))->second.definition].position;
2033 if constexpr(std::is_same_v<T, dcon::army_id>) {
2034 auto ptr = make_element_by_type<unit_details_army_listbox>(state,
2035 state.ui_state.defs_by_name.find(state.lookup_key("sup_subunits"))->second.definition);
2036 ptr->base_data.position.y = base_position.y + item_offset.y + (3 * base_offset.y) + 72 - 32;
2037 ptr->base_data.size.y += 32;
2038 add_child_to_front(std::move(ptr));
2039 } else {
2040 auto ptr = make_element_by_type<unit_details_navy_listbox>(state,
2041 state.ui_state.defs_by_name.find(state.lookup_key("sup_subunits"))->second.definition);
2042 ptr->base_data.position.y = base_position.y + item_offset.y + (3 * base_offset.y) + 72 - 32;
2043 ptr->base_data.size.y += 32;
2044 add_child_to_front(std::move(ptr));
2045 }
2046
2047 {
2048 auto ptr = make_element_by_type<unit_details_buttons<T>>(state,
2049 state.ui_state.defs_by_name.find(state.lookup_key("sup_buttons_window"))->second.definition);
2050 ptr->base_data.position.y = base_data.size.y; // Nudge
2051 add_child_to_front(std::move(ptr));
2052 }
2053
2054 {
2055 auto ptr =
2056 make_element_by_type<unit_selection_panel<T>>(state, state.ui_state.defs_by_name.find(state.lookup_key("unitpanel"))->second.definition);
2057 unit_selection_win = ptr.get();
2058 ptr->base_data.position.y = -80;
2059 add_child_to_front(std::move(ptr));
2060 }
2061
2062 {
2063 auto ptr =
2064 make_element_by_type<unit_upgrade_window<T>>(state, state.ui_state.defs_by_name.find(state.lookup_key("unit_upgrade_window"))->second.definition);
2065 unit_upgrade_win = ptr.get();
2066 add_child_to_front(std::move(ptr));
2067 unit_upgrade_win->set_visible(state, false);
2068 }
2069 }
2070
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 == "unit_bottom_bg") {
2073 return make_element_by_type<unit_panel_dynamic_tinted_bg<T>>(state, id);
2074 } else if(name == "icon_speed") {
2075 return make_element_by_type<image_element_base>(state, id);
2076 } else if(name == "speed") {
2077 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
2078 unitspeed_text = ptr.get();
2079 return ptr;
2080 } else if(name == "icon_recon") {
2081 auto ptr = make_element_by_type<image_element_base>(state, id);
2082 unitrecon_icon = ptr.get();
2083 return ptr;
2084 } else if(name == "recon") {
2085 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
2086 unitrecon_text = ptr.get();
2087 return ptr;
2088 } else if(name == "icon_engineer") {
2089 auto ptr = make_element_by_type<image_element_base>(state, id);
2090 unitengineer_icon = ptr.get();
2091 return ptr;
2092 } else if(name == "engineer") {
2093 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
2094 unitengineer_text = ptr.get();
2095 return ptr;
2096 } else if(name == "icon_supplies_small") {
2097 return make_element_by_type<image_element_base>(state, id);
2098 } else if(name == "supply_status") {
2099 auto ptr = make_element_by_type<unit_supply_bar>(state, id);
2100 unitsupply_bar = ptr.get();
2101 return ptr;
2102 } else if(name == "unitstatus_dugin") {
2103 auto ptr = make_element_by_type<image_element_base>(state, id);
2104 unitdugin_icon = ptr.get();
2105 return ptr;
2106 } else {
2107 return nullptr;
2108 }
2109 }
2110
2111 void on_update(sys::state& state) noexcept override {
2112 if constexpr(std::is_same_v<T, dcon::navy_id>) {
2113 unitengineer_icon->set_visible(state, false);
2114 unitengineer_text->set_visible(state, false);
2115 unitrecon_icon->set_visible(state, false);
2116 unitrecon_text->set_visible(state, false);
2117
2120 unitspeed_text->set_text(state, text::resolve_string_substitution(state, std::string_view("speed"), sub));
2121 } else if constexpr(std::is_same_v<T, dcon::army_id>) {
2122 unitengineer_icon->set_visible(state, true);
2123 unitengineer_text->set_visible(state, true);
2124 unitrecon_icon->set_visible(state, true);
2125 unitrecon_text->set_visible(state, true);
2126
2129 unitspeed_text->set_text(state, text::resolve_string_substitution(state, std::string_view("speed"), sub));
2130 }
2131 }
2132
2133 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
2134 if(payload.holds_type<T>()) {
2135 payload.emplace<T>(unit_id);
2137 } else if(payload.holds_type<element_selection_wrapper<T>>()) {
2138 unit_id = any_cast<element_selection_wrapper<T>>(payload).data;
2141 } else if(payload.holds_type<element_selection_wrapper<dcon::leader_id>>()) {
2142 auto content = any_cast<element_selection_wrapper<dcon::leader_id>>(payload).data;
2143 if constexpr(std::is_same_v<T, dcon::army_id>) {
2144 command::change_general(state, state.local_player_nation, unit_id, content);
2145 } else {
2146 command::change_admiral(state, state.local_player_nation, unit_id, content);
2147 }
2149 } else if(payload.holds_type<element_selection_wrapper<unitpanel_action>>()) {
2150 auto content = any_cast<element_selection_wrapper<unitpanel_action>>(payload).data;
2151 switch(content) {
2153 {
2155 unit_selection_win->reorg_window->impl_get(state, cpayload);
2156 state.selected_armies.clear();
2157 state.selected_navies.clear();
2158 set_visible(state, false);
2159 state.game_state_updated.store(true, std::memory_order_release);
2160 break;
2161 }
2163 unit_upgrade_win->is_visible() ? unit_upgrade_win->set_visible(state, false) : unit_upgrade_win->set_visible(state, true);
2164 unit_upgrade_win->impl_on_update(state);
2165 break;
2166 }
2167 default:
2168 break;
2169 };
2171 }
2173 }
2174};
2175
2177public:
2178 void on_update(sys::state& state) noexcept override {
2180 text::add_to_substitution_map(m, text::variable_type::x, int64_t(state.selected_armies.size() + state.selected_navies.size()));
2181 set_text(state, text::resolve_string_substitution(state, "multiunit_header", m));
2182 }
2183};
2184
2186public:
2187 void button_action(sys::state& state) noexcept override {
2188 if(state.selected_armies.size() > 0) {
2189 auto first = state.selected_armies[0];
2190 for(uint32_t i = 1; i < state.selected_armies.size(); ++i) {
2191 command::merge_armies(state, state.local_player_nation, first, state.selected_armies[i]);
2192 }
2193 }
2194 if(state.selected_navies.size() > 0) {
2195 auto first = state.selected_navies[0];
2196 for(uint32_t i = 1; i < state.selected_navies.size(); ++i) {
2197 command::merge_navies(state, state.local_player_nation, first, state.selected_navies[i]);
2198 }
2199 }
2200 }
2201
2202 void on_update(sys::state& state) noexcept override {
2203 disabled = false;
2204
2205 if(state.selected_armies.size() > 0) {
2206
2207 auto first = state.selected_armies[0];
2208
2209 for(uint32_t i = 1; i < state.selected_armies.size(); ++i) {
2210 if(!command::can_merge_armies(state, state.local_player_nation, first, state.selected_armies[i])) {
2211 disabled = true;
2212 return;
2213 }
2214 }
2215 }
2216 if(state.selected_navies.size() > 0) {
2217 auto first = state.selected_navies[0];
2218
2219 for(uint32_t i = 1; i < state.selected_navies.size(); ++i) {
2220 if(!command::can_merge_navies(state, state.local_player_nation, first, state.selected_navies[i])) {
2221 disabled = true;
2222 return;
2223 }
2224 }
2225 }
2226 }
2227};
2228
2230public:
2231 void button_action(sys::state& state) noexcept override {
2232 state.selected_armies.clear();
2233 state.selected_navies.clear();
2234 state.game_state_updated.store(true, std::memory_order_release);
2235 }
2236};
2237
2239public:
2240 void button_action(sys::state& state) noexcept override {
2241 for(auto a : state.selected_armies) {
2242 command::delete_army(state, state.local_player_nation, a);
2243 }
2244 for(auto a : state.selected_navies) {
2245 command::delete_navy(state, state.local_player_nation, a);
2246 }
2247 }
2250 }
2251
2252 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
2253 text::add_line(state, contents, "disband_all");
2254 }
2255};
2256
2258public:
2259 void button_action(sys::state& state) noexcept override {
2260 auto foru = retrieve<unit_var>(state, parent);
2261 if(std::holds_alternative<dcon::army_id>(foru)) {
2262 state.selected_armies.clear();
2263 state.selected_navies.clear();
2264 state.select(std::get<dcon::army_id>(foru));
2265 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2266 state.selected_armies.clear();
2267 state.selected_navies.clear();
2268 state.select(std::get<dcon::navy_id>(foru));
2269 }
2270 }
2271 void button_shift_action(sys::state& state) noexcept override {
2272 auto foru = retrieve<unit_var>(state, parent);
2273 if(std::holds_alternative<dcon::army_id>(foru)) {
2274 state.deselect(std::get<dcon::army_id>(foru));
2275 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2276 state.deselect(std::get<dcon::navy_id>(foru));
2277 }
2278 }
2279};
2280
2282public:
2283 void on_update(sys::state& state) noexcept override {
2284 auto foru = retrieve<unit_var>(state, parent);
2285 float total = 0.0f;
2286 if(std::holds_alternative<dcon::army_id>(foru)) {
2287 auto a = std::get<dcon::army_id>(foru);
2288 for(auto r : state.world.army_get_army_membership(a)) {
2289 total += r.get_regiment().get_strength() * state.defines.pop_size_per_regiment;
2290 }
2291 set_text(state, text::format_wholenum(int32_t(total)));
2292 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2293 auto a = std::get<dcon::navy_id>(foru);
2294 for(auto r : state.world.navy_get_navy_membership(a)) {
2295 total += r.get_ship().get_strength();
2296 }
2297 set_text(state, text::format_float(total, 1));
2298 }
2299 }
2300};
2301
2303 bool visible = false;
2304 void on_update(sys::state& state) noexcept override {
2305 auto foru = retrieve<unit_var>(state, parent);
2306 if(std::holds_alternative<dcon::army_id>(foru)) {
2307 auto a = std::get<dcon::army_id>(foru);
2309 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2310 auto a = std::get<dcon::navy_id>(foru);
2312 } else {
2313 visible = false;
2314 }
2315 }
2316 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
2317 if(visible)
2319 }
2320};
2321
2323 void on_update(sys::state& state) noexcept override {
2324 float current = 0.0f;
2325 float total = 0.0f;
2326 auto foru = retrieve<unit_var>(state, parent);
2327 if(std::holds_alternative<dcon::army_id>(foru)) {
2328 auto a = std::get<dcon::army_id>(foru);
2329 for(auto r : state.world.army_get_army_membership(a)) {
2330 current += r.get_regiment().get_org();
2331 total += 1.0f;
2332 }
2333 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2334 auto a = std::get<dcon::navy_id>(foru);
2335 for(auto r : state.world.navy_get_navy_membership(a)) {
2336 current += r.get_ship().get_org();
2337 total += 1.0f;
2338 }
2339 }
2340 progress = total > 0.0f ? current / total : 0.0f;
2341 }
2342
2343 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
2345 }
2346
2347 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
2349 auto foru = retrieve<unit_var>(state, parent);
2350 if(std::holds_alternative<dcon::army_id>(foru)) {
2351 ui::active_modifiers_description(state, contents, state.local_player_nation, 0, sys::national_mod_offsets::land_organisation, true);
2352 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2353 ui::active_modifiers_description(state, contents, state.local_player_nation, 0, sys::national_mod_offsets::naval_organisation, true);
2354 }
2355 }
2356};
2357
2359 void on_update(sys::state& state) noexcept override {
2360 float current = 0.0f;
2361 float total = 0.0f;
2362 auto foru = retrieve<unit_var>(state, parent);
2363 if(std::holds_alternative<dcon::army_id>(foru)) {
2364 auto a = std::get<dcon::army_id>(foru);
2365 for(auto r : state.world.army_get_army_membership(a)) {
2366 current += r.get_regiment().get_strength();
2367 total += 1.0f;
2368 }
2369 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2370 auto a = std::get<dcon::navy_id>(foru);
2371 for(auto r : state.world.navy_get_navy_membership(a)) {
2372 current += r.get_ship().get_strength();
2373 total += 1.0f;
2374 }
2375 }
2376 progress = total > 0.0f ? current / total : 0.0f;
2377 }
2378
2379 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
2381 }
2382};
2383
2385public:
2386 void on_update(sys::state& state) noexcept override {
2387 auto foru = retrieve<unit_var>(state, parent);
2388 if(std::holds_alternative<dcon::army_id>(foru)) {
2389 disabled = !command::can_delete_army(state, state.local_player_nation, std::get<dcon::army_id>(foru));
2390 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2391 disabled = !command::can_delete_navy(state, state.local_player_nation, std::get<dcon::navy_id>(foru));
2392 }
2393 }
2394 void button_action(sys::state& state) noexcept override {
2395 auto foru = retrieve<unit_var>(state, parent);
2396 if(std::holds_alternative<dcon::army_id>(foru)) {
2397 command::delete_army(state, state.local_player_nation, std::get<dcon::army_id>(foru));
2398 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2399 command::delete_navy(state, state.local_player_nation, std::get<dcon::navy_id>(foru));
2400 }
2401 }
2404 }
2405 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
2406 text::add_line(state, contents, "disband_unit");
2407 }
2408};
2409
2411public:
2412 void button_action(sys::state& state) noexcept override {
2413 auto foru = retrieve<unit_var>(state, parent);
2414 if(std::holds_alternative<dcon::army_id>(foru)) {
2415 state.deselect(std::get<dcon::army_id>(foru));
2416 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2417 state.deselect(std::get<dcon::navy_id>(foru));
2418 }
2419 }
2422 }
2423 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
2424 text::add_line(state, contents, "deselect_unit");
2425 }
2426};
2427
2429public:
2430 void button_action(sys::state& state) noexcept override {
2431 auto foru = retrieve<unit_var>(state, parent);
2432 if(std::holds_alternative<dcon::army_id>(foru)) {
2433 command::evenly_split_army(state, state.local_player_nation, std::get<dcon::army_id>(foru));
2434 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2435 command::evenly_split_navy(state, state.local_player_nation, std::get<dcon::navy_id>(foru));
2436 }
2437 }
2438
2439 void on_update(sys::state& state) noexcept override {
2440 auto foru = retrieve<unit_var>(state, parent);
2441 if(std::holds_alternative<dcon::army_id>(foru)) {
2442 disabled = !command::can_evenly_split_army(state, state.local_player_nation, std::get<dcon::army_id>(foru));
2443 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2444 disabled = !command::can_evenly_split_navy(state, state.local_player_nation, std::get<dcon::navy_id>(foru));
2445 }
2446 }
2447
2450 }
2451
2452 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
2453 text::add_line(state, contents, "splitinhalf");
2454 }
2455};
2456
2458public:
2459 void button_action(sys::state& state) noexcept override {
2460 // TODO
2461 }
2462};
2463
2465public:
2466 void on_update(sys::state& state) noexcept override {
2467 auto foru = retrieve<unit_var>(state, parent);
2468 if(std::holds_alternative<dcon::army_id>(foru)) {
2469 frame = 0;
2470 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2471 frame = 3;
2472 }
2473 }
2474};
2475
2477public:
2478 void on_update(sys::state& state) noexcept override {
2479 auto foru = retrieve<unit_var>(state, parent);
2480 if(std::holds_alternative<dcon::army_id>(foru)) {
2481 frame = 1;
2482 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2483 frame = 4;
2484 }
2485 }
2486};
2487
2489public:
2490 void on_update(sys::state& state) noexcept override {
2491 auto foru = retrieve<unit_var>(state, parent);
2492 if(std::holds_alternative<dcon::army_id>(foru)) {
2493 frame = 2;
2494 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2495 frame = 5;
2496 }
2497 }
2498};
2499
2501public:
2502 void on_update(sys::state& state) noexcept override {
2503 int32_t total = 0;
2504 auto foru = retrieve<unit_var>(state, parent);
2505 if(std::holds_alternative<dcon::army_id>(foru)) {
2506 auto a = std::get<dcon::army_id>(foru);
2507 for(auto r : state.world.army_get_army_membership(a)) {
2508 if(state.military_definitions.unit_base_definitions[r.get_regiment().get_type()].type == military::unit_type::infantry) {
2509 ++total;
2510 }
2511 }
2512 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2513 auto a = std::get<dcon::navy_id>(foru);
2514 for(auto r : state.world.navy_get_navy_membership(a)) {
2515 if(state.military_definitions.unit_base_definitions[r.get_ship().get_type()].type == military::unit_type::big_ship) {
2516 ++total;
2517 }
2518 }
2519 }
2520
2521 set_text(state, std::to_string(total));
2522 }
2523};
2524
2526public:
2527 void on_update(sys::state& state) noexcept override {
2528 int32_t total = 0;
2529 auto foru = retrieve<unit_var>(state, parent);
2530 if(std::holds_alternative<dcon::army_id>(foru)) {
2531 auto a = std::get<dcon::army_id>(foru);
2532 for(auto r : state.world.army_get_army_membership(a)) {
2533 if(state.military_definitions.unit_base_definitions[r.get_regiment().get_type()].type == military::unit_type::cavalry) {
2534 ++total;
2535 }
2536 }
2537 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2538 auto a = std::get<dcon::navy_id>(foru);
2539 for(auto r : state.world.navy_get_navy_membership(a)) {
2540 if(state.military_definitions.unit_base_definitions[r.get_ship().get_type()].type == military::unit_type::light_ship) {
2541 ++total;
2542 }
2543 }
2544 }
2545
2546 set_text(state, std::to_string(total));
2547 }
2548};
2549
2551public:
2552 void on_update(sys::state& state) noexcept override {
2553 int32_t total = 0;
2554 auto foru = retrieve<unit_var>(state, parent);
2555 if(std::holds_alternative<dcon::army_id>(foru)) {
2556 auto a = std::get<dcon::army_id>(foru);
2557 for(auto r : state.world.army_get_army_membership(a)) {
2558 if(state.military_definitions.unit_base_definitions[r.get_regiment().get_type()].type == military::unit_type::support || state.military_definitions.unit_base_definitions[r.get_regiment().get_type()].type == military::unit_type::special) {
2559 ++total;
2560 }
2561 }
2562 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2563 auto a = std::get<dcon::navy_id>(foru);
2564 for(auto r : state.world.navy_get_navy_membership(a)) {
2565 if(state.military_definitions.unit_base_definitions[r.get_ship().get_type()].type == military::unit_type::transport) {
2566 ++total;
2567 }
2568 }
2569 }
2570
2571 set_text(state, std::to_string(total));
2572 }
2573};
2574
2576public:
2577 void on_update(sys::state& state) noexcept override {
2578 dcon::province_id loc;
2579 auto foru = retrieve<unit_var>(state, parent);
2580 if(std::holds_alternative<dcon::army_id>(foru)) {
2581 auto a = std::get<dcon::army_id>(foru);
2582 loc = state.world.army_get_location_from_army_location(a);
2583 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2584 auto a = std::get<dcon::navy_id>(foru);
2585 loc = state.world.navy_get_location_from_navy_location(a);
2586 }
2587
2588 set_text(state, text::produce_simple_string(state, state.world.province_get_name(loc)));
2589 }
2590};
2591
2592
2594public:
2595 dcon::gfx_object_id default_img;
2596
2597 void on_update(sys::state& state) noexcept override {
2598 if(!default_img) {
2603 }
2604
2605 auto foru = retrieve<unit_var>(state, parent);
2606 dcon::leader_id lid;
2607 if(std::holds_alternative<dcon::army_id>(foru)) {
2608 lid = state.world.army_get_general_from_army_leadership(std::get<dcon::army_id>(foru));
2609 disabled = !command::can_change_general(state, state.local_player_nation, std::get<dcon::army_id>(foru), dcon::leader_id{});
2610 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2611 lid = state.world.navy_get_admiral_from_navy_leadership(std::get<dcon::navy_id>(foru));
2612 disabled = !command::can_change_admiral(state, state.local_player_nation, std::get<dcon::navy_id>(foru), dcon::leader_id{});
2613 }
2614
2615 auto pculture = state.world.nation_get_primary_culture(state.local_player_nation);
2616 auto ltype = pculture.get_group_from_culture_group_membership().get_leader();
2617
2618 if(ltype && lid) {
2619 auto admiral = state.world.leader_get_is_admiral(lid);
2620 if(admiral) {
2621 auto arange = ltype.get_admirals();
2622 if(arange.size() > 0) {
2623 auto rval = rng::get_random(state, uint32_t(state.world.leader_get_since(lid).value), uint32_t(lid.value));
2624 auto in_range = rng::reduce(uint32_t(rval), arange.size());
2625
2627 base_data.data.image.gfx_object = arange[in_range];
2629 base_data.data.button.button_image = arange[in_range];
2630 }
2631 } else {
2632 auto grange = ltype.get_generals();
2633 if(grange.size() > 0) {
2634 auto rval = rng::get_random(state, uint32_t(state.world.leader_get_since(lid).value), uint32_t(lid.value));
2635 auto in_range = rng::reduce(uint32_t(rval), grange.size());
2636
2638 base_data.data.image.gfx_object = grange[in_range];
2640 base_data.data.button.button_image = grange[in_range];
2641 }
2642 }
2643 } else {
2648 }
2649 }
2650
2653 }
2654
2655 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
2656 auto foru = retrieve<unit_var>(state, parent);
2657 dcon::leader_id lid;
2658 if(std::holds_alternative<dcon::army_id>(foru)) {
2659 lid = state.world.army_get_general_from_army_leadership(std::get<dcon::army_id>(foru));
2660 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2661 lid = state.world.navy_get_admiral_from_navy_leadership(std::get<dcon::navy_id>(foru));
2662 }
2663 if(lid)
2664 display_leader_full(state, lid, contents, 0);
2665 }
2666
2667
2668 void button_action(sys::state& state) noexcept override {
2669 auto foru = retrieve<unit_var>(state, parent);
2671 if(std::holds_alternative<dcon::army_id>(foru)) {
2672 open_leader_selection(state, std::get<dcon::army_id>(foru), dcon::navy_id{}, location.x + base_data.size.x, location.y);
2673 } else {
2674 open_leader_selection(state, dcon::army_id{}, std::get<dcon::navy_id>(foru), location.x + base_data.size.x, location.y);
2675 }
2676 }
2677};
2678
2680public:
2681 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2682 if(name == "unitpanel_bg") {
2683 return make_element_by_type<whole_panel_button>(state, id);
2684 } else if(name == "leader_photo") {
2685 return make_element_by_type<multi_selection_leader_image>(state, id);
2686 } else if(name == "unitstrength") {
2687 return make_element_by_type <u_row_strength> (state, id);
2688 } else if(name == "unitattrition_icon") {
2689 return make_element_by_type<u_row_attrit_icon>(state, id);
2690 } else if(name == "org_bar") {
2691 return make_element_by_type<u_row_org_bar>(state, id);
2692 } else if(name == "str_bar") {
2693 return make_element_by_type<u_row_str_bar>(state, id);
2694 } else if(name == "disbandbutton") {
2695 return make_element_by_type<u_row_disband>(state, id);
2696 } else if(name == "splitinhalf") {
2697 return make_element_by_type<u_row_split>(state, id);
2698 } else if(name == "newunitbutton") {
2699 return make_element_by_type<u_row_new>(state, id);
2700 } else if(name == "remove_unit_from_selection_button") {
2701 return make_element_by_type<u_row_remove>(state, id);
2702 } else if(name == "unit_inf") {
2703 return make_element_by_type<u_row_inf>(state, id);
2704 } else if(name == "unit_inf_count") {
2705 return make_element_by_type<u_row_inf_count>(state, id);
2706 } else if(name == "unit_cav") {
2707 return make_element_by_type<u_row_cav>(state, id);
2708 } else if(name == "unit_cav_count") {
2709 return make_element_by_type<u_row_cav_count>(state, id);
2710 } else if(name == "unit_art") {
2711 return make_element_by_type<u_row_art>(state, id);
2712 } else if(name == "unit_art_count") {
2713 return make_element_by_type<u_row_art_count>(state, id);
2714 } else if(name == "location") {
2715 return make_element_by_type<u_row_location>(state, id);
2716 } else {
2717 return nullptr;
2718 }
2719 }
2720};
2721
2722class selected_unit_list : public listbox_element_base<selected_unit_item, unit_var> {
2723public:
2724 std::string_view get_row_element_name() override {
2725 return "alice_unit_row";
2726 }
2727 void on_update(sys::state& state) noexcept override {
2728 row_contents.clear();
2729 for(auto i : state.selected_armies)
2730 row_contents.push_back(i);
2731 for(auto i : state.selected_navies)
2732 row_contents.push_back(i);
2733 update(state);
2734 }
2735};
2736
2738 bool visible = true;
2739public:
2740 bool is_active(sys::state& state) noexcept override {
2741 for(auto i : state.selected_armies) {
2742 if(state.world.army_get_is_ai_controlled(i) == false)
2743 return false;
2744 }
2745 return true;
2746 }
2747 void on_update(sys::state& state) noexcept override {
2749 visible = state.selected_navies.empty();
2750 }
2753 }
2754 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
2755 text::add_line(state, contents, "alice_ai_controlled_unit");
2756 }
2757 void button_action(sys::state& state) noexcept override {
2758 bool all_on = true;
2759 for(auto i : state.selected_armies) {
2760 if(state.world.army_get_is_ai_controlled(i) == false) {
2761 all_on = false;
2762 break;
2763 }
2764 }
2765 for(auto a : state.selected_armies) {
2766 if(all_on) { //all on -> turn all off
2767 command::toggle_unit_ai_control(state, state.local_player_nation, a);
2768 } else { //some on -> turn all that are off into on, all off -> turn all on
2769 if(!state.world.army_get_is_ai_controlled(a)) {
2770 command::toggle_unit_ai_control(state, state.local_player_nation, a);
2771 }
2772 }
2773 }
2774 }
2775 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
2776 if(visible)
2778 }
2779};
2780
2782public:
2783 void on_create(sys::state& state) noexcept override {
2785 auto ptr = make_element_by_type<multi_unit_details_ai_controlled>(state, "alice_enable_ai_controlled_multi");
2786 add_child_to_front(std::move(ptr));
2787 }
2788
2789 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2790 if(name == "desc") {
2791 return make_element_by_type<units_selected_text>(state, id);
2792 } else if(name == "mergebutton") {
2793 return make_element_by_type<merge_all_button>(state, id);
2794 } else if(name == "close_multiunit") {
2795 return make_element_by_type<deselect_all_button> (state, id);
2796 } else if(name == "disband_multiunit") {
2797 return make_element_by_type<disband_all_button>(state, id);
2798 } else if(name == "unit_listbox") {
2799 return make_element_by_type<selected_unit_list>(state, id);
2800 } else {
2801 return nullptr;
2802 }
2803 }
2804};
2805
2807 dcon::unit_type_id id;
2809
2811 return id == o.id && amount == o.amount;
2812 }
2814 return !(*this == o);
2815 }
2816};
2817
2818using army_group_unit_type_info_optional = std::variant<std::monostate, army_group_unit_type_info>;
2819
2820using army_group_unit_type_info_grid_row = std::array<army_group_unit_type_info_optional, 3>;
2821
2823 void on_update(sys::state& state) noexcept override {
2824 auto regiment_type_data = retrieve<army_group_unit_type_info_optional>(state, parent);
2825 if(!std::holds_alternative<std::monostate>(regiment_type_data)) {
2826 frame = state.military_definitions.unit_base_definitions[std::get<army_group_unit_type_info>(regiment_type_data).id].icon - 1;
2827 }
2828 }
2829};
2830
2832 void on_update(sys::state& state) noexcept override {
2833 auto regiment_type_data = retrieve<army_group_unit_type_info_optional>(state, parent);
2834 if(!std::holds_alternative<std::monostate>(regiment_type_data)) {
2835 auto name_string_def = state.military_definitions.unit_base_definitions[std::get<army_group_unit_type_info>(regiment_type_data).id].name;
2836 set_text(state, text::produce_simple_string(state, name_string_def));
2837 }
2838 }
2839};
2840
2842 void on_update(sys::state& state) noexcept override {
2843 auto regiment_type_data = retrieve<army_group_unit_type_info_optional>(state, parent);
2844 if(!std::holds_alternative<std::monostate>(regiment_type_data)) {
2845 set_text(state, std::to_string(std::get<army_group_unit_type_info>(regiment_type_data).amount));
2846 }
2847 }
2848};
2849
2851public:
2853
2854 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2855 if(name == "alice_army_group_unit_type_entry_icon") {
2856 return make_element_by_type<unit_type_row_image>(state, id);
2857 } else if(name == "alice_army_group_unit_type_entry_name") {
2858 return make_element_by_type<unit_type_row_label>(state, id);
2859 } else if(name == "alice_army_group_unit_type_entry_amount") {
2860 return make_element_by_type<unit_type_row_amount>(state, id);
2861 }
2862 return nullptr;
2863 }
2864
2865 void impl_render(sys::state& state, int32_t x, int32_t y) noexcept override {
2866 if(!std::holds_alternative<std::monostate>(display_unit)) {
2868 }
2869 }
2870
2871 mouse_probe impl_probe_mouse(sys::state& state, int32_t x, int32_t y, mouse_probe_type type) noexcept override {
2872 if(!std::holds_alternative<std::monostate>(display_unit)) {
2874 } else {
2875 return mouse_probe{ nullptr, ui::xy_pair{} };
2876 }
2877 }
2878
2879 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
2880 if(payload.holds_type<army_group_unit_type_info_optional>()) {
2883 }
2885 }
2886};
2887
2888class unit_type_row : public listbox_row_element_base<army_group_unit_type_info_grid_row> {
2889public:
2890 std::array< unit_type_grid_item*, 3> grid_items;
2891
2892 void on_create(sys::state& state) noexcept override {
2894 auto def = state.ui_state.defs_by_name.find(state.lookup_key("alice_army_group_unit_type_grid_item"))->second.definition;
2895
2896 uint8_t additional_padding = 5;
2897
2898 {
2899 auto win = make_element_by_type<unit_type_grid_item>(state, def);
2900 win->base_data.position.x = int16_t(additional_padding);
2901 win->base_data.position.y = int16_t(3);
2902 grid_items[0] = win.get();
2903 add_child_to_front(std::move(win));
2904 }
2905 {
2906 auto win = make_element_by_type<unit_type_grid_item>(state, def);
2907 win->base_data.position.x = int16_t(additional_padding * 2 + win->base_data.size.x);
2908 win->base_data.position.y = int16_t(3);
2909 grid_items[1] = win.get();
2910 add_child_to_front(std::move(win));
2911 }
2912 {
2913 auto win = make_element_by_type<unit_type_grid_item>(state, def);
2914 win->base_data.position.x = int16_t(additional_padding * 3 + win->base_data.size.x * 2);
2915 win->base_data.position.y = int16_t(3);
2916 grid_items[2] = win.get();
2917 add_child_to_front(std::move(win));
2918 }
2919 }
2920
2921 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2922 return nullptr;
2923 }
2924
2925 void on_update(sys::state& state) noexcept override {
2926 grid_items[0]->display_unit = content[0];
2927 grid_items[1]->display_unit = content[1];
2928 grid_items[2]->display_unit = content[2];
2929 }
2930};
2931
2932class selected_army_group_land_units_list : public listbox_element_base<unit_type_row, army_group_unit_type_info_grid_row> {
2933public:
2934 std::string_view get_row_element_name() override {
2935 return "alice_army_group_unit_type_row";
2936 }
2937
2938 void on_update(sys::state& state) noexcept override {
2939 row_contents.clear();
2940
2941 std::vector<uint32_t> regiments_by_type{ };
2942 regiments_by_type.resize(state.military_definitions.unit_base_definitions.size() + 2);
2943
2944 if(state.selected_army_group) {
2945 auto group = fatten(state.world, state.selected_army_group);
2946
2947 for(auto regiment_membership : group.get_automated_army_group_membership_regiment()) {
2948 auto regiment = regiment_membership.get_regiment().get_regiment_from_automation();
2949 auto type = regiment.get_type();
2950 if(type) {
2951 regiments_by_type[type.index()] += 1;
2952 }
2953 }
2954 for(auto navy_membership : group.get_automated_army_group_membership_navy()) {
2955 for(auto ship_membership : state.world.navy_get_navy_membership(navy_membership.get_navy())) {
2956 auto type = ship_membership.get_ship().get_type();
2957 if(type) {
2958 regiments_by_type[type.index()] += 1;
2959 }
2960 }
2961 }
2962 }
2963
2964 size_t unit_types = state.military_definitions.unit_base_definitions.size();
2965 for(size_t i = 2; i < unit_types; i += 3) {
2966 army_group_unit_type_info_grid_row content_of_grid_row;
2967
2968 for(size_t j = 0; (j + i < unit_types) && (j < 3); j += 1) {
2969 dcon::unit_type_id type_id{ dcon::unit_type_id::value_base_t(j + i) };
2970
2971 army_group_unit_type_info new_item = {
2972 .id = type_id,
2973 .amount = regiments_by_type[type_id.index()]
2974 };
2975
2976 content_of_grid_row[j] = new_item;
2977 }
2978
2979 row_contents.push_back({
2980 content_of_grid_row
2981 });
2982 }
2983 update(state);
2984 }
2985};
2986
2987class selected_army_group_sea_units_list : public listbox_element_base<selected_unit_item, unit_var> {
2988public:
2989 std::string_view get_row_element_name() override {
2990 return "alice_unit_row";
2991 }
2992 void on_update(sys::state& state) noexcept override {
2993 row_contents.clear();
2994 if(state.selected_army_group) {
2995 auto group = dcon::fatten(state.world, state.selected_army_group);
2996 for(auto navy_membership : group.get_automated_army_group_membership_navy()) {
2997 row_contents.push_back(navy_membership.get_navy());
2998 }
2999 }
3000 update(state);
3001 }
3002};
3003
3005public:
3006 void on_create(sys::state& state) noexcept override {
3008
3009 xy_pair base_position = { 15, 0 };
3010 uint16_t base_offset = 95;
3011
3012 {
3013 auto win = make_element_by_type<selected_army_group_land_details_item<0>>(state,
3014 state.ui_state.defs_by_name.find(state.lookup_key("unittype_item"))->second.definition);
3015 win->base_data.position.x = base_position.x + (0 * base_offset); // Flexnudge
3016 add_child_to_front(std::move(win));
3017 }
3018 {
3019 auto win = make_element_by_type<selected_army_group_land_details_item<1>>(state,
3020 state.ui_state.defs_by_name.find(state.lookup_key("unittype_item"))->second.definition);
3021 win->base_data.position.x = base_position.x + (1 * base_offset); // Flexnudge
3022 add_child_to_front(std::move(win));
3023 }
3024 {
3025 auto win = make_element_by_type<selected_army_group_land_details_item<2>>(state,
3026 state.ui_state.defs_by_name.find(state.lookup_key("unittype_item"))->second.definition);
3027 win->base_data.position.x = base_position.x + (2 * base_offset); // Flexnudge
3028 add_child_to_front(std::move(win));
3029 }
3030
3031 {
3032 auto win = make_element_by_type<selected_army_group_sea_details_item<0>>(state,
3033 state.ui_state.defs_by_name.find(state.lookup_key("unittype_item"))->second.definition);
3034 win->base_data.position.x = base_position.x + (0 * base_offset); // Flexnudge
3035 win->base_data.position.y = 40;
3036 add_child_to_front(std::move(win));
3037 }
3038 {
3039 auto win = make_element_by_type<selected_army_group_sea_details_item<1>>(state,
3040 state.ui_state.defs_by_name.find(state.lookup_key("unittype_item"))->second.definition);
3041 win->base_data.position.x = base_position.x + (1 * base_offset); // Flexnudge
3042 win->base_data.position.y = 40;
3043 add_child_to_front(std::move(win));
3044 }
3045 {
3046 auto win = make_element_by_type<selected_army_group_sea_details_item<2>>(state,
3047 state.ui_state.defs_by_name.find(state.lookup_key("unittype_item"))->second.definition);
3048 win->base_data.position.x = base_position.x + (2 * base_offset); // Flexnudge
3049 win->base_data.position.y = 40;
3050 add_child_to_front(std::move(win));
3051 }
3052 }
3053};
3054
3056public:
3057 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
3058 if(name == "alice_army_group_unit_listbox") {
3059 return make_element_by_type<selected_army_group_land_units_list>(state, id);
3060 }
3061 return nullptr;
3062 }
3063};
3064
3066 void button_action(sys::state& state) noexcept final {
3067 if(state.selected_army_group_order == sys::army_group_order::defend) {
3068 state.selected_army_group_order = sys::army_group_order::none;
3069 } else {
3070 state.selected_army_group_order = sys::army_group_order::defend;
3071 }
3072 on_update(state);
3073 state.game_state_updated.store(true, std::memory_order_release);
3074 }
3075
3076 void on_update(sys::state& state) noexcept override {
3077 if(state.selected_army_group_order == sys::army_group_order::defend) {
3078 frame = 1;
3079 } else {
3080 frame = 0;
3081 }
3082 }
3083
3084 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
3086 }
3087
3088 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
3089 text::add_line(state, contents, "alice_battleplanner_defend_order");
3090 }
3091};
3092
3094 void button_action(sys::state& state) noexcept final {
3095 if(state.selected_army_group_order == sys::army_group_order::siege) {
3096 state.selected_army_group_order = sys::army_group_order::none;
3097 } else {
3098 state.selected_army_group_order = sys::army_group_order::siege;
3099 }
3100
3101 on_update(state);
3102 state.game_state_updated.store(true, std::memory_order_release);
3103 }
3104
3105 void on_update(sys::state& state) noexcept override {
3106 if(state.selected_army_group_order == sys::army_group_order::siege) {
3107 frame = 1;
3108 } else {
3109 frame = 0;
3110 }
3111 }
3112
3113 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
3115 }
3116
3117 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
3118 text::add_line(state, contents, "alice_battleplanner_enforce_control_order");
3119 }
3120};
3121
3123 void button_action(sys::state& state) noexcept final {
3124 if(state.selected_army_group_order == sys::army_group_order::designate_port) {
3125 state.selected_army_group_order = sys::army_group_order::none;
3126 } else {
3127 state.selected_army_group_order = sys::army_group_order::designate_port;
3128 }
3129 on_update(state);
3130 state.game_state_updated.store(true, std::memory_order_release);
3131 }
3132
3133 void on_update(sys::state& state) noexcept override {
3134 if(state.selected_army_group_order == sys::army_group_order::designate_port) {
3135 frame = 1;
3136 } else {
3137 frame = 0;
3138 }
3139 }
3140
3141 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
3143 }
3144
3145 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
3146 text::add_line(state, contents, "alice_battleplanner_travel_origin_order");
3147 }
3148};
3149
3151 void button_action(sys::state& state) noexcept final {
3152 for(auto item : state.selected_armies) {
3153 state.world.for_each_automated_army_group([&](dcon::automated_army_group_id group) {
3154 state.remove_army_army_group_clean(group, item);
3155 });
3156 state.add_army_to_army_group(state.selected_army_group, item);
3157 }
3158 for(auto item : state.selected_navies) {
3159 state.world.for_each_automated_army_group([&](dcon::automated_army_group_id group) {
3160 state.remove_navy_from_army_group(group, item);
3161 });
3162 state.add_navy_to_army_group(state.selected_army_group, item);
3163 }
3164 }
3165
3166 void on_update(sys::state& state) noexcept override {
3167 if(state.selected_army_group) {
3168 disabled = false;
3169 } else {
3170 disabled = true;
3171 }
3172 }
3173
3174 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
3176 }
3177
3178 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
3179 text::add_line(state, contents, "alice_armygroup_go_to_selection");
3180 }
3181};
3182
3184 void button_action(sys::state& state) noexcept final {
3185 if(state.selected_army_group) {
3186 for(auto item : state.selected_armies) {
3187 state.remove_army_army_group_clean(state.selected_army_group, item);
3188 }
3189 for(auto item : state.selected_navies) {
3190 state.remove_navy_from_army_group(state.selected_army_group, item);
3191 }
3192 }
3193 }
3194
3195 void on_update(sys::state& state) noexcept override {
3196 if(state.selected_army_group) {
3197 disabled = false;
3198 } else {
3199 disabled = true;
3200 }
3201 }
3202
3203 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
3205 }
3206
3207 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
3208 text::add_line(state, contents, "alice_battleplanner_travel_origin_order");
3209 }
3210};
3211
3213 void button_action(sys::state& state) noexcept override {
3214 auto selected = state.map_state.selected_province;
3215 if(selected) {
3216 state.new_army_group(selected);
3217 }
3218 }
3219
3220 void on_update(sys::state& state) noexcept override {
3221 if(state.map_state.selected_province) {
3222 disabled = false;
3223 return;
3224 }
3225 disabled = true;
3226 }
3227};
3228
3230 void button_action(sys::state& state) noexcept override {
3231 auto selected = state.selected_army_group;
3232 if(selected) {
3233 state.delete_army_group(selected);
3234 }
3235 }
3236
3237 void on_update(sys::state& state) noexcept override {
3238 if(state.selected_army_group) {
3239 disabled = false;
3240 return;
3241 }
3242 disabled = true;
3243 }
3244};
3245
3247public:
3248 void on_update(sys::state & state) noexcept override {
3249 auto content = retrieve<dcon::automated_army_group_id>(state, parent);
3250 auto hq = state.world.automated_army_group_get_hq(content);
3252 }
3253};
3254
3256 void button_action(sys::state& state) noexcept override {
3257 auto info = retrieve<dcon::automated_army_group_id>(state, parent);
3258 state.select_army_group(info);
3259 }
3260
3261 void on_update(sys::state& state) noexcept override {
3262 auto info = retrieve<dcon::automated_army_group_id>(state, parent);
3263
3264
3265 if(state.selected_army_group) {
3266 if(info) {
3267 auto local_hq = state.world.automated_army_group_get_hq(info);
3268 auto selected_hq = state.world.automated_army_group_get_hq(state.selected_army_group);
3269 if(local_hq == selected_hq) {
3270 frame = 1;
3271 return;
3272 }
3273 }
3274 }
3275 frame = 0;
3276 }
3277};
3278
3279class army_group_entry : public listbox_row_element_base<dcon::automated_army_group_id> {
3280 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
3281 if(name == "alice_select_army_group_button") {
3282 return make_element_by_type<select_army_group_button>(state, id);
3283 } else if(name == "alice_army_group_location") {
3284 return make_element_by_type<army_group_location>(state, id);
3285 } else {
3286 return nullptr;
3287 }
3288 }
3289};
3290
3291class army_groups_list : public listbox_element_base<army_group_entry, dcon::automated_army_group_id> {
3292public:
3293 std::string_view get_row_element_name() override {
3294 return "alice_army_group_entry";
3295 }
3296 void on_update(sys::state& state) noexcept override {
3297 row_contents.clear();
3298 state.world.for_each_automated_army_group([&](dcon::automated_army_group_id item) {
3299 row_contents.push_back(item);
3300 });
3301 update(state);
3302 }
3303};
3304
3306 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
3307 if(name == "alice_army_group_listbox") {
3308 return make_element_by_type<army_groups_list>(state, id);
3309 } else {
3310 return nullptr;
3311 }
3312 }
3313};
3314
3316 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
3317 if(name == "alice_armygroup_new_button") {
3318 return make_element_by_type<new_army_group_button>(state, id);
3319 } else if(name == "alice_armygroup_delete_button") {
3320 return make_element_by_type<delete_army_group_button>(state, id);
3321 } else if(name == "alice_battleplanner_remove_selected") {
3322 return make_element_by_type<remove_selected_units_from_army_group_button>(state, id);
3323 } else if(name == "alice_army_group_listbox_wrapper") {
3324 return make_element_by_type<army_groups_list_wrapper>(state, id);
3325 } else {
3326 return nullptr;
3327 }
3328 }
3329};
3330
3332 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
3333 if(name == "alice_battleplanner_add_selected") {
3334 return make_element_by_type<add_selected_units_to_army_group_button>(state, id);
3335 } if(name == "alice_battleplanner_remove_selected") {
3336 return make_element_by_type<remove_selected_units_from_army_group_button>(state, id);
3337 } else {
3338 return nullptr;
3339 }
3340 }
3341};
3342
3344public:
3345 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
3346 if(name == "alice_armygroup_defend_button") {
3347 return make_element_by_type<toggle_defend_order_button>(state, id);
3348 } else if(name == "alice_armygroup_enforce_control_button") {
3349 return make_element_by_type<toggle_enforce_control_order_button>(state, id);
3350 } else if(name == "alice_armygroup_naval_travel_origin_button") {
3351 return make_element_by_type<toggle_ferry_origin_order_button>(state, id);
3352 } else if(name == "alice_armygroup_go_to_selection") {
3353 return make_element_by_type<go_to_battleplanner_selection_button>(state, id);
3354 } else {
3355 return nullptr;
3356 }
3357 }
3358};
3359
3361public:
3362 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
3363 if(name == "alice_army_group_regiments_list_header") {
3364 return make_element_by_type<army_group_details_window_header>(state, id);
3365 }
3366 if(name == "alice_army_group_control") {
3367 return make_element_by_type<army_group_control_window>(state, id);
3368 }
3369 if(name == "alice_army_group_unit_listbox_wrapper") {
3370 return make_element_by_type<army_group_details_window_body>(state, id);
3371 }
3372 return nullptr;
3373 }
3374};
3375
3376} // namespace ui
dcon::text_key get_name() noexcept
void on_update(sys::state &state) noexcept override
void on_create(sys::state &state) noexcept override
void button_action(sys::state &state) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
void on_create(sys::state &state) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
void on_update(sys::state &state) noexcept override
std::string_view get_row_element_name() override
void on_update(sys::state &state) noexcept override
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 render(sys::state &state, int32_t x, int32_t y) noexcept override
void add_child_to_front(std::unique_ptr< element_base > child) noexcept final
void move_child_to_front(element_base *child) noexcept final
void impl_on_update(sys::state &state) noexcept override
void button_action(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void button_action(sys::state &state) noexcept override
element_base * parent
virtual message_result test_mouse(sys::state &state, int32_t x, int32_t y, mouse_probe_type type) noexcept
virtual message_result get(sys::state &state, Cyto::Any &payload) noexcept
virtual void on_update(sys::state &state) 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)
virtual mouse_probe impl_probe_mouse(sys::state &state, int32_t x, int32_t y, mouse_probe_type type) noexcept
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
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
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
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 on_update(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
void button_action(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
bool is_active(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_create(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
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::string_view get_row_element_name() 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::string_view get_row_element_name() override
void on_update(sys::state &state) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
std::string_view get_row_element_name() override
void on_update(sys::state &state) noexcept override
void on_create(sys::state &state) noexcept override
void set_text(sys::state &state, std::string const &new_text)
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 render(sys::state &state, int32_t x, int32_t y) noexcept override
message_result on_lbutton_down(sys::state &state, int32_t x, int32_t y, sys::key_modifiers mods) 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
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 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
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 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
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
bool is_active(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 button_action(sys::state &state) noexcept override
std::string_view get_row_element_name() override
void on_update(sys::state &state) noexcept override
void on_create(sys::state &state) noexcept override
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 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 render(sys::state &state, int32_t x, int32_t y) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
message_result test_mouse(sys::state &state, int32_t x, int32_t y, mouse_probe_type type) noexcept override
void on_update(sys::state &state) noexcept override
message_result test_mouse(sys::state &state, int32_t x, int32_t y, mouse_probe_type type) 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 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
message_result test_mouse(sys::state &state, int32_t x, int32_t y, mouse_probe_type t) noexcept override
void button_action(sys::state &state) noexcept override
void on_update(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
std::string_view get_row_element_name() override
void on_create(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
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 render(sys::state &state, int32_t x, int32_t y) noexcept override
void button_action(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
message_result test_mouse(sys::state &state, int32_t x, int32_t y, mouse_probe_type t) 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
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
void on_create(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
message_result get(sys::state &state, Cyto::Any &payload) 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_create(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 on_update(sys::state &state) noexcept override
void on_update(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
void button_action(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 button_action(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
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
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 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 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
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
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
window_element_base * reorg_window
void on_create(sys::state &state) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
window_element_base * combat_window
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 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 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 on_update(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 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 on_update(sys::state &state) noexcept override
army_group_unit_type_info_optional display_unit
void impl_render(sys::state &state, int32_t x, int32_t y) noexcept override
mouse_probe impl_probe_mouse(sys::state &state, int32_t x, int32_t y, mouse_probe_type type) noexcept override
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
void on_update(sys::state &state) noexcept override
std::string_view get_row_element_name() override
void on_create(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
std::array< unit_type_grid_item *, 3 > grid_items
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 button_shift_action(sys::state &state) noexcept override
void on_create(sys::state &state) noexcept override
void mark_ships_to_split(sys::state &state, dcon::nation_id source, std::array< dcon::ship_id, num_packed_units > const &list)
Definition: commands.cpp:4417
constexpr size_t num_packed_units
Definition: commands.hpp:414
bool can_change_unit_type(sys::state &state, dcon::nation_id source, dcon::regiment_id regiments[num_packed_units], dcon::ship_id ships[num_packed_units], dcon::unit_type_id new_type)
Definition: commands.cpp:3909
bool can_change_admiral(sys::state &state, dcon::nation_id source, dcon::navy_id a, dcon::leader_id l)
Definition: commands.cpp:4386
void toggle_rebel_hunting(sys::state &state, dcon::nation_id source, dcon::army_id a)
Definition: commands.cpp:3814
bool can_change_general(sys::state &state, dcon::nation_id source, dcon::army_id a, dcon::leader_id l)
Definition: commands.cpp:4367
bool can_delete_army(sys::state &state, dcon::nation_id source, dcon::army_id a)
Definition: commands.cpp:4324
void mark_regiments_to_split(sys::state &state, dcon::nation_id source, std::array< dcon::regiment_id, num_packed_units > const &list)
Definition: commands.cpp:4396
void evenly_split_army(sys::state &state, dcon::nation_id source, dcon::army_id a)
Definition: commands.cpp:4110
bool can_evenly_split_army(sys::state &state, dcon::nation_id source, dcon::army_id a)
Definition: commands.cpp:4118
bool can_evenly_split_navy(sys::state &state, dcon::nation_id source, dcon::navy_id a)
Definition: commands.cpp:4174
bool can_disband_undermanned_regiments(sys::state &state, dcon::nation_id source, dcon::army_id a)
Definition: commands.cpp:3799
void disband_undermanned_regiments(sys::state &state, dcon::nation_id source, dcon::army_id a)
Definition: commands.cpp:3791
bool can_merge_navies(sys::state &state, dcon::nation_id source, dcon::navy_id a, dcon::navy_id b)
Definition: commands.cpp:3744
bool can_split_navy(sys::state &state, dcon::nation_id source, dcon::navy_id a)
Definition: commands.cpp:4277
bool can_delete_navy(sys::state &state, dcon::nation_id source, dcon::navy_id a)
Definition: commands.cpp:4345
bool can_split_army(sys::state &state, dcon::nation_id source, dcon::army_id a)
Definition: commands.cpp:4229
void evenly_split_navy(sys::state &state, dcon::nation_id source, dcon::navy_id a)
Definition: commands.cpp:4166
bool can_merge_armies(sys::state &state, dcon::nation_id source, dcon::army_id a, dcon::army_id b)
Definition: commands.cpp:3689
pop_satisfaction_wrapper_fat fatten(data_container const &c, pop_satisfaction_wrapper_id id) noexcept
int32_t free_transport_capacity(sys::state &state, dcon::navy_id n)
Definition: military.cpp:6851
float effective_army_speed(sys::state &state, dcon::army_id a)
Definition: military.cpp:4217
float attrition_amount(sys::state &state, dcon::navy_id a)
Definition: military.cpp:5471
economy::commodity_set get_required_supply(sys::state &state, dcon::nation_id owner, dcon::army_id army)
Definition: military.cpp:7217
bool can_embark_onto_sea_tile(sys::state &state, dcon::nation_id from, dcon::province_id p, dcon::army_id a)
Definition: military.cpp:4191
bool will_recieve_attrition(sys::state &state, dcon::navy_id a)
Definition: military.cpp:5340
float effective_navy_speed(sys::state &state, dcon::navy_id n)
Definition: military.cpp:4242
int32_t transport_capacity(sys::state &state, dcon::navy_id n)
Definition: military.cpp:6843
void render_tinted_subsprite(sys::state const &state, int frame, int total_frames, float x, float y, float width, float height, float r, float g, float b, GLuint texture_handle, ui::rotation rot, bool flipped, bool rtl)
GLuint get_texture_handle(sys::state &state, dcon::texture_id id, bool keep_data)
Definition: texture.cpp:1066
void render_tinted_textured_rect(sys::state const &state, float x, float y, float width, float height, float r, float g, float b, GLuint texture_handle, ui::rotation rot, bool flipped, bool rtl)
uint32_t reduce(uint32_t value_in, uint32_t upper_bound)
Definition: prng.cpp:46
uint64_t get_random(sys::state const &state, uint32_t value_in)
Definition: prng.cpp:8
void selected_ships_add(sys::state &state, dcon::ship_id sh)
void selected_ships_clear(sys::state &state)
float blue_from_int(uint32_t v)
float green_from_int(uint32_t v)
void selected_regiments_clear(sys::state &state)
uint32_t pack_color(float r, float g, float b)
key_modifiers
Definition: constants.hpp:156
float red_from_int(uint32_t v)
void selected_regiments_add(sys::state &state, dcon::regiment_id reg)
void add_to_layout_box(sys::state &state, layout_base &dest, layout_box &box, embedded_flag ico)
Definition: text.cpp:1165
std::string resolve_string_substitution(sys::state &state, dcon::text_key source_text, substitution_map const &mp)
Definition: text.cpp:2137
std::string get_name_as_string(sys::state &state, T t)
Definition: text.hpp:957
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
endless_layout create_endless_layout(sys::state &state, layout &dest, layout_parameters const &params)
Definition: text.cpp:1100
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
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
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
void open_leader_selection(sys::state &state, dcon::army_id a, dcon::navy_id v, int32_t x, int32_t y)
std::array< army_group_unit_type_info_optional, 3 > army_group_unit_type_info_grid_row
unitpanel_action
tooltip_behavior
void send(sys::state &state, element_base *parent, T value)
message_result
std::variant< std::monostate, army_group_unit_type_info > army_group_unit_type_info_optional
void display_leader_full(sys::state &state, dcon::leader_id lid, text::layout_base &contents, int32_t indent)
xy_pair get_absolute_non_mirror_location(sys::state &state, element_base const &node)
void active_modifiers_description(sys::state &state, text::layout_base &layout, dcon::nation_id n, int32_t identation, dcon::national_modifier_value nmid, bool header)
uint uint32_t
uchar uint8_t
static constexpr uint32_t set_size
Holds important data about the game world, state, and other data regarding windowing,...
bool operator!=(army_group_unit_type_info const &o) const
bool operator==(army_group_unit_type_info const &o) const
dcon::gfx_object_id button_image
element_type get_element_type() const
rotation get_rotation() const
union ui::element_data::internal_data data
dcon::gfx_object_id gfx_object
int32_t current_template
std::vector< sys::macro_builder_template > templates
ankerl::unordered_dense::map< dcon::text_key, element_target, hash_text_key > defs_by_name