Project Alice
Loading...
Searching...
No Matches
gui_diplomacy_window.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "dcon_generated.hpp"
5#include "gui_graphics.hpp"
6#include "text.hpp"
7#include "parsers.hpp"
8#include <algorithm>
9#include <functional>
10
13#include "gui_peace_window.hpp"
14#include "gui_crisis_window.hpp"
15
16namespace military {
17std::string get_war_name(sys::state&, dcon::war_id);
18}
19
20namespace ui {
21
22
24public:
25 void on_update(sys::state& state) noexcept override {
26 const dcon::cb_type_id cbt = retrieve<dcon::cb_type_id>(state, parent);
27 frame = state.world.cb_type_get_sprite_index(cbt) - 1;
28 }
29};
30
32public:
33 void on_update(sys::state& state) noexcept override {
34 dcon::cb_type_id content = retrieve<dcon::cb_type_id>(state, parent);
35 dcon::nation_id target = retrieve<dcon::nation_id>(state, parent);
36
37 dcon::state_definition_id target_state = retrieve<dcon::state_definition_id>(state, parent);
38
39 auto war = retrieve<dcon::war_id>(state, parent);
40 auto cb_infamy = military::has_truce_with(state, state.local_player_nation, target)
41 ? military::truce_break_cb_infamy(state, content, target, target_state)
42 : military::cb_infamy(state, content, target, target_state);
43 if(state.world.nation_get_infamy(state.local_player_nation) + cb_infamy >= state.defines.badboy_limit) {
44 color = sys::pack_color(255, 196, 196);
45 } else {
46 color = sys::pack_color(255, 255, 255);
47 }
48
50 if(parent) {
51 auto selected = retrieve<dcon::cb_type_id>(state, parent->parent);
52 if (selected == content) {
53 color = sys::pack_color(196, 196, 196);
54 } else {
55 color = sys::pack_color(255, 255, 255);
56 }
57 }
58 }
59
60 void button_action(sys::state& state) noexcept override {
61 const dcon::cb_type_id content = retrieve<dcon::cb_type_id>(state, parent);
63 }
64
67 }
68
69 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
70 dcon::cb_type_id content = retrieve<dcon::cb_type_id>(state, parent);
71 dcon::nation_id target = retrieve<dcon::nation_id>(state, parent);
72 auto cb_infamy = military::has_truce_with(state, state.local_player_nation, target)
73 ? military::truce_break_cb_infamy(state, content, target)
74 : military::cb_infamy(state, content, target);
75 if(state.world.nation_get_infamy(state.local_player_nation) + cb_infamy >= state.defines.badboy_limit) {
76 text::add_line(state, contents, "alice_tt_wg_infamy_limit");
77 }
78 text::add_line_with_condition(state, contents, "alice_wg_condition_5", military::cb_conditions_satisfied(state, state.local_player_nation, target, content));
79 text::add_line(state, contents, "alice_wg_usage_trigger");
80 ui::trigger_description(state, contents, state.world.cb_type_get_can_use(content), trigger::to_generic(target), trigger::to_generic(state.local_player_nation), trigger::to_generic(target));
81 }
82};
83
84class diplomacy_make_cb_type : public listbox_row_element_base<dcon::cb_type_id> {
85public:
86 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
87 if(name == "wargoal_icon") {
88 return make_element_by_type<cb_wargoal_icon>(state, id);
89 } else if(name == "select_cb") {
90 return make_element_by_type<cb_wargoal_button>(state, id);
91 } else {
92 return nullptr;
93 }
94 }
95};
96
97class diplomacy_make_cb_listbox : public listbox_element_base<diplomacy_make_cb_type, dcon::cb_type_id> {
98protected:
99 std::string_view get_row_element_name() override {
100 return "cb_type_item";
101 }
102public:
103 void on_update(sys::state& state) noexcept override {
104 row_contents.clear();
105 dcon::nation_id content = retrieve<dcon::nation_id>(state, parent);
106 state.world.for_each_cb_type([&](dcon::cb_type_id cb) {
107 if(command::can_fabricate_cb(state, state.local_player_nation, content, cb))
108 row_contents.push_back(cb);
109 });
110 update(state);
111 }
112};
113
115public:
116 void button_action(sys::state& state) noexcept override {
117 auto content = retrieve<dcon::cb_type_id>(state, parent);
118 auto target_nation = retrieve<dcon::nation_id>(state, parent);
119 auto target_state = retrieve<dcon::state_definition_id>(state, parent);
120 command::fabricate_cb(state, state.local_player_nation, target_nation, content, target_state);
121 parent->set_visible(state, false);
122 }
123
124 void on_update(sys::state& state) noexcept override {
125 auto wargoal_decided_upon = retrieve<bool>(state, parent);
126
127 if(!wargoal_decided_upon) {
128 disabled = true;
129 return;
130 }
131 auto content = retrieve<dcon::cb_type_id>(state, parent);
132 auto target_nation = retrieve<dcon::nation_id>(state, parent);
133 auto target_state = retrieve<dcon::state_definition_id>(state, parent);
134 disabled = !command::can_fabricate_cb(state, state.local_player_nation, target_nation, content, target_state);
135 }
136};
137
139public:
140 void populate_layout(sys::state& state, text::endless_layout& contents) noexcept override {
141 auto fat_cb = dcon::fatten(state.world, retrieve<dcon::cb_type_id>(state, parent));
142 auto box = text::open_layout_box(contents);
143 auto fab_time = std::ceil(100.0f / (state.defines.cb_generation_base_speed * fat_cb.get_construction_speed() * (state.world.nation_get_modifier_values(state.local_player_nation, sys::national_mod_offsets::cb_generation_speed_modifier) + 1.0f)));
144 auto target_nation = retrieve<dcon::nation_id>(state, parent);
145 auto target_state = retrieve<dcon::state_definition_id>(state, parent);
146
147 if(fat_cb.is_valid()) {
153
156 text::localised_format_box(state, contents, box, std::string_view("alice_cb_creation_detail_state"), sub);
157 }
158 else {
159 text::localised_format_box(state, contents, box, std::string_view("alice_cb_creation_detail"), sub);
160 }
161 } else {
164 text::localised_format_box(state, contents, box, std::string_view("alice_cb_creation_detail_none"), sub);
165 }
166 text::close_layout_box(contents, box);
167 }
168};
169
171public:
172 void on_update(sys::state& state) noexcept override {
174 }
175};
176
177class diplomacy_make_cb_window : public window_element_base { // eu3dialogtype
178private:
179 dcon::cb_type_id root_cb{};
180 dcon::state_definition_id target_state = dcon::state_definition_id{};
181public:
183
184 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
185 if(name == "background") {
186 auto ptr = make_element_by_type<draggable_target>(state, id);
187 ptr->base_data.size = base_data.size; // Nudge size for proper sizing
188 return ptr;
189 } else if(name == "diplo_makecb_bg") {
190 return make_element_by_type<image_element_base>(state, id);
191 } else if(name == "title") {
192 return make_element_by_type<make_cb_title>(state, id);
193 } else if(name == "description") {
194 return make_element_by_type<diplomacy_make_cb_desc>(state, id);
195 } else if(name == "leftshield") {
196 return make_element_by_type<nation_player_flag>(state, id);
197 } else if(name == "rightshield") {
198 return make_element_by_type<flag_button>(state, id);
199 } else if(name == "agreebutton") {
200 return make_element_by_type<diplomacy_make_cb_button>(state, id);
201 } else if(name == "declinebutton") {
202 return make_element_by_type<generic_close_button>(state, id);
203 } else if(name == "cb_list") {
204 return make_element_by_type<diplomacy_make_cb_listbox>(state, id);
205 } else {
206 return nullptr;
207 }
208 }
209
211 target_state = dcon::state_definition_id{};
212 wargoal_decided_upon = false;
213 }
214
216 dcon::nation_id target = retrieve<dcon::nation_id>(state, parent);
217 auto cb_to_use = root_cb;
218 target_state = dcon::state_definition_id{};
219
221 seldata.single_state_select = true;
222 auto actor = state.local_player_nation;
223 dcon::cb_type_id cb = cb_to_use;
224 auto war = military::find_war_between(state, actor, target);
225 auto allowed_substate_regions = state.world.cb_type_get_allowed_substate_regions(cb);
226 if(allowed_substate_regions) {
227 for(auto v : state.world.nation_get_overlord_as_ruler(target)) {
228 if(v.get_subject().get_is_substate()) {
229 for(auto si : state.world.nation_get_state_ownership(target)) {
230 if(trigger::evaluate(state, allowed_substate_regions, trigger::to_generic(si.get_state().id), trigger::to_generic(actor), trigger::to_generic(actor))) {
231 auto def = si.get_state().get_definition().id;
232 if(std::find(seldata.selectable_states.begin(), seldata.selectable_states.end(), def) == seldata.selectable_states.end()) {
233 if(!military::war_goal_would_be_duplicate(state, state.local_player_nation, war, v.get_subject(), cb, def, dcon::national_identity_id{}, dcon::nation_id{})) {
234 seldata.selectable_states.push_back(def);
235 }
236 }
237 }
238 }
239 }
240 }
241 } else {
242 auto allowed_states = state.world.cb_type_get_allowed_states(cb);
243 if(auto ac = state.world.cb_type_get_allowed_countries(cb); ac) {
244 auto in_nation = target;
245 auto target_identity = state.world.nation_get_identity_from_identity_holder(target);
246 for(auto si : state.world.nation_get_state_ownership(target)) {
247 if(trigger::evaluate(state, allowed_states, trigger::to_generic(si.get_state().id), trigger::to_generic(actor), trigger::to_generic(in_nation))) {
248 auto def = si.get_state().get_definition().id;
249 if(!military::war_goal_would_be_duplicate(state, state.local_player_nation, war, target, cb, def, target_identity, dcon::nation_id{})) {
250 seldata.selectable_states.push_back(def);
251 }
252 }
253 }
254 } else {
255 for(auto si : state.world.nation_get_state_ownership(target)) {
256 if(trigger::evaluate(state, allowed_states, trigger::to_generic(si.get_state().id), trigger::to_generic(actor), trigger::to_generic(actor))) {
257 auto def = si.get_state().get_definition().id;
258 if(!military::war_goal_would_be_duplicate(state, state.local_player_nation, war, target, cb, def, dcon::national_identity_id{}, dcon::nation_id{})) {
259 seldata.selectable_states.push_back(def);
260 }
261 }
262 }
263 }
264 }
265 seldata.on_select = [&](sys::state& state, dcon::state_definition_id sdef) {
266 target_state = sdef;
269 };
270 seldata.on_cancel = [&](sys::state& state) {
271 target_state = dcon::state_definition_id{};
272 cb_to_use = dcon::cb_type_id{};
273 wargoal_decided_upon = false;
275 };
276 state.start_state_selection(seldata);
277 }
278
279 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
280 if(payload.holds_type<element_selection_wrapper<dcon::cb_type_id>>()) {
281 root_cb = any_cast<element_selection_wrapper<dcon::cb_type_id>>(payload).data;
284 }
285 else {
287 }
290 } else if(payload.holds_type<bool>()) {
291 payload.emplace<bool>(wargoal_decided_upon);
293 } else if(payload.holds_type<dcon::cb_type_id>()) {
294 payload.emplace<dcon::cb_type_id>(root_cb);
296 }
297 else if(payload.holds_type<dcon::state_definition_id>()) {
298 payload.emplace<dcon::state_definition_id>(target_state);
300 }
302 }
303};
304
305
306enum class diplomacy_window_tab : uint8_t { great_powers = 0x0, wars = 0x1, casus_belli = 0x2, crisis = 0x3 };
307
309public:
312 }
313
314 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
315 auto n = retrieve<dcon::nation_id>(state, parent);
318 int32_t total = 0;
319 int32_t discovered = 0;
320 state.world.for_each_technology([&](dcon::technology_id id) {
321 auto fat_id = dcon::fatten(state.world, id);
322 if(state.culture_definitions.tech_folders[fat_id.get_folder_index()].category != culture::tech_category::navy)
323 return;
324 ++total;
325 if(state.world.nation_get_active_technologies(n, id))
326 ++discovered;
327 });
328 text::add_line(state, contents, "navy_technology_levels", text::variable_type::val, discovered, text::variable_type::max, total);
329 }
330};
331
333public:
336 }
337
338 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
339 auto n = retrieve<dcon::nation_id>(state, parent);
342 int32_t total = 0;
343 int32_t discovered = 0;
344 state.world.for_each_technology([&](dcon::technology_id id) {
345 auto fat_id = dcon::fatten(state.world, id);
346 if(state.culture_definitions.tech_folders[fat_id.get_folder_index()].category != culture::tech_category::army)
347 return;
348 ++total;
349 if(state.world.nation_get_active_technologies(n, id))
350 ++discovered;
351 });
352 text::add_line(state, contents, "army_technology_levels", text::variable_type::val, discovered, text::variable_type::max, total);
353 }
354};
355
357public:
358 std::string get_text(sys::state& state, dcon::nation_id nation_id) noexcept override {
359 auto fat_id = dcon::fatten(state.world, nation_id);
360 return text::format_percentage(fat_id.get_war_exhaustion() / 100.0f, 1);
361 }
362
365 }
366
367 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
368 auto n = retrieve<dcon::nation_id>(state, parent);
369
370 auto box = text::open_layout_box(contents);
371 text::localised_format_box(state, contents, box, "diplomacy_wx_1");
372 auto mod = state.world.nation_get_modifier_values(n, sys::national_mod_offsets::war_exhaustion);
373 if(mod > 0) {
374 text::add_to_layout_box(state, contents, box, std::string_view("+"), text::text_color::red);
376 } else if(mod == 0) {
377 text::add_to_layout_box(state, contents, box, std::string_view("+0"));
378 } else {
380 }
381 text::close_layout_box(contents, box);
382
383 active_modifiers_description(state, contents, n, 15, sys::national_mod_offsets::war_exhaustion, false);
384 }
385};
386
388public:
389 void on_update(sys::state& state) noexcept override {
390 if(!parent)
391 return;
392 auto content = retrieve<dcon::nation_id>(state, parent);
393 auto window_content = retrieve<dcon::nation_id>(state, parent->parent);
394 if(content == window_content)
395 frame = 1;
396 else
397 frame = 0;
398 }
399 void button_action(sys::state& state) noexcept override {
400 auto content = retrieve<dcon::nation_id>(state, parent);
402 }
403};
404
405void explain_influence(sys::state& state, dcon::nation_id target, text::columnar_layout& contents) {
406 int32_t total_influence_shares = 0;
407 auto n = fatten(state.world, state.local_player_nation);
408
409 for(auto rel : state.world.nation_get_gp_relationship_as_great_power(state.local_player_nation)) {
410 if(nations::can_accumulate_influence_with(state, state.local_player_nation, rel.get_influence_target(), rel)) {
411 switch(rel.get_status() & nations::influence::priority_mask) {
413 total_influence_shares += 1;
414 break;
416 total_influence_shares += 2;
417 break;
419 total_influence_shares += 3;
420 break;
421 default:
423 break;
424 }
425 }
426 }
427
428 auto rel = fatten(state.world, state.world.get_gp_relationship_by_gp_influence_pair(target, state.local_player_nation));
429
430 if((state.world.gp_relationship_get_status(rel) & nations::influence::is_banned) != 0) {
431 text::add_line(state, contents, "influence_explain_1");
432 return;
433 }
434 if(military::has_truce_with(state, state.local_player_nation, target)) {
435 text::add_line(state, contents, "influence_explain_2");
436 return;
437 }
438 if(military::are_at_war(state, state.local_player_nation, target)) {
439 text::add_line(state, contents, "influence_explain_3");
440 return;
441 }
442
443 if(total_influence_shares > 0) {
444 float total_gain = state.defines.base_greatpower_daily_influence
445 * (1.0f + n.get_modifier_values(sys::national_mod_offsets::influence_modifier))
446 * (1.0f + n.get_modifier_values(sys::national_mod_offsets::influence));
447 float gp_score = n.get_industrial_score() + n.get_military_score() + nations::prestige_score(state, n);
448 float base_shares = nations::get_base_shares(state, rel, total_gain, total_influence_shares);
449
450 float total_fi = nations::get_foreign_investment(state, n);
451 auto gp_invest = state.world.unilateral_relationship_get_foreign_investment(
452 state.world.get_unilateral_relationship_by_unilateral_pair(target, n));
453
454 float discredit_factor = (rel.get_status() & nations::influence::is_discredited) != 0
455 ? state.defines.discredit_influence_gain_factor
456 : 0.0f;
457 float neighbor_factor = bool(state.world.get_nation_adjacency_by_nation_adjacency_pair(n, target))
458 ? state.defines.neighbour_bonus_influence_percent
459 : 0.0f;
460 float sphere_neighbor_factor = nations::has_sphere_neighbour(state, n, target)
461 ? state.defines.sphere_neighbour_bonus_influence_percent
462 : 0.0f;
463 float continent_factor =
464 n.get_capital().get_continent() != state.world.nation_get_capital(target).get_continent()
465 ? state.defines.other_continent_bonus_influence_percent
466 : 0.0f;
467 float puppet_factor =
468 fatten(state.world, state.world.nation_get_overlord_as_subject(target)).get_ruler() == n
469 ? state.defines.puppet_bonus_influence_percent
470 : 0.0f;
471 float relationship_factor =
472 state.world.diplomatic_relation_get_value(state.world.get_diplomatic_relation_by_diplomatic_pair(n, target)) / state.defines.relation_influence_modifier;
473
474 float investment_factor =
475 total_fi > 0.0f
476 ? state.defines.investment_influence_defense * gp_invest / total_fi
477 : 0.0f;
478 float pop_factor =
479 state.world.nation_get_demographics(target, demographics::total) > state.defines.large_population_limit
480 ? state.defines.large_population_influence_penalty * state.world.nation_get_demographics(target, demographics::total) / state.defines.large_population_influence_penalty_chunk
481 : 0.0f;
482 float score_factor =
483 gp_score > 0.0f
484 ? std::max(1.0f - (state.world.nation_get_industrial_score(target) + state.world.nation_get_military_score(target) + nations::prestige_score(state, target)) / gp_score, 0.0f)
485 : 0.0f;
486
487 float total_multiplier = 1.0f + discredit_factor + neighbor_factor + sphere_neighbor_factor + continent_factor + puppet_factor + relationship_factor + investment_factor + pop_factor + score_factor;
488
489 auto gain_amount = std::max(0.0f, base_shares * total_multiplier);
490
491 text::add_line(state, contents, "remove_diplomacy_dailyinflulence_gain", text::variable_type::num, text::fp_two_places{ gain_amount }, text::variable_type::country, target);
493
494 text::add_line(state, contents, "influence_explain_4", text::variable_type::x, text::fp_two_places{ total_gain });
495 text::add_line(state, contents, "influence_explain_5", text::variable_type::x, text::fp_two_places{ state.defines.base_greatpower_daily_influence }, text::variable_type::y, text::fp_percentage{ 1.0f + n.get_modifier_values(sys::national_mod_offsets::influence_modifier) }, text::variable_type::val, text::fp_percentage{ 1.0f + n.get_modifier_values(sys::national_mod_offsets::influence) });
496
497 text::add_line(state, contents, "influence_explain_6", text::variable_type::x, text::fp_percentage{ 1.0f + n.get_modifier_values(sys::national_mod_offsets::influence_modifier) });
498 active_modifiers_description(state, contents, n, 15, sys::national_mod_offsets::influence_modifier, false);
499
500 text::add_line(state, contents, "influence_explain_7", text::variable_type::x, text::fp_percentage{ 1.0f + n.get_modifier_values(sys::national_mod_offsets::influence) });
501 active_modifiers_description(state, contents, n, 15, sys::national_mod_offsets::influence, false);
502
504
505 text::add_line(state, contents, "influence_explain_8", text::variable_type::x, text::fp_two_places{ base_shares });
506
507 if(discredit_factor != 0 || neighbor_factor != 0 || sphere_neighbor_factor != 0 || continent_factor != 0 || puppet_factor != 0 || relationship_factor != 0 || investment_factor != 0 || pop_factor != 0 || score_factor != 0) {
508
509 text::add_line(state, contents, "influence_explain_9");
510
511 if(discredit_factor != 0) {
512 text::add_line(state, contents, "influence_explain_10", text::variable_type::x, text::fp_two_places{ discredit_factor }, 15);
513 }
514 if(neighbor_factor != 0) {
515 text::add_line(state, contents, "influence_explain_11", text::variable_type::x, text::fp_two_places{ neighbor_factor }, 15);
516 }
517 if(sphere_neighbor_factor != 0) {
518 text::add_line(state, contents, "influence_explain_12", text::variable_type::x, text::fp_two_places{ sphere_neighbor_factor }, 15);
519 }
520 if(continent_factor != 0) {
521 text::add_line(state, contents, "influence_explain_13", text::variable_type::x, text::fp_two_places{ continent_factor }, 15);
522 }
523 if(puppet_factor != 0) {
524 text::add_line(state, contents, "influence_explain_14", text::variable_type::x, text::fp_two_places{ puppet_factor }, 15);
525 }
526 if(relationship_factor != 0) {
527 text::add_line(state, contents, "influence_explain_15", text::variable_type::x, text::fp_two_places{ relationship_factor }, 15);
528 }
529 if(investment_factor != 0) {
530 text::add_line(state, contents, "influence_explain_16", text::variable_type::x, text::fp_two_places{ investment_factor }, 15);
531 }
532 if(pop_factor != 0) {
533 text::add_line(state, contents, "influence_explain_17", text::variable_type::x, text::fp_two_places{ pop_factor }, 15);
534 }
535 if(score_factor != 0) {
536 text::add_line(state, contents, "influence_explain_18", text::variable_type::x, text::fp_two_places{ score_factor }, 15);
537 }
538 }
539 }
540}
541
543 static std::string_view get_prio_key(uint8_t f) {
546 return "diplomacy_prio_none";
548 return "diplomacy_prio_low";
550 return "diplomacy_prio_middle";
552 return "diplomacy_prio_high";
553 default:
554 return "diplomacy_prio_none";
555 }
556 }
557
558public:
559 void on_update(sys::state& state) noexcept override {
560 auto nation_id = retrieve<dcon::nation_id>(state, parent);
561
562 auto rel = state.world.get_gp_relationship_by_gp_influence_pair(nation_id, state.local_player_nation);
563 uint8_t rel_flags = bool(rel) ? state.world.gp_relationship_get_status(rel) : 0;
564 switch(rel_flags & nations::influence::priority_mask) {
566 frame = 0;
567 disabled = !command::can_change_influence_priority(state, state.local_player_nation, nation_id, 1);
568 break;
570 frame = 1;
571 disabled = !command::can_change_influence_priority(state, state.local_player_nation, nation_id, 2);
572 break;
574 frame = 2;
575 disabled = !command::can_change_influence_priority(state, state.local_player_nation, nation_id, 3);
576 break;
578 frame = 3;
579 disabled = !command::can_change_influence_priority(state, state.local_player_nation, nation_id, 0);
580 break;
581 default:
582 break;
583 }
584 }
585
586 void button_action(sys::state& state) noexcept override {
587 auto nation_id = retrieve<dcon::nation_id>(state, parent);
588
589 auto rel = state.world.get_gp_relationship_by_gp_influence_pair(nation_id, state.local_player_nation);
590 uint8_t rel_flags = bool(rel) ? state.world.gp_relationship_get_status(rel) : 0;
591 switch(rel_flags & nations::influence::priority_mask) {
593 command::change_influence_priority(state, state.local_player_nation, nation_id, 1);
594 break;
596 command::change_influence_priority(state, state.local_player_nation, nation_id, 2);
597 break;
599 command::change_influence_priority(state, state.local_player_nation, nation_id, 3);
600 break;
602 command::change_influence_priority(state, state.local_player_nation, nation_id, 0);
603 break;
604 }
605 }
606
607 void button_right_action(sys::state& state) noexcept override {
608 auto nation_id = retrieve<dcon::nation_id>(state, parent);
609 auto rel = state.world.get_gp_relationship_by_gp_influence_pair(nation_id, state.local_player_nation);
610 uint8_t rel_flags = bool(rel) ? state.world.gp_relationship_get_status(rel) : 0;
611 switch(rel_flags & nations::influence::priority_mask) {
613 command::change_influence_priority(state, state.local_player_nation, nation_id, 3);
614 break;
616 command::change_influence_priority(state, state.local_player_nation, nation_id, 0);
617 break;
619 command::change_influence_priority(state, state.local_player_nation, nation_id, 1);
620 break;
622 command::change_influence_priority(state, state.local_player_nation, nation_id, 2);
623 break;
624 default:
625 break;
626 }
627 }
628
631 }
632
633 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
634 auto nation_id = retrieve<dcon::nation_id>(state, parent);
635
636 if(!nations::is_great_power(state, state.local_player_nation)) {
637 text::add_line(state, contents, "diplomacy_cannot_set_prio");
638 } else if(nations::is_great_power(state, nation_id)) {
639 text::add_line(state, contents, "diplomacy_cannot_set_prio_gp");
640 } else {
641 explain_influence(state, nation_id, contents);
642 }
643
644 auto box = text::open_layout_box(contents, 0);
646 text::localised_format_box(state, contents, box, std::string_view("diplomacy_set_prio_desc"));
647 text::close_layout_box(contents, box);
648 active_modifiers_description(state, contents, state.local_player_nation, 0, sys::national_mod_offsets::influence, false);
649 }
650};
651
653public:
654 bool is_active(sys::state& state) noexcept override {
655 auto const n = retrieve<dcon::nation_id>(state, parent);
656 auto const rel = state.world.get_unilateral_relationship_by_unilateral_pair(n, state.local_player_nation);
657 return state.world.unilateral_relationship_get_interested_in_alliance(rel);
658 }
659 void on_update(sys::state& state) noexcept override {
660 auto const n = retrieve<dcon::nation_id>(state, parent);
662 frame = is_active(state) ? 1 : 0;
663 }
664 void button_action(sys::state& state) noexcept override {
665 auto const n = retrieve<dcon::nation_id>(state, parent);
666 command::toggle_interested_in_alliance(state, state.local_player_nation, n);
667 }
670 }
671 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
672 text::add_line(state, contents, "alice_interested_in_alliance");
673 }
674};
675
676class diplomacy_country_info : public listbox_row_element_base<dcon::nation_id> {
677public:
678 void on_create(sys::state& state) noexcept override {
680 base_data.position.x -= 14;
681 base_data.position.y -= 524;
682 }
683 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
684 if(name == "country_select") {
685 return make_element_by_type<diplomacy_country_select>(state, id);
686 } else if(name == "country_flag") {
687 auto ptr = make_element_by_type<flag_button>(state, id);
688 ptr->base_data.position.y -= 2; // Nudge
689 return ptr;
690 } else if(name == "country_name") {
691 return make_element_by_type<generic_name_text<dcon::nation_id>>(state, id);
692 } else if(name == "country_prio") {
693 auto ptr = make_element_by_type<diplomacy_priority_button>(state, id);
694 //
695 auto btn = make_element_by_type<diplomacy_country_interested_in_alliance>(state, "alice_interested_in_alliance");
696 btn->base_data.position = ptr->base_data.position;
697 btn->base_data.position.x -= btn->base_data.size.x;
698 add_child_to_front(std::move(btn));
699 //
700 return ptr;
701 } else if(name == "country_boss_flag") {
702 return make_element_by_type<nation_overlord_flag>(state, id);
703 } else if(name == "country_prestige") {
704 return make_element_by_type<nation_prestige_rank_text>(state, id);
705 } else if(name == "country_economic") {
706 return make_element_by_type<nation_industry_rank_text>(state, id);
707 } else if(name == "country_military") {
708 return make_element_by_type<nation_military_rank_text>(state, id);
709 } else if(name == "country_total") {
710 return make_element_by_type<nation_rank_text>(state, id);
711 } else if(name == "country_opinion") {
712 return make_element_by_type<nation_player_opinion_text>(state, id);
713 } else if(name == "country_relation") {
714 return make_element_by_type<nation_player_relations_text>(state, id);
715 } else if(name.substr(0, 10) == "country_gp") {
716 auto ptr = make_element_by_type<nation_gp_opinion_text>(state, id);
717 ptr->rank = uint16_t(std::stoi(std::string{name.substr(10)}));
718 return ptr;
719 } else {
720 return nullptr;
721 }
722 }
723};
724
726 dcon::nation_id data;
727};
728
729class diplomacy_country_listbox : public listbox_element_base<diplomacy_country_info, dcon::nation_id> {
730protected:
731 std::string_view get_row_element_name() override {
732 return "diplomacy_country_info";
733 }
734 void on_update(sys::state& state) noexcept override {
735 auto current_filter = retrieve< country_filter_setting>(state, parent);
736 auto current_sort = retrieve<country_sort_setting>(state, parent);
737
738 row_contents.clear();
739 state.world.for_each_nation([&](dcon::nation_id id) {
740 if(state.world.nation_get_owned_province_count(id) != 0) {
741 bool passes_filter = country_category_filter_check(state, current_filter.general_category, state.local_player_nation, id);
742 bool right_continent = !current_filter.continent || state.world.nation_get_capital(id).get_continent() == current_filter.continent;
743 if(passes_filter && right_continent)
744 row_contents.push_back(id);
745 }
746 });
747 sort_countries(state, row_contents, current_sort.sort, current_sort.sort_ascend);
748 update(state);
749 }
750
751 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
752 if(payload.holds_type<dip_make_nation_visible>()) {
754
755 auto n = any_cast<dip_make_nation_visible>(payload).data;
756 int32_t i = int32_t(row_contents.size());
757 for(; i-- > 0;) {
758 if(row_contents[i] == n) {
759 break;
760 }
761 }
762 if(i != -1) {
763 auto current_vis = list_scrollbar->raw_value();
764 auto vis_count = int32_t(row_windows.size());
765
766 if(i < current_vis || i >= current_vis + vis_count) {
768 update(state);
769 }
770 }
772 } else {
774 }
775 }
776};
777
779public:
780 void on_update(sys::state& state) noexcept override {
781 auto cb = retrieve<military::available_cb>(state, parent);
782 dcon::cb_type_id content = cb.cb_type;
783 frame = state.world.cb_type_get_sprite_index(content) - 1;
784
785 auto conditions = state.world.cb_type_get_can_use(cb.cb_type);
786 if(conditions) {
787 disabled = !trigger::evaluate(state, conditions, trigger::to_generic(retrieve<dcon::nation_id>(state, parent)), trigger::to_generic(state.local_player_nation), trigger::to_generic(retrieve<dcon::nation_id>(state, parent)));
788 } else {
789 disabled = false;
790 }
791 }
792
795 }
796
797 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
798 auto cb = retrieve<military::available_cb>(state, parent);
799 text::add_line(state, contents, state.world.cb_type_get_name(cb.cb_type));
800 if(cb.expiration) {
801 text::add_line(state, contents, "until_date", text::variable_type::x, cb.expiration);
802 }
803 auto conditions = state.world.cb_type_get_can_use(cb.cb_type);
804 if(conditions) {
806 text::add_line(state, contents, "cb_conditions_header");
807 ui::trigger_description(state, contents, conditions, trigger::to_generic(retrieve<dcon::nation_id>(state, parent)), trigger::to_generic(state.local_player_nation), trigger::to_generic(retrieve<dcon::nation_id>(state, parent)));
808 }
809 }
810};
811
812class overlapping_cb_icon : public listbox_row_element_base<military::available_cb> {
813public:
814 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
815 if(name == "wargoal_icon") {
816 return make_element_by_type<cb_icon>(state, id);
817 } else {
818 return nullptr;
819 }
820 }
821};
822
823class overlapping_wargoals : public overlapping_listbox_element_base<overlapping_cb_icon, military::available_cb> {
824protected:
825 std::string_view get_row_element_name() override {
826 return "wargoal";
827 }
828
829public:
830 void on_update(sys::state& state) noexcept override {
831 row_contents.clear();
832
833 auto content = retrieve<dcon::nation_id>(state, parent);
834 if(!content || content == state.local_player_nation)
835 return;
836
837 auto one_cbs = state.world.nation_get_available_cbs(state.local_player_nation);
838 for(auto& cb : one_cbs)
839 if(cb.target == content)
840 row_contents.push_back(cb);
841
842 for(auto cb : state.world.in_cb_type) {
843 if((cb.get_type_bits() & military::cb_flag::always) != 0) {
844 if(military::cb_conditions_satisfied(state, state.local_player_nation, content, cb))
845 row_contents.push_back(military::available_cb{ sys::date{}, content, cb, dcon::state_definition_id{} });
846 }
847 }
848 update(state);
849
850 }
851};
852
853class overlapping_active_wargoals : public overlapping_listbox_element_base<overlapping_wg_icon, military::wg_summary> {
854protected:
855 std::string_view get_row_element_name() override {
856 return "wargoal";
857 }
858
859public:
860 void on_update(sys::state& state) noexcept override {
861 row_contents.clear();
862
863 auto content = retrieve<dcon::nation_id>(state, parent);
864
865 auto war = military::find_war_between(state, content, state.local_player_nation);
866
867 if(content && content != state.local_player_nation && war) {
868 for(auto wg : state.world.war_get_wargoals_attached(war)) {
869 if(wg.get_wargoal().get_added_by() == state.local_player_nation && wg.get_wargoal().get_target_nation() == content) {
871 wg.get_wargoal().get_secondary_nation(),
872 wg.get_wargoal().get_associated_tag(),
873 wg.get_wargoal().get_associated_state(),
874 wg.get_wargoal().get_type()
875 });
876 }
877 }
878 }
879
880
881 update(state);
882
883 }
884};
885
887public:
888 void on_update(sys::state& state) noexcept override {
889 auto content = retrieve<dcon::nation_id>(state, parent);
890 if(!content)
891 return;
892
893 disabled = true;
894 if(state.cheat_data.always_allow_wargoals) {
895 disabled = false;
896 return;
897 }
898
899 if(content == state.local_player_nation) {
900 return;
901 }
902
903 if(state.world.nation_get_diplomatic_points(state.local_player_nation) < state.defines.addwargoal_diplomatic_cost) {
904 return;
905 }
906
907 auto w = military::find_war_between(state, state.local_player_nation, content);
908 if(!w) {
909 return;
910 }
911
912 bool is_attacker = military::is_attacker(state, w, state.local_player_nation);
914 return;
915
916 for(auto cb_type : state.world.in_cb_type) {
917 if((state.world.cb_type_get_type_bits(cb_type) & military::cb_flag::always) == 0 && military::cb_conditions_satisfied(state, state.local_player_nation, content, cb_type)) {
918 bool cb_fabbed = false;
919 for(auto& fab_cb : state.world.nation_get_available_cbs(state.local_player_nation)) {
920 if(fab_cb.cb_type == cb_type && fab_cb.target == content) {
921 cb_fabbed = true;
922 break;
923 }
924 }
925 if(!cb_fabbed) {
926 if((state.world.cb_type_get_type_bits(cb_type) & military::cb_flag::is_not_constructing_cb) != 0)
927 continue; // can only add a constructable cb this way
928
929 auto totalpop = state.world.nation_get_demographics(state.local_player_nation, demographics::total);
930 auto jingoism_perc = totalpop > 0 ? state.world.nation_get_demographics(state.local_player_nation, demographics::to_key(state, state.culture_definitions.jingoism)) / totalpop : 0.0f;
931
932 if(state.world.war_get_is_great(w)) {
933 if(jingoism_perc >= state.defines.wargoal_jingoism_requirement * state.defines.gw_wargoal_jingoism_requirement_mod) {
934 disabled = false;
935 return;
936 }
937 } else {
938 if(jingoism_perc >= state.defines.wargoal_jingoism_requirement) {
939 disabled = false;
940 return;
941 }
942 }
943 } else {
944 disabled = false;
945 return;
946 }
947 } else { // this is an always CB
948 // prevent duplicate war goals
949 if(military::cb_conditions_satisfied(state, state.local_player_nation, content, cb_type) && military::can_add_always_cb_to_war(state, state.local_player_nation, content, cb_type, w)) {
950 disabled = false;
951 return;
952 }
953 }
954 }
955 }
956
957 void button_action(sys::state& state) noexcept override {
959 }
960
963 }
964
965 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
966 auto content = retrieve<dcon::nation_id>(state, parent);
967 if(content == state.local_player_nation) {
968 text::add_line_with_condition(state, contents, "add_wg_1", false);
969 return;
970 }
971
972 if(state.defines.addwargoal_diplomatic_cost > 0) {
973 text::add_line_with_condition(state, contents, "add_wg_3", state.world.nation_get_diplomatic_points(state.local_player_nation) >= state.defines.addwargoal_diplomatic_cost, text::variable_type::x, int64_t(state.defines.addwargoal_diplomatic_cost));
974 }
975
976 auto w = military::find_war_between(state, state.local_player_nation, content);
977 text::add_line_with_condition(state, contents, "add_wg_2", bool(w));
978 if(!w) {
979 return;
980 }
981
982 bool is_attacker = military::is_attacker(state, w, state.local_player_nation);
984
985 for(auto cb_type : state.world.in_cb_type) {
986 if(military::cb_conditions_satisfied(state, state.local_player_nation, content, cb_type)) {
987 if((state.world.cb_type_get_type_bits(cb_type) & military::cb_flag::always) == 0) {
988 for(auto& fab_cb : state.world.nation_get_available_cbs(state.local_player_nation)) {
989 if(fab_cb.cb_type == cb_type && fab_cb.target == content) {
990 return;
991 }
992 }
993 } else { // this is an always CB
994 // prevent duplicate war goals
995 if(military::can_add_always_cb_to_war(state, state.local_player_nation, content, cb_type, w)) {
996 return;
997 }
998 }
999 }
1000 }
1001
1002 // if we hit this, it means no existing cb is ready to be applied
1003 auto totalpop = state.world.nation_get_demographics(state.local_player_nation, demographics::total);
1004 auto jingoism_perc = totalpop > 0 ? state.world.nation_get_demographics(state.local_player_nation, demographics::to_key(state, state.culture_definitions.jingoism)) / totalpop : 0.0f;
1005 if(state.world.war_get_is_great(w)) {
1006 text::add_line_with_condition(state, contents, "add_wg_4", jingoism_perc >= state.defines.wargoal_jingoism_requirement * state.defines.gw_wargoal_jingoism_requirement_mod, text::variable_type::x, text::fp_percentage_one_place{jingoism_perc}, text::variable_type::y, text::fp_percentage_one_place{state.defines.wargoal_jingoism_requirement * state.defines.gw_wargoal_jingoism_requirement_mod});
1007 } else {
1008 text::add_line_with_condition(state, contents, "add_wg_4", jingoism_perc >= state.defines.wargoal_jingoism_requirement, text::variable_type::x, text::fp_percentage_one_place{jingoism_perc}, text::variable_type::y, text::fp_percentage_one_place{state.defines.wargoal_jingoism_requirement});
1009 }
1010 }
1011};
1012
1014public:
1015 void on_update(sys::state& state) noexcept override {
1016 auto pc = state.world.nation_get_primary_culture(retrieve<dcon::nation_id>(state, parent));
1017 auto pr = state.world.nation_get_religion(retrieve<dcon::nation_id>(state, parent));
1018 std::string t = text::produce_simple_string(state, pc.get_name());
1019 t += ", ";
1020 t += text::produce_simple_string(state, pr.get_name());
1021 set_text(state, t);
1022 }
1025 }
1026 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1027 auto content = retrieve<dcon::nation_id>(state, parent);
1028 text::add_line(state, contents, "is_primary_culture", text::variable_type::name, state.world.culture_get_name(state.world.nation_get_primary_culture(content)));
1029 text::add_line(state, contents, "is_primary_religion", text::variable_type::name, state.world.religion_get_name(state.world.nation_get_religion(content)));
1030 }
1031};
1032
1034 void on_update(sys::state& state) noexcept override {
1035 auto n = retrieve<dcon::nation_id>(state, parent);
1036 bool first = true;
1037 std::string t;
1038 for(const auto ac : state.world.in_culture) {
1039 if(state.world.nation_get_accepted_cultures(n, ac)) {
1040 if(first) {
1041 first = false;
1042 } else {
1043 t += ", ";
1044 }
1045 t += text::produce_simple_string(state, state.world.culture_get_name(ac));
1046 }
1047 }
1049 }
1050 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
1052 }
1053 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1054 auto n = retrieve<dcon::nation_id>(state, parent);
1055 for(const auto c : state.world.in_culture) {
1056 if(state.world.nation_get_accepted_cultures(n, c))
1057 text::add_line(state, contents, "is_accepted_culture2", text::variable_type::name, state.world.culture_get_name(c));
1058 }
1059 }
1060};
1061
1063public:
1064 bool show = false;
1065
1066 void on_update(sys::state& state) noexcept override {
1067 show = nations::is_great_power(state, retrieve<dcon::nation_id>(state, parent));
1068 }
1069 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
1070 if(show)
1072 }
1073};
1074
1076 int32_t value = 0;
1077};
1078
1080public:
1081 bool show = false;
1082 void on_update(sys::state& state) noexcept override {
1083 auto gp = nations::get_nth_great_power(state, uint16_t(retrieve<gp_detail_num>(state, parent).value));
1084 auto target = retrieve<dcon::nation_id>(state, parent);
1085 show = (state.world.gp_relationship_get_status(state.world.get_gp_relationship_by_gp_influence_pair(target, gp)) & nations::influence::is_banned) != 0;
1086 }
1089 }
1090
1091 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1092 auto gp = nations::get_nth_great_power(state, uint16_t(retrieve<gp_detail_num>(state, parent).value));
1093 auto target = retrieve<dcon::nation_id>(state, parent);
1094 auto rel = state.world.get_gp_relationship_by_gp_influence_pair(target, gp);
1095
1096 text::add_line(state, contents, "dp_inf_tooltip_ban", text::variable_type::x, state.world.gp_relationship_get_penalty_expires_date(rel));
1097 }
1098 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
1099 if(show)
1101 }
1102};
1103
1105public:
1106 bool show = false;
1107 void on_update(sys::state& state) noexcept override {
1108 auto gp = nations::get_nth_great_power(state, uint16_t(retrieve<gp_detail_num>(state, parent).value));
1109 auto target = retrieve<dcon::nation_id>(state, parent);
1110 show = (state.world.gp_relationship_get_status(state.world.get_gp_relationship_by_gp_influence_pair(target, gp)) & nations::influence::is_discredited) != 0;
1111 }
1114 }
1115
1116 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1117 auto gp = nations::get_nth_great_power(state, uint16_t(retrieve<gp_detail_num>(state, parent).value));
1118 auto target = retrieve<dcon::nation_id>(state, parent);
1119 auto rel = state.world.get_gp_relationship_by_gp_influence_pair(target, gp);
1120
1121 text::add_line(state, contents, "dp_inf_tooltip_discredit", text::variable_type::x, state.world.gp_relationship_get_penalty_expires_date(rel));
1122 }
1123 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
1124 if(show)
1126 }
1127};
1128
1130public:
1131 void on_update(sys::state& state) noexcept override {
1132 auto gp = nations::get_nth_great_power(state, uint16_t(retrieve<gp_detail_num>(state, parent).value));
1133 auto target = retrieve<dcon::nation_id>(state, parent);
1134
1135 set_text(state, text::get_influence_level_name(state, state.world.gp_relationship_get_status(state.world.get_gp_relationship_by_gp_influence_pair(target, gp))));
1136 }
1137};
1139public:
1140 void on_update(sys::state& state) noexcept override {
1141 auto gp = nations::get_nth_great_power(state, uint16_t(retrieve<gp_detail_num>(state, parent).value));
1142 auto target = retrieve<dcon::nation_id>(state, parent);
1143
1144 set_text(state, text::format_float(state.world.gp_relationship_get_influence(state.world.get_gp_relationship_by_gp_influence_pair(target, gp)), 1));
1145 }
1146};
1148public:
1149 void on_update(sys::state& state) noexcept override {
1150 auto gp = nations::get_nth_great_power(state, uint16_t(retrieve<gp_detail_num>(state, parent).value));
1151 auto target = retrieve<dcon::nation_id>(state, parent);
1152
1153 set_text(state, text::format_money(state.world.unilateral_relationship_get_foreign_investment(state.world.get_unilateral_relationship_by_unilateral_pair(target, gp))));
1154 }
1155};
1156
1158public:
1159 virtual dcon::national_identity_id get_current_nation(sys::state& state) noexcept override {
1160 auto gp = nations::get_nth_great_power(state, uint16_t(retrieve<gp_detail_num>(state, parent).value));
1161 return state.world.nation_get_identity_from_identity_holder(gp);
1162 }
1163};
1164
1167};
1168
1170public:
1171 int32_t gp_num = 0;
1172
1173 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1174 if(name == "country_flag") {
1175 return make_element_by_type<great_power_detail_flag>(state, id);
1176 } else if(name == "nongp_country_opinion") {
1177 return make_element_by_type<great_power_opinion_detail>(state, id);
1178 } else if(name == "nongp_country_influence") {
1179 return make_element_by_type<great_power_influence_detail>(state, id);
1180 } else if(name == "nongp_country_invest") {
1181 return make_element_by_type<great_power_investment_detail>(state, id);
1182 } else if(name == "country_discredited") {
1183 return make_element_by_type<gp_detail_discredited>(state, id);
1184 } else if(name == "country_banned_embassy") {
1185 return make_element_by_type<gp_detail_banned>(state, id);
1186 }
1187
1188 return nullptr;
1189 }
1190
1191 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
1192 if(payload.holds_type<gp_detail_num>()) {
1193 payload.emplace<gp_detail_num>(gp_detail_num{ gp_num });
1195 }
1196 return window_element_base::get(state, payload);
1197 }
1198};
1199
1200template<class T>
1202public:
1203
1204 void on_update(sys::state& state) noexcept override {
1205 T content = retrieve<T>(state, parent);
1206 dcon::overlord_id overlord = state.world.nation_get_overlord_as_subject(content);
1207 dcon::nation_id overlord_nation = state.world.overlord_get_ruler(overlord);
1208 auto fat_id = dcon::fatten(state.world, overlord_nation);
1209 if(state.world.nation_get_is_substate(content)) {
1211 } else if(overlord_nation) {
1213 } else {
1215 }
1216 }
1217};
1218
1220private:
1221 flag_button* country_flag = nullptr;
1222 nation_player_relations_text* country_relation = nullptr;
1223 image_element_base* country_relation_icon = nullptr;
1224
1225 ui::xy_pair sub_window_top_left = {};
1226
1227 std::array<element_base*, 7> gp_elements;
1228 std::array<element_base*, 9> non_gp_elements;
1229 std::array<element_base*, 21> war_elements;
1230
1231public:
1232 void on_create(sys::state& state) noexcept override {
1234 uint32_t row_count = uint32_t(state.defines.great_nations_count) / 2;
1235 for(uint32_t i = 0; i < uint32_t(state.defines.great_nations_count); i++) {
1236 auto win = make_element_by_type<great_power_inf_detail>(state, state.ui_state.defs_by_name.find(state.lookup_key("diplomacy_non_gp_extra_info"))->second.definition);
1237 win->gp_num = int32_t(i);
1238 win->base_data.position = sub_window_top_left;
1239 win->base_data.position.x += win->base_data.size.x * int16_t(i / row_count);
1240 win->base_data.position.y += win->base_data.size.y * int16_t(i % row_count);
1241 non_gp_elements[1 + i] = win.get();
1242 add_child_to_front(std::move(win));
1243 }
1244 }
1245
1246 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1247 if(name == "gp_extra_info_bg") {
1248 auto ptr = make_element_by_type<image_element_base>(state, id);
1249 gp_elements[0] = ptr.get();
1250 return ptr;
1251 } else if(name == "country_gp_friendly_label") {
1252 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1253 gp_elements[1] = ptr.get();
1254 return ptr;
1255 } else if(name == "country_gp_cordial_label") {
1256 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1257 gp_elements[2] = ptr.get();
1258 return ptr;
1259 } else if(name == "country_gp_sphere_label") {
1260 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1261 gp_elements[3] = ptr.get();
1262 return ptr;
1263 } else if(name == "country_gp_friendly") {
1264 auto ptr = make_element_by_type<overlapping_friendly_flags>(state, id);
1265 ptr->base_data.position.y -= 8 - 1; // Nudge
1266 gp_elements[4] = ptr.get();
1267 return ptr;
1268 } else if(name == "country_gp_cordial") {
1269 auto ptr = make_element_by_type<overlapping_cordial_flags>(state, id);
1270 ptr->base_data.position.y -= 8 - 1; // Nudge
1271 gp_elements[5] = ptr.get();
1272 return ptr;
1273 } else if(name == "country_gp_sphere") {
1274 auto ptr = make_element_by_type<overlapping_sphere_flags>(state, id);
1275 ptr->base_data.position.y -= 8 - 1; // Nudge
1276 gp_elements[6] = ptr.get();
1277 return ptr;
1278 } else if(name == "nongp_extra_info_bg") {
1279 auto ptr = make_element_by_type<image_element_base>(state, id);
1280 non_gp_elements[0] = ptr.get();
1281 auto const& def = state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("diplomacy_non_gp_extra_fact_pos"))->second.definition];
1282 sub_window_top_left = def.position;
1283 return ptr;
1284 } else if(name == "country_flag") {
1285 return make_element_by_type<flag_button>(state, id);
1286 } else if(name == "country_flag_overlay") {
1287 return make_element_by_type<nation_flag_frame>(state, id);
1288 } else if(name == "country_name") {
1289 return make_element_by_type<generic_name_text<dcon::nation_id>>(state, id);
1290 } else if(name == "country_status") {
1291 auto ptr = make_element_by_type<nation_status_diplomacy_window<dcon::nation_id>>(state, id);
1292 return ptr;
1293 } else if(name == "selected_nation_totalrank") {
1294 return make_element_by_type<nation_rank_text>(state, id);
1295 } else if(name == "ideology_icon") {
1296 return make_element_by_type<nation_ruling_party_ideology_plupp>(state, id);
1297 } else if(name == "country_party") {
1298 return make_element_by_type<nation_ruling_party_text>(state, id);
1299 } else if(name == "country_gov") {
1300 return make_element_by_type<nation_government_type_text>(state, id);
1301 } else if(name == "country_tech") {
1302 return make_element_by_type<national_tech_school>(state, id);
1303 } else if(name == "our_relation_icon") {
1304 auto ptr = make_element_by_type<image_element_base>(state, id);
1305 country_relation_icon = ptr.get();
1306 return ptr;
1307 } else if(name == "our_relation") {
1308 auto ptr = make_element_by_type<nation_player_relations_text>(state, id);
1309 country_relation = ptr.get();
1310 return ptr;
1311 } else if(name == "country_prestige") {
1312 return make_element_by_type<nation_prestige_text>(state, id);
1313 } else if(name == "selected_prestige_rank") {
1314 return make_element_by_type<nation_prestige_rank_text>(state, id);
1315 } else if(name == "country_economic") {
1316 return make_element_by_type<nation_industry_score_text>(state, id);
1317 } else if(name == "selected_industry_rank") {
1318 return make_element_by_type<nation_industry_rank_text>(state, id);
1319 } else if(name == "country_military") {
1320 return make_element_by_type<nation_military_score_text>(state, id);
1321 } else if(name == "selected_military_rank") {
1322 return make_element_by_type<nation_military_rank_text>(state, id);
1323 } else if(name == "country_total") {
1324 return make_element_by_type<nation_total_score_text>(state, id);
1325 } else if(name == "selected_total_rank") {
1326 return make_element_by_type<nation_rank_text>(state, id);
1327 } else if(name == "country_population") {
1328 return make_element_by_type<nation_population_text>(state, id);
1329 } else if(name == "country_primary_cultures") {
1330 return make_element_by_type<nation_primary_culture>(state, id);
1331 } else if(name == "country_accepted_cultures") {
1332 return make_element_by_type<nation_accepted_cultures>(state, id);
1333 } else if(name == "war_extra_info_bg") {
1334 auto ptr = make_element_by_type<image_element_base>(state, id);
1335 war_elements[0] = ptr.get();
1336 return ptr;
1337 } else if(name == "country_wars") {
1338 auto ptr = make_element_by_type<overlapping_enemy_flags>(state, id);
1339 ptr->base_data.position.y -= 8 - 1; // Nudge
1340 war_elements[1] = ptr.get();
1341 return ptr;
1342 } else if(name == "country_wars_text") {
1343 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1344 war_elements[2] = ptr.get();
1345 return ptr;
1346 } else if(name == "country_allies_text") {
1347 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1348 war_elements[3] = ptr.get();
1349 return ptr;
1350 } else if(name == "country_protected_text") {
1351 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1352 war_elements[4] = ptr.get();
1353 return ptr;
1354 } else if(name == "country_truce_text") {
1355 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1356 war_elements[5] = ptr.get();
1357 return ptr;
1358 } else if(name == "country_cb_text") {
1359 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1360 war_elements[6] = ptr.get();
1361 return ptr;
1362 } else if(name == "infamy_icon") {
1363 auto ptr = make_element_by_type<image_element_base>(state, id);
1364 war_elements[7] = ptr.get();
1365 return ptr;
1366 } else if(name == "warexhastion_icon") {
1367 auto ptr = make_element_by_type<image_element_base>(state, id);
1368 war_elements[8] = ptr.get();
1369 return ptr;
1370 } else if(name == "brigade_icon") {
1371 auto ptr = make_element_by_type<image_element_base>(state, id);
1372 war_elements[9] = ptr.get();
1373 return ptr;
1374 } else if(name == "ships_icon") {
1375 auto ptr = make_element_by_type<image_element_base>(state, id);
1376 war_elements[10] = ptr.get();
1377 return ptr;
1378 } else if(name == "country_allies") {
1379 auto ptr = make_element_by_type<overlapping_ally_flags>(state, id);
1380 ptr->base_data.position.y -= 8 - 1; // Nudge
1381 war_elements[11] = ptr.get();
1382 return ptr;
1383 } else if(name == "country_protected") {
1384 auto ptr = make_element_by_type<overlapping_sphere_flags>(state, id);
1385 ptr->base_data.position.y -= 8 - 1; // Nudge
1386 war_elements[12] = ptr.get();
1387 return ptr;
1388 } else if(name == "country_truce") {
1389 auto ptr = make_element_by_type<overlapping_truce_flags>(state, id);
1390 ptr->base_data.position.y -= 8 - 1; // Nudge
1391 war_elements[13] = ptr.get();
1392 return ptr;
1393 } else if(name == "current_wargoals") {
1394 auto ptr = make_element_by_type<overlapping_active_wargoals>(state, id);
1395 war_elements[14] = ptr.get();
1396 return ptr;
1397 } else if(name == "country_cb") {
1398 auto ptr = make_element_by_type<overlapping_wargoals>(state, id);
1399 war_elements[15] = ptr.get();
1400 return ptr;
1401 } else if(name == "infamy_text") {
1402 auto ptr = make_element_by_type<nation_infamy_text>(state, id);
1403 war_elements[16] = ptr.get();
1404 return ptr;
1405 } else if(name == "warexhastion_text") {
1406 auto ptr = make_element_by_type<diplomacy_war_exhaustion>(state, id);
1407 war_elements[17] = ptr.get();
1408 return ptr;
1409 } else if(name == "brigade_text") {
1410 auto ptr = make_element_by_type<diplomacy_nation_armies_text>(state, id);
1411 war_elements[18] = ptr.get();
1412 return ptr;
1413 } else if(name == "ships_text") {
1414 auto ptr = make_element_by_type<diplomacy_nation_navies_text>(state, id);
1415 war_elements[19] = ptr.get();
1416 return ptr;
1417 } else if(name == "add_wargoal") {
1418 auto ptr = make_element_by_type<diplomacy_action_add_wargoal_button>(state, id);
1419 war_elements[20] = ptr.get();
1420 return ptr;
1421 } else if(name == "selected_military_icon") {
1422 return make_element_by_type<military_score_icon>(state, id);
1423 } else {
1424 return nullptr;
1425 }
1426 }
1427
1428 void on_update(sys::state& state) noexcept override {
1429 auto content = retrieve<dcon::nation_id>(state, parent);
1430 country_relation->set_visible(state, content != state.local_player_nation);
1431 country_relation_icon->set_visible(state, content != state.local_player_nation);
1432 auto active_tab = retrieve<dip_tab_request>(state, parent).tab;
1433
1434 if(active_tab != diplomacy_window_tab::great_powers) {
1435 for(auto p : gp_elements) {
1436 if(p)
1437 p->set_visible(state, false);
1438 }
1439 for(auto p : non_gp_elements) {
1440 if(p)
1441 p->set_visible(state, false);
1442 }
1443 for(auto p : war_elements) {
1444 if(p)
1445 p->set_visible(state, true);
1446 }
1447 } else if(nations::is_great_power(state, content)) {
1448 for(auto p : gp_elements) {
1449 if(p)
1450 p->set_visible(state, true);
1451 }
1452 for(auto p : non_gp_elements) {
1453 if(p)
1454 p->set_visible(state, false);
1455 }
1456 for(auto p : war_elements) {
1457 if(p)
1458 p->set_visible(state, false);
1459 }
1460 } else {
1461 for(auto p : gp_elements) {
1462 if(p)
1463 p->set_visible(state, false);
1464 }
1465 for(auto p : non_gp_elements) {
1466 if(p)
1467 p->set_visible(state, true);
1468 }
1469 for(auto p : war_elements) {
1470 if(p)
1471 p->set_visible(state, false);
1472 }
1473 }
1474
1475 }
1476};
1477
1479protected:
1481 row_contents.clear();
1482 dcon::war_id w = retrieve<dcon::war_id>(state, parent);
1483 auto war = dcon::fatten(state.world, w);
1484 row_contents.push_back(war.get_primary_attacker().get_identity_from_identity_holder().id);
1485 for(auto o : war.get_war_participant())
1486 if(o.get_is_attacker() == true && o.get_nation() != war.get_primary_attacker())
1487 row_contents.push_back(o.get_nation().get_identity_from_identity_holder().id);
1488 update(state);
1489 }
1490};
1492protected:
1494 row_contents.clear();
1495 dcon::war_id w = retrieve<dcon::war_id>(state, parent);
1496 auto war = dcon::fatten(state.world, w);
1497 row_contents.push_back(war.get_primary_defender().get_identity_from_identity_holder().id);
1498 for(auto o : war.get_war_participant())
1499 if(o.get_is_attacker() == false && o.get_nation() != war.get_primary_defender())
1500 row_contents.push_back(o.get_nation().get_identity_from_identity_holder().id);
1501 update(state);
1502 }
1503};
1504
1505template<bool IsAttacker>
1507public:
1508 void on_update(sys::state& state) noexcept override {
1509 dcon::war_id content = retrieve<dcon::war_id>(state, parent);
1510
1511 auto fat_id = dcon::fatten(state.world, content);
1512 int32_t strength = 0;
1513 for(auto o : fat_id.get_war_participant())
1514 if(o.get_is_attacker() == IsAttacker)
1515 strength += int32_t(o.get_nation().get_military_score());
1516 set_button_text(state, std::to_string(strength));
1517 }
1518
1521 }
1522
1523 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1524 dcon::war_id content = retrieve<dcon::war_id>(state, parent);
1525 auto fat_id = dcon::fatten(state.world, content);
1526 {
1527 auto box = text::open_layout_box(contents, 0);
1529 text::add_to_substitution_map(sub, text::variable_type::date, fat_id.get_start_date());
1530 text::localised_format_box(state, contents, box, "war_start_date_desc", sub);
1531 text::close_layout_box(contents, box);
1532 }
1533 for(auto o : fat_id.get_war_participant()) {
1534 if(o.get_is_attacker() == IsAttacker) {
1535 auto name = text::get_name(state, o.get_nation().id);
1536 auto box = text::open_layout_box(contents, 0);
1538 text::add_to_layout_box(state, contents, box, std::string{":"}, text::text_color::yellow);
1539 text::add_space_to_layout_box(state, contents, box);
1540 auto strength = int32_t(o.get_nation().get_military_score());
1541 text::add_to_layout_box(state, contents, box, std::to_string(strength), text::text_color::white);
1542 text::close_layout_box(contents, box);
1543 }
1544 }
1545 }
1546};
1547
1548template<bool B>
1550public:
1551 void on_create(sys::state& state) noexcept override {
1554 }
1555
1556 void on_update(sys::state& state) noexcept override {
1557 dcon::war_id war_id = retrieve<dcon::war_id>(state, parent);
1558 disabled = !command::can_intervene_in_war(state, state.local_player_nation, war_id, B);
1559 }
1560
1561 void button_action(sys::state& state) noexcept override {
1562 dcon::war_id war_id = retrieve<dcon::war_id>(state, parent);
1563 command::intervene_in_war(state, state.local_player_nation, war_id, B);
1564 }
1565
1568 }
1569
1570 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1571
1572 dcon::nation_id nation_id = retrieve<dcon::nation_id>(state, parent);
1573 dcon::war_id w = retrieve<dcon::war_id>(state, parent);
1574
1575 if(!state.world.war_get_is_great(w)) {
1576 text::add_line(state, contents, "intervene_1");
1577 } else {
1578 text::add_line(state, contents, "intervene_2");
1579 }
1581
1582 text::add_line_with_condition(state, contents, "intervene_3", nations::is_great_power(state, state.local_player_nation));
1583 text::add_line_with_condition(state, contents, "intervene_4", !nations::is_involved_in_crisis(state, state.local_player_nation));
1584 if(state.defines.min_months_to_intervene > 0) {
1585 text::add_line_with_condition(state, contents, "intervene_5", state.current_date >= state.world.war_get_start_date(w) + int32_t(30.0f * state.defines.min_months_to_intervene), text::variable_type::x, int64_t(state.defines.min_months_to_intervene));
1586 }
1587 text::add_line_with_condition(state, contents, "intervene_6", military::joining_war_does_not_violate_constraints(state, state.local_player_nation, w, B));
1588
1589 if constexpr(!B) {
1590 text::add_line_with_condition(state, contents, "intervene_8", !military::has_truce_with(state, state.local_player_nation, state.world.war_get_primary_attacker(w)));
1591 }
1592
1593 if(!state.world.war_get_is_great(w)) {
1594 auto defender = state.world.war_get_primary_defender(w);
1595 auto rel_w_defender = state.world.get_gp_relationship_by_gp_influence_pair(defender, state.local_player_nation);
1596 auto inf = state.world.gp_relationship_get_status(rel_w_defender) & nations::influence::level_mask;
1597
1599
1600 text::add_line_with_condition(state, contents, "intervene_7", !state.world.war_get_is_crisis_war(w));
1601 text::add_line_with_condition(state, contents, "intervene_9", !B);
1603 text::add_line_with_condition(state, contents, "intervene_11", military::primary_warscore(state, w) >= -state.defines.min_warscore_to_intervene, text::variable_type::x, int64_t(-state.defines.min_warscore_to_intervene));
1604
1605 } else {
1606 if constexpr(B) {
1607 text::add_line_with_condition(state, contents, "intervene_8", !military::joining_as_attacker_would_break_truce(state, state.local_player_nation, w));
1608 }
1609
1610 text::add_line_with_condition(state, contents, "intervene_12", state.world.nation_get_war_exhaustion(state.local_player_nation) < state.defines.gw_intervene_max_exhaustion, text::variable_type::x, int64_t(state.defines.gw_intervene_max_exhaustion));
1611
1612 auto primary_on_side = B ? state.world.war_get_primary_attacker(w) : state.world.war_get_primary_defender(w);
1613 auto rel = state.world.get_diplomatic_relation_by_diplomatic_pair(primary_on_side, state.local_player_nation);
1614
1615 text::add_line_with_condition(state, contents, "intervene_13", state.world.diplomatic_relation_get_value(rel) >= state.defines.gw_intervene_min_relations, text::variable_type::x, int64_t(state.defines.gw_intervene_min_relations));
1616
1617 bool any_in_sphere = false;
1618 bool any_allied = false;
1619 bool any_armies = false;
1620
1621 for(auto p : state.world.war_get_war_participant(w)) {
1622 if(p.get_is_attacker() != B) { // scan nations on other side
1623 if(p.get_nation().get_in_sphere_of() == state.local_player_nation)
1624 any_in_sphere = true;
1625
1626 auto irel = state.world.get_diplomatic_relation_by_diplomatic_pair(p.get_nation(), state.local_player_nation);
1627 if(state.world.diplomatic_relation_get_are_allied(irel))
1628 any_allied = true;
1629
1630 for(auto prov : p.get_nation().get_province_ownership()) {
1631 for(auto arm : prov.get_province().get_army_location()) {
1632 if(arm.get_army().get_controller_from_army_control() == state.local_player_nation)
1633 any_armies = true;
1634 }
1635 }
1636 }
1637 }
1638 text::add_line_with_condition(state, contents, "intervene_14", !any_in_sphere);
1639 text::add_line_with_condition(state, contents, "intervene_15", !any_allied);
1640 text::add_line_with_condition(state, contents, "intervene_16", !any_armies);
1641 }
1642
1643
1644 }
1645};
1646
1648public:
1649 void on_update(sys::state& state) noexcept override {
1650 auto wg = retrieve<dcon::wargoal_id>(state, parent);
1651 frame = state.world.cb_type_get_sprite_index(state.world.wargoal_get_type(wg)) - 1;
1652 }
1653
1656 }
1657
1658 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1659 auto wg = retrieve<dcon::wargoal_id>(state, parent);
1660 auto cb = state.world.wargoal_get_type(wg);
1661 text::add_line(state, contents, state.world.cb_type_get_name(cb));
1662
1664 text::add_line(state, contents, "war_goal_1", text::variable_type::x, state.world.wargoal_get_added_by(wg));
1665 text::add_line(state, contents, "war_goal_2", text::variable_type::x, state.world.wargoal_get_target_nation(wg));
1666 if(state.world.wargoal_get_associated_state(wg)) {
1667 text::add_line(state, contents, "war_goal_3", text::variable_type::x, state.world.wargoal_get_associated_state(wg));
1668 }
1669 if(state.world.wargoal_get_associated_tag(wg)) {
1670 text::add_line(state, contents, "war_goal_10", text::variable_type::x, state.world.wargoal_get_associated_tag(wg));
1671 } else if(state.world.wargoal_get_secondary_nation(wg)) {
1672 text::add_line(state, contents, "war_goal_4", text::variable_type::x, state.world.wargoal_get_secondary_nation(wg));
1673 }
1674 if(state.world.wargoal_get_ticking_war_score(wg) != 0) {
1675 text::add_line(state, contents, "war_goal_5", text::variable_type::x, text::fp_one_place{state.world.wargoal_get_ticking_war_score(wg)});
1676 {
1677 auto box = text::open_layout_box(contents);
1679 text::add_to_substitution_map(sub, text::variable_type::x, text::fp_percentage{ state.defines.tws_fulfilled_idle_space });
1681 text::localised_format_box(state, contents, box, "war_goal_6", sub);
1682 text::close_layout_box(contents, box);
1683 }
1684 {
1685 auto box = text::open_layout_box(contents);
1687 text::add_to_substitution_map(sub, text::variable_type::x, text::pretty_integer{ int32_t(state.defines.tws_grace_period_days) });
1688 text::add_to_substitution_map(sub, text::variable_type::y, text::fp_two_places{ state.defines.tws_not_fulfilled_speed });
1689 text::localised_format_box(state, contents, box, "war_goal_7", sub);
1690 text::close_layout_box(contents, box);
1691 }
1692 auto const start_date = state.world.war_get_start_date(state.world.wargoal_get_war_from_wargoals_attached(wg));
1693 auto const end_date = start_date + int32_t(state.defines.tws_grace_period_days);
1694 auto box = text::open_layout_box(contents);
1698 if(end_date <= state.current_date) {
1699 text::localised_format_box(state, contents, box, "war_goal_9", sub);
1700 } else {
1701 text::localised_format_box(state, contents, box, "war_goal_8", sub);
1702 }
1703 text::close_layout_box(contents, box);
1704 }
1705 }
1706};
1707
1708class overlapping_wargoal_icon : public listbox_row_element_base<dcon::wargoal_id> {
1709public:
1710 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1711 if(name == "wargoal_icon") {
1712 return make_element_by_type<wargoal_icon>(state, id);
1713 } else {
1714 return nullptr;
1715 }
1716 }
1717};
1718
1719template<bool B>
1720class diplomacy_war_overlapping_wargoals : public overlapping_listbox_element_base<overlapping_wargoal_icon, dcon::wargoal_id> {
1721protected:
1722 std::string_view get_row_element_name() override {
1723 return "wargoal";
1724 }
1725
1726public:
1727 void on_update(sys::state& state) noexcept override {
1728 row_contents.clear();
1729
1730 dcon::war_id content = retrieve<dcon::war_id>(state, parent);
1731 for(auto wg : state.world.war_get_wargoals_attached(content)) {
1732 if(military::is_attacker(state, content, wg.get_wargoal().get_added_by()) == B)
1733 row_contents.push_back(wg.get_wargoal().id);
1734 }
1735
1736 update(state);
1737 }
1738};
1739
1741 void on_update(sys::state& state) noexcept override {
1742 auto w = retrieve<dcon::war_id>(state, parent);
1743 auto s = military::get_war_name(state, w);
1744 set_text(state, s);
1745 }
1746};
1747
1749public:
1750 void on_update(sys::state& state) noexcept override {
1751 auto war = retrieve<dcon::war_id>(state, parent);
1752 if(war) {
1753 auto ws = military::primary_warscore(state, war);
1754 progress = ws / 200.0f + 0.5f;
1755 }
1756 }
1757
1760 }
1761
1762 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1763 auto war = retrieve<dcon::war_id>(state, parent);
1768 }
1769};
1770
1773 int16_t width = 0;
1774};
1775
1777public:
1778 void on_update(sys::state& state) noexcept override {
1779 auto bar_pos = retrieve<war_bar_position>(state, parent);
1780 auto war = retrieve<dcon::war_id>(state, parent);
1781
1782 auto attacker_cost = std::min(military::attacker_peace_cost(state, war), 100);
1783 auto x_pos = int16_t((float(attacker_cost) / 200.0f + 0.5f) * float(bar_pos.width));
1784
1785 base_data.position.x = int16_t(x_pos + bar_pos.bottom_left.x - base_data.size.x / 2);
1786 base_data.position.y = bar_pos.bottom_left.y;
1787 }
1788};
1789
1791public:
1792 void on_update(sys::state& state) noexcept override {
1793 auto bar_pos = retrieve<war_bar_position>(state, parent);
1794 auto war = retrieve<dcon::war_id>(state, parent);
1795
1796 auto defender_cost = std::min(military::defender_peace_cost(state, war), 100);
1797 auto x_pos = int16_t((float(-defender_cost) / 200.0f + 0.5f) * float(bar_pos.width));
1798
1799 base_data.position.x = int16_t(x_pos + bar_pos.bottom_left.x - base_data.size.x / 2);
1800 base_data.position.y = bar_pos.bottom_left.y;
1801 }
1802};
1803
1805 void on_update(sys::state& state) noexcept override {
1806 auto war = retrieve<dcon::war_id>(state, parent);
1807 if(state.world.war_get_is_great(war)) {
1808 frame = 2;
1809 } else if(state.world.war_get_is_crisis_war(war)) {
1810 frame = 1;
1811 } else {
1812 frame = 0;
1813 }
1814 }
1815};
1816
1818public:
1819 void on_update(sys::state& state) noexcept override {
1820 auto war = retrieve<dcon::war_id>(state, parent);
1821 if(war) {
1822 auto ws = military::primary_warscore(state, war) / 100.0f;
1824 }
1825 }
1826};
1827
1828class diplomacy_war_info : public listbox_row_element_base<dcon::war_id> {
1829public:
1831
1832 void on_create(sys::state& state) noexcept override {
1835 }
1836
1837 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1838 if(name == "diplo_war_entrybg") {
1839 return make_element_by_type<war_bg>(state, id);
1840 } else if(name == "war_name") {
1841 return make_element_by_type<war_name_text>(state, id);
1842 } else if(name == "attackers_mil_strength") {
1843 auto ptr = make_element_by_type<war_side_strength_text<true>>(state, id);
1844 ptr->base_data.position.y -= 4; // Nudge
1845 return ptr;
1846 } else if(name == "defenders_mil_strength") {
1847 auto ptr = make_element_by_type<war_side_strength_text<false>>(state, id);
1848 ptr->base_data.position.y -= 4; // Nudge
1849 return ptr;
1850 } else if(name == "warscore") {
1851 auto ptr = make_element_by_type<war_score_progress_bar>(state, id);
1852 bar_position.width = ptr->base_data.size.x;
1853 bar_position.bottom_left = ui::xy_pair{ptr->base_data.position.x, int16_t(ptr->base_data.position.y + ptr->base_data.size.y)};
1854 return ptr;
1855 } if(name == "diplo_warscore_marker1") {
1856 return make_element_by_type<attacker_peace_goal>(state, id);
1857 } else if(name == "diplo_warscore_marker2") {
1858 return make_element_by_type<defender_peace_goal>(state, id);
1859 } else if(name == "warscore_text") {
1860 auto ptr = make_element_by_type<war_score_text>(state, id);
1861 ptr->base_data.position.y -= 2;
1862 return ptr;
1863 } else if(name == "attackers") {
1864 auto ptr = make_element_by_type<overlapping_attacker_flags>(state, id);
1865 ptr->base_data.position.y -= 8 - 2;
1866 return ptr;
1867 } else if(name == "defenders") {
1868 auto ptr = make_element_by_type<overlapping_defender_flags>(state, id);
1869 ptr->base_data.position.y -= 8 - 2;
1870 return ptr;
1871 } else if(name == "attackers_wargoals") {
1872 return make_element_by_type<diplomacy_war_overlapping_wargoals<true>>(state, id);
1873 } else if(name == "defenders_wargoals") {
1874 return make_element_by_type<diplomacy_war_overlapping_wargoals<false>>(state, id);
1875 } else if(name == "join_attackers") {
1876 return make_element_by_type<diplomacy_join_war_button<true>>(state, id);
1877 } else if(name == "join_defenders") {
1878 return make_element_by_type<diplomacy_join_war_button<false>>(state, id);
1879 } else {
1880 return nullptr;
1881 }
1882 }
1883
1884 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
1885 if(payload.holds_type<war_bar_position>()) {
1886 payload.emplace<war_bar_position>(bar_position);
1888 }
1890 }
1891};
1892
1894public:
1895 void on_update(sys::state& state) noexcept override {
1896 const dcon::nation_id content = retrieve<dcon::nation_id>(state, parent);
1897 auto fat = dcon::fatten(state.world, content);
1898 frame = fat.get_constructing_cb_type().get_sprite_index() - 1;
1899 }
1900
1903 }
1904
1905 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1906 const dcon::nation_id content = retrieve<dcon::nation_id>(state, parent);
1907 auto fat = dcon::fatten(state.world, content);
1908 auto box = text::open_layout_box(contents);
1909 text::add_to_layout_box(state, contents, box, fat.get_constructing_cb_type().get_name(), text::text_color::yellow);
1910 text::add_to_layout_box(state, contents, box, std::string_view(": "), text::text_color::yellow);
1911 text::add_to_layout_box(state, contents, box, fat.get_constructing_cb_target());
1912
1913 if(military::cb_requires_selection_of_a_state(state, fat.get_constructing_cb_type())) {
1914 text::add_to_layout_box(state, contents, box, std::string_view(" ("), text::text_color::yellow);
1915 text::add_to_layout_box(state, contents, box, fat.get_constructing_cb_target_state().get_name());
1916 text::add_to_layout_box(state, contents, box, std::string_view(")"), text::text_color::yellow);
1917 }
1918 text::close_layout_box(contents, box);
1919 }
1920};
1921
1923public:
1924 void on_update(sys::state& state) noexcept override {
1925 const dcon::nation_id content = retrieve<dcon::nation_id>(state, parent);
1926 auto fat = dcon::fatten(state.world, content);
1927 progress = (fat.get_constructing_cb_progress() / 100.0f);
1928 }
1929
1932 }
1933
1934 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1935 auto fab_by = retrieve<dcon::nation_id>(state, parent);
1936 auto target = state.world.nation_get_constructing_cb_target(fab_by);
1938 text::add_line(state, contents, "fab_is_paused");
1939 } else {
1940 auto rem_progress = 100.0f - state.world.nation_get_constructing_cb_progress(fab_by);
1941 auto daily_progress = state.defines.cb_generation_base_speed * state.world.nation_get_constructing_cb_type(fab_by).get_construction_speed()* (state.world.nation_get_modifier_values(fab_by, sys::national_mod_offsets::cb_generation_speed_modifier) + 1.0f);
1942 auto days = int32_t(std::ceil(rem_progress / daily_progress));
1943 text::add_line(state, contents, "fab_finish_date", text::variable_type::date, state.current_date + days);
1944 }
1946 active_modifiers_description(state, contents, fab_by, 0, sys::national_mod_offsets::cb_generation_speed_modifier, true);
1947 }
1948};
1949
1951protected:
1952 void populate_flags(sys::state& state) noexcept override {
1953 const dcon::nation_id content = retrieve<dcon::nation_id>(state, parent);
1954 auto fat = dcon::fatten(state.world, content);
1955 row_contents.clear();
1956 row_contents.push_back(fat.get_identity_from_identity_holder().id);
1957 update(state);
1958 }
1959};
1960
1962protected:
1963 void populate_flags(sys::state& state) noexcept override {
1964 const dcon::nation_id content = retrieve<dcon::nation_id>(state, parent);
1965 auto fat = dcon::fatten(state.world, content);
1966 row_contents.clear();
1967 row_contents.push_back(fat.get_constructing_cb_target().get_identity_from_identity_holder().id);
1968 update(state);
1969 }
1970};
1971
1973public:
1974 void on_update(sys::state& state) noexcept override {
1975 const dcon::nation_id content = retrieve<dcon::nation_id>(state, parent);
1976 if(content != state.local_player_nation) {
1977 disabled = true;
1978 } else {
1980 }
1981 }
1982
1983 void button_action(sys::state& state) noexcept override {
1984 const dcon::nation_id content = retrieve<dcon::nation_id>(state, parent);
1986 }
1987
1988 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
1989 if(retrieve<dcon::nation_id>(state, parent) == state.local_player_nation)
1991 }
1992};
1993
1995public:
1996 void on_update(sys::state& state) noexcept override {
1997 auto just_progress = state.world.nation_get_constructing_cb_progress(retrieve<dcon::nation_id>(state, parent));
1998 set_text(state, text::format_percentage(just_progress / 100.0f, 0));
1999 }
2000};
2001
2003public:
2004 void on_create(sys::state& state) noexcept override {
2005 base_data.position.y -= int16_t(20); //nudge
2007 }
2008
2009 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2010 if(name == "diplo_cb_entrybg") {
2011 return make_element_by_type<image_element_base>(state, id);
2012 } else if(name == "cb_type_icon") {
2013 return make_element_by_type<justifying_cb_type_icon>(state, id);
2014 } else if(name == "cb_progress") {
2015 return make_element_by_type<justifying_cb_progress>(state, id);
2016 } else if(name == "cb_progress_text") {
2017 return make_element_by_type<cb_progress_text>(state, id);
2018 } else if(name == "attackers") {
2019 auto ptr = make_element_by_type<justifying_attacker_flag>(state, id);
2020 ptr->base_data.position.y -= 7; // Nudge
2021 return ptr;
2022 } else if(name == "defenders") {
2023 auto ptr = make_element_by_type<justifying_defender_flag>(state, id);
2024 ptr->base_data.position.y -= 7; // Nudge
2025 return ptr;
2026 } else if(name == "cancel") {
2027 return make_element_by_type<diplomacy_casus_belli_cancel_button>(state, id);
2028 } else {
2029 return nullptr;
2030 }
2031 }
2032};
2033
2034class diplomacy_casus_belli_listbox : public listbox_element_base<diplomacy_casus_belli_entry, dcon::nation_id> {
2035protected:
2036 std::string_view get_row_element_name() override {
2037 return "diplomacy_cb_info_player";
2038 }
2039
2040public:
2041 void on_create(sys::state& state) noexcept override {
2042 base_data.size.x += int16_t(400);
2044 }
2045 void on_update(sys::state& state) noexcept override {
2046 row_contents.clear();
2047 // Put player wargoals first
2048 for(const auto id : state.world.in_nation) {
2049 if(id == state.local_player_nation && dcon::fatten(state.world, state.local_player_nation).get_constructing_cb_type().is_valid()) {
2050 row_contents.push_back(id);
2051 }
2052 }
2053 // And after - everyone elses
2054 for(const auto id : state.world.in_nation) {
2055 if(id != state.local_player_nation && dcon::fatten(state.world, id).get_constructing_cb_is_discovered()) {
2056 row_contents.push_back(id);
2057 }
2058 }
2059 update(state);
2060 }
2061};
2062
2064public:
2065 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2066 if(name == "cb_listbox") {
2067 auto ptr = make_element_by_type<diplomacy_casus_belli_listbox>(state, id);
2068 ptr->base_data.position.x -= 400; // Nudge
2069 return ptr;
2070 } else {
2071 return nullptr;
2072 }
2073 }
2074};
2075
2076class diplomacy_war_listbox : public listbox_element_base<diplomacy_war_info, dcon::war_id> {
2077protected:
2078 std::string_view get_row_element_name() override {
2079 return "diplomacy_war_info";
2080 }
2081
2082public:
2083 void on_update(sys::state& state) noexcept override {
2084 row_contents.clear();
2085 state.world.for_each_war([&](dcon::war_id id) { row_contents.push_back(id); });
2086 std::sort(row_contents.begin(), row_contents.end(), [&](dcon::war_id a, dcon::war_id b) {
2087 auto in_a = military::get_role(state, a, state.local_player_nation) != military::war_role::none;
2088 auto in_b = military::get_role(state, b, state.local_player_nation) != military::war_role::none;
2089 if(in_a != in_b) {
2090 return in_a;
2091 } else {
2092 return state.world.war_get_start_date(a) < state.world.war_get_start_date(b);
2093 }
2094 });
2095 update(state);
2096 }
2097};
2098
2100public:
2101 uint8_t rank = 0;
2102
2103 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2104 if(name == "country_name") {
2105 return make_element_by_type<generic_name_text<dcon::nation_id>>(state, id);
2106 } else if(name == "country_flag") {
2107 return make_element_by_type<flag_button>(state, id);
2108 } else if(name == "country_puppets") {
2109 auto ptr = make_element_by_type<overlapping_sphere_flags>(state, id);
2110 ptr->base_data.position.y -= 8; // Nudge
2111 return ptr;
2112 } else if(name == "gp_prestige") {
2113 return make_element_by_type<nation_prestige_text>(state, id);
2114 } else if(name == "gp_economic") {
2115 return make_element_by_type<nation_industry_score_text>(state, id);
2116 } else if(name == "gp_military") {
2117 return make_element_by_type<nation_military_score_text>(state, id);
2118 } else if(name == "gp_total") {
2119 return make_element_by_type<nation_total_score_text>(state, id);
2120 } else {
2121 return nullptr;
2122 }
2123 }
2124
2125 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
2126 if(payload.holds_type<dcon::nation_id>()) {
2127 payload.emplace<dcon::nation_id>(nations::get_nth_great_power(state, rank));
2128 return message_result::consumed;
2129 }
2130 return window_element_base::get(state, payload);
2131 }
2132};
2133
2135public:
2136 void button_action(sys::state& state) noexcept override {
2137 send(state, parent, element_selection_wrapper<country_list_sort>{country_list_sort(uint8_t(country_list_sort::gp_influence) | rank)});
2138 }
2139};
2140
2142public:
2143 bool is_active(sys::state& state) noexcept final {
2144 return parent && static_cast<generic_tabbed_window<diplomacy_window_tab>*>(parent)->active_tab == diplomacy_window_tab::crisis;
2145 }
2146
2147 void button_action(sys::state& state) noexcept final {
2148 diplomacy_window_tab target = diplomacy_window_tab::crisis;
2149 send(state, parent, target);
2150 }
2151
2152 void on_update(sys::state& state) noexcept override {
2153 checkbox_button::on_update(state);
2154 disabled = state.current_crisis_state == sys::crisis_state::inactive;
2155 }
2156};
2157
2159public:
2160 void on_create(sys::state& state) noexcept override {
2161 simple_text_element_base::on_create(state);
2162 set_text(state, text::produce_simple_string(state, "tut_8c_3"));
2163 }
2164};
2165inline const int DiplomaticActionsRows = 10;
2166
2167inline static diplomacy_action_ally_button diplomacy_action_ally_button_s;
2168inline static diplomacy_action_call_ally_button diplomacy_action_call_ally_button_s;
2169inline static diplomacy_action_military_access_button diplomacy_action_military_access_button_s;
2170inline static diplomacy_action_give_military_access_button diplomacy_action_give_military_access_button_s;
2171inline static diplomacy_action_increase_relations_button diplomacy_action_increase_relations_button_s;
2172inline static diplomacy_action_decrease_relations_button diplomacy_action_decrease_relations_button_s;
2173inline static diplomacy_action_war_subisides_button diplomacy_action_war_subisides_button_s;
2174inline static diplomacy_action_declare_war_button diplomacy_action_declare_war_button_s;
2175inline static diplomacy_action_release_subject_button diplomacy_action_release_subject_button_s;
2176inline static diplomacy_action_discredit_button diplomacy_action_discredit_button_s;
2177inline static diplomacy_action_expel_advisors_button diplomacy_action_expel_advisors_button_s;
2178inline static diplomacy_action_ban_embassy_button diplomacy_action_ban_embassy_button_s;
2179inline static diplomacy_action_increase_opinion_button diplomacy_action_increase_opinion_button_s;
2180inline static diplomacy_action_decrease_opinion_button diplomacy_action_decrease_opinion_button_s;
2181inline static diplomacy_action_add_to_sphere_button diplomacy_action_add_to_sphere_button_s;
2182inline static diplomacy_action_remove_from_sphere_button diplomacy_action_remove_from_sphere_button_s;
2183inline static diplomacy_action_justify_war_button diplomacy_action_justify_war_button_s;
2184inline static diplomacy_action_state_transfer_button diplomacy_action_state_transfer_button_s;
2185
2186inline static diplomacy_action_btn_logic* leftcolumnlogics[DiplomaticActionsRows] = {
2187 &diplomacy_action_ally_button_s,
2188 &diplomacy_action_call_ally_button_s,
2189 &diplomacy_action_military_access_button_s,
2190 &diplomacy_action_give_military_access_button_s,
2191 &diplomacy_action_increase_relations_button_s,
2192 &diplomacy_action_decrease_relations_button_s,
2193 &diplomacy_action_war_subisides_button_s,
2194 &diplomacy_action_declare_war_button_s,
2195 &diplomacy_action_release_subject_button_s
2196};
2198 &diplomacy_action_discredit_button_s,
2199 &diplomacy_action_expel_advisors_button_s,
2200 &diplomacy_action_ban_embassy_button_s,
2201 &diplomacy_action_increase_opinion_button_s,
2202 &diplomacy_action_decrease_opinion_button_s,
2203 &diplomacy_action_add_to_sphere_button_s,
2204 &diplomacy_action_remove_from_sphere_button_s,
2205 &diplomacy_action_justify_war_button_s,
2206 &diplomacy_action_state_transfer_button_s
2207};
2208
2210 void on_update(sys::state& state) noexcept override {
2211 auto i = retrieve<int16_t>(state, parent);
2212 auto target = retrieve<dcon::nation_id>(state, parent);
2213
2214 if (leftcolumnlogics[i]) {
2215 diplomacy_action_btn_logic* curlogic = leftcolumnlogics[i];
2216 base_data.data.button.txt = curlogic->get_name(state, target);
2217 disabled = !curlogic->is_available(state, target);
2218 button_element_base::on_reset_text(state);
2219 }
2220 }
2221
2222 void button_action(sys::state& state) noexcept final {
2223 auto i = retrieve<int16_t>(state, parent);
2224 auto target = retrieve<dcon::nation_id>(state, parent);
2225
2226 if (leftcolumnlogics[i]) {
2227 diplomacy_action_btn_logic* curlogic = leftcolumnlogics[i];
2228 curlogic->button_action(state, target, parent);
2229 }
2230 }
2231
2232 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
2233 return tooltip_behavior::variable_tooltip;
2234 }
2235
2236 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
2237 auto i = retrieve<int16_t>(state, parent);
2238 auto target = retrieve<dcon::nation_id>(state, parent);
2239
2240 if(leftcolumnlogics[i]) {
2241 diplomacy_action_btn_logic* curlogic = leftcolumnlogics[i];
2242 curlogic->update_tooltip(state, x, y, contents, target);
2243 }
2244 }
2245
2246 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
2247 auto i = retrieve<int16_t>(state, parent);
2248
2249 if(leftcolumnlogics[i])
2250 button_element_base::render(state, x, y);
2251 }
2252};
2253
2254
2256 void on_update(sys::state& state) noexcept override {
2257 auto i = retrieve<int16_t>(state, parent);
2258 auto target = retrieve<dcon::nation_id>(state, parent);
2259
2260 if(rightcolumnlogics[i]) {
2262 base_data.data.button.txt = curlogic->get_name(state, target);
2263 disabled = !curlogic->is_available(state, target);
2264 button_element_base::on_reset_text(state);
2265 }
2266 }
2267
2268 void button_action(sys::state& state) noexcept final {
2269 auto i = retrieve<int16_t>(state, parent);
2270 auto target = retrieve<dcon::nation_id>(state, parent);
2271
2272 if(rightcolumnlogics[i]) {
2274 curlogic->button_action(state, target, parent);
2275 }
2276 }
2277
2278 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
2279 return tooltip_behavior::variable_tooltip;
2280 }
2281
2282 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
2283 auto i = retrieve<int16_t>(state, parent);
2284 auto target = retrieve<dcon::nation_id>(state, parent);
2285
2286 if(rightcolumnlogics[i]) {
2288 curlogic->update_tooltip(state, x, y, contents, target);
2289 }
2290 }
2291
2292 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
2293 auto i = retrieve<int16_t>(state, parent);
2294
2295 if(rightcolumnlogics[i])
2296 button_element_base::render(state, x, y);
2297 }
2298};
2299
2301public:
2302 template<typename T>
2303 std::unique_ptr<T> add_action_button(sys::state& state, xy_pair offset) noexcept {
2304 auto ptr = make_element_by_type<T>(state, state.ui_state.defs_by_name.find(state.lookup_key("diplomacy_option"))->second.definition);
2305 ptr->base_data.position = offset;
2306 return ptr;
2307 }
2308
2309 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2310
2311 auto i = retrieve<int16_t>(state, parent);
2312
2313 xy_pair options_size = state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("diplomacy_option"))->second.definition].size;
2314 xy_pair options_offset = xy_pair{};
2315
2316 if(name == "action_option_1") {
2317 return add_action_button<diplomacy_action_window<diplomacy_action_btn_left>>(state, options_offset);
2318 } else if(name == "action_option_2") {
2319 // 2nd column
2320 options_offset.x += options_size.x;
2321 return add_action_button<diplomacy_action_window<diplomacy_action_btn_right>>(state, options_offset);
2322 }
2323
2324 return nullptr;
2325 }
2326};
2327
2328class diplo_actions_listbox : public listbox_element_base<diplo_actions_row_entry, int16_t> {
2329protected:
2330 std::string_view get_row_element_name() override {
2331 return "diplomacy_actions_list_entry";
2332 }
2333public:
2334 void on_update(sys::state& state) noexcept override {
2336
2337 row_contents.clear();
2338
2339 for(int16_t i = 0; i < DiplomaticActionsRows; i ++) {
2340 row_contents.push_back(i);
2341 }
2342
2343 update(state);
2344 }
2345};
2346
2347class diplomacy_window : public generic_tabbed_window<diplomacy_window_tab> {
2348private:
2349 diplomacy_country_listbox* country_listbox = nullptr;
2350 diplomacy_war_listbox* war_listbox = nullptr;
2351 diplomacy_country_facts* country_facts = nullptr;
2352 diplomacy_action_dialog_window* action_dialog_win = nullptr;
2353 diplomacy_gp_action_dialog_window* gp_action_dialog_win = nullptr;
2354 diplomacy_declare_war_dialog* declare_war_win = nullptr;
2355 offer_war_goal_dialog* offer_goal_win = nullptr;
2356 diplomacy_setup_peace_dialog* setup_peace_win = nullptr;
2357 diplomacy_make_cb_window* make_cb_win = nullptr;
2358 crisis_resolution_dialog* crisis_backdown_win = nullptr;
2359 diplomacy_casus_belli_window* casus_belli_window = nullptr;
2360 // element_base* casus_belli_window = nullptr;
2361 diplomacy_crisis_info_window* crisis_window = nullptr;
2362 crisis_add_wargoal_window* crisis_add_wargoal_win = nullptr;
2363
2364 std::vector<diplomacy_greatpower_info*> gp_infos{};
2365
2366 dcon::nation_id facts_nation_id{};
2367
2370
2371public:
2372
2373 void on_create(sys::state& state) noexcept override {
2374 generic_tabbed_window::on_create(state);
2375 state.ui_state.diplomacy_subwindow = this;
2376
2377 xy_pair base_gp_info_offset =
2378 state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("diplomacy_greatpower_pos"))->second.definition].position;
2379 xy_pair gp_info_offset = base_gp_info_offset;
2380 for(uint8_t i = 0; i < uint8_t(state.defines.great_nations_count); i++) {
2381 auto ptr = make_element_by_type<diplomacy_greatpower_info>(state,
2382 state.ui_state.defs_by_name.find(state.lookup_key("diplomacy_greatpower_info"))->second.definition);
2383 ptr->base_data.position = gp_info_offset;
2384 ptr->rank = i;
2385 // Increment gp offset
2386 gp_info_offset.y += ptr->base_data.size.y;
2387 if(i + 1 == uint8_t(state.defines.great_nations_count) / 2) {
2388 gp_info_offset.y = base_gp_info_offset.y;
2389 gp_info_offset.x += (ptr->base_data.size.x / 2) + 62; // Nudge
2390 }
2391 gp_infos.push_back(ptr.get());
2392 add_child_to_front(std::move(ptr));
2393 }
2394
2395 // Fill out all the options for the diplomacy window
2396 xy_pair options_base_offset =
2397 state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("diplomacy_actions_pos"))->second.definition].position;
2398 xy_pair options_size = state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("diplomacy_option"))->second.definition].size;
2399
2400 auto ptr = make_element_by_type<diplo_actions_listbox>(state, state.ui_state.defs_by_name.find(state.lookup_key("diplomacy_actions_list"))->second.definition);
2401 ptr->base_data.position = options_base_offset;
2402 add_child_to_front(std::move(ptr));
2403
2404 auto new_win1 = make_element_by_type<diplomacy_action_dialog_window>(state,
2405 state.ui_state.defs_by_name.find(state.lookup_key("defaultdiplomacydialog"))->second.definition);
2406 new_win1->set_visible(state, false);
2407 action_dialog_win = new_win1.get();
2408 add_child_to_front(std::move(new_win1));
2409
2410 auto new_win2 = make_element_by_type<diplomacy_gp_action_dialog_window>(state,
2411 state.ui_state.defs_by_name.find(state.lookup_key("gpselectdiplomacydialog"))->second.definition);
2412 new_win2->set_visible(state, false);
2413 gp_action_dialog_win = new_win2.get();
2414 add_child_to_front(std::move(new_win2));
2415
2416 auto new_win3 = make_element_by_type<diplomacy_declare_war_dialog>(state,
2417 state.ui_state.defs_by_name.find(state.lookup_key("declarewardialog"))->second.definition);
2418 new_win3->set_visible(state, false);
2419 declare_war_win = new_win3.get();
2420 add_child_to_front(std::move(new_win3));
2421
2422 {
2423 auto new_winc = make_element_by_type<offer_war_goal_dialog>(state,
2424 state.ui_state.defs_by_name.find(state.lookup_key("declarewardialog"))->second.definition);
2425 new_winc->set_visible(state, false);
2426 offer_goal_win = new_winc.get();
2427 add_child_to_front(std::move(new_winc));
2428 }
2429
2430 auto new_win4 = make_element_by_type<diplomacy_setup_peace_dialog>(state,
2431 state.ui_state.defs_by_name.find(state.lookup_key("setuppeacedialog"))->second.definition);
2432 new_win4->set_visible(state, false);
2433 setup_peace_win = new_win4.get();
2434 add_child_to_front(std::move(new_win4));
2435
2436 auto new_win5 = make_element_by_type<diplomacy_make_cb_window>(state,
2437 state.ui_state.defs_by_name.find(state.lookup_key("makecbdialog"))->second.definition);
2438 new_win5->set_visible(state, false);
2439 make_cb_win = new_win5.get();
2440 add_child_to_front(std::move(new_win5));
2441
2442 auto new_win6 = make_element_by_type<crisis_resolution_dialog>(state,
2443 state.ui_state.defs_by_name.find(state.lookup_key("setuppeacedialog"))->second.definition);
2444 new_win6->set_visible(state, false);
2445 crisis_backdown_win = new_win6.get();
2446 add_child_to_front(std::move(new_win6));
2447
2448 auto new_winc7 = make_element_by_type<crisis_add_wargoal_window>(state,
2449 state.ui_state.defs_by_name.find(state.lookup_key("declarewardialog"))->second.definition);
2450 new_winc7->set_visible(state, false);
2451 crisis_add_wargoal_win = new_winc7.get();
2452 add_child_to_front(std::move(new_winc7));
2453
2454 if(state.great_nations.size() > 1) {
2455 Cyto::Any payload = element_selection_wrapper<dcon::nation_id>{ state.great_nations[0].nation };
2456 impl_get(state, payload);
2457 }
2458
2459 set_visible(state, false);
2460 }
2461
2462 void on_update(sys::state& state) noexcept override {
2463 if(active_tab == diplomacy_window_tab::crisis && state.current_crisis_state == sys::crisis_state::inactive) {
2464 send<diplomacy_window_tab>(state, this, diplomacy_window_tab::great_powers);
2465 }
2466 }
2467
2468 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2469 if(name == "main_bg") {
2470 return make_element_by_type<image_element_base>(state, id);
2471 } else if(name == "bg_diplomacy") {
2472 return make_element_by_type<opaque_element_base>(state, id);
2473 } else if(name == "close_button") {
2474 return make_element_by_type<generic_close_button>(state, id);
2475 } else if(name == "gp_info") {
2476 auto ptr = make_element_by_type<generic_tab_button<diplomacy_window_tab>>(state, id);
2477 ptr->target = diplomacy_window_tab::great_powers;
2478 return ptr;
2479 } else if(name == "gp_info_text") {
2480 return make_element_by_type<gp_tab_text>(state, id);
2481 } else if(name == "war_info") {
2482 auto ptr = make_element_by_type<generic_tab_button<diplomacy_window_tab>>(state, id);
2483 ptr->target = diplomacy_window_tab::wars;
2484 return ptr;
2485 } else if(name == "cb_info") {
2486 auto ptr = make_element_by_type<generic_tab_button<diplomacy_window_tab>>(state, id);
2487 ptr->target = diplomacy_window_tab::casus_belli;
2488 return ptr;
2489 } else if(name == "crisis_info") {
2490 return make_element_by_type<crisis_tab_button>(state, id);
2491 } else if(name == "filter_all") {
2492 return make_element_by_type<category_filter_button<country_list_filter::all>>(state, id);
2493 } else if(name == "filter_enemies") {
2494 return make_element_by_type<category_filter_button<country_list_filter::enemies>>(state, id);
2495 } else if(name == "filter_allies") {
2496 return make_element_by_type<category_filter_button<country_list_filter::allies>>(state, id);
2497 } else if(name == "filter_neighbours") {
2498 return make_element_by_type<category_filter_button<country_list_filter::neighbors>>(state, id);
2499 } else if(name == "filter_sphere") {
2500 return make_element_by_type<category_filter_button<country_list_filter::sphere>>(state, id);
2501 } else if(name == "cb_info_win") {
2502 auto ptr = make_element_by_type<diplomacy_casus_belli_window>(state, id);
2503 // auto ptr = make_element_immediate(state, id);
2504 casus_belli_window = ptr.get();
2505 ptr->set_visible(state, false);
2506 return ptr;
2507 } else if(name == "crisis_info_win") {
2508 auto ptr = make_element_by_type<diplomacy_crisis_info_window>(state, id);
2509 crisis_window = ptr.get();
2510 ptr->set_visible(state, false);
2511 return ptr;
2512 } else if(name == "country_listbox") {
2513 auto ptr = make_element_by_type<diplomacy_country_listbox>(state, id);
2514 country_listbox = ptr.get();
2515 return ptr;
2516 } else if(name == "war_listbox") {
2517 auto ptr = make_element_by_type<diplomacy_war_listbox>(state, id);
2518 war_listbox = ptr.get();
2519 war_listbox->set_visible(state, false);
2520 return ptr;
2521 } else if(name == "diplomacy_country_facts") {
2522 auto ptr = make_element_by_type<diplomacy_country_facts>(state, id);
2523 country_facts = ptr.get();
2524 return ptr;
2525 } else if(name == "sort_by_country") {
2526 auto ptr = make_element_by_type<country_sort_button<country_list_sort::country>>(state, id);
2527 return ptr;
2528 } else if(name == "sort_by_boss") {
2529 auto ptr = make_element_by_type<country_sort_button<country_list_sort::boss>>(state, id);
2530 ptr->base_data.position.y -= 1; // Nudge
2531 return ptr;
2532 } else if(name == "sort_by_prestige") {
2533 auto ptr = make_element_by_type<country_sort_button<country_list_sort::prestige_rank>>(state, id);
2534 ptr->base_data.position.y -= 1; // Nudge
2535 return ptr;
2536 } else if(name == "sort_by_economic") {
2537 auto ptr = make_element_by_type<country_sort_button<country_list_sort::economic_rank>>(state, id);
2538 ptr->base_data.position.y -= 1; // Nudge
2539 return ptr;
2540 } else if(name == "sort_by_military") {
2541 auto ptr = make_element_by_type<country_sort_button<country_list_sort::military_rank>>(state, id);
2542 ptr->base_data.position.y -= 1; // Nudge
2543 return ptr;
2544 } else if(name == "sort_by_total") {
2545 auto ptr = make_element_by_type<country_sort_button<country_list_sort::total_rank>>(state, id);
2546 ptr->base_data.position.y -= 1; // Nudge
2547 return ptr;
2548 } else if(name == "sort_by_relation") {
2549 auto ptr = make_element_by_type<country_sort_button<country_list_sort::relation>>(state, id);
2550 ptr->base_data.position.y -= 1; // Nudge
2551 return ptr;
2552 } else if(name == "sort_by_opinion") {
2553 return make_element_by_type<country_sort_button<country_list_sort::opinion>>(state, id);
2554 } else if(name == "sort_by_prio") {
2555 return make_element_by_type<country_sort_button<country_list_sort::priority>>(state, id);
2556 } else if(name.substr(0, 14) == "sort_by_gpflag") {
2557 auto ptr = make_element_by_type<diplomacy_sort_nation_gp_flag>(state, id);
2558 ptr->rank = uint16_t(std::stoi(std::string{name.substr(14)}));
2559 ptr->base_data.position.y -= 2; // Nudge
2560 return ptr;
2561 } else if(name.substr(0, 10) == "sort_by_gp") {
2562 auto ptr = make_element_by_type<country_sort_button<country_list_sort::gp_influence>>(state, id);
2563 ptr->offset = uint8_t(std::stoi(std::string{name.substr(10)}));
2564 ptr->base_data.position.y -= 2; // Nudge
2565 return ptr;
2566 } else if(name.length() >= 7 && name.substr(0, 7) == "filter_") {
2567 auto const filter_name = name.substr(7);
2568 auto ptr = make_element_by_type<continent_filter_button>(state, id);
2569 auto k = state.lookup_key(filter_name);
2570 if(k) {
2571 for(auto m : state.world.in_modifier) {
2572 if(m.get_name() == k) {
2573 ptr->continent = m;
2574 break;
2575 }
2576 }
2577 }
2578 return ptr;
2579 } else {
2580 return nullptr;
2581 }
2582 }
2583
2585 war_listbox->set_visible(state, false);
2586 casus_belli_window->set_visible(state, false);
2587 crisis_window->set_visible(state, false);
2588 for(auto e : gp_infos)
2589 e->set_visible(state, false);
2590 }
2591
2592 void on_hide(sys::state& state) noexcept override {
2593 offer_goal_win->set_visible(state, false);
2594 action_dialog_win->set_visible(state, false);
2595 declare_war_win->set_visible(state, false);
2596 setup_peace_win->set_visible(state, false);
2597 make_cb_win->set_visible(state, false);
2598 crisis_backdown_win->set_visible(state, false);
2599 gp_action_dialog_win->set_visible(state, false);
2600 }
2601
2602 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
2603 if(payload.holds_type<diplomacy_window_tab>()) {
2604 auto enum_val = any_cast<diplomacy_window_tab>(payload);
2605 hide_tabs(state);
2606 switch(enum_val) {
2607 case diplomacy_window_tab::great_powers:
2608 for(auto e : gp_infos)
2609 e->set_visible(state, true);
2610 break;
2611 case diplomacy_window_tab::wars:
2612 war_listbox->set_visible(state, true);
2613 break;
2614 case diplomacy_window_tab::casus_belli:
2615 casus_belli_window->set_visible(state, true);
2616 break;
2617 case diplomacy_window_tab::crisis:
2618 crisis_window->set_visible(state, true);
2619 break;
2620 default:
2621 break;
2622 }
2623 active_tab = enum_val;
2624 country_facts->impl_on_update(state);
2625 return message_result::consumed;
2626 } else if(payload.holds_type<dip_tab_request>()) {
2627 payload.emplace<dip_tab_request>(dip_tab_request{ active_tab });
2628 return message_result::consumed;
2629 } else if(payload.holds_type<country_sort_setting>()) {
2630 payload.emplace<country_sort_setting>(sort);
2631 return message_result::consumed;
2632 } else if(payload.holds_type< country_filter_setting>()) {
2633 payload.emplace<country_filter_setting>(filter);
2634 return message_result::consumed;
2635 } else if(payload.holds_type<element_selection_wrapper<country_list_sort>>()) {
2636 auto new_sort = any_cast<element_selection_wrapper<country_list_sort>>(payload).data;
2637 sort.sort_ascend = (new_sort == sort.sort) ? !sort.sort_ascend : true;
2638 sort.sort = new_sort;
2639 country_listbox->impl_on_update(state);
2640 return message_result::consumed;
2641 } else if(payload.holds_type<country_list_filter>()) {
2642 auto temp = any_cast<country_list_filter>(payload);
2643 filter.general_category = filter.general_category != temp ? temp : country_list_filter::all;
2644 country_listbox->impl_on_update(state);
2645 return message_result::consumed;
2646 } else if(payload.holds_type<dcon::modifier_id>()) {
2647 auto temp_c = any_cast<dcon::modifier_id>(payload);
2648 filter.continent = filter.continent == temp_c ? dcon::modifier_id{} : temp_c;
2649 country_listbox->impl_on_update(state);
2650 return message_result::consumed;
2651 } else if(payload.holds_type<dcon::nation_id>()) {
2652 payload.emplace<dcon::nation_id>(facts_nation_id);
2653 return message_result::consumed;
2654 } else if(payload.holds_type<element_selection_wrapper<dcon::nation_id>>()) {
2655 facts_nation_id = any_cast<element_selection_wrapper<dcon::nation_id>>(payload).data;
2656 send(state, country_listbox, dip_make_nation_visible{ facts_nation_id });
2657 impl_on_update(state);
2658 return message_result::consumed;
2659 } else if(payload.holds_type<open_offer_window>()) {
2660 auto offer_to = any_cast<open_offer_window>(payload).to;
2661
2662 offer_goal_win->set_visible(state, false);
2663 offer_goal_win->reset_window(state, offer_to);
2664 offer_goal_win->set_visible(state, true);
2665
2666 } else if(payload.holds_type<trigger_gp_choice>()) {
2667 auto action = any_cast<trigger_gp_choice>(payload).action;
2668
2669 action_dialog_win->set_visible(state, false);
2670 declare_war_win->set_visible(state, false);
2671 setup_peace_win->set_visible(state, false);
2672 make_cb_win->set_visible(state, false);
2673 crisis_backdown_win->set_visible(state, false);
2674
2675 gp_action_dialog_win->set_visible(state, false);
2676 gp_action_dialog_win->action_target = facts_nation_id;
2677 gp_action_dialog_win->current_action = action;
2678 gp_action_dialog_win->set_visible(state, true); // this will also force an update
2679
2680 } else if(payload.holds_type<diplomacy_action>()) {
2681 auto v = any_cast<diplomacy_action>(payload);
2682 gp_action_dialog_win->set_visible(state, false);
2683 action_dialog_win->set_visible(state, false);
2684 declare_war_win->set_visible(state, false);
2685 setup_peace_win->set_visible(state, false);
2686 make_cb_win->set_visible(state, false);
2687 crisis_backdown_win->set_visible(state, false);
2688 Cyto::Any new_payload = facts_nation_id;
2689 auto fat = dcon::fatten(state.world, facts_nation_id);
2690 switch(v) {
2691 case diplomacy_action::add_to_sphere:
2692 command::add_to_sphere(state, state.local_player_nation, facts_nation_id);
2693 break;
2694 case diplomacy_action::military_access:
2695 command::ask_for_military_access(state, state.local_player_nation, facts_nation_id);
2696 break;
2697 case diplomacy_action::cancel_military_access:
2698 command::cancel_military_access(state, state.local_player_nation, facts_nation_id);
2699 break;
2700 case diplomacy_action::give_military_access:
2701 command::give_military_access(state, state.local_player_nation, facts_nation_id);
2702 break;
2703 case diplomacy_action::cancel_give_military_access:
2704 command::cancel_given_military_access(state, state.local_player_nation, facts_nation_id);
2705 break;
2706 case diplomacy_action::increase_relations:
2707 command::increase_relations(state, state.local_player_nation, facts_nation_id);
2708 break;
2709 case diplomacy_action::decrease_relations:
2710 command::decrease_relations(state, state.local_player_nation, facts_nation_id);
2711 break;
2712 case diplomacy_action::war_subsidies:
2713 command::give_war_subsidies(state, state.local_player_nation, facts_nation_id);
2714 break;
2715 case diplomacy_action::cancel_war_subsidies:
2716 command::cancel_war_subsidies(state, state.local_player_nation, facts_nation_id);
2717 break;
2718 case diplomacy_action::ally:
2719 command::ask_for_alliance(state, state.local_player_nation, facts_nation_id);
2720 break;
2721 case diplomacy_action::cancel_ally:
2722 command::cancel_alliance(state, state.local_player_nation, facts_nation_id);
2723 break;
2724 case diplomacy_action::call_ally:
2725 for(auto war_par : fat.get_war_participant()) {
2726 command::call_to_arms(state, state.local_player_nation, facts_nation_id,
2727 dcon::fatten(state.world, war_par).get_war().id);
2728 }
2729 break;
2730 case diplomacy_action::remove_from_sphere:
2731 gp_action_dialog_win->set_visible(state, true);
2732 gp_action_dialog_win->impl_set(state, new_payload);
2733 gp_action_dialog_win->impl_set(state, payload);
2734 gp_action_dialog_win->impl_on_update(state);
2735 break;
2736 case diplomacy_action::declare_war:
2737 case diplomacy_action::add_wargoal:
2738 declare_war_win->set_visible(state, false);
2739 declare_war_win->reset_window(state);
2740 declare_war_win->set_visible(state, true);
2741
2742 break;
2743 case diplomacy_action::make_peace:
2744 setup_peace_win->open_window(state);
2745 setup_peace_win->set_visible(state, true);
2746 setup_peace_win->impl_set(state, new_payload);
2747 setup_peace_win->impl_set(state, payload);
2748 setup_peace_win->impl_on_update(state);
2749 break;
2750 case diplomacy_action::justify_war:
2751 make_cb_win->reset_window(state);
2752 make_cb_win->impl_set(state, new_payload);
2753 make_cb_win->impl_set(state, payload);
2754 make_cb_win->set_visible(state, true);
2755 break;
2756 case diplomacy_action::crisis_backdown:
2757 crisis_backdown_win->open_window(state);
2758 crisis_backdown_win->set_visible(state, true);
2759 crisis_backdown_win->impl_on_update(state);
2760 break;
2761 case diplomacy_action::crisis_support:
2762 break;
2763 case diplomacy_action::crisis_add_wargoal:
2764 crisis_add_wargoal_win->set_visible(state, false);
2765 crisis_add_wargoal_win->reset_window(state);
2766 crisis_add_wargoal_win->set_visible(state, true);
2767 break;
2768 default:
2769 action_dialog_win->set_visible(state, true);
2770 action_dialog_win->impl_set(state, new_payload);
2771 action_dialog_win->impl_set(state, payload);
2772 action_dialog_win->impl_on_update(state);
2773 break;
2774 }
2775 return message_result::consumed;
2776 }
2778 }
2779};
2780
2781} // namespace ui
dcon::text_key get_name() noexcept
void on_update(sys::state &state) noexcept override
void set_button_text(sys::state &state, std::string const &new_text)
void render(sys::state &state, int32_t x, int32_t y) noexcept override
void on_create(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void 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
message_result impl_set(sys::state &state, Cyto::Any &payload) noexcept final
void add_child_to_front(std::unique_ptr< element_base > child) noexcept final
void impl_on_update(sys::state &state) noexcept override
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
void reset_window(sys::state &state)
void open_window(sys::state &state)
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
void on_update(sys::state &state) noexcept override
void button_action(sys::state &state) noexcept final
bool is_active(sys::state &state) noexcept final
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::unique_ptr< T > add_action_button(sys::state &state, xy_pair offset) noexcept
void button_action(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
virtual dcon::text_key get_name(sys::state &state, dcon::nation_id target)
virtual void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents, dcon::nation_id target)
virtual bool is_available(sys::state &state, dcon::nation_id target)
virtual void button_action(sys::state &state, dcon::nation_id target, ui::element_base *parent)
void on_update(sys::state &state) noexcept override
void render(sys::state &state, int32_t x, int32_t y) noexcept override
void button_action(sys::state &state) noexcept override
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_create(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::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_create(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
bool is_active(sys::state &state) noexcept override
void button_action(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
std::string_view get_row_element_name() override
void on_update(sys::state &state) noexcept override
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
void button_action(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
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
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
void button_action(sys::state &state) noexcept override
void on_create(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void button_action(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void populate_layout(sys::state &state, text::endless_layout &contents) 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
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
void select_state(sys::state &state)
void reset_window(sys::state &state)
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 update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void button_action(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void button_right_action(sys::state &state) noexcept override
void open_window(sys::state &state)
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
void button_action(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
std::string get_text(sys::state &state, dcon::nation_id nation_id) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void on_create(sys::state &state) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
std::string_view get_row_element_name() override
void on_update(sys::state &state) noexcept override
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_hide(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 hide_tabs(sys::state &state)
element_base * parent
virtual message_result get(sys::state &state, Cyto::Any &payload) noexcept
virtual void on_create(sys::state &state) noexcept
element_data base_data
void set_visible(sys::state &state, bool vis)
void 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 on_update(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void render(sys::state &state, int32_t x, int32_t y) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void render(sys::state &state, int32_t x, int32_t y) noexcept override
void on_update(sys::state &state) noexcept override
void on_create(sys::state &state) noexcept override
virtual dcon::national_identity_id get_current_nation(sys::state &state) noexcept override
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
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 populate_flags(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 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 populate_flags(sys::state &state) noexcept override
standard_listbox_scrollbar< diplomacy_country_info, dcon::nation_id > * list_scrollbar
void on_create(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
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 reset_window(sys::state &state, dcon::nation_id offer_to)
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
void on_update(sys::state &state) noexcept override
std::string_view get_row_element_name() override
void populate_flags(sys::state &state) override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
void populate_flags(sys::state &state) 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
int32_t raw_value() const
void update_raw_value(sys::state &state, int32_t v)
void set_text(sys::state &state, std::string const &new_text)
void on_update(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void on_update(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void on_create(sys::state &state) noexcept override
#define B(name, bit)
Definition: cpu.h:216
bool can_intervene_in_war(sys::state &state, dcon::nation_id source, dcon::war_id w, bool for_attacker)
Definition: commands.cpp:1697
void give_war_subsidies(sys::state &state, dcon::nation_id source, dcon::nation_id target)
Definition: commands.cpp:251
bool can_fabricate_cb(sys::state &state, dcon::nation_id source, dcon::nation_id target, dcon::cb_type_id type, dcon::state_definition_id target_state)
Definition: commands.cpp:2224
bool can_cancel_cb_fabrication(sys::state &state, dcon::nation_id source)
Definition: commands.cpp:2282
bool can_toggle_interested_in_alliance(sys::state &state, dcon::nation_id asker, dcon::nation_id target)
Definition: commands.cpp:2439
bool can_change_influence_priority(sys::state &state, dcon::nation_id source, dcon::nation_id influence_target, uint8_t priority)
Definition: commands.cpp:1049
pop_satisfaction_wrapper_fat fatten(data_container const &c, pop_satisfaction_wrapper_id id) noexcept
constexpr dcon::demographics_key total(0)
dcon::demographics_key to_key(sys::state const &state, dcon::pop_type_id v)
constexpr uint32_t is_not_constructing_cb
Definition: military.hpp:12
constexpr uint32_t always
Definition: military.hpp:10
bool cb_conditions_satisfied(sys::state &state, dcon::nation_id actor, dcon::nation_id target, dcon::cb_type_id cb)
Definition: military.cpp:404
float primary_warscore(sys::state &state, dcon::war_id w)
Definition: military.cpp:3997
int32_t total_regiments(sys::state &state, dcon::nation_id n)
Definition: military.cpp:25
int32_t defender_peace_cost(sys::state &state, dcon::war_id war)
Definition: military.cpp:1952
bool has_truce_with(sys::state &state, dcon::nation_id attacker, dcon::nation_id target)
Definition: military.cpp:2296
int32_t attacker_peace_cost(sys::state &state, dcon::war_id war)
Definition: military.cpp:1941
bool is_attacker(sys::state &state, dcon::war_id w, dcon::nation_id n)
Definition: military.cpp:2493
float truce_break_cb_infamy(sys::state &state, dcon::cb_type_id t, dcon::nation_id target, dcon::state_definition_id cb_state)
Definition: military.cpp:1709
bool joining_as_attacker_would_break_truce(sys::state &state, dcon::nation_id a, dcon::war_id w)
Definition: military.cpp:783
float primary_warscore_from_blockades(sys::state &state, dcon::war_id w)
Definition: military.cpp:3958
dcon::war_id find_war_between(sys::state const &state, dcon::nation_id a, dcon::nation_id b)
Definition: military.cpp:718
float primary_warscore_from_battles(sys::state &state, dcon::war_id w)
Definition: military.cpp:4036
float cb_infamy(sys::state &state, dcon::cb_type_id t, dcon::nation_id target, dcon::state_definition_id cb_state)
Definition: military.cpp:1519
float primary_warscore_from_occupation(sys::state &state, dcon::war_id w)
Definition: military.cpp:4005
bool are_at_war(sys::state const &state, dcon::nation_id a, dcon::nation_id b)
Definition: military.cpp:649
bool defenders_have_non_status_quo_wargoal(sys::state const &state, dcon::war_id w)
Definition: military.cpp:760
float primary_warscore_from_war_goals(sys::state &state, dcon::war_id w)
Definition: military.cpp:4040
int32_t total_ships(sys::state &state, dcon::nation_id n)
Definition: military.cpp:28
bool joining_war_does_not_violate_constraints(sys::state const &state, dcon::nation_id a, dcon::war_id w, bool as_attacker)
Definition: military.cpp:722
std::string get_war_name(sys::state &, dcon::war_id)
Definition: military.cpp:2575
bool can_add_always_cb_to_war(sys::state &state, dcon::nation_id actor, dcon::nation_id target, dcon::cb_type_id cb, dcon::war_id w)
Definition: military.cpp:260
bool defenders_have_status_quo_wargoal(sys::state const &state, dcon::war_id w)
Definition: military.cpp:768
bool war_goal_would_be_duplicate(sys::state &state, dcon::nation_id source, dcon::war_id w, dcon::nation_id target, dcon::cb_type_id cb_type, dcon::state_definition_id cb_state, dcon::national_identity_id cb_tag, dcon::nation_id cb_secondary_nation)
Definition: military.cpp:7693
bool cb_requires_selection_of_a_state(sys::state const &state, dcon::cb_type_id t)
Definition: military.cpp:2065
constexpr uint8_t is_banned
Definition: nations.hpp:183
constexpr uint8_t level_friendly
Definition: nations.hpp:172
constexpr uint8_t is_discredited
Definition: nations.hpp:182
constexpr uint8_t priority_zero
Definition: nations.hpp:176
constexpr uint8_t priority_three
Definition: nations.hpp:179
constexpr uint8_t priority_mask
Definition: nations.hpp:175
constexpr uint8_t priority_one
Definition: nations.hpp:177
constexpr uint8_t level_mask
Definition: nations.hpp:167
constexpr uint8_t priority_two
Definition: nations.hpp:178
bool is_great_power(sys::state const &state, dcon::nation_id id)
Definition: nations.cpp:1068
bool is_involved_in_crisis(sys::state const &state, dcon::nation_id n)
Definition: nations.cpp:1632
float get_foreign_investment(sys::state &state, dcon::nation_id n)
Definition: nations.cpp:884
float get_base_shares(sys::state &state, dcon::gp_relationship_id gp, float total_gain, int32_t total_influence_shares)
Definition: nations.cpp:2083
bool has_sphere_neighbour(sys::state &state, dcon::nation_id n, dcon::nation_id target)
Definition: nations.cpp:2099
dcon::nation_id get_nth_great_power(sys::state const &state, uint16_t n)
Definition: nations.cpp:75
float prestige_score(sys::state const &state, dcon::nation_id n)
Definition: nations.cpp:961
bool can_accumulate_influence_with(sys::state &state, dcon::nation_id gp, dcon::nation_id target, dcon::gp_relationship_id rel)
Definition: nations.cpp:2070
uint32_t pack_color(float r, float g, float b)
void add_to_layout_box(sys::state &state, layout_base &dest, layout_box &box, embedded_flag ico)
Definition: text.cpp:1165
std::string format_money(float num)
Definition: text.cpp:1029
std::string get_name_as_string(sys::state &state, T t)
Definition: text.hpp:957
layout_box open_layout_box(layout_base &dest, int32_t indent)
Definition: text.cpp:1823
void localised_format_box(sys::state &state, layout_base &dest, layout_box &box, std::string_view key, text::substitution_map const &sub)
Definition: text.cpp:1904
std::string format_float(float num, size_t digits)
Definition: text.cpp:981
void add_line(sys::state &state, layout_base &dest, dcon::text_key txt, int32_t indent)
Definition: text.cpp:1923
void add_line_with_condition(sys::state &state, layout_base &dest, std::string_view key, bool condition_met, int32_t indent)
Definition: text.cpp:1979
void add_line_break_to_layout(sys::state &state, columnar_layout &dest)
Definition: text.cpp:1152
void add_to_substitution_map(substitution_map &mp, variable_type key, substitution value)
Definition: text.cpp:1068
void add_divider_to_layout_box(sys::state &state, layout_base &dest, layout_box &box)
Definition: text.cpp:2122
ankerl::unordered_dense::map< uint32_t, substitution > substitution_map
Definition: text.hpp:797
std::string produce_simple_string(sys::state const &state, dcon::text_key id)
Definition: text.cpp:617
dcon::text_key get_name(sys::state &state, dcon::nation_id id)
Definition: text.cpp:880
std::string format_percentage(float num, size_t digits)
Definition: text.cpp:977
std::string get_influence_level_name(sys::state const &state, uint8_t v)
Definition: text.cpp:958
void add_space_to_layout_box(sys::state &state, layout_base &dest, layout_box &box)
Definition: text.cpp:1812
void close_layout_box(columnar_layout &dest, layout_box &box)
Definition: text.cpp:1831
int32_t to_generic(dcon::province_id v)
Definition: triggers.hpp:12
bool evaluate(sys::state &state, dcon::trigger_key key, int32_t primary, int32_t this_slot, int32_t from_slot)
Definition: triggers.cpp:5895
void sort_countries(sys::state &state, std::vector< dcon::nation_id > &list, country_list_sort sort, bool sort_ascend)
tooltip_behavior
void send(sys::state &state, element_base *parent, T value)
diplomacy_action_btn_logic * rightcolumnlogics[DiplomaticActionsRows]
void trigger_description(sys::state &state, text::layout_base &layout, dcon::trigger_key k, int32_t primary_slot=-1, int32_t this_slot=-1, int32_t from_slot=-1)
message_result
std::string get_status_text(sys::state &state, dcon::nation_id nation_id)
void explain_influence(sys::state &state, dcon::nation_id target, text::columnar_layout &contents)
const int DiplomaticActionsRows
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
std::vector< dcon::state_definition_id > selectable_states
std::function< void(sys::state &, dcon::state_definition_id)> on_select
std::function< void(sys::state &)> on_cancel
Holds important data about the game world, state, and other data regarding windowing,...
ui::diplomacy_window_tab tab
ankerl::unordered_dense::map< dcon::text_key, element_target, hash_text_key > defs_by_name
element_base * diplomacy_subwindow