Project Alice
Loading...
Searching...
No Matches
gui_peace_window.hpp
Go to the documentation of this file.
1#pragma once
2
4
5namespace ui {
6
8public:
9 void populate_layout(sys::state& state, text::endless_layout& contents) noexcept override {
10 auto target = retrieve<dcon::nation_id>(state, parent);
11 auto war = military::find_war_between(state, target, state.local_player_nation);
12
13 auto const we_lead = (state.local_player_nation == state.world.war_get_primary_attacker(war) || state.local_player_nation == state.world.war_get_primary_defender(war));
14 auto const they_lead = (target == state.world.war_get_primary_attacker(war) || target == state.world.war_get_primary_defender(war));
15
16 auto box = text::open_layout_box(contents);
17 text::localised_format_box(state, contents, box, we_lead ? std::string_view("po_welead") : std::string_view("po_wenotlead"));
18 text::localised_format_box(state, contents, box, they_lead ? std::string_view("po_theylead") : std::string_view("po_theynotlead"));
19 text::close_layout_box(contents, box);
20 }
21};
22
23template<bool is_concession>
25public:
26 void button_action(sys::state& state) noexcept override {
28 }
29 void on_update(sys::state& state) noexcept override {
30 frame = (retrieve<bool>(state, parent) == is_concession) ? 1 : 0;
31 }
32};
33
35public:
36 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
37 if(name == "war_desc") {
38 return make_element_by_type<diplomacy_peace_pick_side_description>(state, id);
39 } else if(name == "offer_button") {
40 return make_element_by_type<diplomacy_peace_tab_button<true>>(state, id);
41 } else if(name == "offer_text") {
42 return make_element_by_type<simple_text_element_base>(state, id);
43 } else if(name == "demand_button") {
44 return make_element_by_type<diplomacy_peace_tab_button<false>>(state, id);
45 } else if(name == "demand_text") {
46 return make_element_by_type<simple_text_element_base>(state, id);
47 } else {
48 return nullptr;
49 }
50 }
51};
52
54 dcon::wargoal_id wg;
55 bool added = false;
56};
57
59 dcon::wargoal_id wg;
60};
61
63 bool result = false;
64};
65
66class peace_wg_from : public flag_button {
67 dcon::national_identity_id get_current_nation(sys::state& state) noexcept override {
68 auto wg = retrieve<dcon::wargoal_id>(state, parent);
69 return state.world.nation_get_identity_from_identity_holder(state.world.wargoal_get_target_nation(wg));
70 }
71};
72
73class peace_wg_to : public flag_button {
74 dcon::national_identity_id get_current_nation(sys::state& state) noexcept override {
75 auto wg = retrieve<dcon::wargoal_id>(state, parent);
76 return state.world.nation_get_identity_from_identity_holder(state.world.wargoal_get_added_by(wg));
77 }
78};
79
81public:
82 void on_update(sys::state& state) noexcept override {
83 dcon::wargoal_id wg = retrieve<dcon::wargoal_id>(state, parent);
84 dcon::cb_type_id cbt = state.world.wargoal_get_type(wg);
85
87 text::add_to_substitution_map(sub, text::variable_type::recipient, state.world.wargoal_get_target_nation(wg));
88 text::add_to_substitution_map(sub, text::variable_type::from, state.world.wargoal_get_added_by(wg));
89 if(state.world.wargoal_get_secondary_nation(wg))
90 text::add_to_substitution_map(sub, text::variable_type::third, state.world.wargoal_get_secondary_nation(wg));
91 else if(state.world.wargoal_get_associated_tag(wg))
92 text::add_to_substitution_map(sub, text::variable_type::third, state.world.wargoal_get_associated_tag(wg));
93 text::add_to_substitution_map(sub, text::variable_type::state, state.world.wargoal_get_associated_state(wg));
94
95 set_text(state, text::resolve_string_substitution(state, state.world.cb_type_get_shortest_desc(cbt), sub));
96 }
97};
98
100public:
101 void on_update(sys::state& state) noexcept override {
102 auto wg = fatten(state.world, retrieve<dcon::wargoal_id>(state, parent));
103 assert(wg.is_valid());
104 int32_t score = military::peace_cost(state, retrieve<dcon::war_id>(state, parent), wg.get_type(), wg.get_added_by(), wg.get_target_nation(), wg.get_secondary_nation(), wg.get_associated_state(), wg.get_associated_tag());
105 set_text(state, std::to_string(score));
106 }
107};
108
110public:
111 void on_update(sys::state& state) noexcept override {
112 auto wg = retrieve<dcon::wargoal_id>(state, parent);
113 Cyto::Any setting = toggled_wargoal{ wg, false };
114 if(parent)
115 parent->impl_get(state, setting);
116
117 frame = any_cast<toggled_wargoal>(setting).added ? 1 : 0;
118 }
119
120 void button_action(sys::state& state) noexcept override {
121 auto wg = retrieve<dcon::wargoal_id>(state, parent);
123 }
124};
125
126class diplomacy_peace_goal_row : public listbox_row_element_base<dcon::wargoal_id> {
127public:
128 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
129 if(name == "select") {
130 return make_element_by_type<diplomacy_peace_select_button>(state, id);
131 } else if(name == "country_flag") {
132 return make_element_by_type<peace_wg_from>(state, id);
133 } else if(name == "country_flag2") {
134 return make_element_by_type<peace_wg_to>(state, id);
135 } else if(name == "cb_direction_arrow") {
136 return make_element_by_type<image_element_base>(state, id);
137 } else if(name == "select_label") {
138 return make_element_by_type<diplomacy_peace_wargoal_text>(state, id);
139 } else if(name == "score") {
140 return make_element_by_type<diplomacy_peace_wargoal_score_text>(state, id);
141 } else {
142 return nullptr;
143 }
144 }
145};
146
147class diplomacy_peace_goal_listbox : public listbox_element_base<diplomacy_peace_goal_row, dcon::wargoal_id> {
148protected:
149 std::string_view get_row_element_name() override {
150 return "peace_goal_item";
151 }
152
153public:
154 void on_update(sys::state& state) noexcept override {
155 row_contents.clear();
156 auto is_concession = retrieve<bool>(state, parent);
157
158 auto target = retrieve<dcon::nation_id>(state, parent);
159 auto war = military::find_war_between(state, target, state.local_player_nation);
160
161 auto we_lead = (state.local_player_nation == state.world.war_get_primary_attacker(war) || state.local_player_nation == state.world.war_get_primary_defender(war));
162 auto they_lead = (target == state.world.war_get_primary_attacker(war) || target == state.world.war_get_primary_defender(war));
163
164 bool player_is_attacker = military::is_attacker(state, war, state.local_player_nation);
165 if(they_lead && we_lead && is_concession) {
166 for(auto wg : state.world.war_get_wargoals_attached(war)) {
167 if(military::get_role(state, war, wg.get_wargoal().get_target_nation()) == (player_is_attacker ? military::war_role::attacker : military::war_role::defender)) {
168 row_contents.push_back(wg.get_wargoal().id);
169 }
170 }
171 } else if(they_lead && we_lead && !is_concession) {
172 for(auto wg : state.world.war_get_wargoals_attached(war)) {
173 if(military::get_role(state, war, wg.get_wargoal().get_target_nation()) == (player_is_attacker ? military::war_role::defender : military::war_role::attacker)) {
174 row_contents.push_back(wg.get_wargoal().id);
175 }
176 }
177 } else if(!they_lead && !is_concession) {
178 for(auto wg : state.world.war_get_wargoals_attached(war)) {
179 if(wg.get_wargoal().get_target_nation() == target || wg.get_wargoal().get_target_nation().get_overlord_as_subject().get_ruler() == target) {
180 row_contents.push_back(wg.get_wargoal().id);
181 }
182 }
183 } else if(!we_lead && is_concession) {
184 for(auto wg : state.world.war_get_wargoals_attached(war)) {
185 if(wg.get_wargoal().get_target_nation() == state.local_player_nation || wg.get_wargoal().get_target_nation().get_overlord_as_subject().get_ruler() == state.local_player_nation) {
186 row_contents.push_back(wg.get_wargoal().id);
187 }
188 }
189 } else if(we_lead && is_concession) {
190 for(auto wg : state.world.war_get_wargoals_attached(war)) {
191 if(wg.get_wargoal().get_added_by() == target || wg.get_wargoal().get_added_by().get_overlord_as_subject().get_ruler() == target) {
192 row_contents.push_back(wg.get_wargoal().id);
193 }
194 }
195 } else if(they_lead && !is_concession) {
196 for(auto wg : state.world.war_get_wargoals_attached(war)) {
197 if(wg.get_wargoal().get_added_by() == state.local_player_nation || wg.get_wargoal().get_added_by().get_overlord_as_subject().get_ruler() == state.local_player_nation) {
198 row_contents.push_back(wg.get_wargoal().id);
199 }
200 }
201 } else {
202 std::abort(); // should be impossible: neither is war leader
203 }
204
205 update(state);
206 }
207};
208
210 int32_t val = 0;
211};
212
214public:
215 void on_update(sys::state& state) noexcept override {
217 text::add_to_substitution_map(m, text::variable_type::val, int64_t(retrieve<offer_cost>(state, parent).val));
218 set_text(state, text::resolve_string_substitution(state, "calculated_warscore", m));
219 }
220};
221
223public:
224 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
225 if(name == "wargoal_list") {
226 return make_element_by_type<diplomacy_peace_goal_listbox>(state, id);
227 } else if(name == "score") {
228 return make_element_by_type<total_peace_cost>(state, id);
229 } else if(name == "acceptance") {
230 return make_element_by_type<simple_text_element_base>(state, id);
231 } else {
232 return nullptr;
233 }
234 }
235};
236
238public:
239 void on_update(sys::state& state) noexcept override {
240 const dcon::war_id w = retrieve<dcon::war_id>(state, parent);
241 const dcon::nation_id target = retrieve<dcon::nation_id>(state, parent);
242 if( (state.world.war_get_primary_attacker(w) == target && state.world.war_get_primary_defender(w) == state.local_player_nation)
243 || (state.world.war_get_primary_defender(w) == target && state.world.war_get_primary_attacker(w) == state.local_player_nation)) {
244
245 const int32_t score = int32_t(military::primary_warscore(state, w));
246 if(state.world.war_get_primary_attacker(w) == state.local_player_nation)
247 set_text(state, std::to_string(score));
248 else
249 set_text(state, std::to_string(-score));
250 } else {
251 const int32_t score = int32_t(military::directed_warscore(state, w, state.local_player_nation, target));
252 set_text(state, std::to_string(score));
253 }
254 }
255};
256
257struct send_offer { };
258
260public:
261 void button_action(sys::state& state) noexcept override {
263 }
266 }
267 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
268 auto target = retrieve<dcon::nation_id>(state, parent);
269
270 auto war = military::find_war_between(state, target, state.local_player_nation);
271 auto const we_lead = (state.local_player_nation == state.world.war_get_primary_attacker(war) || state.local_player_nation == state.world.war_get_primary_defender(war));
272 if(we_lead) {
273 text::add_line(state, contents, "alice_warn_war_ends_for_us");
274 }
275
276 if(state.world.nation_get_is_player_controlled(target)) {
277 // no tooltip -- no expected acceptance from players
278 return;
279 }
280 auto res = retrieve<test_acceptance>(state, parent);
281 if(res.result) {
282 text::add_line(state, contents, "ai_will_accept_po");
283 } else {
284 text::add_line(state, contents, "ai_will_not_accept_po");
285 }
286 }
287};
288
289class diplomacy_setup_peace_dialog : public window_element_base { // eu3dialogtype
290 bool is_concession = false;
291 std::vector<toggled_wargoal> wargoals;
292
293public:
295 wargoals.clear();
296
297 auto target = retrieve<dcon::nation_id>(state, parent);
298 auto war = military::find_war_between(state, state.local_player_nation, target);
299 is_concession = false;
300
301 if(state.world.war_get_primary_attacker(war) == state.local_player_nation && state.world.war_get_primary_defender(war) == target) {
302 for(auto wg : state.world.war_get_wargoals_attached(war)) {
303 wargoals.push_back(toggled_wargoal{ wg.get_wargoal().id, true });
304 }
305 } else if(state.world.war_get_primary_attacker(war) == target && state.world.war_get_primary_defender(war) == state.local_player_nation) {
306 for(auto wg : state.world.war_get_wargoals_attached(war)) {
307 wargoals.push_back(toggled_wargoal{ wg.get_wargoal().id, true });
308 }
309 } else {
310 for(auto wg : state.world.war_get_wargoals_attached(war)) {
311 if(state.world.war_get_primary_attacker(war) == state.local_player_nation || state.world.war_get_primary_defender(war) == state.local_player_nation) {
312 if(wg.get_wargoal().get_added_by() == target || wg.get_wargoal().get_added_by().get_overlord_as_subject().get_ruler() == target || wg.get_wargoal().get_target_nation() == target || wg.get_wargoal().get_target_nation().get_overlord_as_subject().get_ruler() == target) {
313 wargoals.push_back(toggled_wargoal{ wg.get_wargoal().id, true });
314 }
315 } else {
316 if(wg.get_wargoal().get_added_by() == state.local_player_nation || wg.get_wargoal().get_added_by().get_overlord_as_subject().get_ruler() == state.local_player_nation || wg.get_wargoal().get_target_nation() == state.local_player_nation || wg.get_wargoal().get_target_nation().get_overlord_as_subject().get_ruler() == state.local_player_nation) {
317 wargoals.push_back(toggled_wargoal{ wg.get_wargoal().id, true });
318 }
319 }
320 }
321 }
322 }
323
324 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
325 if(name == "background") {
326 auto ptr = make_element_by_type<draggable_target>(state, id);
327 ptr->base_data.size = base_data.size; // Nudge size for proper sizing
328 return ptr;
329 } else if(name == "diplo_peace_bg") {
330 return make_element_by_type<image_element_base>(state, id);
331 } else if(name == "leftshield") {
332 return make_element_by_type<nation_player_flag>(state, id);
333 } else if(name == "rightshield") {
334 return make_element_by_type<flag_button>(state, id);
335 } else if(name == "title") {
336 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
337 !is_concession ? ptr->set_text(state, text::produce_simple_string(state, "demand_peace"))
338 : ptr->set_text(state, text::produce_simple_string(state, "offer_peace"));
339 return ptr;
340 } else if(name == "warscore_label") {
341 return make_element_by_type<simple_text_element_base>(state, id);
342 } else if(name == "warscore") {
343 return make_element_by_type<diplomacy_peace_total_warscore>(state, id);
344 } else if(name == "agreebutton") {
345 return make_element_by_type<diplomacy_peace_send>(state, id);
346 } else if(name == "declinebutton") {
347 return make_element_by_type<generic_close_button>(state, id);
348 } else if(name == "pick_side") {
349 return make_element_by_type<diplomacy_peace_pick_side_window>(state, id);
350 } else if(name == "setup_goals") {
351 return make_element_by_type<diplomacy_peace_setup_goals_window>(state, id);
352 } else {
353 return nullptr;
354 }
355 }
356
357 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
358 if(payload.holds_type<dcon::war_id>()) {
359 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
360 const dcon::war_id w = military::find_war_between(state, state.local_player_nation, n);
361 payload.emplace<dcon::war_id>(w);
363 } else if(payload.holds_type<element_selection_wrapper<bool>>()) {
364 is_concession = any_cast<element_selection_wrapper<bool>>(payload).data;
367 } else if(payload.holds_type<bool>()) {
368 payload.emplace<bool>(is_concession);
370 } else if(payload.holds_type<toggled_wargoal>()) {
371 toggled_wargoal twg = any_cast<toggled_wargoal>(payload);
372 for(auto& w : wargoals) {
373 if(w.wg == twg.wg) {
374 payload.emplace<toggled_wargoal>(w);
375 break;
376 }
377 }
379 } else if(payload.holds_type<toggle_wg_state>()) {
380 toggle_wg_state twg = any_cast<toggle_wg_state>(payload);
381 for(auto& w : wargoals) {
382 if(w.wg == twg.wg) {
383 w.added = !w.added;
384 break;
385 }
386 }
389 } else if(payload.holds_type< offer_cost>()) {
390 int32_t total = 0;
391 auto target = retrieve<dcon::nation_id>(state, parent);
392 auto war = military::find_war_between(state, state.local_player_nation, target);
393
394 bool attacker_filter = (military::is_attacker(state, war, state.local_player_nation) != is_concession);
395 for(auto& twg : wargoals) {
396 if(twg.added) {
397 auto wg = fatten(state.world, twg.wg);
398 if(military::get_role(state, war, wg.get_added_by()) == (attacker_filter ? military::war_role::attacker : military::war_role::defender)) {
399 total += military::peace_cost(state, war, wg.get_type(), wg.get_added_by(), wg.get_target_nation(), wg.get_secondary_nation(), wg.get_associated_state(), wg.get_associated_tag());
400 }
401 }
402 }
403
404 payload.emplace<offer_cost>(offer_cost{total});
406 } else if(payload.holds_type<send_offer>()) {
407 auto target = retrieve<dcon::nation_id>(state, parent);
408 auto war = military::find_war_between(state, state.local_player_nation, target);
409 command::start_peace_offer(state, state.local_player_nation, target, war, is_concession);
410 bool attacker_filter = (military::is_attacker(state, war, state.local_player_nation) != is_concession);
411 for(auto& twg : wargoals) {
412 if(twg.added) {
413 auto wg = fatten(state.world, twg.wg);
414 if(military::get_role(state, war, wg.get_added_by()) == (attacker_filter ? military::war_role::attacker : military::war_role::defender)) {
415 command::add_to_peace_offer(state, state.local_player_nation, twg.wg);
416 }
417 }
418 }
419 command::send_peace_offer(state, state.local_player_nation);
420 set_visible(state, false);
422 } else if(payload.holds_type<test_acceptance>()) { // test_acceptance
423 auto target = retrieve<dcon::nation_id>(state, parent);
424 const dcon::war_id w = military::find_war_between(state, state.local_player_nation, target);
425 auto war_duration = state.current_date.value - state.world.war_get_start_date(w).value;
426
427 int32_t target_personal_po_value = 0;
428 int32_t potential_peace_score_against = 0;
429 int32_t my_side_against_target = 0;
430 int32_t my_side_peace_cost = !military::is_attacker(state, w, state.local_player_nation) ? military::attacker_peace_cost(state, w) : military::defender_peace_cost(state, w);
431 int32_t overall_po_value = 0;
432 int32_t my_po_target = 0;
433 auto prime_attacker = state.world.war_get_primary_attacker(w);
434 auto prime_defender = state.world.war_get_primary_defender(w);
435 bool contains_sq = false;
436
437 for(auto& twg : wargoals) {
438 auto wg = fatten(state.world, twg.wg);
439 auto wg_value = military::peace_cost(state, w, wg.get_type(), wg.get_added_by(), wg.get_target_nation(), wg.get_secondary_nation(), wg.get_associated_state(), wg.get_associated_tag());
440
441 if(twg.added) {
442 overall_po_value += wg_value;
443 if(wg.get_target_nation() == target) {
444 target_personal_po_value += wg_value;
445 }
446 if(wg.get_target_nation() == state.local_player_nation) {
447 my_side_against_target += wg_value;
448 }
449 if((wg.get_type().get_type_bits() & military::cb_flag::po_status_quo) != 0)
450 contains_sq = true;
451 }
452 if(wg.get_target_nation() == target || wg.get_added_by() == target) {
453 if(wg.get_target_nation() == target && (wg.get_added_by() == state.local_player_nation || state.local_player_nation == prime_attacker || state.local_player_nation == prime_defender)) {
454 potential_peace_score_against += wg_value;
455 }
456 if(wg.get_added_by() == target && (wg.get_target_nation() == state.local_player_nation || state.local_player_nation == prime_attacker || state.local_player_nation == prime_defender)) {
457 my_po_target += wg_value;
458 }
459 }
460 }
461
463 target, state.local_player_nation,
464 prime_attacker, prime_defender,
465 military::primary_warscore(state, w), military::directed_warscore(state, w, state.local_player_nation, target),
466 military::is_attacker(state, w, state.local_player_nation), is_concession,
467 overall_po_value, my_po_target,
468 target_personal_po_value, potential_peace_score_against,
469 my_side_against_target, my_side_peace_cost,
470 war_duration, contains_sq);
471
472 if(state.cheat_data.always_accept_deals)
473 acceptance = true;
474
475 payload.emplace<test_acceptance>(test_acceptance{ acceptance });
477 }
479 }
480};
481
482
484 int32_t index = 0;
485 bool added = false;
486};
487
489 int32_t index = 0;
490};
491
493public:
494 void on_create(sys::state& state) noexcept override {
495 set_visible(state, false);
496 }
497};
498
500 dcon::national_identity_id get_current_nation(sys::state& state) noexcept override {
501 auto wg = nations::get_nth_crisis_war_goal(state, retrieve<int32_t>(state, parent));
502 return state.world.nation_get_identity_from_identity_holder(wg.target_nation);
503 }
504};
505
507 dcon::national_identity_id get_current_nation(sys::state& state) noexcept override {
508 auto wg = nations::get_nth_crisis_war_goal(state, retrieve<int32_t>(state, parent));
509 return state.world.nation_get_identity_from_identity_holder(wg.added_by);
510 }
511};
512
514public:
515 void on_update(sys::state& state) noexcept override {
516 auto wg = nations::get_nth_crisis_war_goal(state, retrieve<int32_t>(state, parent));
517 dcon::cb_type_id cbt = wg.cb;
518
522 if(wg.secondary_nation)
524 else if(wg.wg_tag)
527
528 set_text(state, text::resolve_string_substitution(state, state.world.cb_type_get_shortest_desc(cbt), sub));
529 }
530};
531
533public:
534 void on_update(sys::state& state) noexcept override {
535 auto wg = nations::get_nth_crisis_war_goal(state, retrieve<int32_t>(state, parent));
536 int32_t score = military::peace_cost(state, dcon::war_id{}, wg.cb, wg.added_by, wg.target_nation, wg.secondary_nation, wg.state, wg.wg_tag);
537 set_text(state, std::to_string(score));
538 }
539};
540
542public:
543 void on_update(sys::state& state) noexcept override {
544 auto wg = retrieve<int32_t>(state, parent);
545 Cyto::Any setting = toggled_crisis_wargoal{ wg, false };
546 if(parent)
547 parent->impl_get(state, setting);
548
549 frame = any_cast<toggled_crisis_wargoal>(setting).added ? 1 : 0;
550 }
551
552 void button_action(sys::state& state) noexcept override {
553 auto wg = retrieve<int32_t>(state, parent);
555 }
556};
557
559public:
560 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
561 if(name == "select") {
562 return make_element_by_type<diplomacy_crisis_peace_select_button>(state, id);
563 } else if(name == "country_flag") {
564 return make_element_by_type<crisis_peace_wg_from>(state, id);
565 } else if(name == "country_flag2") {
566 return make_element_by_type<crisis_peace_wg_to>(state, id);
567 } else if(name == "select_label") {
568 return make_element_by_type<diplomacy_crisis_peace_wargoal_text>(state, id);
569 } else if(name == "score") {
570 return make_element_by_type<diplomacy_crisis_peace_wargoal_score_text>(state, id);
571 } else {
572 return nullptr;
573 }
574 }
575};
576
577class diplomacy_crisis_peace_goal_listbox : public listbox_element_base<diplomacy_crisis_peace_goal_row, int32_t> {
578protected:
579 std::string_view get_row_element_name() override {
580 return "peace_goal_item";
581 }
582
583public:
584 void on_update(sys::state& state) noexcept override {
585 row_contents.clear();
586 auto is_concession = retrieve<bool>(state, parent);
587
588 bool attacker_filter = ((state.local_player_nation == state.primary_crisis_attacker) != is_concession);
590 for(int32_t i = 0; i < count; ++i) {
591 if(nations::nth_crisis_war_goal_is_for_attacker(state, i) == attacker_filter) {
592 row_contents.push_back(i);
593 }
594 }
595
596 update(state);
597 }
598};
599
601public:
602 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
603 if(name == "wargoal_list") {
604 return make_element_by_type<diplomacy_crisis_peace_goal_listbox>(state, id);
605 } else if(name == "score") {
606 return make_element_by_type<total_peace_cost>(state, id);
607 } else {
608 return nullptr;
609 }
610 }
611};
612
613class crisis_resolution_dialog : public window_element_base { // eu3dialogtype
614 bool is_concession = false;
615 std::vector<bool> wargoals;
616
617public:
619 wargoals.clear();
620 wargoals.resize(nations::num_crisis_wargoals(state), false);
621 is_concession = false;
622 }
623
624 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
625 if(name == "background") {
626 auto ptr = make_element_by_type<draggable_target>(state, id);
627 ptr->base_data.size = base_data.size; // Nudge size for proper sizing
628 return ptr;
629 } else if(name == "leftshield") {
630 return make_element_by_type<nation_player_flag>(state, id);
631 } else if(name == "rightshield") {
632 return make_element_by_type<flag_button>(state, id);
633 } else if(name == "title") {
634 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
635 !is_concession ? ptr->set_text(state, text::produce_simple_string(state, "demand_peace"))
636 : ptr->set_text(state, text::produce_simple_string(state, "offer_peace"));
637 return ptr;
638 } else if(name == "warscore_label") {
639 return make_element_by_type<simple_text_element_base>(state, id);
640 } else if(name == "warscore") {
641 return make_element_by_type<diplomacy_crisis_peace_total_warscore>(state, id);
642 } else if(name == "agreebutton") {
643 return make_element_by_type<diplomacy_peace_send>(state, id);
644 } else if(name == "declinebutton") {
645 return make_element_by_type<generic_close_button>(state, id);
646 } else if(name == "pick_side") {
647 return make_element_by_type<diplomacy_peace_pick_side_window>(state, id);
648 } else if(name == "setup_goals") {
649 return make_element_by_type<diplomacy_crisis_peace_setup_goals_window>(state, id);
650 } else {
651 return nullptr;
652 }
653 }
654
655 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
656 if(payload.holds_type<dcon::nation_id>()) {
657 payload.emplace<dcon::nation_id>(state.local_player_nation == state.primary_crisis_attacker ? state.primary_crisis_defender : state.primary_crisis_attacker);
659 } else if(payload.holds_type<dcon::national_identity_id>()) {
660 payload.emplace<dcon::national_identity_id>(state.world.nation_get_identity_from_identity_holder(state.local_player_nation == state.primary_crisis_attacker ? state.primary_crisis_defender : state.primary_crisis_attacker));
662 } else if(payload.holds_type<element_selection_wrapper<bool>>()) {
663 is_concession = any_cast<element_selection_wrapper<bool>>(payload).data;
666 } else if(payload.holds_type<bool>()) {
667 payload.emplace<bool>(is_concession);
669 } else if(payload.holds_type<toggled_crisis_wargoal>()) {
670 toggled_crisis_wargoal twg = any_cast<toggled_crisis_wargoal>(payload);
671 if(uint32_t(twg.index) < wargoals.size())
672 payload.emplace<toggled_crisis_wargoal>(toggled_crisis_wargoal{twg.index, wargoals[twg.index] });
674 } else if(payload.holds_type<toggle_crisis_wargoal>()) {
675 toggle_crisis_wargoal twg = any_cast<toggle_crisis_wargoal>(payload);
676 if(uint32_t(twg.index) < wargoals.size())
677 wargoals[twg.index] = !wargoals[twg.index];
680 } else if(payload.holds_type<offer_cost>()) {
681 int32_t total = 0;
682
683 bool attacker_filter = ((state.local_player_nation == state.primary_crisis_attacker) != is_concession);
684 for(uint32_t i = 0; i < wargoals.size(); ++i) {
685 if(wargoals[i] && nations::nth_crisis_war_goal_is_for_attacker(state, i) == attacker_filter) {
687 total += military::peace_cost(state, retrieve<dcon::war_id>(state, parent), wg.cb, wg.added_by, wg.target_nation, wg.secondary_nation, wg.state, wg.wg_tag);
688 }
689 }
690
691 payload.emplace<offer_cost>(offer_cost{ total });
693 } else if(payload.holds_type<send_offer>()) {
694 command::start_crisis_peace_offer(state, state.local_player_nation, is_concession);
695
696 bool attacker_filter = ((state.local_player_nation == state.primary_crisis_attacker) != is_concession);
698 for(uint32_t i = 0; i < wargoals.size(); ++i) {
699 if(wargoals[i] && nations::nth_crisis_war_goal_is_for_attacker(state, i) == attacker_filter) {
701 command::add_to_crisis_peace_offer(state, state.local_player_nation,wg.added_by, wg.target_nation, wg.cb, wg.state, wg.wg_tag, wg.secondary_nation);
702 }
703 }
704 command::send_crisis_peace_offer(state, state.local_player_nation);
705 set_visible(state, false);
706
708 } else if(payload.holds_type<test_acceptance>()) { // test_acceptance
709 auto target = state.local_player_nation == state.primary_crisis_attacker ? state.primary_crisis_defender : state.primary_crisis_attacker;
710 bool missing_wargoal = false;
711
712 bool attacker_filter = ((state.local_player_nation == state.primary_crisis_attacker) != is_concession);
714 for(uint32_t i = 0; i < wargoals.size(); ++i) {
715 if(nations::nth_crisis_war_goal_is_for_attacker(state, i) == attacker_filter) {
716 missing_wargoal = missing_wargoal || !wargoals[i];
717 }
718 }
719
720 bool acceptance = ai::will_accept_crisis_peace_offer(state, target, is_concession, missing_wargoal);
721
722 payload.emplace<test_acceptance>(test_acceptance{ acceptance });
724 }
726 }
727};
728
729} // namespace ui
void impl_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 open_window(sys::state &state)
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::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
void on_update(sys::state &state) noexcept override
void button_action(sys::state &state) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
void on_create(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
std::string_view get_row_element_name() override
void on_update(sys::state &state) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
void populate_layout(sys::state &state, text::endless_layout &contents) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
void button_action(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void 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_update(sys::state &state) noexcept override
void button_action(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void open_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
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
element_base * parent
message_result impl_get(sys::state &state, Cyto::Any &payload) noexcept
element_data base_data
void set_visible(sys::state &state, bool vis)
void set_text(sys::state &state, std::string const &new_text)
void on_update(sys::state &state) noexcept override
#define assert(condition)
Definition: debug.h:74
bool will_accept_crisis_peace_offer(sys::state &state, dcon::nation_id to, bool is_concession, bool missing_wg)
Definition: ai.cpp:1892
bool will_accept_peace_offer_value(sys::state &state, dcon::nation_id n, dcon::nation_id from, dcon::nation_id prime_attacker, dcon::nation_id prime_defender, float primary_warscore, float scoreagainst_me, bool offer_from_attacker, bool concession, int32_t overall_po_value, int32_t my_po_target, int32_t target_personal_po_value, int32_t potential_peace_score_against, int32_t my_side_against_target, int32_t my_side_peace_cost, int32_t war_duration, bool contains_sq)
Definition: ai.cpp:2754
void add_to_crisis_peace_offer(sys::state &state, dcon::nation_id source, dcon::nation_id wargoal_from, dcon::nation_id target, dcon::cb_type_id primary_cb, dcon::state_definition_id cb_state, dcon::national_identity_id cb_tag, dcon::nation_id cb_secondary_nation)
Definition: commands.cpp:2990
void add_to_peace_offer(sys::state &state, dcon::nation_id source, dcon::wargoal_id goal)
Definition: commands.cpp:2919
constexpr uint32_t po_status_quo
Definition: military.hpp:27
float primary_warscore(sys::state &state, dcon::war_id w)
Definition: military.cpp:3629
float directed_warscore(sys::state &state, dcon::war_id w, dcon::nation_id primary, dcon::nation_id secondary)
Definition: military.cpp:3686
int32_t defender_peace_cost(sys::state &state, dcon::war_id war)
Definition: military.cpp:1693
war_role get_role(sys::state const &state, dcon::war_id w, dcon::nation_id n)
Definition: military.cpp:2242
int32_t attacker_peace_cost(sys::state &state, dcon::war_id war)
Definition: military.cpp:1682
bool is_attacker(sys::state &state, dcon::war_id w, dcon::nation_id n)
Definition: military.cpp:2234
dcon::war_id find_war_between(sys::state const &state, dcon::nation_id a, dcon::nation_id b)
Definition: military.cpp:542
int32_t peace_cost(sys::state &state, dcon::war_id war, dcon::cb_type_id wargoal, dcon::nation_id from, dcon::nation_id target, dcon::nation_id secondary_nation, dcon::state_definition_id wargoal_state, dcon::national_identity_id wargoal_tag)
Definition: military.cpp:1540
bool nth_crisis_war_goal_is_for_attacker(sys::state &state, int32_t index)
Definition: nations.cpp:2458
military::full_wg get_nth_crisis_war_goal(sys::state &state, int32_t index)
Definition: nations.cpp:2497
int32_t num_crisis_wargoals(sys::state &state)
Definition: nations.cpp:2439
std::string resolve_string_substitution(sys::state &state, dcon::text_key source_text, substitution_map const &mp)
Definition: text.cpp:2113
layout_box open_layout_box(layout_base &dest, int32_t indent)
Definition: text.cpp:1799
void localised_format_box(sys::state &state, layout_base &dest, layout_box &box, std::string_view key, text::substitution_map const &sub)
Definition: text.cpp:1880
void add_line(sys::state &state, layout_base &dest, dcon::text_key txt, int32_t indent)
Definition: text.cpp:1899
void add_to_substitution_map(substitution_map &mp, variable_type key, substitution value)
Definition: text.cpp:1068
ankerl::unordered_dense::map< uint32_t, substitution > substitution_map
Definition: text.hpp:794
std::string produce_simple_string(sys::state const &state, dcon::text_key id)
Definition: text.cpp:617
void close_layout_box(columnar_layout &dest, layout_box &box)
Definition: text.cpp:1807
tooltip_behavior
void send(sys::state &state, element_base *parent, T value)
@ count
Definition: gui_event.hpp:126
message_result
uint uint32_t
dcon::wargoal_id wg
dcon::wargoal_id wg