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 {
36 }
37
40 }
41
42 void on_update(sys::state& state) noexcept override {
43 auto content = retrieve<T>(state, parent);
44 if constexpr(std::is_same_v<T, dcon::army_id>) {
45 disabled = !command::can_split_army(state, state.local_player_nation, content);
46 } else if constexpr(std::is_same_v<T, dcon::navy_id>) {
47 disabled = !command::can_split_navy(state, state.local_player_nation, content);
48 }
49 }
50
51 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
52 text::add_line(state, contents, "new_unit");
53 }
54};
55
56template<class T>
58public:
59 void button_action(sys::state& state) noexcept override {
60 auto content = retrieve<T>(state, parent);
61 if constexpr(std::is_same_v<T, dcon::army_id>) {
62 command::evenly_split_army(state, state.local_player_nation, content);
63 } else {
64 command::evenly_split_navy(state, state.local_player_nation, content);
65 }
66 state.select(content); //deselect original
67 }
68
69 void on_update(sys::state& state) noexcept override {
70 auto content = retrieve<T>(state, parent);
71 if constexpr(std::is_same_v<T, dcon::army_id>) {
72 disabled = !command::can_evenly_split_army(state, state.local_player_nation, content);
73 } else {
74 disabled = !command::can_evenly_split_navy(state, state.local_player_nation, content);
75 }
76 }
77
80 }
81
82 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
83 text::add_line(state, contents, "splitinhalf");
84 }
85};
86
87template<class T>
89public:
90 void button_action(sys::state& state) noexcept override {
91 auto content = retrieve<T>(state, parent);
92 if constexpr(std::is_same_v<T, dcon::army_id>) {
93 command::delete_army(state, state.local_player_nation, content);
94 } else {
95 command::delete_navy(state, state.local_player_nation, content);
96 }
98 }
99
100 void on_update(sys::state& state) noexcept override {
101 auto content = retrieve<T>(state, parent);
102 if constexpr(std::is_same_v<T, dcon::army_id>) {
103 disabled = !command::can_delete_army(state, state.local_player_nation, content);
104 } else {
105 disabled = !command::can_delete_navy(state, state.local_player_nation, content);
106 }
107 }
108
111 }
112
113 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
114 text::add_line(state, contents, "disband_unit");
115 }
116};
117
119public:
120 void on_update(sys::state& state) noexcept override {
121 disabled = !command::can_disband_undermanned_regiments(state, state.local_player_nation, retrieve<dcon::army_id>(state, parent));
122 color = sys::pack_color(255, 196, 196);
123 if(state.user_settings.color_blind_mode == sys::color_blind_mode::deutan || state.user_settings.color_blind_mode == sys::color_blind_mode::protan) {
124 color = sys::pack_color(255, 255, 255); //remap to blue
125 }
126 }
127 void button_action(sys::state& state) noexcept override {
128 command::disband_undermanned_regiments(state, state.local_player_nation, retrieve<dcon::army_id>(state, parent));
129 }
132 }
133 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
134 text::add_line(state, contents, "disband_too_small_unit");
135 }
136};
137
138template<typename T>
140public:
141 void on_update(sys::state& state) noexcept override {
142 auto content = retrieve<T>(state, parent);
143 set_text(state, std::string(state.to_string_view(dcon::fatten(state.world, content).get_name())));
144 }
145};
146
147template<typename T>
149 void on_update(sys::state& state) noexcept override {
150 auto content = retrieve<T>(state, parent);
151 if constexpr(std::is_same_v<T, dcon::army_id>) {
152 auto fat = dcon::fatten(state.world, content);
153 set_text(state, std::string(state.to_string_view(fat.get_general_from_army_leadership().get_name())));
154 } else {
155 auto fat = dcon::fatten(state.world, content);
156 set_text(state, std::string(state.to_string_view(fat.get_admiral_from_navy_leadership().get_name())));
157 }
158 }
159};
160
161template<class T>
163public:
164
167 }
168
169 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
170 auto unit = retrieve<T>(state, parent);
171 dcon::leader_id lid;
172 if constexpr(std::is_same_v<T, dcon::army_id>) {
173 lid = state.world.army_get_general_from_army_leadership(unit);
174 } else {
175 lid = state.world.navy_get_admiral_from_navy_leadership(unit);
176 }
177 if(lid)
178 display_leader_full(state, lid, contents, 0);
179 }
180
181
182 void button_action(sys::state& state) noexcept override {
183 auto unit = retrieve<T>(state, parent);
185 if constexpr(std::is_same_v<T, dcon::army_id>) {
186 if(command::can_change_general(state, state.local_player_nation, unit, dcon::leader_id{}))
187 open_leader_selection(state, unit, dcon::navy_id{}, location.x, location.y);
188 } else {
189 if(command::can_change_admiral(state, state.local_player_nation, unit, dcon::leader_id{}))
190 open_leader_selection(state, dcon::army_id{}, unit, location.x, location.y);
191 }
192 }
193};
194
195template<class T>
197public:
198 dcon::gfx_object_id default_img;
199
200 void on_update(sys::state& state) noexcept override {
201 if(!default_img) {
206 }
207
208 auto unit = retrieve<T>(state, parent);
209 dcon::leader_id lid;
210 if constexpr(std::is_same_v<T, dcon::army_id>) {
211 lid = state.world.army_get_general_from_army_leadership(unit);
212 disabled = !command::can_change_general(state, state.local_player_nation, unit, dcon::leader_id{});
213 } else {
214 lid = state.world.navy_get_admiral_from_navy_leadership(unit);
215 disabled = !command::can_change_admiral(state, state.local_player_nation, unit, dcon::leader_id{});
216 }
217
218 auto pculture = state.world.nation_get_primary_culture(state.local_player_nation);
219 auto ltype = pculture.get_group_from_culture_group_membership().get_leader();
220
221 if(ltype && lid) {
222 auto admiral = state.world.leader_get_is_admiral(lid);
223 if(admiral) {
224 auto arange = ltype.get_admirals();
225 if(arange.size() > 0) {
226 auto rval = rng::get_random(state, uint32_t(state.world.leader_get_since(lid).value), uint32_t(lid.value));
227 auto in_range = rng::reduce(uint32_t(rval), arange.size());
229 base_data.data.image.gfx_object = arange[in_range];
231 base_data.data.button.button_image = arange[in_range];
232 }
233 } else {
234 auto grange = ltype.get_generals();
235 if(grange.size() > 0) {
236 auto rval = rng::get_random(state, uint32_t(state.world.leader_get_since(lid).value), uint32_t(lid.value));
237 auto in_range = rng::reduce(uint32_t(rval), grange.size());
239 base_data.data.image.gfx_object = grange[in_range];
241 base_data.data.button.button_image = grange[in_range];
242 }
243 }
244 } else {
249 }
250 }
251
254 }
255
256 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
257 auto unit = retrieve<T>(state, parent);
258 dcon::leader_id lid;
259 if constexpr(std::is_same_v<T, dcon::army_id>) {
260 lid = state.world.army_get_general_from_army_leadership(unit);
261 } else {
262 lid = state.world.navy_get_admiral_from_navy_leadership(unit);
263 }
264 if(lid)
265 display_leader_full(state, lid, contents, 0);
266 }
267
268
269 void button_action(sys::state& state) noexcept override {
270 auto unit = retrieve<T>(state, parent);
272 if constexpr(std::is_same_v<T, dcon::army_id>) {
273 open_leader_selection(state, unit, dcon::navy_id{}, location.x + base_data.size.x, location.y);
274 } else {
275 open_leader_selection(state, dcon::army_id{}, unit, location.x + base_data.size.x, location.y);
276 }
277 }
278};
279
280template<class T>
282public:
283 void on_update(sys::state& state) noexcept override {
284 auto content = retrieve<T>(state, parent);
285 if constexpr(std::is_same_v<T, dcon::army_id>) {
286 set_text(state, text::produce_simple_string(state, dcon::fatten(state.world, content).get_location_from_army_location().get_name()));
287 } else {
288 set_text(state, text::produce_simple_string(state, dcon::fatten(state.world, content).get_location_from_navy_location().get_name()));
289 }
290 }
291};
292template<class T>
294public:
297 }
298 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
299 text::add_line(state, contents, "uw_loc_iro");
300 }
301 void button_action(sys::state& state) noexcept override {
302 auto content = retrieve<T>(state, parent);
303 if constexpr(std::is_same_v<T, dcon::army_id>) {
304 auto p = dcon::fatten(state.world, content).get_location_from_army_location();
305 state.map_state.center_map_on_province(state, p);
306 } else {
307 auto p = dcon::fatten(state.world, content).get_location_from_navy_location();
308 state.map_state.center_map_on_province(state, p);
309 }
310 }
311};
312
313template<class T>
315public:
316 void on_update(sys::state& state) noexcept override {
317 auto content = retrieve<T>(state, parent);
318
319 float total_strength = 0.0f;
320 int32_t unit_count = 0;
321 if constexpr(std::is_same_v<T, dcon::army_id>) {
322 state.world.army_for_each_army_membership_as_army(content, [&](dcon::army_membership_id nmid) {
323 auto regiment = dcon::fatten(state.world, state.world.army_membership_get_regiment(nmid));
324 total_strength += regiment.get_strength();
325 ++unit_count;
326 });
327 } else {
328 state.world.navy_for_each_navy_membership_as_navy(content, [&](dcon::navy_membership_id nmid) {
329 auto ship = dcon::fatten(state.world, state.world.navy_membership_get_ship(nmid));
330 total_strength += ship.get_strength();
331 ++unit_count;
332 });
333 }
334 total_strength /= static_cast<float>(unit_count);
335 progress = total_strength;
336 }
337
340 }
341
342 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
343 auto content = retrieve<T>(state, parent);
344 float total_strength = 0.0f;
345 int32_t unit_count = 0;
346 if constexpr(std::is_same_v<T, dcon::army_id>) {
347 state.world.army_for_each_army_membership_as_army(content, [&](dcon::army_membership_id nmid) {
348 auto regiment = dcon::fatten(state.world, state.world.army_membership_get_regiment(nmid));
349 total_strength += regiment.get_strength();
350 ++unit_count;
351 });
352 } else {
353 state.world.navy_for_each_navy_membership_as_navy(content, [&](dcon::navy_membership_id nmid) {
354 auto ship = dcon::fatten(state.world, state.world.navy_membership_get_ship(nmid));
355 total_strength += ship.get_strength();
356 ++unit_count;
357 });
358 }
359 total_strength /= static_cast<float>(unit_count);
360
361 auto box = text::open_layout_box(contents, 0);
362 text::localised_format_box(state, contents, box, std::string_view("curr_comb_str"));
364 text::close_layout_box(contents, box);
365 }
366};
367
368template<class T>
370public:
371 void on_update(sys::state& state) noexcept override {
372 auto content = retrieve<T>(state, parent);
373
374 float total_org = 0.0f;
375 int32_t unit_count = 0;
376 if constexpr(std::is_same_v<T, dcon::army_id>) {
377 state.world.army_for_each_army_membership_as_army(content, [&](dcon::army_membership_id nmid) {
378 auto regiment = dcon::fatten(state.world, state.world.army_membership_get_regiment(nmid));
379 total_org += regiment.get_org();
380 ++unit_count;
381 });
382 } else {
383 state.world.navy_for_each_navy_membership_as_navy(content, [&](dcon::navy_membership_id nmid) {
384 auto ship = dcon::fatten(state.world, state.world.navy_membership_get_ship(nmid));
385 total_org += ship.get_org();
386 ++unit_count;
387 });
388 }
389 total_org /= static_cast<float>(unit_count);
390 progress = total_org;
391 }
392
395 }
396
397 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
398 auto content = retrieve<T>(state, parent);
399 float total_org = 0.0f;
400 int32_t unit_count = 0;
401 if constexpr(std::is_same_v<T, dcon::army_id>) {
402 state.world.army_for_each_army_membership_as_army(content, [&](dcon::army_membership_id nmid) {
403 auto regiment = dcon::fatten(state.world, state.world.army_membership_get_regiment(nmid));
404 total_org += regiment.get_org();
405 ++unit_count;
406 });
407 } else {
408 state.world.navy_for_each_navy_membership_as_navy(content, [&](dcon::navy_membership_id nmid) {
409 auto ship = dcon::fatten(state.world, state.world.navy_membership_get_ship(nmid));
410 total_org += ship.get_org();
411 ++unit_count;
412 });
413 }
414 total_org /= static_cast<float>(unit_count);
415
416 auto box = text::open_layout_box(contents, 0);
417 text::localised_format_box(state, contents, box, std::string_view("curr_comb_org"));
419 text::close_layout_box(contents, box);
420
421 if constexpr(std::is_same_v<T, dcon::army_id>) {
422 ui::active_modifiers_description(state, contents, state.local_player_nation, 0, sys::national_mod_offsets::land_organisation, true);
423 } else {
424 ui::active_modifiers_description(state, contents, state.local_player_nation, 0, sys::national_mod_offsets::naval_organisation, true);
425 }
426 }
427};
428
429template<class T>
431public:
432 void on_update(sys::state& state) noexcept override {
433 if constexpr(std::is_same_v<T, dcon::regiment_id>) {
434 auto regiment = retrieve<dcon::regiment_id>(state, parent);
435 frame = int(state.world.regiment_get_experience(regiment) * 10);
436 } else {
437 auto ship = retrieve<dcon::ship_id>(state, parent);
438 frame = int(state.world.ship_get_experience(ship) * 10);
439 }
440 }
441
442 void on_create(sys::state& state) noexcept override {
443 if constexpr(std::is_same_v<T, dcon::regiment_id>) {
444 auto regiment = retrieve<dcon::regiment_id>(state, parent);
445 frame = int(state.world.regiment_get_experience(regiment) * 10);
446 } else {
447 auto ship = retrieve<dcon::ship_id>(state, parent);
448 frame = int(state.world.ship_get_experience(ship) * 10);
449 }
450 }
451
454 }
455
456 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
457 if constexpr(std::is_same_v<T, dcon::regiment_id>) {
458 auto regiment = retrieve<dcon::regiment_id>(state, parent);
459 auto exp = state.world.regiment_get_experience(regiment);
460 auto box = text::open_layout_box(contents);
461 text::localised_format_box(state, contents, box, "unit_experience");
462 text::add_space_to_layout_box(state, contents, box);
464 text::close_layout_box(contents, box);
465 } else {
466 auto ship = retrieve<dcon::ship_id>(state, parent);
467 auto exp = state.world.ship_get_experience(ship);
468 auto box = text::open_layout_box(contents);
469 text::localised_format_box(state, contents, box, "unit_experience");
470 text::add_space_to_layout_box(state, contents, box);
472 text::close_layout_box(contents, box);
473 }
474 }
475};
476
477template<class T>
479 void on_update(sys::state& state) noexcept override {
480 auto content = retrieve<T>(state, parent);
481
482 int32_t total_strength = 0;
483 if constexpr(std::is_same_v<T, dcon::army_id>) {
484 state.world.army_for_each_army_membership_as_army(content, [&](dcon::army_membership_id nmid) {
485 auto regiment = dcon::fatten(state.world, state.world.army_membership_get_regiment(nmid));
486 total_strength += int32_t(regiment.get_strength() * state.defines.pop_size_per_regiment);
487 });
488 } else {
489 state.world.navy_for_each_navy_membership_as_navy(content, [&](dcon::navy_membership_id nmid) {
490 auto ship = dcon::fatten(state.world, state.world.navy_membership_get_ship(nmid));
491 ++total_strength;
492 });
493 }
494
495 set_text(state, text::prettify(total_strength));
496 }
497};
498
499template<class T>
501public:
502 bool visible = false;
503 void on_update(sys::state& state) noexcept override {
504 auto content = retrieve<T>(state, parent);
506 }
507 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
508 if(visible)
510 }
511};
512
513template<class T>
515public:
516 void on_update(sys::state& state) noexcept override {
517 auto content = retrieve<T>(state, parent);
518 auto amount = military::attrition_amount(state, content);
519 if(amount > 0)
521 else
522 set_text(state, "");
523 }
524};
525
526template<class T>
528public:
530
531 void on_update(sys::state& state) noexcept override {
532 auto content = retrieve<T>(state, parent);
533 if constexpr(std::is_same_v<T, dcon::army_id>) {
534 if(state.world.army_get_controller_from_army_control(content) == state.local_player_nation) {
535 color = sys::pack_color(210, 255, 210);
536 } else {
537 color = sys::pack_color(170, 190, 170);
538 }
539 } else {
540 if(state.world.navy_get_controller_from_navy_control(content) == state.local_player_nation) {
541 color = sys::pack_color(210, 210, 255);
542 } else {
543 color = sys::pack_color(170, 170, 190);
544 }
545 }
546 }
547
548 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
549 dcon::gfx_object_id gid;
554 }
555 if(gid) {
556 auto const& gfx_def = state.ui_defs.gfx[gid];
557 if(gfx_def.primary_texture_handle) {
558 if(gfx_def.number_of_frames > 1) {
560 gfx_def.number_of_frames, float(x), float(y), float(base_data.size.x), float(base_data.size.y),
562 ogl::get_texture_handle(state, gfx_def.primary_texture_handle, gfx_def.is_partially_transparent()),
563 base_data.get_rotation(), gfx_def.is_vertically_flipped(),
564 state.world.locale_get_native_rtl(state.font_collection.get_current_locale()));
565 } else {
566 ogl::render_tinted_textured_rect(state, float(x), float(y), float(base_data.size.x), float(base_data.size.y),
568 ogl::get_texture_handle(state, gfx_def.primary_texture_handle, gfx_def.is_partially_transparent()),
569 base_data.get_rotation(), gfx_def.is_vertically_flipped(),
570 state.world.locale_get_native_rtl(state.font_collection.get_current_locale()));
571 }
572 }
573 }
574 }
575};
576
577template<class T>
579 dcon::gfx_object_id disband_gfx{};
580 unit_selection_disband_too_small_button* disband_too_small_btn = nullptr;
581public:
584
585 void on_create(sys::state& state) noexcept override {
586 {
587 if constexpr(std::is_same_v<T, dcon::army_id>) {
588 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);
589 win2->base_data.position.y = base_data.position.y - 29;
590 win2->set_visible(state, false);
591 reorg_window = win2.get();
592 add_child_to_front(std::move(win2));
593 } else {
594 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);
595 win2->base_data.position.y = base_data.position.y - 29;
596 win2->set_visible(state, false);
597 reorg_window = win2.get();
598 add_child_to_front(std::move(win2));
599 }
600 }
602 if(disband_too_small_btn && disband_gfx) {
603 disband_too_small_btn->base_data.data.button.button_image = disband_gfx;
604 }
605 }
606
607 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
608 if(name == "unitpanel_bg") {
609 return make_element_by_type<unit_panel_dynamic_tinted_bg<T>>(state, id);
610 } else if(name == "leader_prestige_icon") {
611 return make_element_by_type<invisible_element>(state, id);
612 } else if(name == "leader_prestige_bar") {
613 return make_element_by_type<leader_prestige_progress_bar<T>>(state, id);
614 } else if(name == "prestige_bar_frame") {
615 return make_element_by_type<image_element_base>(state, id);
616 } else if(name == "unitname") {
617 auto ptr = make_element_by_type<unit_selection_unit_name_text<T>>(state, id);
618 ptr->base_data.position.x += 9;
619 ptr->base_data.position.y += 4;
620 return ptr;
621 } else if(name == "only_unit_from_selection_button") {
622 return make_element_by_type<invisible_element>(state, id);
623 } else if(name == "remove_unit_from_selection_button") {
624 return make_element_by_type<unit_selection_close_button>(state, id);
625 } else if(name == "newunitbutton") {
626 return make_element_by_type<unit_selection_new_unit_button<T>>(state, id);
627 } else if(name == "splitinhalf") {
628 return make_element_by_type<unit_selection_split_in_half_button<T>>(state, id);
629 } else if(name == "disbandbutton") {
630 auto ptr = make_element_by_type<unit_selection_disband_button<T>>(state, id);
631 disband_gfx = ptr->base_data.data.button.button_image;
632 return ptr;
633 } else if(name == "disbandtoosmallbutton") {
634 if constexpr(std::is_same_v<T, dcon::army_id>) {
635 auto ptr = make_element_by_type<unit_selection_disband_too_small_button>(state, id);
636 disband_too_small_btn = ptr.get();
637 return ptr;
638 } else {
639 return make_element_by_type<invisible_element>(state, id);
640 }
641 } else if(name == "str_bar") {
642 return make_element_by_type<unit_selection_str_bar<T>>(state, id);
643 } else if(name == "org_bar") {
644 return make_element_by_type<unit_selection_org_bar<T>>(state, id);
645 } else if(name == "unitattrition_icon") {
646 return make_element_by_type<unit_selection_attrition_icon<T>>(state, id);
647 } else if(name == "unitattrition") {
648 return make_element_by_type<unit_selection_attrition_amount<T>>(state, id);
649 } else if(name == "unitstrength") {
650 return make_element_by_type<unit_selection_total_str_text<T>>(state, id);
651 } else if(name == "unitlocation") {
652 return make_element_by_type<unit_selection_unit_location_text<T>>(state, id);
653 } else if(name == "unit_location_button") {
654 return make_element_by_type<unit_selection_unit_location_button<T>>(state, id);
655 } else if(name == "unitleader") {
656 return make_element_by_type<unit_selection_leader_name<T>>(state, id);
657 } else if(name == "leader_button") {
658 return make_element_by_type<unit_selection_change_leader_button<T>>(state, id);
659 } else if(name == "unit_activity") {
660 return make_element_by_type<image_element_base>(state, id);
661 } else if(name == "leader_photo") {
662 return make_element_by_type<unit_selection_leader_image<T>>(state, id);
663 } else {
664 return nullptr;
665 }
666 }
667
668 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
669 if(payload.holds_type<element_selection_wrapper<unitpanel_action>>()) {
670 auto action = any_cast<element_selection_wrapper<unitpanel_action>>(payload).data;
671 switch(action) {
673 // Bucket Carry, we dont handle this, but the parent does
674 parent->impl_get(state, payload);
675 // Tell reorg window to clean up after itself
677 reorg_window->impl_get(state, cpayload);
678 break;
682 break;
684
685 break;
686 } default: {
687 break;
688 }
689 }
691 }
693 }
694};
695
696template<std::size_t N>
698private:
699 simple_text_element_base* unitamount_text = nullptr;
700 simple_text_element_base* unitstrength_text = nullptr;
701public:
702 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
703 if(name == "unit_amount") {
704 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
705 unitamount_text = ptr.get();
706 return ptr;
707 } else if(name == "unit_strength") {
708 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
709 unitstrength_text = ptr.get();
710 return ptr;
711 } else if(name == "unit_icon") {
712 auto ptr = make_element_by_type<image_element_base>(state, id);
713 ptr->frame = N;
714 return ptr;
715 } else {
716 return nullptr;
717 }
718 }
719
720 void on_update(sys::state& state) noexcept override {
721 if(parent) {
722 uint16_t totalunits = 0;
723 uint32_t totalpops = 0;
724
725 if(state.selected_army_group) {
726 auto group = fatten(state.world, state.selected_army_group);
727 for(auto regiment_membership : group.get_automated_army_group_membership_regiment()) {
728 auto fat = regiment_membership.get_regiment().get_regiment_from_automation();
729 auto strenght = fat.get_strength() * state.defines.pop_size_per_regiment;
730 unitstrength_text->set_visible(state, true);
731
732 dcon::unit_type_id utid = fat.get_type();
733 auto result = utid ? state.military_definitions.unit_base_definitions[utid].type : military::unit_type::infantry;
734 if constexpr(N == 0) {
735 if(result == military::unit_type::infantry) {
736 totalunits++;
737 totalpops += uint32_t(strenght);
738 }
739 } else if constexpr(N == 1) {
740 if(result == military::unit_type::cavalry) {
741 totalunits++;
742 totalpops += uint32_t(strenght);
743 }
744 } else if constexpr(N == 2) {
746 totalunits++;
747 totalpops += uint32_t(strenght);
748 }
749 }
750 }
751 }
752 unitamount_text->set_text(state, text::format_float(totalunits, 0));
753 unitstrength_text->set_text(state, text::format_wholenum(totalpops));
754 }
755 }
756};
757
758template<std::size_t N>
760private:
761 simple_text_element_base* unitamount_text = nullptr;
762 simple_text_element_base* unitstrength_text = nullptr;
763public:
764 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
765 if(name == "unit_amount") {
766 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
767 unitamount_text = ptr.get();
768 return ptr;
769 } else if(name == "unit_strength") {
770 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
771 unitstrength_text = ptr.get();
772 return ptr;
773 } else if(name == "unit_icon") {
774 auto ptr = make_element_by_type<image_element_base>(state, id);
775 ptr->frame = 3 + N;
776 return ptr;
777 } else {
778 return nullptr;
779 }
780 }
781
782 void on_update(sys::state& state) noexcept override {
783 if(parent) {
784 unitstrength_text->set_visible(state, false);
785 uint16_t total = 0;
786
787 if(state.selected_army_group) {
788 auto army_group = fatten(state.world, state.selected_army_group);
789
790 for(auto navy_membership : army_group.get_automated_army_group_membership_navy()) {
791 auto fat = navy_membership.get_navy();
792
793 for(auto n : fat.get_navy_membership()) {
794 dcon::unit_type_id utid = n.get_ship().get_type();
795 auto result = utid ? state.military_definitions.unit_base_definitions[utid].type : military::unit_type::infantry;
796 if constexpr(N == 0) {
797 if(result == military::unit_type::big_ship) {
798 total++;
799 }
800 } else if constexpr(N == 1) {
801 if(result == military::unit_type::light_ship) {
802 total++;
803 }
804 } else if constexpr(N == 2) {
805 if(result == military::unit_type::transport) {
806 total++;
807 }
808 }
809 }
810 }
811 }
812
813 unitamount_text->set_text(state, text::format_float(total, 0));
814 }
815 }
816};
817
818template<class T, std::size_t N>
820private:
821 simple_text_element_base* unitamount_text = nullptr;
822 simple_text_element_base* unitstrength_text = nullptr;
823public:
824 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
825 if(name == "unit_amount") {
826 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
827 unitamount_text = ptr.get();
828 return ptr;
829 } else if(name == "unit_strength") {
830 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
831 unitstrength_text = ptr.get();
832 return ptr;
833 } else if(name == "unit_icon") {
834 auto ptr = make_element_by_type<image_element_base>(state, id);
835 if constexpr(std::is_same_v<T, dcon::army_id>) {
836 ptr->frame = N;
837 } else {
838 ptr->frame = 3 + N;
839 }
840 return ptr;
841 } else {
842 return nullptr;
843 }
844 }
845
846 void on_update(sys::state& state) noexcept override {
847 if(parent) {
848 Cyto::Any payload = T{};
849 parent->impl_get(state, payload);
850 auto content = any_cast<T>(payload);
851 auto fat = dcon::fatten(state.world, content);
852
853 if constexpr(std::is_same_v<T, dcon::army_id>) {
854 unitstrength_text->set_visible(state, true);
855
856 uint16_t totalunits = 0;
857 uint32_t totalpops = 0;
858 for(auto n : fat.get_army_membership()) {
859 dcon::unit_type_id utid = n.get_regiment().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::infantry) {
863 totalunits++;
864 totalpops += uint32_t(state.world.regiment_get_strength(n.get_regiment().id) * state.defines.pop_size_per_regiment);
865 }
866 } else if constexpr(N == 1) {
867 if(result == military::unit_type::cavalry) {
868 totalunits++;
869 totalpops += uint32_t(state.world.regiment_get_strength(n.get_regiment().id) * state.defines.pop_size_per_regiment);
870 }
871 } else if constexpr(N == 2) {
873 totalunits++;
874 totalpops += uint32_t(state.world.regiment_get_strength(n.get_regiment().id) * state.defines.pop_size_per_regiment);
875 }
876 }
877 }
878 unitamount_text->set_text(state, text::format_float(totalunits, 0));
879 unitstrength_text->set_text(state, text::format_wholenum(totalpops));
880 } else {
881 unitstrength_text->set_visible(state, false);
882 uint16_t total = 0;
883 for(auto n : fat.get_navy_membership()) {
884 dcon::unit_type_id utid = n.get_ship().get_type();
885 auto result = utid ? state.military_definitions.unit_base_definitions[utid].type : military::unit_type::infantry;
886 if constexpr(N == 0) {
887 if(result == military::unit_type::big_ship) {
888 total++;
889 }
890 } else if constexpr(N == 1) {
891 if(result == military::unit_type::light_ship) {
892 total++;
893 }
894 } else if constexpr(N == 2) {
895 if(result == military::unit_type::transport) {
896 total++;
897 }
898 }
899 }
900 unitamount_text->set_text(state, text::format_float(total, 0));
901 }
902 }
903 }
904};
905
907public:
908 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
909 if(name == "select") {
910 return make_element_by_type<image_element_base>(state, id);
911 } else if(name == "select_naval") {
912 return make_element_by_type<invisible_element>(state, id);
913 } else if(name == "sunit_icon") {
914 return make_element_by_type<subunit_details_type_icon<dcon::regiment_id>>(state, id);
915 } else if(name == "subunit_name") {
916 return make_element_by_type<subunit_details_name<dcon::regiment_id>>(state, id);
917 } else if(name == "subunit_type") {
918 return make_element_by_type<subunit_details_type_text<dcon::regiment_id>>(state, id);
919 } else if(name == "subunit_amount") {
920 return make_element_by_type<subunit_details_regiment_amount>(state, id);
921 } else if(name == "subunit_amount_naval") {
922 return make_element_by_type<invisible_element>(state, id);
923 } else if(name == "connected_pop") {
924 return make_element_by_type<regiment_pop_icon>(state, id);
925 } else if(name == "rebel_faction") {
926 return make_element_by_type<invisible_element>(state, id);
927 } else if(name == "unit_experience") {
928 return make_element_by_type<unit_experience_bar<dcon::regiment_id>>(state, id);
929 } else if(name == "org_bar") {
930 return make_element_by_type<subunit_organisation_progress_bar<dcon::regiment_id>>(state, id);
931 } else if(name == "str_bar") {
932 return make_element_by_type<subunit_strength_progress_bar<dcon::regiment_id>>(state, id);
933 } else {
934 return nullptr;
935 }
936 }
937};
938
940public:
941 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
942 if(name == "select") {
943 return make_element_by_type<invisible_element>(state, id);
944 } else if(name == "select_naval") {
945 return make_element_by_type<image_element_base>(state, id);
946 } else if(name == "sunit_icon") {
947 return make_element_by_type<subunit_details_type_icon<dcon::ship_id>>(state, id);
948 } else if(name == "subunit_name") {
949 return make_element_by_type<subunit_details_name<dcon::ship_id>>(state, id);
950 } else if(name == "subunit_type") {
951 return make_element_by_type<subunit_details_type_text<dcon::ship_id>>(state, id);
952 } else if(name == "subunit_amount") {
953 return make_element_by_type<invisible_element>(state, id);
954 } else if(name == "subunit_amount_naval") {
955 return make_element_by_type<subunit_details_ship_amount>(state, id);
956 } else if(name == "connected_pop") {
957 return make_element_by_type<invisible_element>(state, id);
958 } else if(name == "rebel_faction") {
959 return make_element_by_type<invisible_element>(state, id);
960 } else if(name == "unit_experience") {
961 return make_element_by_type<unit_experience_bar<dcon::ship_id>>(state, id);
962 } else if(name == "org_bar") {
963 return make_element_by_type<subunit_organisation_progress_bar<dcon::ship_id>>(state, id);
964 } else if(name == "str_bar") {
965 return make_element_by_type<subunit_strength_progress_bar<dcon::ship_id>>(state, id);
966 } else {
967 return nullptr;
968 }
969 }
970
971 void on_update(sys::state& state) noexcept override {
972 }
973};
974
975class unit_details_army_listbox : public listbox_element_base<subunit_details_entry_regiment, dcon::regiment_id> {
976protected:
977 std::string_view get_row_element_name() override {
978 return "subunit_entry";
979 }
980
981public:
982 void on_create(sys::state& state) noexcept override {
983 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
985 }
986
987 void on_update(sys::state& state) noexcept override {
988 auto content = retrieve<dcon::army_id>(state, parent);
989 row_contents.clear();
990 state.world.army_for_each_army_membership_as_army(content, [&](dcon::army_membership_id amid) {
991 auto rid = state.world.army_membership_get_regiment(amid);
992 row_contents.push_back(rid);
993 });
994 std::sort(row_contents.begin(), row_contents.end(), [&](dcon::regiment_id a, dcon::regiment_id b) {
995 auto av = state.world.regiment_get_type(a).index();
996 auto bv = state.world.regiment_get_type(b).index();
997 if(av != bv)
998 return av > bv;
999 else
1000 return a.index() < b.index();
1001 });
1002 update(state);
1003 }
1004};
1005class unit_details_navy_listbox : public listbox_element_base<subunit_details_entry_ship, dcon::ship_id> {
1006protected:
1007 std::string_view get_row_element_name() override {
1008 return "subunit_entry";
1009 }
1010
1011public:
1012 void on_create(sys::state& state) noexcept override {
1013 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
1015 }
1016
1017 void on_update(sys::state& state) noexcept override {
1018 auto content = retrieve<dcon::navy_id>(state, parent);
1019 row_contents.clear();
1020 state.world.navy_for_each_navy_membership_as_navy(content, [&](dcon::navy_membership_id nmid) {
1021 auto sid = state.world.navy_membership_get_ship(nmid);
1022 row_contents.push_back(sid);
1023 });
1024 std::sort(row_contents.begin(), row_contents.end(), [&](dcon::ship_id a, dcon::ship_id b) {
1025 auto av = state.world.ship_get_type(a).index();
1026 auto bv = state.world.ship_get_type(b).index();
1027 if(av != bv)
1028 return av > bv;
1029 else
1030 return a.index() < b.index();
1031 });
1032 update(state);
1033 }
1034};
1035
1037public:
1038 bool visible = false;
1039
1040 void button_action(sys::state& state) noexcept override {
1041 auto a = retrieve<dcon::army_id>(state, parent);
1042 auto p = state.world.army_get_location_from_army_location(a);
1043 int32_t max_cap = 0;
1044 for(auto n : state.world.province_get_navy_location(p)) {
1045 if(n.get_navy().get_controller_from_navy_control() == state.local_player_nation &&
1046 !bool(n.get_navy().get_battle_from_navy_battle_participation())) {
1047 max_cap = std::max(military::free_transport_capacity(state, n.get_navy()), max_cap);
1048 }
1049 }
1050 if(!military::can_embark_onto_sea_tile(state, state.local_player_nation, p, a)
1051 && max_cap > 0) { //require splitting
1052 auto regs = state.world.army_get_army_membership(a);
1053 int32_t army_cap = int32_t(regs.end() - regs.begin());
1054 int32_t to_split = army_cap - max_cap;
1055 //can mark 10 regiments to be split at a time
1056 std::array<dcon::regiment_id, command::num_packed_units> data;
1057 int32_t i = 0;
1058 data.fill(dcon::regiment_id{});
1059 for(auto reg : state.world.army_get_army_membership(a)) {
1060 if(to_split == 0)
1061 break;
1062 //
1063 data[i] = reg.get_regiment();
1064 ++i;
1065 if(i >= int32_t(command::num_packed_units)) { //reached max allowed
1066 command::mark_regiments_to_split(state, state.local_player_nation, data);
1067 data.fill(dcon::regiment_id{});
1068 i = 0;
1069 }
1070 //
1071 --to_split;
1072 }
1073 if(i > 0) { //leftovers
1074 command::mark_regiments_to_split(state, state.local_player_nation, data);
1075 }
1076 command::split_army(state, state.local_player_nation, a);
1077 command::embark_army(state, state.local_player_nation, a);
1078 } else { //no split
1079 command::embark_army(state, state.local_player_nation, a);
1080 }
1081 }
1082 void on_update(sys::state& state) noexcept override {
1083 auto a = retrieve<dcon::army_id>(state, parent);
1084 auto p = state.world.army_get_location_from_army_location(a);
1085 visible = !bool(state.world.army_get_navy_from_army_transport(a)); //not already in ship
1086 disabled = true;
1087 frame = 0;
1088 if(visible) {
1089 int32_t max_cap = 0;
1090 for(auto n : state.world.province_get_navy_location(p)) {
1091 if(n.get_navy().get_controller_from_navy_control() == state.local_player_nation &&
1092 !bool(n.get_navy().get_battle_from_navy_battle_participation())) {
1093 max_cap = std::max(military::free_transport_capacity(state, n.get_navy()), max_cap);
1094 }
1095 }
1096 disabled = max_cap <= 0;
1097 //require splitting
1098 if(!military::can_embark_onto_sea_tile(state, state.local_player_nation, p, a)
1099 && max_cap > 0) {
1100 frame = 1;
1101 }
1102 }
1103 }
1106 }
1107
1108 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1109 auto n = retrieve<dcon::army_id>(state, parent);
1110 auto loc = state.world.army_get_location_from_army_location(n);
1111
1112 text::add_line(state, contents, "uw_load_is_valid");
1113 text::add_line_with_condition(state, contents, "alice_load_unload_1", military::can_embark_onto_sea_tile(state, state.local_player_nation, loc, n));
1114 }
1115 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
1116 if(visible)
1118 }
1119 message_result test_mouse(sys::state& state, int32_t x, int32_t y, mouse_probe_type t) noexcept override {
1120 if(visible)
1121 return button_element_base::test_mouse(state, x, y, t);
1123 }
1124};
1126public:
1127 bool visible = false;
1128
1129 void button_action(sys::state& state) noexcept override {
1130 auto n = retrieve<dcon::army_id>(state, parent);
1131 command::embark_army(state, state.local_player_nation, n);
1132 }
1133 void on_update(sys::state& state) noexcept override {
1134 auto n = retrieve<dcon::army_id>(state, parent);
1135 auto tprted = state.world.army_get_navy_from_army_transport(n);
1136 auto loc = state.world.army_get_location_from_army_location(n);
1137
1138 visible = bool(tprted);
1139
1140 if(loc.index() >= state.province_definitions.first_sea_province.index()) {
1141 disabled = true;
1142 } else {
1143 disabled = false;
1144 }
1145 }
1148 }
1149
1150 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1151 auto n = retrieve<dcon::army_id>(state, parent);
1152 auto tprted = state.world.army_get_navy_from_army_transport(n);
1153 auto loc = state.world.army_get_location_from_army_location(n);
1154
1155 text::add_line(state, contents, "uw_unload_valid");
1156 text::add_line_with_condition(state, contents, "alice_load_unload_2", bool(tprted));
1157 text::add_line_with_condition(state, contents, "alice_load_unload_3", loc.index() < state.province_definitions.first_sea_province.index());
1158 }
1159 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
1160 if(visible)
1162 }
1163 message_result test_mouse(sys::state& state, int32_t x, int32_t y, mouse_probe_type t) noexcept override {
1164 if(visible)
1165 return button_element_base::test_mouse(state, x, y, t);
1167 }
1168};
1170public:
1171 void button_action(sys::state& state) noexcept override {
1172 auto n = retrieve<dcon::navy_id>(state, parent);
1173 auto tprted = state.world.navy_get_army_transport(n);
1174 std::vector<dcon::army_id> tmp;
1175 for(auto t : tprted)
1176 tmp.push_back(t.get_army());
1177 for(auto a : tmp)
1178 command::embark_army(state, state.local_player_nation, a);
1179 }
1180
1181 void on_update(sys::state& state) noexcept override {
1182 auto n = retrieve<dcon::navy_id>(state, parent);
1183 auto tprted = state.world.navy_get_army_transport(n);
1184 auto loc = state.world.navy_get_location_from_navy_location(n);
1185
1186 if(tprted.begin() == tprted.end() || loc.index() >= state.province_definitions.first_sea_province.index()) {
1187 disabled = true;
1188 } else {
1189 disabled = false;
1190 }
1191 }
1192
1195 }
1196
1197 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1198 auto n = retrieve<dcon::navy_id>(state, parent);
1199 auto tprted = state.world.navy_get_army_transport(n);
1200 auto loc = state.world.navy_get_location_from_navy_location(n);
1201
1202 text::add_line(state, contents, "alice_unload_fleet");
1203 text::add_line_with_condition(state, contents, "alice_load_unload_4", tprted.begin() != tprted.end());
1204 text::add_line_with_condition(state, contents, "alice_load_unload_5", loc.index() < state.province_definitions.first_sea_province.index());
1205 }
1206};
1207
1209public:
1210 void on_create(sys::state& state) noexcept override {
1211 base_data.position.x -= int16_t(50);
1213 }
1214 void on_update(sys::state& state) noexcept override {
1215 auto n = retrieve<dcon::navy_id>(state, parent);
1216
1217 auto tcap = military::transport_capacity(state, n);
1220 if(tcap != tfree) {
1221 auto txt = std::to_string(tfree) + " (" + std::to_string(tcap) + ")";
1222 text::add_to_substitution_map(sub, text::variable_type::num, std::string_view(txt));
1223 set_text(state, text::resolve_string_substitution(state, std::string_view("load_capacity_label"), sub));
1224 } else {
1226 set_text(state, text::resolve_string_substitution(state, std::string_view("load_capacity_label"), sub));
1227 }
1228 }
1229
1230};
1231
1233public:
1234 bool visible = false;
1235 void on_update(sys::state& state) noexcept override {
1236 auto a = retrieve<dcon::army_id>(state, parent);
1237 visible = !state.world.army_get_is_rebel_hunter(a) && state.world.army_get_controller_from_army_control(a) == state.local_player_nation;
1238 }
1239 message_result test_mouse(sys::state& state, int32_t x, int32_t y, mouse_probe_type type) noexcept override {
1240 if(visible)
1243 }
1246 }
1247 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1248 text::add_line(state, contents, "unit_enable_rebel_hunt");
1249 }
1250 void button_action(sys::state& state) noexcept override {
1251 command::toggle_rebel_hunting(state, state.local_player_nation, retrieve<dcon::army_id>(state, parent));
1252 }
1253 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
1254 if(visible)
1256 }
1257};
1259public:
1260 bool visible = false;
1261 void on_update(sys::state& state) noexcept override {
1262 auto a = retrieve<dcon::army_id>(state, parent);
1263 visible = state.world.army_get_is_rebel_hunter(a) && state.world.army_get_controller_from_army_control(a) == state.local_player_nation;
1264 }
1265 message_result test_mouse(sys::state& state, int32_t x, int32_t y, mouse_probe_type type) noexcept override {
1266 if(visible)
1269 }
1272 }
1273 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1274 text::add_line(state, contents, "alice_unit_disable_rebel_hunt");
1275 }
1276 void button_action(sys::state& state) noexcept override {
1277 command::toggle_rebel_hunting(state, state.local_player_nation, retrieve<dcon::army_id>(state, parent));
1278 }
1279 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
1280 if(visible)
1282 }
1283};
1285public:
1286 bool is_active(sys::state& state) noexcept override {
1287 return state.world.army_get_is_ai_controlled(retrieve<dcon::army_id>(state, parent));
1288 }
1291 }
1292 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1293 text::add_line(state, contents, "alice_ai_controlled_unit");
1294 }
1295 void button_action(sys::state& state) noexcept override {
1296 auto a = retrieve<dcon::army_id>(state, parent);
1297 command::toggle_unit_ai_control(state, state.local_player_nation, a);
1298 }
1299 void on_update(sys::state& state) noexcept override {
1300 auto a = retrieve<dcon::army_id>(state, parent);
1301 disabled = state.world.army_get_controller_from_army_control(a) != state.local_player_nation;
1302 }
1303};
1304
1306public:
1307 void on_update(sys::state& state) noexcept override {
1308 auto army = retrieve<dcon::army_id>(state, parent);
1309 auto navy = retrieve<dcon::navy_id>(state, parent);
1310
1311 economy::commodity_set commodities;
1312
1313 auto owner = state.local_player_nation;
1314
1315 float spending_level = .0f;
1316
1317 if(army) {
1318 commodities = military::get_required_supply(state, state.local_player_nation, army);
1319 spending_level = float(state.world.nation_get_land_spending(owner)) / 100.0f;
1320 } else if(navy) {
1321 commodities = military::get_required_supply(state, state.local_player_nation, navy);
1322 spending_level = float(state.world.nation_get_naval_spending(owner)) / 100.0f;
1323 }
1324
1325
1326 uint32_t total_commodities = state.world.commodity_size();
1327
1328 float max_supply = 0.0f;
1329 float actual_supply = 0.0f;
1330
1331
1332 auto nations_commodity_spending = state.world.nation_get_spending_level(owner);
1333
1334 for(uint32_t i = 0; i < total_commodities; ++i) {
1335 if(!commodities.commodity_type[i]) {
1336 break;
1337 }
1338
1339 dcon::commodity_id c{ dcon::commodity_id::value_base_t(i) };
1340
1341 auto satisfaction = state.world.nation_get_demand_satisfaction(owner, c);
1342 auto val = commodities.commodity_type[i];
1343
1344 max_supply += commodities.commodity_amounts[i];
1345 actual_supply += commodities.commodity_amounts[i] * satisfaction * nations_commodity_spending * spending_level;
1346 }
1347
1348 float median_supply = max_supply > 0.0f ? actual_supply / max_supply : 0.0f;
1349
1350 progress = median_supply;
1351 }
1352
1355 }
1356
1357 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1358 auto army = retrieve<dcon::army_id>(state, parent);
1359 auto navy = retrieve<dcon::navy_id>(state, parent);
1360 economy::commodity_set commodities;
1361
1362 float spending_level = .0f;
1363 auto owner = state.local_player_nation;
1364
1365 if(army) {
1366 commodities = military::get_required_supply(state, state.local_player_nation, army);
1367 spending_level = float(state.world.nation_get_land_spending(owner)) / 100.0f;
1368 } else if(navy) {
1369 commodities = military::get_required_supply(state, state.local_player_nation, navy);
1370 spending_level = float(state.world.nation_get_naval_spending(owner)) / 100.0f;
1371 }
1372
1373
1374 uint32_t total_commodities = state.world.commodity_size();
1375
1376 float max_supply = 0.0f;
1377 float actual_supply = 0.0f;
1378
1379 auto nations_commodity_spending = state.world.nation_get_spending_level(owner);
1380 for(uint32_t i = 0; i < total_commodities; ++i) {
1381 if(!commodities.commodity_type[i]) {
1382 break;
1383 }
1384 dcon::commodity_id c{ dcon::commodity_id::value_base_t(i) };
1385
1386 auto satisfaction = state.world.nation_get_demand_satisfaction(owner, c);
1387 auto val = commodities.commodity_type[i];
1388
1389 max_supply += commodities.commodity_amounts[i];
1390 actual_supply += commodities.commodity_amounts[i] * satisfaction * nations_commodity_spending * spending_level;
1391 }
1392
1393 float median_supply = max_supply > 0.0f ? actual_supply / max_supply : 0.0f;
1394 text::add_line(state, contents, "unit_current_supply", text::variable_type::val, int16_t(median_supply * 100.f));
1396 for(uint32_t i = 0; i < economy::commodity_set::set_size; ++i) {
1397 if(commodities.commodity_type[i] && commodities.commodity_amounts[i] > 0) {
1398 dcon::commodity_id c{ dcon::commodity_id::value_base_t(i) };
1399 float satisfaction = state.world.nation_get_demand_satisfaction(owner, c);
1400 float wanted_commodity = commodities.commodity_amounts[i];
1401 float actual_commodity = commodities.commodity_amounts[i] * satisfaction * nations_commodity_spending * spending_level;
1402
1403 int32_t display_satisfaction = int32_t(satisfaction * 100);
1404
1405 if(satisfaction == 1 || satisfaction >= 0.95) {
1406 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);
1407 } else if (satisfaction < 0.95 && satisfaction >= 0.5) {
1408 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);
1409 } else {
1410 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);
1411 }
1412 }
1413 }
1414 }
1415};
1416
1418public:
1419 void on_update(sys::state& state) noexcept override {
1420 auto contents = text::create_endless_layout(
1421 state,
1424 0,
1425 0,
1426 static_cast<int16_t>(base_data.size.x),
1427 static_cast<int16_t>(base_data.size.y),
1429 0,
1432 true
1433 });
1434
1435 auto box = text::open_layout_box(contents);
1436
1437 for(dcon::unit_type_id::value_base_t i = 0; i < state.military_definitions.unit_base_definitions.size(); i++) {
1438 auto amount = state.ui_state.main_template.amounts[i];
1439
1440 if(amount < 1) {
1441 continue;
1442 }
1443
1444 auto const utid = dcon::unit_type_id(i);
1445
1446 std::string padding = i < 10 ? "0" : "";
1447
1448 text::add_to_layout_box(state, contents, box, text::int_wholenum{ amount });
1449
1450 std::string description = "@*" + padding + std::to_string(i);
1451
1452 text::add_unparsed_text_to_layout_box(state, contents, box, description);
1453 }
1454
1455 text::close_layout_box(contents, box);
1456 }
1457};
1458
1460 std::vector<dcon::province_id> provinces;
1461public:
1462 void on_create(sys::state& state) noexcept override {
1464 }
1465 void on_update(sys::state& state) noexcept override {
1466 disabled = false;
1467 }
1468 void button_action(sys::state& state) noexcept override {
1469 auto army = retrieve<dcon::army_id>(state, parent);
1470 auto army_location = state.world.army_get_location_from_army_location(army);
1471
1472 state.fill_vector_of_connected_provinces(army_location, true, provinces);
1473 if(provinces.empty())
1474 return;
1475
1476 std::array<uint8_t, sys::macro_builder_template::max_types> current_distribution;
1477 current_distribution.fill(0);
1478
1479 for(auto reg : state.world.army_get_army_membership(army)) {
1480 current_distribution[reg.get_regiment().get_type().index()] += 1;
1481 }
1482
1483 state.build_up_to_template_land(
1484 state.ui_state.main_template,
1485 army_location,
1486 provinces,
1487 current_distribution
1488 );
1489 }
1490};
1491
1493 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1494 if(name == "composition") {
1495 return make_element_by_type<main_template_composition_label>(state, id);
1496 } else if(name == "background") {
1497 return make_element_by_type< apply_template_to_army_location_button>(state, id);
1498 } else {
1499 return nullptr;
1500 }
1501 }
1502};
1503
1504template<class T>
1506private:
1507 simple_text_element_base* navytransport_text = nullptr;
1508public:
1509 void on_create(sys::state& state) noexcept override {
1511 if constexpr(std::is_same_v<T, dcon::army_id>) {
1512 auto ptr = make_element_by_type<unit_details_ai_controlled>(state, "alice_enable_ai_controlled");
1513 add_child_to_front(std::move(ptr));
1514 }
1515 }
1516
1517 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1518 if(name == "load_button" && std::is_same_v<T, dcon::army_id>) {
1519 if constexpr(std::is_same_v<T, dcon::army_id>) {
1520 return make_element_by_type<unit_details_load_army_button>(state, id);
1521 } else {
1522 return make_element_by_type<invisible_element>(state, id);
1523 }
1524 } else if(name == "unload_button") {
1525 if constexpr(std::is_same_v<T, dcon::army_id>) {
1526 return make_element_by_type<unit_details_unload_army_button>(state, id);
1527 } else {
1528 return make_element_by_type<unit_details_unload_navy_button>(state, id);
1529 }
1530 } else if(name == "enable_rebel_button") {
1531 if constexpr(std::is_same_v<T, dcon::army_id>) {
1532 return make_element_by_type<unit_details_hunt_rebels>(state, id);
1533 } else {
1534 return make_element_by_type<invisible_element>(state, id);
1535 }
1536 } else if(name == "disable_rebel_button") {
1537 if constexpr(std::is_same_v<T, dcon::army_id>) {
1538 return make_element_by_type<unit_details_dont_hunt_rebels>(state, id);
1539 } else {
1540 return make_element_by_type<invisible_element>(state, id);
1541 }
1542 } else if(name == "attach_unit_button"
1543 || name == "detach_unit_button"
1544 || name == "select_land") {
1545
1546 return make_element_by_type<invisible_element>(state, id);
1547 } else if(name == "header") {
1548 if constexpr(std::is_same_v<T, dcon::army_id>) {
1549 return make_element_by_type<invisible_element>(state, id);
1550 } else {
1551 return make_element_by_type< navy_transport_text>(state, id);
1552 }
1553 } else if(name == "alice_build_up_to_template_window") {
1554 if constexpr(std::is_same_v<T, dcon::army_id>) {
1555 return make_element_by_type<apply_template_container>(state, id);
1556 } else {
1557 return make_element_by_type<invisible_element>(state, id);
1558 }
1559 } else {
1560 return nullptr;
1561 }
1562 }
1563};
1564
1565template<class T>
1567 simple_text_element_base* unitspeed_text = nullptr;
1568 image_element_base* unitrecon_icon = nullptr;
1569 simple_text_element_base* unitrecon_text = nullptr;
1570 image_element_base* unitengineer_icon = nullptr;
1571 simple_text_element_base* unitengineer_text = nullptr;
1572 progress_bar* unitsupply_bar = nullptr;
1573 image_element_base* unitdugin_icon = nullptr;
1574 unit_selection_panel<T>* unit_selection_win = nullptr;
1575
1576
1577
1578public:
1580
1581 void on_create(sys::state& state) noexcept override {
1583 base_data.position.y = 250;
1584
1585 xy_pair base_position = {20,
1586 0}; // state.ui_defs.gui[state.ui_state.defs_by_name.find("unittype_item_start")->second.definition].position;
1587 xy_pair base_offset = state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("unittype_item_offset"))->second.definition].position;
1588
1589 {
1590 auto win = make_element_by_type<unit_details_type_item<T, 0>>(state,
1591 state.ui_state.defs_by_name.find(state.lookup_key("unittype_item"))->second.definition);
1592 win->base_data.position.x = base_position.x + (0 * base_offset.x); // Flexnudge
1593 win->base_data.position.y = base_position.y + (0 * base_offset.y); // Flexnudge
1594 add_child_to_front(std::move(win));
1595 }
1596 {
1597 auto win = make_element_by_type<unit_details_type_item<T, 1>>(state,
1598 state.ui_state.defs_by_name.find(state.lookup_key("unittype_item"))->second.definition);
1599 win->base_data.position.x = base_position.x + (1 * base_offset.x); // Flexnudge
1600 win->base_data.position.y = base_position.y + (1 * base_offset.y); // Flexnudge
1601 add_child_to_front(std::move(win));
1602 }
1603 {
1604 auto win = make_element_by_type<unit_details_type_item<T, 2>>(state,
1605 state.ui_state.defs_by_name.find(state.lookup_key("unittype_item"))->second.definition);
1606 win->base_data.position.x = base_position.x + (2 * base_offset.x); // Flexnudge
1607 win->base_data.position.y = base_position.y + (2 * base_offset.y); // Flexnudge
1608 add_child_to_front(std::move(win));
1609 }
1610
1611 const xy_pair item_offset = state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("unittype_item"))->second.definition].position;
1612 if constexpr(std::is_same_v<T, dcon::army_id>) {
1613 auto ptr = make_element_by_type<unit_details_army_listbox>(state,
1614 state.ui_state.defs_by_name.find(state.lookup_key("sup_subunits"))->second.definition);
1615 ptr->base_data.position.y = base_position.y + item_offset.y + (3 * base_offset.y) + 72 - 32;
1616 ptr->base_data.size.y += 32;
1617 add_child_to_front(std::move(ptr));
1618 } else {
1619 auto ptr = make_element_by_type<unit_details_navy_listbox>(state,
1620 state.ui_state.defs_by_name.find(state.lookup_key("sup_subunits"))->second.definition);
1621 ptr->base_data.position.y = base_position.y + item_offset.y + (3 * base_offset.y) + 72 - 32;
1622 ptr->base_data.size.y += 32;
1623 add_child_to_front(std::move(ptr));
1624 }
1625
1626 {
1627 auto ptr = make_element_by_type<unit_details_buttons<T>>(state,
1628 state.ui_state.defs_by_name.find(state.lookup_key("sup_buttons_window"))->second.definition);
1629 ptr->base_data.position.y = base_data.size.y; // Nudge
1630 add_child_to_front(std::move(ptr));
1631 }
1632
1633 {
1634 auto ptr =
1635 make_element_by_type<unit_selection_panel<T>>(state, state.ui_state.defs_by_name.find(state.lookup_key("unitpanel"))->second.definition);
1636 unit_selection_win = ptr.get();
1637 ptr->base_data.position.y = -80;
1638 add_child_to_front(std::move(ptr));
1639 }
1640 }
1641
1642 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1643 if(name == "unit_bottom_bg") {
1644 return make_element_by_type<unit_panel_dynamic_tinted_bg<T>>(state, id);
1645 } else if(name == "icon_speed") {
1646 return make_element_by_type<image_element_base>(state, id);
1647 } else if(name == "speed") {
1648 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1649 unitspeed_text = ptr.get();
1650 return ptr;
1651 } else if(name == "icon_recon") {
1652 auto ptr = make_element_by_type<image_element_base>(state, id);
1653 unitrecon_icon = ptr.get();
1654 return ptr;
1655 } else if(name == "recon") {
1656 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1657 unitrecon_text = ptr.get();
1658 return ptr;
1659 } else if(name == "icon_engineer") {
1660 auto ptr = make_element_by_type<image_element_base>(state, id);
1661 unitengineer_icon = ptr.get();
1662 return ptr;
1663 } else if(name == "engineer") {
1664 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1665 unitengineer_text = ptr.get();
1666 return ptr;
1667 } else if(name == "icon_supplies_small") {
1668 return make_element_by_type<image_element_base>(state, id);
1669 } else if(name == "supply_status") {
1670 auto ptr = make_element_by_type<unit_supply_bar>(state, id);
1671 unitsupply_bar = ptr.get();
1672 return ptr;
1673 } else if(name == "unitstatus_dugin") {
1674 auto ptr = make_element_by_type<image_element_base>(state, id);
1675 unitdugin_icon = ptr.get();
1676 return ptr;
1677 } else {
1678 return nullptr;
1679 }
1680 }
1681
1682 void on_update(sys::state& state) noexcept override {
1683 if constexpr(std::is_same_v<T, dcon::navy_id>) {
1684 unitengineer_icon->set_visible(state, false);
1685 unitengineer_text->set_visible(state, false);
1686 unitrecon_icon->set_visible(state, false);
1687 unitrecon_text->set_visible(state, false);
1688
1691 unitspeed_text->set_text(state, text::resolve_string_substitution(state, std::string_view("speed"), sub));
1692 } else if constexpr(std::is_same_v<T, dcon::army_id>) {
1693 unitengineer_icon->set_visible(state, true);
1694 unitengineer_text->set_visible(state, true);
1695 unitrecon_icon->set_visible(state, true);
1696 unitrecon_text->set_visible(state, true);
1697
1700 unitspeed_text->set_text(state, text::resolve_string_substitution(state, std::string_view("speed"), sub));
1701 }
1702 }
1703
1704 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
1705 if(payload.holds_type<T>()) {
1706 payload.emplace<T>(unit_id);
1708 } else if(payload.holds_type<element_selection_wrapper<T>>()) {
1709 unit_id = any_cast<element_selection_wrapper<T>>(payload).data;
1712 } else if(payload.holds_type<element_selection_wrapper<dcon::leader_id>>()) {
1713 auto content = any_cast<element_selection_wrapper<dcon::leader_id>>(payload).data;
1714 if constexpr(std::is_same_v<T, dcon::army_id>) {
1715 command::change_general(state, state.local_player_nation, unit_id, content);
1716 } else {
1717 command::change_admiral(state, state.local_player_nation, unit_id, content);
1718 }
1720 } else if(payload.holds_type<element_selection_wrapper<unitpanel_action>>()) {
1721 auto content = any_cast<element_selection_wrapper<unitpanel_action>>(payload).data;
1722 switch(content) {
1724 {
1726 unit_selection_win->reorg_window->impl_get(state, cpayload);
1727 state.selected_armies.clear();
1728 state.selected_navies.clear();
1729 set_visible(state, false);
1730 state.game_state_updated.store(true, std::memory_order_release);
1731 break;
1732 }
1733 default:
1734 break;
1735 };
1737 }
1739 }
1740};
1741
1743public:
1744 void on_update(sys::state& state) noexcept override {
1746 text::add_to_substitution_map(m, text::variable_type::x, int64_t(state.selected_armies.size() + state.selected_navies.size()));
1747 set_text(state, text::resolve_string_substitution(state, "multiunit_header", m));
1748 }
1749};
1750
1752public:
1753 void button_action(sys::state& state) noexcept override {
1754 if(state.selected_armies.size() > 0) {
1755 auto first = state.selected_armies[0];
1756 for(uint32_t i = 1; i < state.selected_armies.size(); ++i) {
1757 command::merge_armies(state, state.local_player_nation, first, state.selected_armies[i]);
1758 }
1759 }
1760 if(state.selected_navies.size() > 0) {
1761 auto first = state.selected_navies[0];
1762 for(uint32_t i = 1; i < state.selected_navies.size(); ++i) {
1763 command::merge_navies(state, state.local_player_nation, first, state.selected_navies[i]);
1764 }
1765 }
1766 }
1767
1768 void on_update(sys::state& state) noexcept override {
1769 disabled = false;
1770
1771 if(state.selected_armies.size() > 0) {
1772
1773 auto first = state.selected_armies[0];
1774
1775 for(uint32_t i = 1; i < state.selected_armies.size(); ++i) {
1776 if(!command::can_merge_armies(state, state.local_player_nation, first, state.selected_armies[i])) {
1777 disabled = true;
1778 return;
1779 }
1780 }
1781 }
1782 if(state.selected_navies.size() > 0) {
1783 auto first = state.selected_navies[0];
1784
1785 for(uint32_t i = 1; i < state.selected_navies.size(); ++i) {
1786 if(!command::can_merge_navies(state, state.local_player_nation, first, state.selected_navies[i])) {
1787 disabled = true;
1788 return;
1789 }
1790 }
1791 }
1792 }
1793};
1794
1796public:
1797 void button_action(sys::state& state) noexcept override {
1798 state.selected_armies.clear();
1799 state.selected_navies.clear();
1800 state.game_state_updated.store(true, std::memory_order_release);
1801 }
1802};
1803
1805public:
1806 void button_action(sys::state& state) noexcept override {
1807 for(auto a : state.selected_armies) {
1808 command::delete_army(state, state.local_player_nation, a);
1809 }
1810 for(auto a : state.selected_navies) {
1811 command::delete_navy(state, state.local_player_nation, a);
1812 }
1813 }
1816 }
1817
1818 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1819 text::add_line(state, contents, "disband_all");
1820 }
1821};
1822
1824public:
1825 void button_action(sys::state& state) noexcept override {
1826 auto foru = retrieve<unit_var>(state, parent);
1827 if(std::holds_alternative<dcon::army_id>(foru)) {
1828 state.selected_armies.clear();
1829 state.selected_navies.clear();
1830 state.select(std::get<dcon::army_id>(foru));
1831 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
1832 state.selected_armies.clear();
1833 state.selected_navies.clear();
1834 state.select(std::get<dcon::navy_id>(foru));
1835 }
1836 }
1837 void button_shift_action(sys::state& state) noexcept override {
1838 auto foru = retrieve<unit_var>(state, parent);
1839 if(std::holds_alternative<dcon::army_id>(foru)) {
1840 state.deselect(std::get<dcon::army_id>(foru));
1841 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
1842 state.deselect(std::get<dcon::navy_id>(foru));
1843 }
1844 }
1845};
1846
1848public:
1849 void on_update(sys::state& state) noexcept override {
1850 auto foru = retrieve<unit_var>(state, parent);
1851 float total = 0.0f;
1852 if(std::holds_alternative<dcon::army_id>(foru)) {
1853 auto a = std::get<dcon::army_id>(foru);
1854 for(auto r : state.world.army_get_army_membership(a)) {
1855 total += r.get_regiment().get_strength() * state.defines.pop_size_per_regiment;
1856 }
1857 set_text(state, text::format_wholenum(int32_t(total)));
1858 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
1859 auto a = std::get<dcon::navy_id>(foru);
1860 for(auto r : state.world.navy_get_navy_membership(a)) {
1861 total += r.get_ship().get_strength();
1862 }
1863 set_text(state, text::format_float(total, 1));
1864 }
1865 }
1866};
1867
1869 bool visible = false;
1870 void on_update(sys::state& state) noexcept override {
1871 auto foru = retrieve<unit_var>(state, parent);
1872 if(std::holds_alternative<dcon::army_id>(foru)) {
1873 auto a = std::get<dcon::army_id>(foru);
1875 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
1876 auto a = std::get<dcon::navy_id>(foru);
1878 } else {
1879 visible = false;
1880 }
1881 }
1882 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
1883 if(visible)
1885 }
1886};
1887
1889 void on_update(sys::state& state) noexcept override {
1890 float current = 0.0f;
1891 float total = 0.0f;
1892 auto foru = retrieve<unit_var>(state, parent);
1893 if(std::holds_alternative<dcon::army_id>(foru)) {
1894 auto a = std::get<dcon::army_id>(foru);
1895 for(auto r : state.world.army_get_army_membership(a)) {
1896 current += r.get_regiment().get_org();
1897 total += 1.0f;
1898 }
1899 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
1900 auto a = std::get<dcon::navy_id>(foru);
1901 for(auto r : state.world.navy_get_navy_membership(a)) {
1902 current += r.get_ship().get_org();
1903 total += 1.0f;
1904 }
1905 }
1906 progress = total > 0.0f ? current / total : 0.0f;
1907 }
1908
1909 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
1911 }
1912
1913 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1915 auto foru = retrieve<unit_var>(state, parent);
1916 if(std::holds_alternative<dcon::army_id>(foru)) {
1917 ui::active_modifiers_description(state, contents, state.local_player_nation, 0, sys::national_mod_offsets::land_organisation, true);
1918 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
1919 ui::active_modifiers_description(state, contents, state.local_player_nation, 0, sys::national_mod_offsets::naval_organisation, true);
1920 }
1921 }
1922};
1923
1925 void on_update(sys::state& state) noexcept override {
1926 float current = 0.0f;
1927 float total = 0.0f;
1928 auto foru = retrieve<unit_var>(state, parent);
1929 if(std::holds_alternative<dcon::army_id>(foru)) {
1930 auto a = std::get<dcon::army_id>(foru);
1931 for(auto r : state.world.army_get_army_membership(a)) {
1932 current += r.get_regiment().get_strength();
1933 total += 1.0f;
1934 }
1935 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
1936 auto a = std::get<dcon::navy_id>(foru);
1937 for(auto r : state.world.navy_get_navy_membership(a)) {
1938 current += r.get_ship().get_strength();
1939 total += 1.0f;
1940 }
1941 }
1942 progress = total > 0.0f ? current / total : 0.0f;
1943 }
1944
1945 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1947 }
1948};
1949
1951public:
1952 void on_update(sys::state& state) noexcept override {
1953 auto foru = retrieve<unit_var>(state, parent);
1954 if(std::holds_alternative<dcon::army_id>(foru)) {
1955 disabled = !command::can_delete_army(state, state.local_player_nation, std::get<dcon::army_id>(foru));
1956 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
1957 disabled = !command::can_delete_navy(state, state.local_player_nation, std::get<dcon::navy_id>(foru));
1958 }
1959 }
1960 void button_action(sys::state& state) noexcept override {
1961 auto foru = retrieve<unit_var>(state, parent);
1962 if(std::holds_alternative<dcon::army_id>(foru)) {
1963 command::delete_army(state, state.local_player_nation, std::get<dcon::army_id>(foru));
1964 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
1965 command::delete_navy(state, state.local_player_nation, std::get<dcon::navy_id>(foru));
1966 }
1967 }
1970 }
1971 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1972 text::add_line(state, contents, "disband_unit");
1973 }
1974};
1975
1977public:
1978 void button_action(sys::state& state) noexcept override {
1979 auto foru = retrieve<unit_var>(state, parent);
1980 if(std::holds_alternative<dcon::army_id>(foru)) {
1981 state.deselect(std::get<dcon::army_id>(foru));
1982 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
1983 state.deselect(std::get<dcon::navy_id>(foru));
1984 }
1985 }
1988 }
1989 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1990 text::add_line(state, contents, "deselect_unit");
1991 }
1992};
1993
1995public:
1996 void button_action(sys::state& state) noexcept override {
1997 auto foru = retrieve<unit_var>(state, parent);
1998 if(std::holds_alternative<dcon::army_id>(foru)) {
1999 command::evenly_split_army(state, state.local_player_nation, std::get<dcon::army_id>(foru));
2000 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2001 command::evenly_split_navy(state, state.local_player_nation, std::get<dcon::navy_id>(foru));
2002 }
2003 }
2004
2005 void on_update(sys::state& state) noexcept override {
2006 auto foru = retrieve<unit_var>(state, parent);
2007 if(std::holds_alternative<dcon::army_id>(foru)) {
2008 disabled = !command::can_evenly_split_army(state, state.local_player_nation, std::get<dcon::army_id>(foru));
2009 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2010 disabled = !command::can_evenly_split_navy(state, state.local_player_nation, std::get<dcon::navy_id>(foru));
2011 }
2012 }
2013
2016 }
2017
2018 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
2019 text::add_line(state, contents, "splitinhalf");
2020 }
2021};
2022
2024public:
2025 void button_action(sys::state& state) noexcept override {
2026 // TODO
2027 }
2028};
2029
2031public:
2032 void on_update(sys::state& state) noexcept override {
2033 auto foru = retrieve<unit_var>(state, parent);
2034 if(std::holds_alternative<dcon::army_id>(foru)) {
2035 frame = 0;
2036 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2037 frame = 3;
2038 }
2039 }
2040};
2041
2043public:
2044 void on_update(sys::state& state) noexcept override {
2045 auto foru = retrieve<unit_var>(state, parent);
2046 if(std::holds_alternative<dcon::army_id>(foru)) {
2047 frame = 1;
2048 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2049 frame = 4;
2050 }
2051 }
2052};
2053
2055public:
2056 void on_update(sys::state& state) noexcept override {
2057 auto foru = retrieve<unit_var>(state, parent);
2058 if(std::holds_alternative<dcon::army_id>(foru)) {
2059 frame = 2;
2060 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2061 frame = 5;
2062 }
2063 }
2064};
2065
2067public:
2068 void on_update(sys::state& state) noexcept override {
2069 int32_t total = 0;
2070 auto foru = retrieve<unit_var>(state, parent);
2071 if(std::holds_alternative<dcon::army_id>(foru)) {
2072 auto a = std::get<dcon::army_id>(foru);
2073 for(auto r : state.world.army_get_army_membership(a)) {
2074 if(state.military_definitions.unit_base_definitions[r.get_regiment().get_type()].type == military::unit_type::infantry) {
2075 ++total;
2076 }
2077 }
2078 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2079 auto a = std::get<dcon::navy_id>(foru);
2080 for(auto r : state.world.navy_get_navy_membership(a)) {
2081 if(state.military_definitions.unit_base_definitions[r.get_ship().get_type()].type == military::unit_type::big_ship) {
2082 ++total;
2083 }
2084 }
2085 }
2086
2087 set_text(state, std::to_string(total));
2088 }
2089};
2090
2092public:
2093 void on_update(sys::state& state) noexcept override {
2094 int32_t total = 0;
2095 auto foru = retrieve<unit_var>(state, parent);
2096 if(std::holds_alternative<dcon::army_id>(foru)) {
2097 auto a = std::get<dcon::army_id>(foru);
2098 for(auto r : state.world.army_get_army_membership(a)) {
2099 if(state.military_definitions.unit_base_definitions[r.get_regiment().get_type()].type == military::unit_type::cavalry) {
2100 ++total;
2101 }
2102 }
2103 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2104 auto a = std::get<dcon::navy_id>(foru);
2105 for(auto r : state.world.navy_get_navy_membership(a)) {
2106 if(state.military_definitions.unit_base_definitions[r.get_ship().get_type()].type == military::unit_type::light_ship) {
2107 ++total;
2108 }
2109 }
2110 }
2111
2112 set_text(state, std::to_string(total));
2113 }
2114};
2115
2117public:
2118 void on_update(sys::state& state) noexcept override {
2119 int32_t total = 0;
2120 auto foru = retrieve<unit_var>(state, parent);
2121 if(std::holds_alternative<dcon::army_id>(foru)) {
2122 auto a = std::get<dcon::army_id>(foru);
2123 for(auto r : state.world.army_get_army_membership(a)) {
2124 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) {
2125 ++total;
2126 }
2127 }
2128 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2129 auto a = std::get<dcon::navy_id>(foru);
2130 for(auto r : state.world.navy_get_navy_membership(a)) {
2131 if(state.military_definitions.unit_base_definitions[r.get_ship().get_type()].type == military::unit_type::transport) {
2132 ++total;
2133 }
2134 }
2135 }
2136
2137 set_text(state, std::to_string(total));
2138 }
2139};
2140
2142public:
2143 void on_update(sys::state& state) noexcept override {
2144 dcon::province_id loc;
2145 auto foru = retrieve<unit_var>(state, parent);
2146 if(std::holds_alternative<dcon::army_id>(foru)) {
2147 auto a = std::get<dcon::army_id>(foru);
2148 loc = state.world.army_get_location_from_army_location(a);
2149 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2150 auto a = std::get<dcon::navy_id>(foru);
2151 loc = state.world.navy_get_location_from_navy_location(a);
2152 }
2153
2154 set_text(state, text::produce_simple_string(state, state.world.province_get_name(loc)));
2155 }
2156};
2157
2158
2160public:
2161 dcon::gfx_object_id default_img;
2162
2163 void on_update(sys::state& state) noexcept override {
2164 if(!default_img) {
2169 }
2170
2171 auto foru = retrieve<unit_var>(state, parent);
2172 dcon::leader_id lid;
2173 if(std::holds_alternative<dcon::army_id>(foru)) {
2174 lid = state.world.army_get_general_from_army_leadership(std::get<dcon::army_id>(foru));
2175 disabled = !command::can_change_general(state, state.local_player_nation, std::get<dcon::army_id>(foru), dcon::leader_id{});
2176 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2177 lid = state.world.navy_get_admiral_from_navy_leadership(std::get<dcon::navy_id>(foru));
2178 disabled = !command::can_change_admiral(state, state.local_player_nation, std::get<dcon::navy_id>(foru), dcon::leader_id{});
2179 }
2180
2181 auto pculture = state.world.nation_get_primary_culture(state.local_player_nation);
2182 auto ltype = pculture.get_group_from_culture_group_membership().get_leader();
2183
2184 if(ltype && lid) {
2185 auto admiral = state.world.leader_get_is_admiral(lid);
2186 if(admiral) {
2187 auto arange = ltype.get_admirals();
2188 if(arange.size() > 0) {
2189 auto rval = rng::get_random(state, uint32_t(state.world.leader_get_since(lid).value), uint32_t(lid.value));
2190 auto in_range = rng::reduce(uint32_t(rval), arange.size());
2191
2193 base_data.data.image.gfx_object = arange[in_range];
2195 base_data.data.button.button_image = arange[in_range];
2196 }
2197 } else {
2198 auto grange = ltype.get_generals();
2199 if(grange.size() > 0) {
2200 auto rval = rng::get_random(state, uint32_t(state.world.leader_get_since(lid).value), uint32_t(lid.value));
2201 auto in_range = rng::reduce(uint32_t(rval), grange.size());
2202
2204 base_data.data.image.gfx_object = grange[in_range];
2206 base_data.data.button.button_image = grange[in_range];
2207 }
2208 }
2209 } else {
2214 }
2215 }
2216
2219 }
2220
2221 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
2222 auto foru = retrieve<unit_var>(state, parent);
2223 dcon::leader_id lid;
2224 if(std::holds_alternative<dcon::army_id>(foru)) {
2225 lid = state.world.army_get_general_from_army_leadership(std::get<dcon::army_id>(foru));
2226 } else if(std::holds_alternative<dcon::navy_id>(foru)) {
2227 lid = state.world.navy_get_admiral_from_navy_leadership(std::get<dcon::navy_id>(foru));
2228 }
2229 if(lid)
2230 display_leader_full(state, lid, contents, 0);
2231 }
2232
2233
2234 void button_action(sys::state& state) noexcept override {
2235 auto foru = retrieve<unit_var>(state, parent);
2237 if(std::holds_alternative<dcon::army_id>(foru)) {
2238 open_leader_selection(state, std::get<dcon::army_id>(foru), dcon::navy_id{}, location.x + base_data.size.x, location.y);
2239 } else {
2240 open_leader_selection(state, dcon::army_id{}, std::get<dcon::navy_id>(foru), location.x + base_data.size.x, location.y);
2241 }
2242 }
2243};
2244
2246public:
2247 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2248 if(name == "unitpanel_bg") {
2249 return make_element_by_type<whole_panel_button>(state, id);
2250 } else if(name == "leader_photo") {
2251 return make_element_by_type<multi_selection_leader_image>(state, id);
2252 } else if(name == "unitstrength") {
2253 return make_element_by_type <u_row_strength> (state, id);
2254 } else if(name == "unitattrition_icon") {
2255 return make_element_by_type<u_row_attrit_icon>(state, id);
2256 } else if(name == "org_bar") {
2257 return make_element_by_type<u_row_org_bar>(state, id);
2258 } else if(name == "str_bar") {
2259 return make_element_by_type<u_row_str_bar>(state, id);
2260 } else if(name == "disbandbutton") {
2261 return make_element_by_type<u_row_disband>(state, id);
2262 } else if(name == "splitinhalf") {
2263 return make_element_by_type<u_row_split>(state, id);
2264 } else if(name == "newunitbutton") {
2265 return make_element_by_type<u_row_new>(state, id);
2266 } else if(name == "remove_unit_from_selection_button") {
2267 return make_element_by_type<u_row_remove>(state, id);
2268 } else if(name == "unit_inf") {
2269 return make_element_by_type<u_row_inf>(state, id);
2270 } else if(name == "unit_inf_count") {
2271 return make_element_by_type<u_row_inf_count>(state, id);
2272 } else if(name == "unit_cav") {
2273 return make_element_by_type<u_row_cav>(state, id);
2274 } else if(name == "unit_cav_count") {
2275 return make_element_by_type<u_row_cav_count>(state, id);
2276 } else if(name == "unit_art") {
2277 return make_element_by_type<u_row_art>(state, id);
2278 } else if(name == "unit_art_count") {
2279 return make_element_by_type<u_row_art_count>(state, id);
2280 } else if(name == "location") {
2281 return make_element_by_type<u_row_location>(state, id);
2282 } else {
2283 return nullptr;
2284 }
2285 }
2286};
2287
2288class selected_unit_list : public listbox_element_base<selected_unit_item, unit_var> {
2289public:
2290 std::string_view get_row_element_name() override {
2291 return "alice_unit_row";
2292 }
2293 void on_update(sys::state& state) noexcept override {
2294 row_contents.clear();
2295 for(auto i : state.selected_armies)
2296 row_contents.push_back(i);
2297 for(auto i : state.selected_navies)
2298 row_contents.push_back(i);
2299 update(state);
2300 }
2301};
2302
2304 bool visible = true;
2305public:
2306 bool is_active(sys::state& state) noexcept override {
2307 for(auto i : state.selected_armies) {
2308 if(state.world.army_get_is_ai_controlled(i) == false)
2309 return false;
2310 }
2311 return true;
2312 }
2313 void on_update(sys::state& state) noexcept override {
2315 visible = state.selected_navies.empty();
2316 }
2319 }
2320 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
2321 text::add_line(state, contents, "alice_ai_controlled_unit");
2322 }
2323 void button_action(sys::state& state) noexcept override {
2324 bool all_on = true;
2325 for(auto i : state.selected_armies) {
2326 if(state.world.army_get_is_ai_controlled(i) == false) {
2327 all_on = false;
2328 break;
2329 }
2330 }
2331 for(auto a : state.selected_armies) {
2332 if(all_on) { //all on -> turn all off
2333 command::toggle_unit_ai_control(state, state.local_player_nation, a);
2334 } else { //some on -> turn all that are off into on, all off -> turn all on
2335 if(!state.world.army_get_is_ai_controlled(a)) {
2336 command::toggle_unit_ai_control(state, state.local_player_nation, a);
2337 }
2338 }
2339 }
2340 }
2341 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
2342 if(visible)
2344 }
2345};
2346
2348public:
2349 void on_create(sys::state& state) noexcept override {
2351 auto ptr = make_element_by_type<multi_unit_details_ai_controlled>(state, "alice_enable_ai_controlled_multi");
2352 add_child_to_front(std::move(ptr));
2353 }
2354
2355 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2356 if(name == "desc") {
2357 return make_element_by_type<units_selected_text>(state, id);
2358 } else if(name == "mergebutton") {
2359 return make_element_by_type<merge_all_button>(state, id);
2360 } else if(name == "close_multiunit") {
2361 return make_element_by_type<deselect_all_button> (state, id);
2362 } else if(name == "disband_multiunit") {
2363 return make_element_by_type<disband_all_button>(state, id);
2364 } else if(name == "unit_listbox") {
2365 return make_element_by_type<selected_unit_list>(state, id);
2366 } else {
2367 return nullptr;
2368 }
2369 }
2370};
2371
2373 dcon::unit_type_id id;
2375
2377 return id == o.id && amount == o.amount;
2378 }
2380 return !(*this == o);
2381 }
2382};
2383
2384using army_group_unit_type_info_optional = std::variant<std::monostate, army_group_unit_type_info>;
2385
2386using army_group_unit_type_info_grid_row = std::array<army_group_unit_type_info_optional, 3>;
2387
2389 void on_update(sys::state& state) noexcept override {
2390 auto regiment_type_data = retrieve<army_group_unit_type_info_optional>(state, parent);
2391 if(!std::holds_alternative<std::monostate>(regiment_type_data)) {
2392 frame = state.military_definitions.unit_base_definitions[std::get<army_group_unit_type_info>(regiment_type_data).id].icon - 1;
2393 }
2394 }
2395};
2396
2398 void on_update(sys::state& state) noexcept override {
2399 auto regiment_type_data = retrieve<army_group_unit_type_info_optional>(state, parent);
2400 if(!std::holds_alternative<std::monostate>(regiment_type_data)) {
2401 auto name_string_def = state.military_definitions.unit_base_definitions[std::get<army_group_unit_type_info>(regiment_type_data).id].name;
2402 set_text(state, text::produce_simple_string(state, name_string_def));
2403 }
2404 }
2405};
2406
2408 void on_update(sys::state& state) noexcept override {
2409 auto regiment_type_data = retrieve<army_group_unit_type_info_optional>(state, parent);
2410 if(!std::holds_alternative<std::monostate>(regiment_type_data)) {
2411 set_text(state, std::to_string(std::get<army_group_unit_type_info>(regiment_type_data).amount));
2412 }
2413 }
2414};
2415
2417public:
2419
2420 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2421 if(name == "alice_army_group_unit_type_entry_icon") {
2422 return make_element_by_type<unit_type_row_image>(state, id);
2423 } else if(name == "alice_army_group_unit_type_entry_name") {
2424 return make_element_by_type<unit_type_row_label>(state, id);
2425 } else if(name == "alice_army_group_unit_type_entry_amount") {
2426 return make_element_by_type<unit_type_row_amount>(state, id);
2427 }
2428 return nullptr;
2429 }
2430
2431 void impl_render(sys::state& state, int32_t x, int32_t y) noexcept override {
2432 if(!std::holds_alternative<std::monostate>(display_unit)) {
2434 }
2435 }
2436
2437 mouse_probe impl_probe_mouse(sys::state& state, int32_t x, int32_t y, mouse_probe_type type) noexcept override {
2438 if(!std::holds_alternative<std::monostate>(display_unit)) {
2440 } else {
2441 return mouse_probe{ nullptr, ui::xy_pair{} };
2442 }
2443 }
2444
2445 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
2446 if(payload.holds_type<army_group_unit_type_info_optional>()) {
2449 }
2451 }
2452};
2453
2454class unit_type_row : public listbox_row_element_base<army_group_unit_type_info_grid_row> {
2455public:
2456 std::array< unit_type_grid_item*, 3> grid_items;
2457
2458 void on_create(sys::state& state) noexcept override {
2460 auto def = state.ui_state.defs_by_name.find(state.lookup_key("alice_army_group_unit_type_grid_item"))->second.definition;
2461
2462 uint8_t additional_padding = 5;
2463
2464 {
2465 auto win = make_element_by_type<unit_type_grid_item>(state, def);
2466 win->base_data.position.x = int16_t(additional_padding);
2467 win->base_data.position.y = int16_t(3);
2468 grid_items[0] = win.get();
2469 add_child_to_front(std::move(win));
2470 }
2471 {
2472 auto win = make_element_by_type<unit_type_grid_item>(state, def);
2473 win->base_data.position.x = int16_t(additional_padding * 2 + win->base_data.size.x);
2474 win->base_data.position.y = int16_t(3);
2475 grid_items[1] = win.get();
2476 add_child_to_front(std::move(win));
2477 }
2478 {
2479 auto win = make_element_by_type<unit_type_grid_item>(state, def);
2480 win->base_data.position.x = int16_t(additional_padding * 3 + win->base_data.size.x * 2);
2481 win->base_data.position.y = int16_t(3);
2482 grid_items[2] = win.get();
2483 add_child_to_front(std::move(win));
2484 }
2485 }
2486
2487 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2488 return nullptr;
2489 }
2490
2491 void on_update(sys::state& state) noexcept override {
2492 grid_items[0]->display_unit = content[0];
2493 grid_items[1]->display_unit = content[1];
2494 grid_items[2]->display_unit = content[2];
2495 }
2496};
2497
2498class selected_army_group_land_units_list : public listbox_element_base<unit_type_row, army_group_unit_type_info_grid_row> {
2499public:
2500 std::string_view get_row_element_name() override {
2501 return "alice_army_group_unit_type_row";
2502 }
2503
2504 void on_update(sys::state& state) noexcept override {
2505 row_contents.clear();
2506
2507 std::vector<uint32_t> regiments_by_type{ };
2508 regiments_by_type.resize(state.military_definitions.unit_base_definitions.size() + 2);
2509
2510 if(state.selected_army_group) {
2511 auto group = fatten(state.world, state.selected_army_group);
2512
2513 for(auto regiment_membership : group.get_automated_army_group_membership_regiment()) {
2514 auto regiment = regiment_membership.get_regiment().get_regiment_from_automation();
2515 auto type = regiment.get_type();
2516 if(type) {
2517 regiments_by_type[type.index()] += 1;
2518 }
2519 }
2520 for(auto navy_membership : group.get_automated_army_group_membership_navy()) {
2521 for(auto ship_membership : state.world.navy_get_navy_membership(navy_membership.get_navy())) {
2522 auto type = ship_membership.get_ship().get_type();
2523 if(type) {
2524 regiments_by_type[type.index()] += 1;
2525 }
2526 }
2527 }
2528 }
2529
2530 size_t unit_types = state.military_definitions.unit_base_definitions.size();
2531 for(size_t i = 2; i < unit_types; i += 3) {
2532 army_group_unit_type_info_grid_row content_of_grid_row;
2533
2534 for(size_t j = 0; (j + i < unit_types) && (j < 3); j += 1) {
2535 dcon::unit_type_id type_id{ dcon::unit_type_id::value_base_t(j + i) };
2536
2537 army_group_unit_type_info new_item = {
2538 .id = type_id,
2539 .amount = regiments_by_type[type_id.index()]
2540 };
2541
2542 content_of_grid_row[j] = new_item;
2543 }
2544
2545 row_contents.push_back({
2546 content_of_grid_row
2547 });
2548 }
2549 update(state);
2550 }
2551};
2552
2553class selected_army_group_sea_units_list : public listbox_element_base<selected_unit_item, unit_var> {
2554public:
2555 std::string_view get_row_element_name() override {
2556 return "alice_unit_row";
2557 }
2558 void on_update(sys::state& state) noexcept override {
2559 row_contents.clear();
2560 if(state.selected_army_group) {
2561 auto group = dcon::fatten(state.world, state.selected_army_group);
2562 for(auto navy_membership : group.get_automated_army_group_membership_navy()) {
2563 row_contents.push_back(navy_membership.get_navy());
2564 }
2565 }
2566 update(state);
2567 }
2568};
2569
2571public:
2572 void on_create(sys::state& state) noexcept override {
2574
2575 xy_pair base_position = { 15, 0 };
2576 uint16_t base_offset = 95;
2577
2578 {
2579 auto win = make_element_by_type<selected_army_group_land_details_item<0>>(state,
2580 state.ui_state.defs_by_name.find(state.lookup_key("unittype_item"))->second.definition);
2581 win->base_data.position.x = base_position.x + (0 * base_offset); // Flexnudge
2582 add_child_to_front(std::move(win));
2583 }
2584 {
2585 auto win = make_element_by_type<selected_army_group_land_details_item<1>>(state,
2586 state.ui_state.defs_by_name.find(state.lookup_key("unittype_item"))->second.definition);
2587 win->base_data.position.x = base_position.x + (1 * base_offset); // Flexnudge
2588 add_child_to_front(std::move(win));
2589 }
2590 {
2591 auto win = make_element_by_type<selected_army_group_land_details_item<2>>(state,
2592 state.ui_state.defs_by_name.find(state.lookup_key("unittype_item"))->second.definition);
2593 win->base_data.position.x = base_position.x + (2 * base_offset); // Flexnudge
2594 add_child_to_front(std::move(win));
2595 }
2596
2597 {
2598 auto win = make_element_by_type<selected_army_group_sea_details_item<0>>(state,
2599 state.ui_state.defs_by_name.find(state.lookup_key("unittype_item"))->second.definition);
2600 win->base_data.position.x = base_position.x + (0 * base_offset); // Flexnudge
2601 win->base_data.position.y = 40;
2602 add_child_to_front(std::move(win));
2603 }
2604 {
2605 auto win = make_element_by_type<selected_army_group_sea_details_item<1>>(state,
2606 state.ui_state.defs_by_name.find(state.lookup_key("unittype_item"))->second.definition);
2607 win->base_data.position.x = base_position.x + (1 * base_offset); // Flexnudge
2608 win->base_data.position.y = 40;
2609 add_child_to_front(std::move(win));
2610 }
2611 {
2612 auto win = make_element_by_type<selected_army_group_sea_details_item<2>>(state,
2613 state.ui_state.defs_by_name.find(state.lookup_key("unittype_item"))->second.definition);
2614 win->base_data.position.x = base_position.x + (2 * base_offset); // Flexnudge
2615 win->base_data.position.y = 40;
2616 add_child_to_front(std::move(win));
2617 }
2618 }
2619};
2620
2622public:
2623 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2624 if(name == "alice_army_group_unit_listbox") {
2625 return make_element_by_type<selected_army_group_land_units_list>(state, id);
2626 }
2627 return nullptr;
2628 }
2629};
2630
2632 void button_action(sys::state& state) noexcept final {
2633 if(state.selected_army_group_order == sys::army_group_order::defend) {
2634 state.selected_army_group_order = sys::army_group_order::none;
2635 } else {
2636 state.selected_army_group_order = sys::army_group_order::defend;
2637 }
2638 on_update(state);
2639 state.game_state_updated.store(true, std::memory_order_release);
2640 }
2641
2642 void on_update(sys::state& state) noexcept override {
2643 if(state.selected_army_group_order == sys::army_group_order::defend) {
2644 frame = 1;
2645 } else {
2646 frame = 0;
2647 }
2648 }
2649
2650 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
2652 }
2653
2654 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
2655 text::add_line(state, contents, "alice_battleplanner_defend_order");
2656 }
2657};
2658
2660 void button_action(sys::state& state) noexcept final {
2661 if(state.selected_army_group_order == sys::army_group_order::siege) {
2662 state.selected_army_group_order = sys::army_group_order::none;
2663 } else {
2664 state.selected_army_group_order = sys::army_group_order::siege;
2665 }
2666
2667 on_update(state);
2668 state.game_state_updated.store(true, std::memory_order_release);
2669 }
2670
2671 void on_update(sys::state& state) noexcept override {
2672 if(state.selected_army_group_order == sys::army_group_order::siege) {
2673 frame = 1;
2674 } else {
2675 frame = 0;
2676 }
2677 }
2678
2679 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
2681 }
2682
2683 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
2684 text::add_line(state, contents, "alice_battleplanner_enforce_control_order");
2685 }
2686};
2687
2689 void button_action(sys::state& state) noexcept final {
2690 if(state.selected_army_group_order == sys::army_group_order::designate_port) {
2691 state.selected_army_group_order = sys::army_group_order::none;
2692 } else {
2693 state.selected_army_group_order = sys::army_group_order::designate_port;
2694 }
2695 on_update(state);
2696 state.game_state_updated.store(true, std::memory_order_release);
2697 }
2698
2699 void on_update(sys::state& state) noexcept override {
2700 if(state.selected_army_group_order == sys::army_group_order::designate_port) {
2701 frame = 1;
2702 } else {
2703 frame = 0;
2704 }
2705 }
2706
2707 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
2709 }
2710
2711 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
2712 text::add_line(state, contents, "alice_battleplanner_travel_origin_order");
2713 }
2714};
2715
2717 void button_action(sys::state& state) noexcept final {
2718 for(auto item : state.selected_armies) {
2719 state.world.for_each_automated_army_group([&](dcon::automated_army_group_id group) {
2720 state.remove_army_army_group_clean(group, item);
2721 });
2722 state.add_army_to_army_group(state.selected_army_group, item);
2723 }
2724 for(auto item : state.selected_navies) {
2725 state.world.for_each_automated_army_group([&](dcon::automated_army_group_id group) {
2726 state.remove_navy_from_army_group(group, item);
2727 });
2728 state.add_navy_to_army_group(state.selected_army_group, item);
2729 }
2730 }
2731
2732 void on_update(sys::state& state) noexcept override {
2733 if(state.selected_army_group) {
2734 disabled = false;
2735 } else {
2736 disabled = true;
2737 }
2738 }
2739
2740 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
2742 }
2743
2744 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
2745 text::add_line(state, contents, "alice_armygroup_go_to_selection");
2746 }
2747};
2748
2750 void button_action(sys::state& state) noexcept final {
2751 if(state.selected_army_group) {
2752 for(auto item : state.selected_armies) {
2753 state.remove_army_army_group_clean(state.selected_army_group, item);
2754 }
2755 for(auto item : state.selected_navies) {
2756 state.remove_navy_from_army_group(state.selected_army_group, item);
2757 }
2758 }
2759 }
2760
2761 void on_update(sys::state& state) noexcept override {
2762 if(state.selected_army_group) {
2763 disabled = false;
2764 } else {
2765 disabled = true;
2766 }
2767 }
2768
2769 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
2771 }
2772
2773 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
2774 text::add_line(state, contents, "alice_battleplanner_travel_origin_order");
2775 }
2776};
2777
2779 void button_action(sys::state& state) noexcept override {
2780 auto selected = state.map_state.selected_province;
2781 if(selected) {
2782 state.new_army_group(selected);
2783 }
2784 }
2785
2786 void on_update(sys::state& state) noexcept override {
2787 if(state.map_state.selected_province) {
2788 disabled = false;
2789 return;
2790 }
2791 disabled = true;
2792 }
2793};
2794
2796 void button_action(sys::state& state) noexcept override {
2797 auto selected = state.selected_army_group;
2798 if(selected) {
2799 state.delete_army_group(selected);
2800 }
2801 }
2802
2803 void on_update(sys::state& state) noexcept override {
2804 if(state.selected_army_group) {
2805 disabled = false;
2806 return;
2807 }
2808 disabled = true;
2809 }
2810};
2811
2813public:
2814 void on_update(sys::state & state) noexcept override {
2815 auto content = retrieve<dcon::automated_army_group_id>(state, parent);
2816 auto hq = state.world.automated_army_group_get_hq(content);
2818 }
2819};
2820
2822 void button_action(sys::state& state) noexcept override {
2823 auto info = retrieve<dcon::automated_army_group_id>(state, parent);
2824 state.select_army_group(info);
2825 }
2826
2827 void on_update(sys::state& state) noexcept override {
2828 auto info = retrieve<dcon::automated_army_group_id>(state, parent);
2829
2830
2831 if(state.selected_army_group) {
2832 if(info) {
2833 auto local_hq = state.world.automated_army_group_get_hq(info);
2834 auto selected_hq = state.world.automated_army_group_get_hq(state.selected_army_group);
2835 if(local_hq == selected_hq) {
2836 frame = 1;
2837 return;
2838 }
2839 }
2840 }
2841 frame = 0;
2842 }
2843};
2844
2845class army_group_entry : public listbox_row_element_base<dcon::automated_army_group_id> {
2846 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2847 if(name == "alice_select_army_group_button") {
2848 return make_element_by_type<select_army_group_button>(state, id);
2849 } else if(name == "alice_army_group_location") {
2850 return make_element_by_type<army_group_location>(state, id);
2851 } else {
2852 return nullptr;
2853 }
2854 }
2855};
2856
2857class army_groups_list : public listbox_element_base<army_group_entry, dcon::automated_army_group_id> {
2858public:
2859 std::string_view get_row_element_name() override {
2860 return "alice_army_group_entry";
2861 }
2862 void on_update(sys::state& state) noexcept override {
2863 row_contents.clear();
2864 state.world.for_each_automated_army_group([&](dcon::automated_army_group_id item) {
2865 row_contents.push_back(item);
2866 });
2867 update(state);
2868 }
2869};
2870
2872 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2873 if(name == "alice_army_group_listbox") {
2874 return make_element_by_type<army_groups_list>(state, id);
2875 } else {
2876 return nullptr;
2877 }
2878 }
2879};
2880
2882 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2883 if(name == "alice_armygroup_new_button") {
2884 return make_element_by_type<new_army_group_button>(state, id);
2885 } else if(name == "alice_armygroup_delete_button") {
2886 return make_element_by_type<delete_army_group_button>(state, id);
2887 } else if(name == "alice_battleplanner_remove_selected") {
2888 return make_element_by_type<remove_selected_units_from_army_group_button>(state, id);
2889 } else if(name == "alice_army_group_listbox_wrapper") {
2890 return make_element_by_type<army_groups_list_wrapper>(state, id);
2891 } else {
2892 return nullptr;
2893 }
2894 }
2895};
2896
2898 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2899 if(name == "alice_battleplanner_add_selected") {
2900 return make_element_by_type<add_selected_units_to_army_group_button>(state, id);
2901 } if(name == "alice_battleplanner_remove_selected") {
2902 return make_element_by_type<remove_selected_units_from_army_group_button>(state, id);
2903 } else {
2904 return nullptr;
2905 }
2906 }
2907};
2908
2910public:
2911 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2912 if(name == "alice_armygroup_defend_button") {
2913 return make_element_by_type<toggle_defend_order_button>(state, id);
2914 } else if(name == "alice_armygroup_enforce_control_button") {
2915 return make_element_by_type<toggle_enforce_control_order_button>(state, id);
2916 } else if(name == "alice_armygroup_naval_travel_origin_button") {
2917 return make_element_by_type<toggle_ferry_origin_order_button>(state, id);
2918 } else if(name == "alice_armygroup_go_to_selection") {
2919 return make_element_by_type<go_to_battleplanner_selection_button>(state, id);
2920 } else {
2921 return nullptr;
2922 }
2923 }
2924};
2925
2927public:
2928 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2929 if(name == "alice_army_group_regiments_list_header") {
2930 return make_element_by_type<army_group_details_window_header>(state, id);
2931 }
2932 if(name == "alice_army_group_control") {
2933 return make_element_by_type<army_group_control_window>(state, id);
2934 }
2935 if(name == "alice_army_group_unit_listbox_wrapper") {
2936 return make_element_by_type<army_group_details_window_body>(state, id);
2937 }
2938 return nullptr;
2939 }
2940};
2941
2942} // 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 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 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_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
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
void on_update(sys::state &state) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void 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
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_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
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
constexpr size_t num_packed_units
Definition: commands.hpp:405
bool can_change_admiral(sys::state &state, dcon::nation_id source, dcon::navy_id a, dcon::leader_id l)
Definition: commands.cpp:4151
void toggle_rebel_hunting(sys::state &state, dcon::nation_id source, dcon::army_id a)
Definition: commands.cpp:3683
bool can_change_general(sys::state &state, dcon::nation_id source, dcon::army_id a, dcon::leader_id l)
Definition: commands.cpp:4132
bool can_delete_army(sys::state &state, dcon::nation_id source, dcon::army_id a)
Definition: commands.cpp:4089
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:4161
void evenly_split_army(sys::state &state, dcon::nation_id source, dcon::army_id a)
Definition: commands.cpp:3875
bool can_evenly_split_army(sys::state &state, dcon::nation_id source, dcon::army_id a)
Definition: commands.cpp:3883
bool can_evenly_split_navy(sys::state &state, dcon::nation_id source, dcon::navy_id a)
Definition: commands.cpp:3939
bool can_disband_undermanned_regiments(sys::state &state, dcon::nation_id source, dcon::army_id a)
Definition: commands.cpp:3668
void disband_undermanned_regiments(sys::state &state, dcon::nation_id source, dcon::army_id a)
Definition: commands.cpp:3660
bool can_merge_navies(sys::state &state, dcon::nation_id source, dcon::navy_id a, dcon::navy_id b)
Definition: commands.cpp:3613
bool can_split_navy(sys::state &state, dcon::nation_id source, dcon::navy_id a)
Definition: commands.cpp:4042
bool can_delete_navy(sys::state &state, dcon::nation_id source, dcon::navy_id a)
Definition: commands.cpp:4110
bool can_split_army(sys::state &state, dcon::nation_id source, dcon::army_id a)
Definition: commands.cpp:3994
void evenly_split_navy(sys::state &state, dcon::nation_id source, dcon::navy_id a)
Definition: commands.cpp:3931
bool can_merge_armies(sys::state &state, dcon::nation_id source, dcon::army_id a, dcon::army_id b)
Definition: commands.cpp:3558
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:6446
float effective_army_speed(sys::state &state, dcon::army_id a)
Definition: military.cpp:3849
float attrition_amount(sys::state &state, dcon::navy_id a)
Definition: military.cpp:5077
economy::commodity_set get_required_supply(sys::state &state, dcon::nation_id owner, dcon::army_id army)
Definition: military.cpp:6812
bool can_embark_onto_sea_tile(sys::state &state, dcon::nation_id from, dcon::province_id p, dcon::army_id a)
Definition: military.cpp:3823
bool will_recieve_attrition(sys::state &state, dcon::navy_id a)
Definition: military.cpp:4946
float effective_navy_speed(sys::state &state, dcon::navy_id n)
Definition: military.cpp:3874
int32_t transport_capacity(sys::state &state, dcon::navy_id n)
Definition: military.cpp:6438
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:577
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
float blue_from_int(uint32_t v)
float green_from_int(uint32_t v)
uint32_t pack_color(float r, float g, float b)
float red_from_int(uint32_t v)
void add_to_layout_box(sys::state &state, layout_base &dest, layout_box &box, embedded_flag ico)
Definition: text.cpp:1165
std::string resolve_string_substitution(sys::state &state, dcon::text_key source_text, substitution_map const &mp)
Definition: text.cpp:2113
std::string get_name_as_string(sys::state &state, T t)
Definition: text.hpp:954
layout_box open_layout_box(layout_base &dest, int32_t indent)
Definition: text.cpp:1799
void 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:1601
void localised_format_box(sys::state &state, layout_base &dest, layout_box &box, std::string_view key, text::substitution_map const &sub)
Definition: text.cpp:1880
std::string prettify(int64_t num)
Definition: text.cpp:762
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:1899
void add_line_with_condition(sys::state &state, layout_base &dest, std::string_view key, bool condition_met, int32_t indent)
Definition: text.cpp:1955
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:794
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:1788
void close_layout_box(columnar_layout &dest, layout_box &box)
Definition: text.cpp:1807
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
float commodity_amounts[set_size]
dcon::commodity_id commodity_type[set_size]
static constexpr uint32_t set_size
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
sys::macro_builder_template main_template
ankerl::unordered_dense::map< dcon::text_key, element_target, hash_text_key > defs_by_name