Project Alice
Loading...
Searching...
No Matches
gui_reforms_window.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "dcon_generated.hpp"
6
7namespace ui {
8
11 0) {
12 text::add_line(state, contents, "voting_rules");
13 if((rules & issue_rule::primary_culture_voting) != 0) {
14 text::add_line(state, contents, "rule_primary_culture_voting");
15 }
16 if((rules & issue_rule::culture_voting) != 0) {
17 text::add_line(state, contents, "rule_culture_voting");
18 }
19 if((rules & issue_rule::all_voting) != 0) {
20 text::add_line(state, contents, "rule_all_voting");
21 }
22 if((rules & issue_rule::largest_share) != 0) {
23 text::add_line(state, contents, "rule_largest_share");
24 }
25 if((rules & issue_rule::dhont) != 0) {
26 text::add_line(state, contents, "rule_dhont");
27 }
28 if((rules & issue_rule::sainte_laque) != 0) {
29 text::add_line(state, contents, "rule_sainte_laque");
30 }
31 if((rules & issue_rule::same_as_ruling_party) != 0) {
32 text::add_line(state, contents, "rule_same_as_ruling_party");
33 }
34 if((rules & issue_rule::rich_only) != 0) {
35 text::add_line(state, contents, "rule_rich_only");
36 }
37 if((rules & issue_rule::state_vote) != 0) {
38 text::add_line(state, contents, "rule_state_vote");
39 }
40 if((rules & issue_rule::population_vote) != 0) {
41 text::add_line(state, contents, "rule_population_vote");
42 }
43 }
44
46
47 text::add_line(state, contents, "special_rules");
48 if((rules & issue_rule::build_factory) != 0) {
49 text::add_line(state, contents, "rule_build_factory");
50 }
51 if((rules & issue_rule::expand_factory) != 0) {
52 text::add_line(state, contents, "rule_expand_factory");
53 }
54 if((rules & issue_rule::open_factory) != 0) {
55 text::add_line(state, contents, "remove_rule_open_factory");
56 }
57 if((rules & issue_rule::destroy_factory) != 0) {
58 text::add_line(state, contents, "rule_destroy_factory");
59 }
60 if((rules & issue_rule::factory_priority) != 0) {
61 text::add_line(state, contents, "rule_factory_priority");
62 }
63 if((rules & issue_rule::can_subsidise) != 0) {
64 text::add_line(state, contents, "rule_can_subsidise");
65 }
66 if((rules & issue_rule::pop_build_factory) != 0) {
67 text::add_line(state, contents, "rule_pop_build_factory");
68 }
69 if((rules & issue_rule::pop_expand_factory) != 0) {
70 text::add_line(state, contents, "rule_pop_expand_factory");
71 }
72 if((rules & issue_rule::pop_open_factory) != 0) {
73 text::add_line(state, contents, "rule_pop_open_factory");
74 }
76 text::add_line(state, contents, "rule_delete_factory_if_no_input");
77 }
78 if((rules & issue_rule::allow_foreign_investment) != 0) {
79 text::add_line(state, contents, "rule_allow_foreign_investment");
80 }
81 if((rules & issue_rule::slavery_allowed) != 0) {
82 text::add_line(state, contents, "rule_slavery_allowed");
83 }
84 if((rules & issue_rule::build_railway) != 0) {
85 text::add_line(state, contents, "rule_build_railway");
86 }
87 if(state.economy_definitions.building_definitions[int32_t(economy::province_building_type::bank)].defined) {
88 if((rules & issue_rule::build_bank) != 0) {
89 text::add_line(state, contents, "rule_build_bank");
90 }
91 }
92 if(state.economy_definitions.building_definitions[int32_t(economy::province_building_type::university)].defined) {
93 if((rules & issue_rule::build_university) != 0) {
94 text::add_line(state, contents, "rule_build_university");
95 }
96 }
97 }
98}
99
100void reform_description(sys::state& state, text::columnar_layout& contents, dcon::issue_option_id ref) {
101 auto reform = fatten(state.world, ref);
102 {
103 auto box = text::open_layout_box(contents);
104 text::add_to_layout_box(state, contents, box, reform.get_name(), text::text_color::yellow);
105 text::close_layout_box(contents, box);
106 }
107 if(auto desc = reform.get_desc(); state.key_is_localized(desc)) {
111 text::add_to_substitution_map(sub, text::variable_type::capital, state.world.nation_get_capital(state.local_player_nation));
112 auto box = text::open_layout_box(contents);
113 text::add_to_layout_box(state, contents, box, desc, sub);
114 text::close_layout_box(contents, box);
115 }
116
117 auto total = state.world.nation_get_demographics(state.local_player_nation, demographics::total);
118 auto support = state.world.nation_get_demographics(state.local_player_nation, demographics::to_key(state, ref));
119 if(total > 0) {
120 text::add_line(state, contents, "there_are_backing", text::variable_type::val, text::fp_percentage{ support / total });
121 }
122
123 auto mod_id = reform.get_modifier();
124 if(bool(mod_id)) {
125 modifier_description(state, contents, mod_id);
126 }
127
128 auto time_limit = state.world.nation_get_last_issue_or_reform_change(state.local_player_nation);
129 auto parent = state.world.issue_option_get_parent_issue(ref);
130 if(parent.get_issue_type() != uint8_t(culture::issue_type::party) && time_limit && !(time_limit + int32_t(state.defines.min_delay_between_reforms * 30) <= state.current_date)) {
131 text::add_line_with_condition(state, contents, "too_soon_for_reform", false, text::variable_type::date, time_limit + int32_t(state.defines.min_delay_between_reforms * 30));
132 }
133
134 auto allow = reform.get_allow();
135 if(allow) {
136 //allow_reform_cond
137 text::add_line(state, contents, "allow_reform_cond");
138 trigger_description(state, contents, allow, trigger::to_generic(state.local_player_nation),
139 trigger::to_generic(state.local_player_nation), -1);
140 }
141
142 auto ext = reform.get_on_execute_trigger();
143 if(ext) {
144 text::add_line(state, contents, "reform_effect_if_desc");
145 trigger_description(state, contents, ext, trigger::to_generic(state.local_player_nation),
146 trigger::to_generic(state.local_player_nation), -1);
147 }
148 auto ex = reform.get_on_execute_effect();
149 if(ex) {
150 if(ext)
151 text::add_line(state, contents, "reform_effect_then_desc");
152 else
153 text::add_line(state, contents, "reform_effect_desc");
154
155 effect_description(state, contents, ex, trigger::to_generic(state.local_player_nation),
156 trigger::to_generic(state.local_player_nation), -1, uint32_t(state.current_date.value),
157 uint32_t((ref.index() << 2) ^ state.local_player_nation.index()));
158 }
159 reform_rules_description(state, contents, reform.get_rules());
161 auto current = state.world.nation_get_issues(state.local_player_nation, reform.get_parent_issue()).id;
162
163 if(current == ref)
164 return;
165
166 bool some_support_shown = false;
167 text::add_line(state, contents, "alice_reform_support_header");
168 auto tag = state.world.nation_get_identity_from_identity_holder(state.local_player_nation);
169 auto start = state.world.national_identity_get_political_party_first(tag).id.index();
170 auto end = start + state.world.national_identity_get_political_party_count(tag);
171 auto count_party_issues = state.world.political_party_get_party_issues_size();
172
173 for(uint32_t icounter = state.world.ideology_size(); icounter-- > 0;) {
174 dcon::ideology_id iid{ dcon::ideology_id::value_base_t(icounter) };
175 dcon::value_modifier_key condition;
176 if(parent.get_issue_type() == uint8_t(culture::issue_type::political)) {
177 condition = ref.index() > current.index() ? state.world.ideology_get_add_political_reform(iid) : state.world.ideology_get_remove_political_reform(iid);
178 } else if(parent.get_issue_type() == uint8_t(culture::issue_type::social)) {
179 condition = ref.index() > current.index() ? state.world.ideology_get_add_social_reform(iid) : state.world.ideology_get_remove_social_reform(iid);
180 }
181 auto upperhouse_weight = 0.01f * state.world.nation_get_upper_house(state.local_player_nation, iid);
182
183 float party_special_issues_support_total = 0.0f;
184 float count_found = 0.0f;
185
186 for(int32_t i = start; i < end; i++) {
187 auto pid = dcon::political_party_id(dcon::political_party_id::value_base_t(i));
188 if(politics::political_party_is_active(state, state.local_player_nation, pid)
189 && (state.world.nation_get_government_type(state.local_player_nation).get_ideologies_allowed() & culture::to_bits(state.world.political_party_get_ideology(pid))) != 0
190 && state.world.political_party_get_ideology(pid) == iid) {
191
192 if(auto special_opt = state.world.political_party_get_party_issues(pid, parent); special_opt) {
193 if(special_opt == ref
194 || (state.world.issue_get_is_next_step_only(parent.id)
195 && ((special_opt.id.index() > current.index() && ref.index() > current.index())
196 || (special_opt.id.index() < current.index() && ref.index() < current.index())
197 )
198 )
199 ) {
200 party_special_issues_support_total = upperhouse_weight;
201 } else {
202 party_special_issues_support_total = 0.0f;
203 }
204 count_found = 1.0f;
205 } else {
206 for(uint32_t j = 0; j < count_party_issues; ++j) {
207 auto popt = state.world.political_party_get_party_issues(pid, dcon::issue_id{ dcon::issue_id::value_base_t(j) });
208 auto opt_mod = state.world.issue_option_get_support_modifiers(popt, ref);
209
210 if(opt_mod) {
211 party_special_issues_support_total += upperhouse_weight * trigger::evaluate_additive_modifier(state, opt_mod, trigger::to_generic(state.local_player_nation), trigger::to_generic(state.local_player_nation), 0);
212 count_found += 1.0f;
213 }
214 }
215 }
216
217 break; // only look at one active party per ideology
218 }
219 }
220
221 if(count_found > 0.0f) {
222 auto result = std::clamp(party_special_issues_support_total / count_found, -1.0f, 1.0f);
223 if(abs(result) >= 0.01) {
224 auto box = text::open_layout_box(contents, 10);
225 text::add_to_layout_box(state, contents, box, state.world.ideology_get_name(iid));
226 text::add_space_to_layout_box(state, contents, box);
228 text::close_layout_box(contents, box);
229 some_support_shown = true;
230 }
231 } else if(condition && upperhouse_weight > 0.0f) {
232 auto result = upperhouse_weight * std::clamp(trigger::evaluate_additive_modifier(state, condition, trigger::to_generic(state.local_player_nation), trigger::to_generic(state.local_player_nation), 0), -1.0f, 1.0f);
233 if(abs(result) >= 0.01) {
234 auto box = text::open_layout_box(contents, 10);
235 text::add_to_layout_box(state, contents, box, state.world.ideology_get_name(iid));
236 text::add_space_to_layout_box(state, contents, box);
238 text::close_layout_box(contents, box);
239 some_support_shown = true;
240 }
241 }
242 }
243
244 if(!some_support_shown) {
245 text::add_line(state, contents, "alice_no_current_support");
246 }
247}
248
250public:
253 }
254
255 void button_action(sys::state& state) noexcept override {
256 auto content = retrieve<dcon::issue_option_id>(state, parent);
257 command::enact_issue(state, state.local_player_nation, content);
258 }
259
260 void on_update(sys::state& state) noexcept override {
261 auto content = retrieve<dcon::issue_option_id>(state, parent);
262 disabled = !command::can_enact_issue(state, state.local_player_nation, content);
263 }
264
267 }
268
269 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
270 auto content = retrieve<dcon::issue_option_id>(state, parent);
271 reform_description(state, contents, content);
272 }
273};
274
275class reforms_option : public listbox_row_element_base<dcon::issue_option_id> {
276 image_element_base* selected_icon = nullptr;
277
278public:
279 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
280 if(name == "reform_name") {
281 return make_element_by_type<generic_name_text<dcon::issue_option_id>>(state, id);
282 } else if(name == "selected") {
283 auto ptr = make_element_by_type<image_element_base>(state, id);
284 selected_icon = ptr.get();
285 return ptr;
286 } else if(name == "reform_option") {
287 return make_element_by_type<reforms_reform_button>(state, id);
288 } else {
289 return nullptr;
290 }
291 }
292
293 void on_update(sys::state& state) noexcept override {
294 selected_icon->set_visible(state, politics::issue_is_selected(state, state.local_player_nation, content));
295 }
296};
297
298class reforms_listbox : public listbox_element_base<reforms_option, dcon::issue_option_id> {
299protected:
300 std::string_view get_row_element_name() override {
301 return "reform_option_window";
302 }
303
304public:
305 message_result set(sys::state& state, Cyto::Any& payload) noexcept override {
306 if(payload.holds_type<dcon::issue_id>()) {
307 auto issue_id = any_cast<dcon::issue_id>(payload);
308 row_contents.clear();
309 auto fat_id = dcon::fatten(state.world, issue_id);
310 for(auto& option : fat_id.get_options())
311 if(option)
312 row_contents.push_back(option);
313 update(state);
315 }
317 }
318};
319
320
322public:
323 void on_create(sys::state& state) noexcept override {
324 base_data.position.y -= int16_t(7);
326 }
327 void on_update(sys::state& state) noexcept override {
328 auto content = retrieve<dcon::issue_id>(state, parent);
333 auto fat_id = dcon::fatten(state.world, content);
334 auto box = text::open_layout_box(container);
335 text::add_to_layout_box(state, container, box, fat_id.get_name(), text::substitution_map{});
336 text::close_layout_box(container, box);
337 }
338};
339
341 dcon::issue_id issue_id{};
342
343public:
344 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
345 if(name == "reform_name") {
346 return make_element_by_type<issue_name_text>(state, id);
347 } else {
348 return nullptr;
349 }
350 }
351
352 void on_create(sys::state& state) noexcept override {
354 auto reforms_box = std::make_unique<reforms_listbox>();
355 reforms_box->base_data.size.x = 130;
356 reforms_box->base_data.size.y = 100;
357 make_size_from_graphics(state, reforms_box->base_data);
358 reforms_box->on_create(state);
359 add_child_to_front(std::move(reforms_box));
360 }
361
362 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
363 if(payload.holds_type<dcon::issue_id>()) {
364 payload.emplace<dcon::issue_id>(issue_id);
366 }
368 }
369
370 message_result set(sys::state& state, Cyto::Any& payload) noexcept override {
371 if(payload.holds_type<dcon::issue_id>()) {
372 issue_id = any_cast<dcon::issue_id>(payload);
374 }
376 }
377};
378
380public:
381 void on_create(sys::state& state) noexcept override {
383 set_visible(state, false);
384 }
385
386 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
387 if(auto issue_id = politics::get_issue_by_name(state, name); bool(issue_id)) {
388 auto ptr = make_element_by_type<reforms_reform_window>(state, id);
389 Cyto::Any payload = issue_id;
390 ptr->impl_set(state, payload);
391 return ptr;
392 } else {
393 return nullptr;
394 }
395 }
396};
397
398} // namespace ui
void add_child_to_front(std::unique_ptr< element_base > child) noexcept final
element_base * parent
virtual message_result get(sys::state &state, Cyto::Any &payload) noexcept
element_data base_data
void set_visible(sys::state &state, bool vis)
void on_create(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void on_create(sys::state &state) noexcept override
message_result set(sys::state &state, Cyto::Any &payload) noexcept override
std::string_view get_row_element_name() override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
void on_update(sys::state &state) noexcept override
void button_action(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
sound::audio_instance & get_click_sound(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
message_result set(sys::state &state, Cyto::Any &payload) noexcept override
std::unique_ptr< element_base > make_child(sys::state &state, std::string_view name, dcon::gui_def_id id) noexcept override
void on_create(sys::state &state) noexcept override
message_result get(sys::state &state, Cyto::Any &payload) 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 enact_issue(sys::state &state, dcon::nation_id source, dcon::issue_option_id i)
Definition: commands.cpp:1878
bool can_enact_issue(sys::state &state, dcon::nation_id source, dcon::issue_option_id i)
Definition: commands.cpp:1886
constexpr uint64_t to_bits(dcon::ideology_id id)
Definition: culture.hpp:92
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 pop_open_factory
Definition: culture.hpp:16
constexpr uint32_t build_railway
Definition: culture.hpp:38
constexpr uint32_t open_factory
Definition: culture.hpp:10
constexpr uint32_t same_as_ruling_party
Definition: culture.hpp:34
constexpr uint32_t state_vote
Definition: culture.hpp:36
constexpr uint32_t build_factory
Definition: culture.hpp:8
constexpr uint32_t can_subsidise
Definition: culture.hpp:13
constexpr uint32_t pop_expand_factory
Definition: culture.hpp:15
constexpr uint32_t delete_factory_if_no_input
Definition: culture.hpp:17
constexpr uint32_t culture_voting
Definition: culture.hpp:29
constexpr uint32_t destroy_factory
Definition: culture.hpp:11
constexpr uint32_t slavery_allowed
Definition: culture.hpp:27
constexpr uint32_t build_bank
Definition: culture.hpp:41
constexpr uint32_t rich_only
Definition: culture.hpp:35
constexpr uint32_t build_university
Definition: culture.hpp:42
constexpr uint32_t all_voting
Definition: culture.hpp:30
constexpr uint32_t allow_foreign_investment
Definition: culture.hpp:26
constexpr uint32_t dhont
Definition: culture.hpp:32
constexpr uint32_t pop_build_factory
Definition: culture.hpp:14
constexpr uint32_t largest_share
Definition: culture.hpp:31
constexpr uint32_t primary_culture_voting
Definition: culture.hpp:28
constexpr uint32_t factory_priority
Definition: culture.hpp:12
constexpr uint32_t sainte_laque
Definition: culture.hpp:33
constexpr uint32_t population_vote
Definition: culture.hpp:37
constexpr uint32_t expand_factory
Definition: culture.hpp:9
dcon::issue_id get_issue_by_name(sys::state &state, std::string_view name)
Definition: politics.cpp:83
bool political_party_is_active(sys::state &state, dcon::nation_id n, dcon::political_party_id p)
Definition: politics.cpp:323
bool issue_is_selected(sys::state &state, dcon::nation_id nation, dcon::issue_option_id issue_option)
Definition: politics.cpp:102
audio_instance & get_enact_sound(sys::state &state)
Definition: sound_nix.cpp:281
void add_to_layout_box(sys::state &state, layout_base &dest, layout_box &box, embedded_flag ico)
Definition: text.cpp:1165
layout_box open_layout_box(layout_base &dest, int32_t indent)
Definition: text.cpp:1799
endless_layout create_endless_layout(sys::state &state, layout &dest, layout_parameters const &params)
Definition: text.cpp:1100
void add_line(sys::state &state, layout_base &dest, dcon::text_key txt, int32_t indent)
Definition: text.cpp:1899
void add_line_with_condition(sys::state &state, layout_base &dest, std::string_view key, bool condition_met, int32_t indent)
Definition: text.cpp:1955
void add_line_break_to_layout(sys::state &state, columnar_layout &dest)
Definition: text.cpp:1152
void add_to_substitution_map(substitution_map &mp, variable_type key, substitution value)
Definition: text.cpp:1068
dcon::text_key get_adjective(sys::state &state, dcon::nation_id id)
Definition: text.cpp:890
ankerl::unordered_dense::map< uint32_t, substitution > substitution_map
Definition: text.hpp:794
void add_space_to_layout_box(sys::state &state, layout_base &dest, layout_box &box)
Definition: text.cpp:1788
void close_layout_box(columnar_layout &dest, layout_box &box)
Definition: text.cpp:1807
int32_t to_generic(dcon::province_id v)
Definition: triggers.hpp:12
float evaluate_additive_modifier(sys::state &state, dcon::value_modifier_key modifier, int32_t primary, int32_t this_slot, int32_t from_slot)
Definition: triggers.cpp:5796
void modifier_description(sys::state &state, text::layout_base &layout, dcon::modifier_id mid, int32_t indentation=0)
void reform_description(sys::state &state, text::columnar_layout &contents, dcon::issue_option_id ref)
void make_size_from_graphics(sys::state &state, ui::element_data &dat)
void effect_description(sys::state &state, text::layout_base &layout, dcon::effect_key k, int32_t primary_slot, int32_t this_slot, int32_t from_slot, uint32_t r_lo, uint32_t r_hi)
tooltip_behavior
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
void reform_rules_description(sys::state &state, text::columnar_layout &contents, uint32_t rules)
uint uint32_t
uchar uint8_t
union ui::element_data::internal_data data