Project Alice
Loading...
Searching...
No Matches
gui_production_window.hpp
Go to the documentation of this file.
1#pragma once
2
12#include "economy_templates.hpp"
14#include "widgets/table.hpp"
15
16namespace ui {
17
19 dcon::state_instance_id data{};
20 bool is_build = false;
22};
23
25public:
26 void on_update(sys::state& state) noexcept override {
27 auto content = retrieve<dcon::factory_id>(state, parent);
28 frame = int32_t(state.world.factory_get_primary_employment(content) * 10.f);
29 }
30
33 }
34
35 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
36 auto fid = retrieve<dcon::factory_id>(state, parent);
37
38 auto max_emp = economy::factory_max_employment(state, fid);
39 {
40 auto box = text::open_layout_box(contents, 0);
41 text::add_to_layout_box(state, contents, box, state.world.pop_type_get_name(state.culture_definitions.primary_factory_worker));
42 text::add_to_layout_box(state, contents, box, std::string_view{": " });
43 text::add_to_layout_box(state, contents, box, int64_t(std::ceil(state.world.factory_get_primary_employment(fid) * max_emp * state.economy_definitions.craftsmen_fraction)));
44 text::add_to_layout_box(state, contents, box, std::string_view{ " / " });
45 text::add_to_layout_box(state, contents, box, int64_t(std::ceil(max_emp * state.economy_definitions.craftsmen_fraction)));
46 text::close_layout_box(contents, box);
47 }
48 {
49 auto box = text::open_layout_box(contents, 0);
50 text::add_to_layout_box(state, contents, box, state.world.pop_type_get_name(state.culture_definitions.secondary_factory_worker));
51 text::add_to_layout_box(state, contents, box, std::string_view{ ": " });
52 text::add_to_layout_box(state, contents, box, int64_t(std::ceil(state.world.factory_get_secondary_employment(fid) * max_emp * (1.0f -state.economy_definitions.craftsmen_fraction))));
53 text::add_to_layout_box(state, contents, box, std::string_view{ " / " });
54 text::add_to_layout_box(state, contents, box, int64_t(std::ceil(max_emp * (1.0f - state.economy_definitions.craftsmen_fraction))));
55 text::close_layout_box(contents, box);
56 }
57 }
58};
59
61public:
62 void on_update(sys::state& state) noexcept override {
63 const dcon::factory_id fid = retrieve<dcon::factory_id>(state, parent);
64 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
66 auto rules = state.world.nation_get_combined_issue_rules(n);
67 disabled = (rules & issue_rule::factory_priority) == 0 || n != state.local_player_nation;
68 }
69
70 void button_action(sys::state& state) noexcept override {
71 const dcon::factory_id fid = retrieve<dcon::factory_id>(state, parent);
72 auto fat = dcon::fatten(state.world, fid);
73 switch(economy::factory_priority(state, fid)) {
74 case 0:
75 command::change_factory_settings(state, state.local_player_nation, fid, 1, fat.get_subsidized());
76 break;
77 case 1:
78 command::change_factory_settings(state, state.local_player_nation, fid, 2, fat.get_subsidized());
79 break;
80 case 2:
81 command::change_factory_settings(state, state.local_player_nation, fid, 3, fat.get_subsidized());
82 break;
83 case 3:
84 command::change_factory_settings(state, state.local_player_nation, fid, 0, fat.get_subsidized());
85 break;
86 default:
87 break;
88 }
89 }
90
93 }
94
95 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
96 const dcon::factory_id fid = retrieve<dcon::factory_id>(state, parent);
97 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
98 if(n != state.local_player_nation)
99 return;
100
101 if(disabled) {
102 text::add_line(state, contents, "production_not_allowed_to_change_prio_tooltip");
103 text::add_line(state, contents, "cant_prioritize_explanation");
104 } else {
105 text::add_line(state, contents, "production_allowed_to_change_prio_tooltip");
106 switch(economy::factory_priority(state, fid)) {
107 case 0:
108 text::add_line(state, contents, "diplomacy_prio_none");
109 break;
110 case 1:
111 text::add_line(state, contents, "diplomacy_prio_low");
112 break;
113 case 2:
114 text::add_line(state, contents, "diplomacy_prio_middle");
115 break;
116 case 3:
117 text::add_line(state, contents, "diplomacy_prio_high");
118 break;
119 default:
120 break;
121 }
122 }
123 text::add_line_break_to_layout(state, contents); // TODO: Classic needs this as a divider
124 text::add_line(state, contents, "production_prio_factory_desc_tooltip");
125 }
126};
127
129public:
130 void on_update(sys::state& state) noexcept override {
131 auto fid = retrieve<dcon::factory_id>(state, parent);
132 auto fat = dcon::fatten(state.world, fid);
133 auto sid = retrieve<dcon::state_instance_id>(state, parent);
134
136 fat.get_building_type().id, true);
137
138 }
139
140 void button_right_action(sys::state& state) noexcept override {
141
142 }
143
144 void button_shift_action(sys::state& state) noexcept override {
145 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
146 auto sid = retrieve<dcon::state_instance_id>(state, parent);
147 for(auto p : state.world.state_definition_get_abstract_state_membership_as_state(state.world.state_instance_get_definition(sid))) {
148 for(auto fac : p.get_province().get_factory_location()) {
150 p.get_province().get_state_membership(), fac.get_factory().get_building_type(), true)) {
152 p.get_province().get_state_membership(), fac.get_factory().get_building_type(), true);
153 }
154 }
155 }
156 }
157
158 void button_shift_right_action(sys::state& state) noexcept override {
159 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
160 auto sid = retrieve<dcon::state_instance_id>(state, parent);
161 for(auto p : state.world.state_definition_get_abstract_state_membership_as_state(state.world.state_instance_get_definition(sid))) {
162 for(auto fac : p.get_province().get_factory_location()) {
163 if(fac.get_factory().get_primary_employment() >= 0.95f && fac.get_factory().get_production_scale() > 0.8f) {
165 p.get_province().get_state_membership(), fac.get_factory().get_building_type(), true)) {
167 p.get_province().get_state_membership(), fac.get_factory().get_building_type(), true);
168 }
169 }
170 }
171 }
172 }
173
174 void button_ctrl_action(sys::state& state) noexcept override {
175 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
176 for(auto p : state.world.nation_get_province_ownership(n)) {
177 for(auto fac : p.get_province().get_factory_location()) {
179 p.get_province().get_state_membership(), fac.get_factory().get_building_type(), true)) {
181 p.get_province().get_state_membership(), fac.get_factory().get_building_type(), true);
182 }
183 }
184 }
185 }
186
187 void button_ctrl_right_action(sys::state& state) noexcept override {
188 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
189 for(auto p : state.world.nation_get_province_ownership(n)) {
190 for(auto fac : p.get_province().get_factory_location()) {
191 if(fac.get_factory().get_primary_employment() >= 0.95f && fac.get_factory().get_production_scale() > 0.8f) {
193 p.get_province().get_state_membership(), fac.get_factory().get_building_type(), true)) {
195 p.get_province().get_state_membership(), fac.get_factory().get_building_type(), true);
196 }
197 }
198 }
199 }
200 }
201
202 void button_ctrl_shift_action(sys::state& state) noexcept override {
203 auto fid = retrieve<dcon::factory_id>(state, parent);
204 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
205 for(auto p : state.world.nation_get_province_ownership(n)) {
206 for(auto fac : p.get_province().get_factory_location()) {
207 if(fac.get_factory().get_building_type() == state.world.factory_get_building_type(fid)
209 p.get_province().get_state_membership(), fac.get_factory().get_building_type(), true)) {
211 p.get_province().get_state_membership(), fac.get_factory().get_building_type(), true);
212 }
213 }
214 }
215 }
216
218 auto fid = retrieve<dcon::factory_id>(state, parent);
219 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
220 for(auto p : state.world.nation_get_province_ownership(n)) {
221 for(auto fac : p.get_province().get_factory_location()) {
222 if(fac.get_factory().get_building_type() == state.world.factory_get_building_type(fid)
223 && fac.get_factory().get_primary_employment() >= 0.95f && fac.get_factory().get_production_scale() > 0.8f) {
225 p.get_province().get_state_membership(), fac.get_factory().get_building_type(), true)) {
227 p.get_province().get_state_membership(), fac.get_factory().get_building_type(), true);
228 }
229 }
230 }
231 }
232 }
233
234 void button_action(sys::state& state) noexcept override {
235 auto fid = retrieve<dcon::factory_id>(state, parent);
236 auto fat = dcon::fatten(state.world, fid);
237 auto sid = retrieve<dcon::state_instance_id>(state, parent);
238 command::begin_factory_building_construction(state, state.local_player_nation, sid, fat.get_building_type().id, true);
239 }
240
241 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
242 auto fid = retrieve<dcon::factory_id>(state, parent);
243 auto sid = retrieve<dcon::state_instance_id>(state, parent);
244 auto type = state.world.factory_get_building_type(fid);
245
246
247 // no double upgrade
248 bool is_not_upgrading = true;
249 for(auto p : state.world.state_instance_get_state_building_construction(sid)) {
250 if(p.get_type() == type)
251 is_not_upgrading = false;
252 }
253 if(is_not_upgrading) {
255 }
256 }
257
260 }
261
262 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
263 const dcon::factory_id fid = retrieve<dcon::factory_id>(state, parent);
264 auto fat = dcon::fatten(state.world, fid);
265 const dcon::state_instance_id sid = retrieve<dcon::state_instance_id>(state, parent);
266 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
267
268 auto type = state.world.factory_get_building_type(fid);
269
270 // no double upgrade
271 bool is_not_upgrading = true;
272 for(auto p : state.world.state_instance_get_state_building_construction(sid)) {
273 if(p.get_type() == type)
274 is_not_upgrading = false;
275 }
276 if(!is_not_upgrading) {
277 return;
278 }
279
280 text::add_line(state, contents, "production_expand_factory_tooltip");
281
283
284 bool is_civ = state.world.nation_get_is_civilized(state.local_player_nation);
285 text::add_line_with_condition(state, contents, "factory_upgrade_condition_1", is_civ);
286
287 bool state_is_not_colonial = !state.world.province_get_is_colonial(state.world.state_instance_get_capital(sid));
288 text::add_line_with_condition(state, contents, "factory_upgrade_condition_2", state_is_not_colonial);
289
290 bool is_activated = state.world.nation_get_active_building(n, type) == true || state.world.factory_type_get_is_available_from_start(type);
291 text::add_line_with_condition(state, contents, "factory_upgrade_condition_3", is_activated);
292 if(n != state.local_player_nation) {
293 bool gp_condition = (state.world.nation_get_is_great_power(state.local_player_nation) == true &&
294 state.world.nation_get_is_great_power(n) == false);
295 text::add_line_with_condition(state, contents, "factory_upgrade_condition_4", gp_condition);
296
297 text::add_line_with_condition(state, contents, "factory_upgrade_condition_5", state.world.nation_get_is_civilized(n));
298
299 auto rules = state.world.nation_get_combined_issue_rules(n);
300 text::add_line_with_condition(state, contents, "factory_upgrade_condition_6",
302
303 text::add_line_with_condition(state, contents, "factory_upgrade_condition_7",
304 !military::are_at_war(state, state.local_player_nation, n));
305 } else {
306 auto rules = state.world.nation_get_combined_issue_rules(state.local_player_nation);
307 text::add_line_with_condition(state, contents, "factory_upgrade_condition_8", (rules & issue_rule::expand_factory) != 0);
308 }
309 text::add_line_with_condition(state, contents, "factory_upgrade_condition_9", is_not_upgrading);
310 text::add_line_with_condition(state, contents, "factory_upgrade_condition_10", fat.get_level() < 255);
312
313 text::add_line(state, contents, "factory_upgrade_shortcuts");
314 }
315};
316
318public:
319 void on_update(sys::state& state) noexcept override {
320 const dcon::factory_id fid = retrieve<dcon::factory_id>(state, parent);
322 }
323
324 void button_action(sys::state& state) noexcept override {
325 const dcon::factory_id fid = retrieve<dcon::factory_id>(state, parent);
327 }
328
329 void on_create(sys::state& state) noexcept override {
330 frame = 0;
331 }
332
335 }
336
337 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
338 const dcon::factory_id fid = retrieve<dcon::factory_id>(state, parent);
339 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
340 if(n == state.local_player_nation) {
341 text::add_line(state, contents, "open_and_sub");
342 if(disabled) {
343 text::add_line(state, contents, "production_not_allowed_to_subsidise_tooltip");
344 text::add_line(state, contents, "cant_subsidize_explanation");
345 }
346 }
347 }
348};
349
351public:
352 void on_update(sys::state& state) noexcept override {
353 const dcon::factory_id fid = retrieve<dcon::factory_id>(state, parent);
354 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
355 auto rules = state.world.nation_get_combined_issue_rules(n);
356 disabled = (rules & issue_rule::can_subsidise) == 0 || state.local_player_nation != n;
357 frame = state.world.factory_get_subsidized(fid) ? 1 : 0;
358 }
359
360 void button_action(sys::state& state) noexcept override {
361 const dcon::factory_id fid = retrieve<dcon::factory_id>(state, parent);
362 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
363 auto fat = dcon::fatten(state.world, fid);
364 if(fat.get_subsidized()) {
365 if(command::can_change_factory_settings(state, state.local_player_nation, fid, uint8_t(economy::factory_priority(state, fid)), false)) {
367 false);
368 }
369 } else {
370 if(command::can_change_factory_settings(state, state.local_player_nation, fid, uint8_t(economy::factory_priority(state, fid)), true)) {
372 }
373 }
374 }
375
378 }
379
380 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
381 const dcon::factory_id fid = retrieve<dcon::factory_id>(state, parent);
382 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
383 if(n == state.local_player_nation) {
384 if(dcon::fatten(state.world, fid).get_subsidized()) {
385 text::add_line(state, contents, "production_cancel_subsidies");
386 } else {
387 if(disabled) {
388 text::add_line(state, contents, "production_not_allowed_to_subsidise_tooltip");
389 text::add_line(state, contents, "cant_subsidize_explanation");
390 } else {
391 text::add_line(state, contents, "production_allowed_to_subsidise_tooltip");
392 }
393 }
395 text::add_line(state, contents, "production_subsidies_desc");
396 }
397 }
398};
399
401public:
402 void on_update(sys::state& state) noexcept override {
403 const dcon::factory_id fid = retrieve<dcon::factory_id>(state, parent);
404 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
405 disabled = !command::can_delete_factory(state, state.local_player_nation, fid);
406 }
407
408 void button_action(sys::state& state) noexcept override {
409 const dcon::factory_id fid = retrieve<dcon::factory_id>(state, parent);
410 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
411 command::delete_factory(state, state.local_player_nation, fid);
412 }
413
416 }
417
418 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
419 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
420 if(n == state.local_player_nation) {
421 text::add_line(state, contents, "factory_delete_header");
422 if(disabled) {
424 text::add_line(state, contents, "factory_delete_not_allowed");
425 }
426 }
427 }
428};
429
431public:
432 bool visible = true;
433
434 void on_update(sys::state& state) noexcept override {
435 const dcon::factory_id fid = retrieve<dcon::factory_id>(state, parent);
436 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
437
438 visible = dcon::fatten(state.world, fid).get_production_scale() >= 0.05f;
439 disabled = !command::can_delete_factory(state, state.local_player_nation, fid);
440 frame = 1;
441 }
442 message_result test_mouse(sys::state& state, int32_t x, int32_t y, mouse_probe_type type) noexcept override {
443 auto prov = retrieve<dcon::province_id>(state, parent);
444 if(visible)
447 }
448 void button_action(sys::state& state) noexcept override {
449 const dcon::factory_id fid = retrieve<dcon::factory_id>(state, parent);
450 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
451 command::delete_factory(state, state.local_player_nation, fid);
452 }
453
454 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
455 if(visible)
457 }
458
461 }
462
463 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
464 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
465 if(n == state.local_player_nation) {
466 text::add_line(state, contents, "close_and_del");
467 if(disabled) {
469 text::add_line(state, contents, "factory_delete_not_allowed");
470 }
471 }
472 }
473};
474
476 dcon::factory_id id;
477 std::variant<std::monostate, economy::upgraded_factory, economy::new_factory> activity;
478};
479
481 size_t index = 0;
482};
483
485public:
486 void on_update(sys::state& state) noexcept override {
487 progress = retrieve<economy::new_factory>(state, parent).progress;
488 }
491 }
492
493 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
494 auto nf = retrieve< economy::new_factory>(state, parent);
495 auto si = retrieve<dcon::state_instance_id>(state, parent);
496 if(!nf.type)
497 return;
498 for(auto p : state.world.state_instance_get_state_building_construction(si)) {
499 if(p.get_type() == nf.type) {
500 float admin_eff = state.world.nation_get_administrative_efficiency(p.get_nation());
501 float factory_mod = state.world.nation_get_modifier_values(p.get_nation(), sys::national_mod_offsets::factory_cost) + 1.0f;
502 float pop_factory_mod = std::max(0.1f, state.world.nation_get_modifier_values(p.get_nation(), sys::national_mod_offsets::factory_owner_cost));
503 float admin_cost_factor = (p.get_is_pop_project() ? pop_factory_mod : (2.0f - admin_eff)) * factory_mod;
504
505 auto& goods = state.world.factory_type_get_construction_costs(nf.type);
506 auto& cgoods = p.get_purchased_goods();
507
508 for(uint32_t i = 0; i < economy::commodity_set::set_size; ++i) {
509 if(goods.commodity_type[i]) {
510 auto box = text::open_layout_box(contents, 0);
511 text::add_to_layout_box(state, contents, box, state.world.commodity_get_name(goods.commodity_type[i]));
512 text::add_to_layout_box(state, contents, box, std::string_view{ ": " });
513 text::add_to_layout_box(state, contents, box, text::fp_one_place{ cgoods.commodity_amounts[i] });
514 text::add_to_layout_box(state, contents, box, std::string_view{ " / " });
515 text::add_to_layout_box(state, contents, box, text::fp_one_place{ goods.commodity_amounts[i] * admin_cost_factor });
516 text::close_layout_box(contents, box);
517 }
518 }
519 return;
520 }
521 }
522 }
523};
524
526public:
527 void on_update(sys::state& state) noexcept override {
528 progress = retrieve<economy::upgraded_factory>(state, parent).progress;
529 }
532 }
533
534 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
535 auto nf = retrieve<economy::upgraded_factory>(state, parent);
536 auto si = retrieve<dcon::state_instance_id>(state, parent);
537 if(!nf.type)
538 return;
539 for(auto p : state.world.state_instance_get_state_building_construction(si)) {
540 if(p.get_type() == nf.type) {
541 float admin_eff = state.world.nation_get_administrative_efficiency(p.get_nation());
542 float factory_mod = state.world.nation_get_modifier_values(p.get_nation(), sys::national_mod_offsets::factory_cost) + 1.0f;
543 float pop_factory_mod = std::max(0.1f, state.world.nation_get_modifier_values(p.get_nation(), sys::national_mod_offsets::factory_owner_cost));
544 float admin_cost_factor = (p.get_is_pop_project() ? pop_factory_mod : (2.0f - admin_eff)) * factory_mod;
545
546 auto& goods = state.world.factory_type_get_construction_costs(nf.type);
547 auto& cgoods = p.get_purchased_goods();
548
549 for(uint32_t i = 0; i < economy::commodity_set::set_size; ++i) {
550 if(goods.commodity_type[i]) {
551 auto box = text::open_layout_box(contents, 0);
552 text::add_to_layout_box(state, contents, box, state.world.commodity_get_name(goods.commodity_type[i]));
553 text::add_to_layout_box(state, contents, box, std::string_view{ ": " });
554 text::add_to_layout_box(state, contents, box, text::fp_one_place{ cgoods.commodity_amounts[i] });
555 text::add_to_layout_box(state, contents, box, std::string_view{ " / " });
556 text::add_to_layout_box(state, contents, box, text::fp_one_place{ goods.commodity_amounts[i] * admin_cost_factor });
557 text::close_layout_box(contents, box);
558 }
559 }
560 return;
561 }
562 }
563 }
564};
565
567 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
569 }
570
571 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
572 auto fid = retrieve<dcon::factory_id>(state, parent);
573 if(!fid)
574 return;
575 dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
576 auto p = state.world.factory_get_province_from_factory_location(retrieve<dcon::factory_id>(state, parent));
577 auto p_fat = fatten(state.world, p);
578 auto sdef = state.world.abstract_state_membership_get_state(state.world.province_get_abstract_state_membership(p));
579 dcon::state_instance_id s{};
580 state.world.for_each_state_instance([&](dcon::state_instance_id id) {
581 if(state.world.state_instance_get_definition(id) == sdef)
582 s = id;
583 });
584
585 // nation data
586
587 float mobilization_impact = state.world.nation_get_is_mobilized(n) ? military::mobilization_impact(state, n) : 1.0f;
588 auto cap_prov = state.world.nation_get_capital(n);
589 auto cap_continent = state.world.province_get_continent(cap_prov);
590 auto cap_region = state.world.province_get_connected_region_id(cap_prov);
591
592
593 auto fac = fatten(state.world, fid);
594 auto type = state.world.factory_get_building_type(fid);
595
596 auto& inputs = type.get_inputs();
597 auto& einputs = type.get_efficiency_inputs();
598
599 //inputs
600
601 float input_total = economy::factory_input_total_cost(state, n, type);
602 float min_input_available = economy::factory_min_input_available(state, n, type);
603 float e_input_total = economy::factory_e_input_total_cost(state, n, type);
604 float min_e_input_available = economy::factory_min_e_input_available(state, n, type);
605
606 //modifiers
607
608 float input_multiplier = economy::factory_input_multiplier(state, fac, n, p, s);
609 float e_input_multiplier = state.world.nation_get_modifier_values(n, sys::national_mod_offsets::factory_maintenance) + 1.0f;
610 float throughput_multiplier = economy::factory_throughput_multiplier(state, type, n, p, s);
611 float output_multiplier = economy::factory_output_multiplier(state, fac, n, p);
612
613 float max_production_scale = economy::factory_max_production_scale(
614 state,
615 fac,
616 mobilization_impact,
617 p_fat.get_nation_from_province_control() != n
618 );
619
620 float effective_production_scale = std::min(fac.get_production_scale() * fac.get_level(), max_production_scale);
621
622 auto amount = (0.75f + 0.25f * min_e_input_available) * min_input_available * state.world.factory_get_production_scale(fid);
623
624 text::add_line(state, contents, "factory_stats_1", text::variable_type::val, text::fp_percentage{amount});
625
626 text::add_line(state, contents, "factory_stats_2", text::variable_type::val,
627 text::fp_percentage{state.world.factory_get_production_scale(fid)});
628
629 text::add_line(state, contents, "factory_stats_3", text::variable_type::val,
630 text::fp_one_place{state.world.factory_get_actual_production(fid) }, text::variable_type::x, type.get_output().get_name());
631
632 text::add_line(state, contents, "factory_stats_4", text::variable_type::val,
633 text::fp_currency{state.world.factory_get_full_profit(fid)});
634
636
637 text::add_line(state, contents, "factory_stats_5");
638
639
640 float total_expenses = 0.f;
641
642 int position_demand_sat = 100;
643 int position_amount = 180;
644 int position_cost = 250;
645
646 auto input_cost_line = [&] (
647 dcon::commodity_id cid,
648 float base_amount
649 ) {
650 auto box = text::open_layout_box(contents);
651 text::layout_box name_entry = box;
653 text::layout_box amount_box = box;
654 text::layout_box cost_box = box;
655
656 demand_satisfaction.x_position += position_demand_sat;
657 amount_box.x_position += position_amount;
658 cost_box.x_position += position_cost;
659
660 name_entry.x_size /= 10;
661 text::add_to_layout_box(state, contents, name_entry, state.world.commodity_get_name(cid));
662
663 auto sat = state.world.nation_get_demand_satisfaction(n, cid);
666 text::fp_percentage{ sat },
668 );
669
670 float amount =
671 base_amount
672 * input_multiplier
673 * throughput_multiplier
674 * min_input_available
675 * effective_production_scale;
676
677 float cost =
678 state.world.nation_get_effective_prices(n, cid)
679 * amount;
680
681 total_expenses += cost;
682
683 text::add_to_layout_box(state, contents, amount_box, text::fp_two_places{ amount });
685
686 text::add_to_layout_box(state, contents, box, std::string(" "));
687 text::close_layout_box(contents, box);
688 };
689
690 auto e_input_cost_line = [&](
691 dcon::commodity_id cid,
692 float base_amount
693 ) {
694 auto box = text::open_layout_box(contents);
695 text::layout_box name_entry = box;
697 text::layout_box amount_box = box;
698 text::layout_box cost_box = box;
699
700 demand_satisfaction.x_position += position_demand_sat;
701 amount_box.x_position += position_amount;
702 cost_box.x_position += position_cost;
703
704 name_entry.x_size /= 10;
705 text::add_to_layout_box(state, contents, name_entry, state.world.commodity_get_name(cid));
706
707 auto sat = state.world.nation_get_demand_satisfaction(n, cid);
710 text::fp_percentage{ sat },
712 );
713
714 float amount =
715 base_amount
716 * input_multiplier * e_input_multiplier
717 * min_e_input_available
718 * min_input_available
719 * effective_production_scale;
720
721 float cost =
722 state.world.nation_get_effective_prices(n, cid)
723 * amount;
724
725 total_expenses += cost;
726
727 text::add_to_layout_box(state, contents, amount_box, text::fp_two_places{ amount });
729
730 text::add_to_layout_box(state, contents, box, std::string(" "));
731 text::close_layout_box(contents, box);
732 };
733
734 auto named_money_line = [&](
735 std::string_view loc,
736 float value
737 ) {
738 auto box = text::open_layout_box(contents);
739 text::layout_box name_entry = box;
740 text::layout_box cost = box;
741
742 cost.x_position += position_cost;
743 name_entry.x_size /= 10;
744
745 text::localised_format_box(state, contents, name_entry, loc);
747
748 text::add_to_layout_box(state, contents, box, std::string(" "));
749 text::close_layout_box(contents, box);
750 };
751
752 auto output_cost_line = [&](
753 dcon::commodity_id cid,
754 float base_amount
755 ) {
756 auto box = text::open_layout_box(contents);
757 text::layout_box name_entry = box;
758 text::layout_box amount = box;
759 text::layout_box cost = box;
760
761 amount.x_position += position_amount;
762 cost.x_position += position_cost;
763
764 name_entry.x_size /= 10;
765 text::add_to_layout_box(state, contents, name_entry, state.world.commodity_get_name(cid));
766
767 float output_amount =
768 base_amount
769 * (0.75f + 0.25f * min_e_input_available)
770 * throughput_multiplier
771 * output_multiplier
772 * min_input_available
773 * effective_production_scale;
774
775 float output_cost =
776 state.world.nation_get_effective_prices(n, cid)
778
781
782 text::add_to_layout_box(state, contents, box, std::string(" "));
783 text::close_layout_box(contents, box);
784 };
785
786 for(uint32_t i = 0; i < economy::commodity_set::set_size; ++i) {
787 if(inputs.commodity_type[i]) {
788 input_cost_line(inputs.commodity_type[i], inputs.commodity_amounts[i]);
789 } else {
790 break;
791 }
792 }
793
795
796 text::add_line(state, contents, "factory_stats_6");
797
799 if(einputs.commodity_type[i]) {
800 e_input_cost_line(einputs.commodity_type[i], einputs.commodity_amounts[i]);
801 } else {
802 break;
803 }
804 }
805
807
808 auto const min_wage_factor = economy::pop_min_wage_factor(state, n);
809 float factory_min_wage = economy::pop_factory_min_wage(state, n, min_wage_factor);
810
811 float wage_estimation =
812 factory_min_wage
813 * state.defines.alice_factory_per_level_employment
814 / state.defines.alice_needs_scaling_factor
815 * effective_production_scale;
816
817 total_expenses += wage_estimation;
818
819 named_money_line("factory_stats_wage",
820 -wage_estimation
821 );
822
824
825 named_money_line("factory_stats_expenses",
826 -total_expenses
827 );
828
829 output_cost_line(type.get_output(), type.get_output_amount());
830
831 float desired_income = economy::factory_desired_raw_profit(fac, total_expenses);
832
833 named_money_line("factory_stats_desired_income",
834 desired_income
835 );
836 }
837};
838
840public:
841 dcon::commodity_id com{};
842
845 }
846
847 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
848 auto n = retrieve<dcon::nation_id>(state, parent);
849 auto p = state.world.factory_get_province_from_factory_location(retrieve<dcon::factory_id>(state, parent));
850 //auto com = retrieve<dcon::commodity_id>(state, parent);
851 if(!com)
852 return;
853
854 auto box = text::open_layout_box(contents, 0);
856 text::close_layout_box(contents, box);
857
858 auto commodity_mod_description = [&](float value, std::string_view locale_base_name, std::string_view locale_farm_base_name) {
859 if(value == 0.f)
860 return;
861 auto box = text::open_layout_box(contents, 0);
863 text::add_space_to_layout_box(state, contents, box);
864 text::add_to_layout_box(state, contents, box, text::produce_simple_string(state, state.world.commodity_get_is_mine(com) ? locale_base_name : locale_farm_base_name), text::text_color::white);
865 text::add_to_layout_box(state, contents, box, std::string{ ":" }, text::text_color::white);
866 text::add_space_to_layout_box(state, contents, box);
867 auto color = value > 0.f ? text::text_color::green : text::text_color::red;
868 text::add_to_layout_box(state, contents, box, (value > 0.f ? "+" : "") + text::format_percentage(value, 1), color);
869 text::close_layout_box(contents, box);
870 };
871 commodity_mod_description(state.world.nation_get_factory_goods_output(n, com), "tech_output", "tech_output");
872 commodity_mod_description(state.world.nation_get_rgo_goods_output(n, com), "tech_mine_output", "tech_farm_output");
873 commodity_mod_description(state.world.nation_get_rgo_size(n, com), "tech_mine_size", "tech_farm_size");
874 if(state.world.commodity_get_key_factory(com)) {
875 active_modifiers_description(state, contents, n, 0, sys::national_mod_offsets::factory_output, true);
876 active_modifiers_description(state, contents, p, 0, sys::provincial_mod_offsets::local_factory_output, true);
877 active_modifiers_description(state, contents, n, 0, sys::national_mod_offsets::factory_throughput, true);
878 active_modifiers_description(state, contents, p, 0, sys::provincial_mod_offsets::local_factory_throughput, true);
879 } else {
880 if(state.world.commodity_get_is_mine(com)) {
881 active_modifiers_description(state, contents, n, 0, sys::national_mod_offsets::mine_rgo_eff, true);
882 active_modifiers_description(state, contents, p, 0, sys::provincial_mod_offsets::mine_rgo_eff, true);
883 active_modifiers_description(state, contents, n, 0, sys::national_mod_offsets::mine_rgo_size, true);
884 active_modifiers_description(state, contents, p, 0, sys::provincial_mod_offsets::mine_rgo_size, true);
885 } else {
886 active_modifiers_description(state, contents, n, 0, sys::national_mod_offsets::farm_rgo_eff, true);
887 active_modifiers_description(state, contents, p, 0, sys::provincial_mod_offsets::farm_rgo_eff, true);
888 active_modifiers_description(state, contents, n, 0, sys::national_mod_offsets::farm_rgo_size, true);
889 active_modifiers_description(state, contents, p, 0, sys::provincial_mod_offsets::farm_rgo_size, true);
890 }
891 }
892 }
893
894 void render(sys::state& state, int32_t x, int32_t y) noexcept override {
895 if(com)
897 }
898};
899
901public:
902 void on_update(sys::state& state) noexcept override {
903 auto v = retrieve<economy::new_factory>(state, parent);
904 auto sid = retrieve<dcon::state_instance_id>(state, parent);
905 disabled = !command::can_cancel_factory_building_construction(state, state.local_player_nation, sid, v.type);
906 }
907 void button_action(sys::state& state) noexcept override {
908 auto v = retrieve<economy::new_factory>(state, parent);
909 auto sid = retrieve<dcon::state_instance_id>(state, parent);
910 command::cancel_factory_building_construction(state, state.local_player_nation, sid, v.type);
911 }
914 }
915 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
916 text::add_line(state, contents, "cancel_fac_construction");
917 }
918};
920public:
921 void on_update(sys::state& state) noexcept override {
922 auto v = retrieve<economy::upgraded_factory>(state, parent);
923 auto sid = retrieve<dcon::state_instance_id>(state, parent);
924 disabled = !command::can_cancel_factory_building_construction(state, state.local_player_nation, sid, v.type);
925 }
926 void button_action(sys::state& state) noexcept override {
927 auto v = retrieve<economy::upgraded_factory>(state, parent);
928 auto sid = retrieve<dcon::state_instance_id>(state, parent);
929 command::cancel_factory_building_construction(state, state.local_player_nation, sid, v.type);
930 }
933 }
934 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
935 text::add_line(state, contents, "cancel_fac_upgrade");
936 }
937};
938
941 image_element_base* input_lack_icons[economy::commodity_set::set_size] = {nullptr};
942 std::vector<element_base*> factory_elements;
943 std::vector<element_base*> upgrade_elements;
944 std::vector<element_base*> build_elements;
945 std::vector<element_base*> closed_elements;
946 dcon::commodity_id output_commodity;
947
948public:
949 uint8_t index = 0; // from 0 to int32_t(state.defines.factories_per_state)
950
951 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
952 if(name == "prod_factory_bg") {
953 return make_element_by_type<normal_factory_background>(state, id);
954 } else if(name == "level") {
955 auto ptr = make_element_by_type<factory_level_text>(state, id);
956 factory_elements.push_back(ptr.get());
957 return ptr;
958 } else if(name == "income") {
959 auto ptr = make_element_by_type<factory_profit_text>(state, id);
960 factory_elements.push_back(ptr.get());
961 return ptr;
962 } else if(name == "income_icon") {
963 auto ptr = make_element_by_type<factory_income_image>(state, id);
964 factory_elements.push_back(ptr.get());
965 return ptr;
966 } else if(name == "output") {
967 return make_element_by_type<commodity_image>(state, id);
968 } else if(name == "closed_overlay") {
969 return make_element_by_type<invisible_element>(state, id);
970 } else if(name == "factory_closed_text") {
971 return make_element_by_type<invisible_element>(state, id);
972 } else if(name == "prod_factory_inprogress_bg") {
973 auto ptr = make_element_by_type<image_element_base>(state, id);
974 build_elements.push_back(ptr.get());
975 return ptr;
976 } else if(name == "build_factory_progress") {
977 auto ptr = make_element_by_type<factory_build_progress_bar>(state, id);
978 build_elements.push_back(ptr.get());
979 return ptr;
980 } else if(name == "prod_cancel_progress") {
981 auto ptr = make_element_by_type<factory_cancel_new_const_button>(state, id);
982 build_elements.push_back(ptr.get());
983 return ptr;
984 } else if(name == "upgrade_factory_progress") {
985 auto ptr = make_element_by_type<factory_upgrade_progress_bar>(state, id);
986 upgrade_elements.push_back(ptr.get());
987 return ptr;
988 } else if(name == "progress_overlay_16_64") {
989 auto ptr = make_element_by_type<image_element_base>(state, id);
990 upgrade_elements.push_back(ptr.get());
991 return ptr;
992 } else if(name == "employment_ratio") {
993 auto ptr = make_element_by_type<factory_employment_image>(state, id);
994 factory_elements.push_back(ptr.get());
995 return ptr;
996 } else if(name == "priority") {
997 auto ptr = make_element_by_type<factory_priority_button>(state, id);
998 factory_elements.push_back(ptr.get());
999 return ptr;
1000 } else if(name == "upgrade") {
1001 auto ptr = make_element_by_type<factory_upgrade_button>(state, id);
1002 factory_elements.push_back(ptr.get());
1003 return ptr;
1004 } else if(name == "subsidise") {
1005 auto ptr = make_element_by_type<factory_subsidise_button>(state, id);
1006 factory_elements.push_back(ptr.get());
1007 return ptr;
1008 } else if(name == "delete_factory") {
1009 auto ptr = make_element_by_type<factory_delete_button>(state, id);
1010 closed_elements.push_back(ptr.get());
1011 return ptr;
1012 } else if(name == "open_close") {
1013 auto ptr = make_element_by_type<factory_reopen_button>(state, id);
1014 closed_elements.push_back(ptr.get());
1015 auto ptrb = make_element_by_type<factory_close_and_delete_button>(state, id);
1016 factory_elements.push_back(ptrb.get());
1017 add_child_to_front(std::move(ptrb));
1018 return ptr;
1019 } else if(name.substr(0, 6) == "input_") {
1020 auto input_index = size_t(std::stoi(std::string(name.substr(6))));
1021 if(name.ends_with("_lack2")) {
1022 auto ptr = make_element_by_type<image_element_base>(state, id);
1023 input_lack_icons[input_index] = ptr.get();
1024 return ptr;
1025 } else {
1026 auto ptr = make_element_by_type<factory_input_icon>(state, id);
1027 input_icons[input_index] = static_cast<factory_input_icon*>(ptr.get());
1028 return ptr;
1029 }
1030 } else {
1031 return nullptr;
1032 }
1033 }
1034
1035 void on_update(sys::state& state) noexcept override {
1036 if(parent) {
1037 Cyto::Any payload = production_factory_slot_data{{dcon::factory_id{}, std::monostate{}}, index};
1038 parent->impl_get(state, payload);
1039 auto content = any_cast<production_factory_slot_data>(payload);
1040
1041 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
1042 dcon::factory_type_fat_id fat_btid(state.world, dcon::factory_type_id{});
1043 if(std::holds_alternative<economy::new_factory>(content.activity)) {
1044 // New factory
1045 economy::new_factory nf = std::get<economy::new_factory>(content.activity);
1046 fat_btid = dcon::fatten(state.world, nf.type);
1047
1048 for(auto const& e : factory_elements)
1049 e->set_visible(state, false);
1050 for(auto const& e : upgrade_elements)
1051 e->set_visible(state, false);
1052 for(auto const& e : build_elements)
1053 e->set_visible(state, true);
1054 for(auto const& e : closed_elements)
1055 e->set_visible(state, false);
1056 } else if(std::holds_alternative<economy::upgraded_factory>(content.activity)) {
1057 // Upgrade
1058 economy::upgraded_factory uf = std::get<economy::upgraded_factory>(content.activity);
1059 fat_btid = dcon::fatten(state.world, uf.type);
1060
1061 for(auto const& e : factory_elements)
1062 e->set_visible(state, true);
1063 for(auto const& e : upgrade_elements)
1064 e->set_visible(state, true);
1065 for(auto const& e : build_elements)
1066 e->set_visible(state, false);
1067 for(auto const& e : closed_elements)
1068 e->set_visible(state, false);
1069 } else {
1070 // "Normal" factory, not being upgraded or built
1071 dcon::factory_id fid = content.id;
1072 fat_btid = state.world.factory_get_building_type(fid);
1073
1074 bool is_closed = dcon::fatten(state.world, fid).get_production_scale() < economy::factory_closed_threshold;
1075 for(auto const& e : factory_elements)
1076 e->set_visible(state, true);
1077 for(auto const& e : upgrade_elements)
1078 e->set_visible(state, false);
1079 for(auto const& e : build_elements)
1080 e->set_visible(state, false);
1081 for(auto const& e : closed_elements)
1082 e->set_visible(state, is_closed);
1083 }
1084
1085 auto& cset = fat_btid.get_inputs();
1086 for(uint32_t i = 0; i < economy::commodity_set::set_size; ++i) {
1087 if(input_icons[size_t(i)]) {
1088 dcon::commodity_id cid = cset.commodity_type[size_t(i)];
1089 input_icons[size_t(i)]->frame = int32_t(state.world.commodity_get_icon(cid));
1090 input_icons[size_t(i)]->com = cid;
1091 bool is_lack = cid != dcon::commodity_id{} ? state.world.nation_get_demand_satisfaction(n, cid) < 0.5f : false;
1092 input_lack_icons[size_t(i)]->set_visible(state, is_lack);
1093 }
1094 }
1095 output_commodity = fat_btid.get_output().id;
1096 }
1097 }
1098
1099 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
1100 if(parent) {
1101 Cyto::Any p_payload = production_factory_slot_data{{dcon::factory_id{}, std::monostate{}}, index};
1102 parent->impl_get(state, p_payload);
1103 auto content = any_cast<production_factory_slot_data>(p_payload);
1104 if(payload.holds_type<dcon::factory_id>()) {
1105 payload.emplace<dcon::factory_id>(content.id);
1107 } else if(payload.holds_type<economy::upgraded_factory>()) {
1108 if(std::holds_alternative<economy::upgraded_factory>(content.activity))
1109 payload.emplace<economy::upgraded_factory>(std::get<economy::upgraded_factory>(content.activity));
1111 } else if(payload.holds_type<economy::new_factory>()) {
1112 if(std::holds_alternative<economy::new_factory>(content.activity))
1113 payload.emplace<economy::new_factory>(std::get<economy::new_factory>(content.activity));
1115 } else if(payload.holds_type<dcon::commodity_id>()) {
1116 payload.emplace<dcon::commodity_id>(output_commodity);
1118 } else if(payload.holds_type<dcon::province_id>()) {
1119 payload.emplace<dcon::province_id>(state.world.factory_get_province_from_factory_location(content.id));
1121 }
1122 }
1124 }
1125};
1126
1127
1128
1130 std::vector<element_base*> infos;
1131 std::vector<state_factory_slot> factories;
1132
1133 bool get_filter(sys::state& state, dcon::commodity_id cid) {
1134 Cyto::Any payload = commodity_filter_query_data{cid, false};
1135 parent->impl_get(state, payload);
1136 auto content = any_cast<commodity_filter_query_data>(payload);
1137 return content.filter;
1138 }
1139
1140public:
1141 void on_create(sys::state& state) noexcept override {
1143 factories.resize(size_t(state.defines.factories_per_state));
1144 xy_pair vert_bound{ 0, 0 };
1145 int16_t num_cols = 8;
1146 // Create factory slots for each of the provinces
1147 for(int16_t factory_index = 0; factory_index < int16_t(state.defines.factories_per_state); ++factory_index) {
1148 auto ptr = make_element_by_type<production_factory_info>(state,
1149 state.ui_state.defs_by_name.find(state.lookup_key("factory_info"))->second.definition);
1150 ptr->index = uint8_t(factory_index);
1151 ptr->base_data.position.x = (factory_index % num_cols) * ptr->base_data.size.x;
1152 ptr->base_data.position.y += std::max<int16_t>(0, (factory_index / num_cols) * (ptr->base_data.size.y - 26));
1153 infos.push_back(ptr.get());
1154 add_child_to_front(std::move(ptr));
1155 }
1156 base_data.size.y += state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("factory_info"))->second.definition].size.y
1157 * ((int16_t(state.defines.factories_per_state) + num_cols - 1) / num_cols);
1158 }
1159
1160 void on_update(sys::state& state) noexcept override {
1161 auto state_id = retrieve<dcon::state_instance_id>(state, parent);
1162
1163 for(auto const c : infos)
1164 c->set_visible(state, false);
1165
1166 std::vector<bool> visited_types(state.world.factory_type_size(), false);
1167 size_t index = 0;
1168 // First, the new factories are taken into account
1169 economy::for_each_new_factory(state, state_id, [&](economy::new_factory const& nf) {
1170 dcon::commodity_id cid = state.world.factory_type_get_output(nf.type).id;
1171 if(!visited_types[nf.type.index()] && get_filter(state, cid) && index < state.defines.factories_per_state) {
1172 factories[index].activity = nf;
1173 factories[index].id = dcon::factory_id{};
1174 visited_types[nf.type.index()] = true;
1175 infos[index]->set_visible(state, true);
1176 ++index;
1177 }
1178 });
1179 // Then, the factories being upgraded
1181 dcon::commodity_id cid = state.world.factory_type_get_output(uf.type).id;
1182 if(!visited_types[uf.type.index()] && get_filter(state, cid) && index < state.defines.factories_per_state) {
1183 factories[index].activity = uf;
1184 province::for_each_province_in_state_instance(state, state_id, [&](dcon::province_id prov) {
1185 for(auto fa : state.world.province_get_factory_location(prov)) {
1186 if(fa.get_factory().get_building_type() == uf.type) {
1187 factories[index].id = fa.get_factory().id;
1188 }
1189 }
1190 });
1191
1192 visited_types[uf.type.index()] = true;
1193 infos[index]->set_visible(state, true);
1194 ++index;
1195 }
1196 });
1197 // Finally, factories "doing nothing" are accounted for
1198 province::for_each_province_in_state_instance(state, state_id, [&](dcon::province_id pid) {
1199 dcon::fatten(state.world, pid).for_each_factory_location_as_province([&](dcon::factory_location_id flid) {
1200 dcon::factory_id fid = state.world.factory_location_get_factory(flid);
1201 dcon::factory_type_id ftid = state.world.factory_get_building_type(fid);
1202 dcon::commodity_id cid = state.world.factory_type_get_output(ftid).id;
1203 if(!visited_types[ftid.index()] && get_filter(state, cid) && index < state.defines.factories_per_state) {
1204 factories[index].activity = std::monostate{};
1205 factories[index].id = fid;
1206 infos[index]->set_visible(state, true);
1207 ++index;
1208 }
1209 });
1210 });
1211 }
1212
1213 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
1214 if(payload.holds_type<production_factory_slot_data>()) {
1215 auto content = any_cast<production_factory_slot_data>(payload);
1216 auto index = content.index;
1217 static_cast<state_factory_slot&>(content) = factories[index];
1218 content.index = index;
1219 payload.emplace<production_factory_slot_data>(content);
1220 return message_result::consumed;
1221 }
1222 return message_result::unseen;
1223 }
1224};
1225
1227public:
1228 void on_update(sys::state& state) noexcept override {
1229 const dcon::province_id pid = retrieve<dcon::province_id>(state, parent);
1230 const dcon::state_instance_id sid = state.world.province_get_state_membership(pid);
1231 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
1232
1233 bool can_build = false;
1234 state.world.for_each_factory_type([&](dcon::factory_type_id ftid) {
1235 can_build =
1236 can_build || command::can_begin_factory_building_construction(state, state.local_player_nation, sid, ftid, false);
1237 });
1238 disabled = !can_build;
1239 }
1240
1241 void button_action(sys::state& state) noexcept override {
1242 if(parent) {
1243 const dcon::province_id pid = retrieve<dcon::province_id>(state, parent);
1244 const dcon::state_instance_id sid = state.world.province_get_state_membership(pid);
1246 state.ui_state.root->move_child_to_front(state.ui_state.production_subwindow);
1248 send(state, state.ui_state.production_subwindow, production_window_tab::factories);
1249 send(state, state.ui_state.production_subwindow, production_selection_wrapper{ sid, true, xy_pair{0, 0} });
1250 }
1251 }
1252
1254 return tooltip_behavior::variable_tooltip;
1255 }
1256
1257 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1258 const dcon::province_id pid = retrieve<dcon::province_id>(state, parent);
1259 const dcon::state_instance_id sid = state.world.province_get_state_membership(pid);
1260 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
1261
1262 bool non_colonial = !state.world.province_get_is_colonial(state.world.state_instance_get_capital(sid));
1263
1264 bool is_civilized = state.world.nation_get_is_civilized(n);
1265 int32_t num_factories = economy::state_factory_count(state, sid, n);
1266
1267 text::add_line(state, contents, "production_build_new_factory_tooltip");
1269 text::add_line_with_condition(state, contents, "factory_condition_1", is_civilized);
1270 text::add_line_with_condition(state, contents, "factory_condition_2", non_colonial);
1271
1272 if(n == state.local_player_nation) {
1273 auto rules = state.world.nation_get_combined_issue_rules(n);
1274 text::add_line_with_condition(state, contents, "factory_condition_3", (rules & issue_rule::build_factory) != 0);
1275 } else {
1276 text::add_line_with_condition(state, contents, "factory_upgrade_condition_4", state.world.nation_get_is_great_power(state.local_player_nation) && !state.world.nation_get_is_great_power(n));
1277
1278 text::add_line_with_condition(state, contents, "factory_upgrade_condition_5", state.world.nation_get_is_civilized(n));
1279
1280 auto target = state.world.nation_get_combined_issue_rules(n);
1281 text::add_line_with_condition(state, contents, "factory_upgrade_condition_6",
1282 (target & issue_rule::allow_foreign_investment) != 0);
1283
1284 text::add_line_with_condition(state, contents, "factory_upgrade_condition_7", !military::are_at_war(state, state.local_player_nation, n));
1285 }
1286
1287 {
1288 auto box = text::open_layout_box(contents);
1289 auto r = num_factories < int32_t(state.defines.factories_per_state);
1290 if(r) {
1292 } else {
1294 }
1295 text::add_space_to_layout_box(state, contents, box);
1296 text::localised_single_sub_box(state, contents, box, "factory_condition_4", text::variable_type::val, int64_t(state.defines.factories_per_state));
1297 text::close_layout_box(contents, box);
1298 }
1299 }
1300};
1301
1303public:
1304 void on_update(sys::state& state) noexcept override {
1305 const dcon::state_instance_id sid = retrieve<dcon::state_instance_id>(state, parent);
1306 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
1307
1308 bool can_build = false;
1309 state.world.for_each_factory_type([&](dcon::factory_type_id ftid) {
1310 can_build =
1311 can_build || command::can_begin_factory_building_construction(state, state.local_player_nation, sid, ftid, false);
1312 });
1313 disabled = !can_build;
1314 }
1315
1316 void button_action(sys::state& state) noexcept override {
1317 if(parent) {
1318 dcon::state_instance_id sid = retrieve<dcon::state_instance_id>(state, parent);
1319 send(state, parent, production_selection_wrapper{sid, true, xy_pair{0, 0}});
1320 }
1321 }
1322
1324 return tooltip_behavior::variable_tooltip;
1325 }
1326
1327 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1328 const dcon::state_instance_id sid = retrieve<dcon::state_instance_id>(state, parent);
1329 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
1330
1331 bool non_colonial = !state.world.province_get_is_colonial(state.world.state_instance_get_capital(sid));
1332
1333 bool is_civilized = state.world.nation_get_is_civilized(n);
1334 int32_t num_factories = economy::state_factory_count(state, sid, n);
1335
1336 text::add_line(state, contents, "production_build_new_factory_tooltip");
1338 text::add_line_with_condition(state, contents, "factory_condition_1", is_civilized);
1339 text::add_line_with_condition(state, contents, "factory_condition_2", non_colonial);
1340
1341 if(n == state.local_player_nation) {
1342 auto rules = state.world.nation_get_combined_issue_rules(n);
1343 text::add_line_with_condition(state, contents, "factory_condition_3", (rules & issue_rule::build_factory) != 0);
1344 } else {
1345 text::add_line_with_condition(state, contents, "factory_upgrade_condition_4", state.world.nation_get_is_great_power(state.local_player_nation) && !state.world.nation_get_is_great_power(n));
1346
1347 text::add_line_with_condition(state, contents, "factory_upgrade_condition_5", state.world.nation_get_is_civilized(n));
1348
1349 auto target = state.world.nation_get_combined_issue_rules(n);
1350 text::add_line_with_condition(state, contents, "factory_upgrade_condition_6",
1351 (target & issue_rule::allow_foreign_investment) != 0);
1352
1353 text::add_line_with_condition(state, contents, "factory_upgrade_condition_7", !military::are_at_war(state, state.local_player_nation, n));
1354 }
1355
1356 {
1357 auto box = text::open_layout_box(contents);
1358 auto r = num_factories < int32_t(state.defines.factories_per_state);
1359 if(r) {
1361 } else {
1363 }
1364 text::add_space_to_layout_box(state, contents, box);
1365 text::localised_single_sub_box(state, contents, box, "factory_condition_4", text::variable_type::val, int64_t(state.defines.factories_per_state));
1366 text::close_layout_box(contents, box);
1367 }
1368 }
1369};
1370
1372 int32_t get_icon_frame(sys::state& state) noexcept {
1373 auto content = retrieve<dcon::state_instance_id>(state, parent);
1374 return bool(state.world.state_instance_get_owner_focus(content).id)
1375 ? state.world.state_instance_get_owner_focus(content).get_icon() - 1
1376 : 0;
1377 }
1378
1379public:
1380 void on_update(sys::state& state) noexcept override {
1381 auto content = retrieve<dcon::state_instance_id>(state, parent);
1382 dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
1383 disabled = true;
1384 for(auto nfid : state.world.in_national_focus) {
1385 disabled = command::can_set_national_focus(state, state.local_player_nation, content, nfid) ? false : disabled;
1386 }
1387 frame = get_icon_frame(state);
1388 }
1389
1390 void button_action(sys::state& state) noexcept override {
1391 auto sid = retrieve<dcon::state_instance_id>(state, parent);
1392 send(state, parent, production_selection_wrapper{sid, false, base_data.position});
1393 }
1394
1395 void button_right_action(sys::state& state) noexcept override {
1396 auto sid = retrieve<dcon::state_instance_id>(state, parent);
1397 command::set_national_focus(state, state.local_player_nation, sid, dcon::national_focus_id{});
1398 }
1399
1401 return tooltip_behavior::variable_tooltip;
1402 }
1403
1404 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1405 auto box = text::open_layout_box(contents, 0);
1406
1407 auto sid = retrieve<dcon::state_instance_id>(state, parent);
1408 auto fat_si = dcon::fatten(state.world, sid);
1409 text::add_to_layout_box(state, contents, box, sid);
1411 auto content = state.world.state_instance_get_owner_focus(sid);
1412 if(bool(content)) {
1413 auto fat_nf = dcon::fatten(state.world, content);
1414 text::add_to_layout_box(state, contents, box, state.world.national_focus_get_name(content), text::substitution_map{});
1416 auto color = text::text_color::white;
1417 if(fat_nf.get_promotion_type()) {
1418 //Is the NF not optimal? Recolor it
1419 if(fat_nf.get_promotion_type() == state.culture_definitions.clergy) {
1420 if((fat_si.get_demographics(demographics::to_key(state, fat_nf.get_promotion_type())) / fat_si.get_demographics(demographics::total)) > state.defines.max_clergy_for_literacy) {
1421 color = text::text_color::red;
1422 }
1423 } else if(fat_nf.get_promotion_type() == state.culture_definitions.bureaucrat) {
1424 if(province::state_admin_efficiency(state, fat_si.id) > state.defines.max_bureaucracy_percentage) {
1425 color = text::text_color::red;
1426 }
1427 }
1428 auto full_str = text::format_percentage(fat_si.get_demographics(demographics::to_key(state, fat_nf.get_promotion_type())) / fat_si.get_demographics(demographics::total));
1429 text::add_to_layout_box(state, contents, box, std::string_view(full_str), color);
1430 }
1431 }
1432 text::close_layout_box(contents, box);
1433 if(auto mid = state.world.national_focus_get_modifier(content); mid) {
1434 modifier_description(state, contents, mid, 15);
1435 }
1436 text::add_line(state, contents, "alice_nf_controls");
1437 }
1438};
1439
1441 void on_update(sys::state& state) noexcept override {
1442 auto content = retrieve<dcon::state_instance_id>(state, parent);
1443 auto total = state.world.state_instance_get_demographics(content, demographics::to_key(state, state.culture_definitions.primary_factory_worker));
1444 auto employed = state.world.state_instance_get_demographics(content, demographics::to_employment_key(state, state.culture_definitions.primary_factory_worker));
1445 auto unemployed = total - employed;
1446 set_text(state, text::prettify(int64_t(unemployed)) + "/" + text::prettify(int64_t(employed)));
1447 }
1448 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
1449 return tooltip_behavior::variable_tooltip;
1450 }
1451 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1452 auto content = retrieve<dcon::state_instance_id>(state, parent);
1453 auto total = state.world.state_instance_get_demographics(content, demographics::to_key(state, state.culture_definitions.primary_factory_worker));
1454 auto employed = state.world.state_instance_get_demographics(content, demographics::to_employment_key(state, state.culture_definitions.primary_factory_worker));
1455 auto unemployed = total - employed;
1456 text::add_line(state, contents, "alice_factory_worker_1", text::variable_type::x, text::pretty_integer{ int32_t(employed) });
1457 text::add_line(state, contents, "alice_factory_worker_2", text::variable_type::x, text::pretty_integer{ int32_t(unemployed) });
1458 }
1459};
1460
1462 void on_update(sys::state& state) noexcept override {
1463 auto content = retrieve<dcon::state_instance_id>(state, parent);
1464 auto total = state.world.state_instance_get_demographics(content, demographics::to_key(state, state.culture_definitions.secondary_factory_worker));
1465 auto employed = state.world.state_instance_get_demographics(content, demographics::to_employment_key(state, state.culture_definitions.secondary_factory_worker));
1466 auto unemployed = total - employed;
1467 set_text(state, text::prettify(int64_t(unemployed)) + "/" + text::prettify(int64_t(employed)));
1468 }
1469 tooltip_behavior has_tooltip(sys::state& state) noexcept override {
1470 return tooltip_behavior::variable_tooltip;
1471 }
1472 void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override {
1473 auto content = retrieve<dcon::state_instance_id>(state, parent);
1474 auto total = state.world.state_instance_get_demographics(content, demographics::to_key(state, state.culture_definitions.secondary_factory_worker));
1475 auto employed = state.world.state_instance_get_demographics(content, demographics::to_employment_key(state, state.culture_definitions.secondary_factory_worker));
1476 auto unemployed = total - employed;
1477 text::add_line(state, contents, "alice_factory_worker_1", text::variable_type::x, text::pretty_integer{ int32_t(employed) });
1478 text::add_line(state, contents, "alice_factory_worker_2", text::variable_type::x, text::pretty_integer{ int32_t(unemployed) });
1479 }
1480};
1481
1483 void on_update(sys::state& state) noexcept override {
1484 auto content = retrieve<dcon::state_instance_id>(state, parent);
1485 auto total = state.world.state_instance_get_demographics(content,
1487 if(total > 0)
1489 state.world.state_instance_get_demographics(content, demographics::to_key(state, state.culture_definitions.capitalists)) / total,
1490 1));
1491 else
1492 set_text(state, "0.0%");
1493 }
1494};
1495
1496
1498 void on_update(sys::state& state) noexcept override {
1499 auto content = retrieve<dcon::state_instance_id>(state, parent);
1500 float total = 0.0f;
1501 float p_total = 0.0f;
1502 province::for_each_province_in_state_instance(state, content, [&](dcon::province_id p) {
1503 total += state.economy_definitions.building_definitions[int32_t(economy::province_building_type::railroad)].infrastructure * float(state.world.province_get_building_level(p, uint8_t(economy::province_building_type::railroad)));
1504 p_total += 1.0f;
1505 });
1506 set_text(state, text::format_float(p_total > 0 ? total / p_total : 0.0f, 3));
1507 }
1508};
1509
1510class production_state_info : public listbox_row_element_base<dcon::state_instance_id> {
1511public:
1513 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1514 if(name == "state_focus") {
1515 return make_element_by_type<production_national_focus_button>(state, id);
1516 } else if(name == "state_name") {
1517 return make_element_by_type<state_name_text>(state, id);
1518 } else if(name == "factory_count") {
1519 auto temp = make_element_by_type<state_factory_count_text>(state, id);
1520 memcpy(&factory_number_def, &(temp->base_data), sizeof(ui::element_data));
1521 return temp;
1522 } else if(name == "build_new_factory") {
1523 return make_element_by_type<production_build_new_factory>(state, id);
1524 } else if(name == "avg_infra_text") {
1525 return make_element_by_type<state_infrastructure>(state, id);
1526 } else if(name == "factory_info_bounds") {
1527 return make_element_by_type<production_factory_info_bounds_window>(state, id);
1528 } else {
1529 return nullptr;
1530 }
1531 }
1532 void on_create(sys::state& state) noexcept override {
1534 constexpr int16_t num_cols = 8;
1535 base_data.size.y += state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("factory_info"))->second.definition].size.y
1536 * (((int16_t(state.defines.factories_per_state) + num_cols - 1) / num_cols) - 1);
1537 // (8 + 7 - 1) - 1 = (8 + 6) - 1 = (14 / 8) - 1 ~= 1.75 rundown 1 - 1 = 0, ok
1538
1539 xy_pair base_sort_template_offset =
1540 state.ui_defs.gui[state.ui_state.defs_by_name.find(state.lookup_key("sort_by_pop_template_offset"))->second.definition].position;
1541
1542 {
1543 auto text_elm = std::make_unique< per_state_primary_worker_amount>();
1544 memcpy(&(text_elm->base_data), &factory_number_def, sizeof(ui::element_data));
1545 text_elm->base_data.position.x = int16_t(500 + base_sort_template_offset.x * 0);
1546 text_elm->on_create(state);
1547 add_child_to_front(std::move(text_elm));
1548 }
1549 {
1550 auto text_elm = std::make_unique< per_state_secondary_worker_amount>();
1551 memcpy(&(text_elm->base_data), &factory_number_def, sizeof(ui::element_data));
1552 text_elm->base_data.position.x = int16_t(500 + base_sort_template_offset.x * 1);
1553 text_elm->on_create(state);
1554 add_child_to_front(std::move(text_elm));
1555 }
1556 {
1557 auto text_elm = std::make_unique< per_state_capitalist_amount>();
1558 memcpy(&(text_elm->base_data), &factory_number_def, sizeof(ui::element_data));
1559 text_elm->base_data.position.x = int16_t(500 + base_sort_template_offset.x * 2);
1560 text_elm->on_create(state);
1561 add_child_to_front(std::move(text_elm));
1562 }
1563 }
1564};
1565
1566void populate_production_states_list(sys::state& state, std::vector<dcon::state_instance_id>& row_contents, dcon::nation_id n, bool show_empty, production_sort_order sort_order);
1567
1569 dcon::nation_id n;
1570};
1571
1572class production_state_invest_listbox : public listbox_element_base<production_state_info, dcon::state_instance_id> {
1573protected:
1574 std::string_view get_row_element_name() override {
1575 return "state_info";
1576 }
1577
1578public:
1579 production_sort_order sort_order = production_sort_order::name;
1580
1581 void on_update(sys::state& state) noexcept override {
1582 row_contents.clear();
1583 if(parent) {
1584 auto show_empty = retrieve<bool>(state, parent);
1585 dcon::nation_id n = retrieve<production_foreign_invest_target>(state, parent).n;
1586
1587 populate_production_states_list(state, row_contents, n, show_empty, sort_order);
1588 }
1589 update(state);
1590 }
1591
1592 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
1593 if(payload.holds_type<dcon::nation_id>()) {
1594 payload.emplace<dcon::nation_id>(retrieve<production_foreign_invest_target>(state, parent).n);
1595 return message_result::consumed;
1596 }
1597 return message_result::unseen;
1598 }
1599};
1600
1601class production_state_listbox : public listbox_element_base<production_state_info, dcon::state_instance_id> {
1602protected:
1603 std::string_view get_row_element_name() override {
1604 return "state_info";
1605 }
1606
1607public:
1608 production_sort_order sort_order = production_sort_order::name;
1609
1610 void on_update(sys::state& state) noexcept override {
1611 row_contents.clear();
1612 if(parent) {
1613 auto show_empty = retrieve<bool>(state, parent);
1614 const dcon::nation_id n = retrieve<dcon::nation_id>(state, parent);
1615 populate_production_states_list(state, row_contents, n, show_empty, sort_order);
1616 }
1617 update(state);
1618 }
1619};
1620
1622 simple_text_element_base* goods_cat_name = nullptr;
1623
1624 std::string_view get_commodity_group_name(sys::commodity_group g) {
1625 switch(g) {
1627 return "military_goods";
1629 return "raw_material_goods";
1631 return "industrial_goods";
1633 return "consumer_goods";
1634 // Non-vanilla
1636 return "industrial_and_consumer_goods";
1637 default:
1638 return "???";
1639 }
1640 }
1641
1642public:
1643 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1644 if(name == "cat_name") {
1645 auto ptr = make_element_by_type<simple_text_element_base>(state, id);
1646 goods_cat_name = ptr.get();
1647 return ptr;
1648 } else {
1649 return nullptr;
1650 }
1651 }
1652
1653 message_result set(sys::state& state, Cyto::Any& payload) noexcept override {
1654 if(payload.holds_type<sys::commodity_group>()) {
1655 auto group = any_cast<sys::commodity_group>(payload);
1656 goods_cat_name->set_text(state, text::produce_simple_string(state, get_commodity_group_name(group)));
1657 return message_result::consumed;
1658 }
1659 return message_result::unseen;
1660 }
1661};
1662
1664 void on_update(sys::state& state) noexcept override {
1665 auto content = retrieve<dcon::commodity_id>(state, parent);
1667
1668 float total = 0.0f;
1669
1670 auto nation = dcon::fatten(state.world, state.local_player_nation);
1671
1672 switch (commodity_type) {
1675 for(auto province_ownership : state.world.nation_get_province_ownership(nation)) {
1676 auto province = province_ownership.get_province();
1677 total += state.world.province_get_rgo_employment(province);
1678 }
1679 break;
1680
1681
1683 total += economy::get_artisan_distribution_slow(state, nation, content) * nation.get_demographics(demographics::to_key(state, state.culture_definitions.artisans));
1684 for(auto province_ownership : state.world.nation_get_province_ownership(nation)) {
1685 auto province = province_ownership.get_province();
1686 for(auto fac : province.get_factory_location()) {
1687 if(fac.get_factory().get_building_type().get_output() == content) {
1688 total += economy::factory_primary_employment(state, fac.get_factory());
1689 }
1690 }
1691 }
1692 break;
1693 default:
1694 break;
1695
1696 }
1697
1698
1699 set_text(state, text::prettify(int64_t(total)));
1700 }
1701};
1702
1704 void on_update(sys::state& state) noexcept override {
1705 auto content = retrieve<dcon::commodity_id>(state, parent);
1707
1708 float total = 0.0f;
1709
1710 auto nation = dcon::fatten(state.world, state.local_player_nation);
1711 switch(commodity_type) {
1713 break;
1714
1716 for(auto province_ownership : state.world.nation_get_province_ownership(nation)) {
1717 auto province = province_ownership.get_province();
1718 for(auto fac : province.get_factory_location()) {
1719 if(fac.get_factory().get_building_type().get_output() == content) {
1720 total += economy::factory_secondary_employment(state, fac.get_factory());
1721 }
1722 }
1723 }
1724 break;
1725
1727 total += nation.get_artisan_distribution(content) * nation.get_demographics(demographics::to_key(state, state.culture_definitions.artisans));
1728 for(auto province_ownership : state.world.nation_get_province_ownership(nation)) {
1729 auto province = province_ownership.get_province();
1730 for(auto fac : province.get_factory_location()) {
1731 if(fac.get_factory().get_building_type().get_output() == content) {
1732 total += economy::factory_primary_employment(state, fac.get_factory()) + economy::factory_secondary_employment(state, fac.get_factory());
1733 }
1734 }
1735 }
1736 break;
1737 }
1738
1739
1740 set_text(state, text::prettify(int64_t(total)));
1741 }
1742};
1743
1745public:
1746 void on_update(sys::state& state) noexcept override {
1747 auto commodity_id = retrieve<dcon::commodity_id>(state, parent);
1748 if(commodity_id)
1749 set_text(state, text::format_float(state.world.nation_get_domestic_market_pool(state.local_player_nation, commodity_id), 1));
1750 }
1751};
1752
1754 commodity_player_production_text* good_output_total = nullptr;
1755 image_element_base* good_not_producing_overlay = nullptr;
1756
1757public:
1758 dcon::commodity_id commodity_id;
1759
1760 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
1761 if(name == "output_factory") {
1762 return make_element_by_type<commodity_image>(state, id);
1763 } else if(name == "output_total") {
1764 auto ptr = make_element_by_type<commodity_player_production_text>(state, id);
1765 good_output_total = ptr.get();
1766 return ptr;
1767 } else if(name == "prod_producing_not_total") {
1768 auto ptr = make_element_by_type<image_element_base>(state, id);
1769 good_not_producing_overlay = ptr.get();
1770 return ptr;
1771 } else if(name == "pop_factory") {
1772 auto ptr = make_element_by_type<image_element_base>(state, id);
1773 ptr->frame = int32_t(dcon::fatten(state.world, state.culture_definitions.primary_factory_worker).get_sprite() - 1);
1774 return ptr;
1775 } else if(name == "pop_factory2") {
1776 auto ptr = make_element_by_type<image_element_base>(state, id);
1777 ptr->frame = int32_t(dcon::fatten(state.world, state.culture_definitions.secondary_factory_worker).get_sprite() - 1);
1778 return ptr;
1779 } else if(name == "output") {
1780 return make_element_by_type<commodity_primary_worker_amount>(state, id);
1781 } else if(name == "output2") {
1782 return make_element_by_type<commodity_secondary_worker_amount>(state, id);
1783 } else {
1784 return nullptr;
1785 }
1786 }
1787
1788 void on_update(sys::state& state) noexcept override {
1789 bool is_producing = economy::commodity_daily_production_amount(state, commodity_id) > 0.f;
1790 // Display red-overlay if not producing
1791 good_not_producing_overlay->set_visible(state, !is_producing);
1792 good_output_total->set_visible(state, is_producing);
1793 }
1794
1795 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
1796 if(payload.holds_type<dcon::commodity_id>()) {
1797 payload.emplace<dcon::commodity_id>(commodity_id);
1798 return message_result::consumed;
1799 }
1800 return message_result::unseen;
1801 }
1802};
1803
1805 dcon::nation_id id;
1806};
1807
1809 .sortable = true,
1810 .header = "method_name",
1811 .compare = [](sys::state& state, element_base* container, dcon::factory_type_id a, dcon::factory_type_id b) {
1812 auto av = text::produce_simple_string(state, state.world.factory_type_get_name(a));
1813 auto bv = text::produce_simple_string(state, state.world.factory_type_get_name(b));
1814 if(av != bv)
1815 return av > bv;
1816 else
1817 return a.index() < b.index();
1818 },
1819 .view = [](sys::state& state, element_base* container, dcon::factory_type_id id) {
1820 auto value = text::produce_simple_string(state, state.world.factory_type_get_name(id));
1821 return value;
1822 },
1823 .cell_definition_string = "thin_cell_name",
1824 .header_definition_string = "thin_cell_name"
1825};
1826
1828 .sortable = true,
1829 .header = "method_input",
1830 .compare = [](sys::state& state, element_base* container, dcon::factory_type_id a, dcon::factory_type_id b) {
1831 auto av = economy::factory_type_input_cost(state, state.local_player_nation, a);
1832 auto bv = economy::factory_type_input_cost(state, state.local_player_nation, b);
1833 if(av != bv)
1834 return av > bv;
1835 else
1836 return a.index() < b.index();
1837 },
1838 .view = [](sys::state& state, element_base* container, dcon::factory_type_id id) {
1839 auto value = economy::factory_type_input_cost(state, state.local_player_nation, id);
1840 return text::format_money(value);
1841 },
1842};
1843
1845 .sortable = true,
1846 .header = "method_output",
1847 .compare = [](sys::state& state, element_base* container, dcon::factory_type_id a, dcon::factory_type_id b) {
1848 auto av = economy::factory_type_output_cost(state, state.local_player_nation, a);
1849 auto bv = economy::factory_type_output_cost(state, state.local_player_nation, b);
1850 if(av != bv)
1851 return av > bv;
1852 else
1853 return a.index() < b.index();
1854 },
1855 .view = [](sys::state& state, element_base* container, dcon::factory_type_id id) {
1856 auto value = economy::factory_type_output_cost(state, state.local_player_nation, id);
1857 return text::format_money(value);
1858 },
1859};
1860
1862 .sortable = true,
1863 .header = "method_profit",
1864 .compare = [](sys::state& state, element_base* container, dcon::factory_type_id a, dcon::factory_type_id b) {
1865 auto av = economy::factory_type_output_cost(state, state.local_player_nation, a)
1866 - economy::factory_type_input_cost(state, state.local_player_nation, a);
1867 auto bv = economy::factory_type_output_cost(state, state.local_player_nation, b)
1868 - economy::factory_type_input_cost(state, state.local_player_nation, b);
1869 if(av != bv)
1870 return av > bv;
1871 else
1872 return a.index() < b.index();
1873 },
1874 .view = [](sys::state& state, element_base* container, dcon::factory_type_id id) {
1875 auto value = economy::factory_type_output_cost(state, state.local_player_nation, id)
1876 - economy::factory_type_input_cost(state, state.local_player_nation, id);
1877 return text::format_money(value);
1878 },
1879};
1880
1882 .sortable = true,
1883 .header = "method_margin",
1884 .compare = [](sys::state& state, element_base* container, dcon::factory_type_id a, dcon::factory_type_id b) {
1885 auto av = economy::factory_type_output_cost(state, state.local_player_nation, a)
1886 - economy::factory_type_input_cost(state, state.local_player_nation, a);
1887 auto bv = economy::factory_type_output_cost(state, state.local_player_nation, b)
1888 - economy::factory_type_input_cost(state, state.local_player_nation, b);
1889
1890 av /= economy::factory_type_output_cost(state, state.local_player_nation, a);
1891 bv /= economy::factory_type_output_cost(state, state.local_player_nation, b);
1892
1893 if(av != bv)
1894 return av > bv;
1895 else
1896 return a.index() < b.index();
1897 },
1898 .view = [](sys::state& state, element_base* container, dcon::factory_type_id id) {
1899 auto value = economy::factory_type_output_cost(state, state.local_player_nation, id)
1900 - economy::factory_type_input_cost(state, state.local_player_nation, id);
1901 value /= economy::factory_type_output_cost(state, state.local_player_nation, id);
1902 return text::format_percentage(value, 2);
1903 },
1904};
1905
1907 .sortable = true,
1908 .header = "method_cost",
1909 .compare = [](sys::state& state, element_base* container, dcon::factory_type_id a, dcon::factory_type_id b) {
1910 auto av = economy::factory_type_build_cost(state, state.local_player_nation, a);
1911 auto bv = economy::factory_type_build_cost(state, state.local_player_nation, b);
1912
1913 if(av != bv)
1914 return av > bv;
1915 else
1916 return a.index() < b.index();
1917 },
1918 .view = [](sys::state& state, element_base* container, dcon::factory_type_id id) {
1919 auto value = economy::factory_type_build_cost(state, state.local_player_nation, id);
1920 return text::format_money(value);
1921 },
1922};
1923
1925 .sortable = true,
1926 .header = "method_payback",
1927 .compare = [](sys::state& state, element_base* container, dcon::factory_type_id a, dcon::factory_type_id b) {
1928
1929
1930 auto av = economy::factory_type_output_cost(state, state.local_player_nation, a)
1931 - economy::factory_type_input_cost(state, state.local_player_nation, a);
1932 auto bv = economy::factory_type_output_cost(state, state.local_player_nation, b)
1933 - economy::factory_type_input_cost(state, state.local_player_nation, b);
1934 av = std::max(0.f, av);
1935 bv = std::max(0.f, bv);
1936 av = economy::factory_type_build_cost(state, state.local_player_nation, a) / av;
1937 bv = economy::factory_type_build_cost(state, state.local_player_nation, b) / bv;
1938
1939 if(av != bv)
1940 return av > bv;
1941 else
1942 return a.index() < b.index();
1943 },
1944 .view = [](sys::state& state, element_base* container, dcon::factory_type_id id) {
1945 auto value = economy::factory_type_output_cost(state, state.local_player_nation, id)
1946 - economy::factory_type_input_cost(state, state.local_player_nation, id);
1947 value = std::max(0.f, value);
1948 value = economy::factory_type_build_cost(state, state.local_player_nation, id) / value;
1949
1950 return text::format_float(value);
1951 },
1952};
1953
1954class production_window : public generic_tabbed_window<production_window_tab> {
1955 bool show_empty_states = true;
1956 std::unique_ptr<bool[]> show_output_commodity;
1957
1958 production_state_listbox* state_listbox = nullptr;
1959 production_state_invest_listbox* state_listbox_invest = nullptr;
1960 element_base* nf_win = nullptr;
1961 element_base* build_win = nullptr;
1962 element_base* project_window = nullptr;
1963 production_foreign_investment_window* foreign_invest_win = nullptr;
1964
1965 sys::commodity_group curr_commodity_group{};
1966 dcon::state_instance_id focus_state{};
1967 dcon::nation_id foreign_nation{};
1968 xy_pair base_commodity_offset{33, 50};
1969 xy_pair commodity_offset{33, 50};
1970
1971 std::vector<element_base*> factory_elements;
1972 std::vector<element_base*> investment_brow_elements;
1973 std::vector<element_base*> project_elements;
1974 std::vector<element_base*> good_elements;
1975 std::vector<element_base*> investment_nation;
1976 std::vector<bool> commodity_filters;
1977 bool open_foreign_invest = false;
1978
1979 void set_visible_vector_elements(sys::state& state, std::vector<element_base*>& elements, bool v) noexcept {
1980 for(auto element : elements)
1981 element->set_visible(state, v);
1982 }
1983
1984 void hide_sub_windows(sys::state& state) noexcept {
1985 set_visible_vector_elements(state, factory_elements, false);
1986 set_visible_vector_elements(state, investment_brow_elements, false);
1987 set_visible_vector_elements(state, project_elements, false);
1988 set_visible_vector_elements(state, good_elements, false);
1989 set_visible_vector_elements(state, investment_nation, false);
1990 }
1991
1992public:
1993 void on_create(sys::state& state) noexcept override {
1994 generic_tabbed_window::on_create(state);
1995
1996 // All filters enabled by default
1997 commodity_filters.resize(state.world.commodity_size(), true);
1998
1999 /*
2000 for(curr_commodity_group = sys::commodity_group::military_goods; curr_commodity_group != sys::commodity_group::count;
2001 curr_commodity_group = static_cast<sys::commodity_group>(uint8_t(curr_commodity_group) + 1)) {
2002
2003 bool is_empty = true;
2004 for(auto id : state.world.in_commodity) {
2005 if(sys::commodity_group(state.world.commodity_get_commodity_group(id)) != curr_commodity_group || !bool(id) || id == economy::money)
2006 continue;
2007 is_empty = false;
2008 }
2009 if(is_empty)
2010 continue;
2011
2012 commodity_offset.x = base_commodity_offset.x;
2013
2014 // Place legend for this category...
2015 auto ptr = make_element_by_type<production_goods_category_name>(state,
2016 state.ui_state.defs_by_name.find(state.lookup_key("production_goods_name"))->second.definition);
2017 ptr->base_data.position = commodity_offset;
2018 Cyto::Any payload = curr_commodity_group;
2019 ptr->impl_set(state, payload);
2020 ptr->set_visible(state, false);
2021 commodity_offset.y += ptr->base_data.size.y;
2022 good_elements.push_back(ptr.get());
2023 add_child_to_front(std::move(ptr));
2024
2025 int16_t cell_height = 0;
2026 // Place infoboxes for each of the goods...
2027 for(auto id : state.world.in_commodity) {
2028 if(sys::commodity_group(state.world.commodity_get_commodity_group(id)) != curr_commodity_group || !bool(id) || id == economy::money)
2029 continue;
2030
2031 auto info_ptr = make_element_by_type<production_good_info>(state,
2032 state.ui_state.defs_by_name.find(state.lookup_key("production_info"))->second.definition);
2033 info_ptr->base_data.position = commodity_offset;
2034 info_ptr->set_visible(state, false);
2035
2036 int16_t cell_width = info_ptr->base_data.size.x;
2037 cell_height = info_ptr->base_data.size.y;
2038
2039 commodity_offset.x += cell_width;
2040 if(commodity_offset.x + cell_width >= base_data.size.x) {
2041 commodity_offset.x = base_commodity_offset.x;
2042 commodity_offset.y += cell_height;
2043 }
2044
2045 info_ptr.get()->commodity_id = id;
2046
2047 good_elements.push_back(info_ptr.get());
2048 add_child_to_front(std::move(info_ptr));
2049 }
2050 // Has atleast 1 good on this row? skip to next row then...
2051 if(commodity_offset.x > base_commodity_offset.x)
2052 commodity_offset.y += cell_height;
2053 }
2054 */
2055
2056 {
2057 auto ptr = make_element_by_type<national_focus_window>(state, "state_focus_window");
2058 ptr->set_visible(state, false);
2059 nf_win = ptr.get();
2060 add_child_to_front(std::move(ptr));
2061 }
2062
2063 auto win = make_element_by_type<factory_build_window>(state, state.ui_state.defs_by_name.find(state.lookup_key("build_factory"))->second.definition);
2064 build_win = win.get();
2065 add_child_to_front(std::move(win));
2066
2067 auto win2 = make_element_by_type<project_investment_window>(state,
2068 state.ui_state.defs_by_name.find(state.lookup_key("invest_project_window"))->second.definition);
2069 win2->set_visible(state, false);
2070 project_window = win2.get();
2071 add_child_to_front(std::move(win2));
2072
2073 show_output_commodity = std::unique_ptr<bool[]>(new bool[state.world.commodity_size()]);
2074 set_visible(state, false);
2075 }
2076 std::unique_ptr<element_base> make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override {
2077 if(name == "main_bg") {
2078 return make_element_by_type<image_element_base>(state, id);
2079 } else if(name == "table_production_methods") {
2080 std::vector<table::column<dcon::factory_type_id>> columns = {
2088 };
2089
2090 auto ptr = make_element_by_type<table::display<dcon::factory_type_id>>(
2091 state,
2092 id,
2093 std::string("table_production_methods_body"),
2094 columns
2095 );
2096 ptr->set_visible(state, false);
2097
2098 state.world.for_each_factory_type([&](dcon::factory_type_id ft) {
2099 ptr->content.data.push_back(ft);
2100 });
2101
2102 good_elements.push_back(ptr.get());
2103 return ptr;
2104 } else if(name == "prod_bg") {
2105 return make_element_by_type<opaque_element_base>(state, id);
2106 } else if(name == "close_button") {
2107 return make_element_by_type<generic_close_button>(state, id);
2108 } else if(name == "tab_factories") {
2109 auto ptr = make_element_by_type<generic_tab_button<production_window_tab>>(state, id);
2110 ptr->target = production_window_tab::factories;
2111 return ptr;
2112 } else if(name == "tab_invest") {
2113 auto ptr = make_element_by_type<generic_tab_button<production_window_tab>>(state, id);
2114 ptr->target = production_window_tab::investments;
2115 return ptr;
2116 } else if(name == "tab_popprojects") {
2117 auto ptr = make_element_by_type<generic_tab_button<production_window_tab>>(state, id);
2118 ptr->target = production_window_tab::projects;
2119 return ptr;
2120 } else if(name == "tab_goodsproduction") {
2121 auto ptr = make_element_by_type<generic_tab_button<production_window_tab>>(state, id);
2122 ptr->target = production_window_tab::goods;
2123 return ptr;
2124 } else if(name == "tab_factories_text") {
2125 return make_element_by_type<invisible_element>(state, id);
2126 } else if(name == "tab_invest_text") {
2127 return make_element_by_type<invisible_element>(state, id);
2128 } else if(name == "tab_goodsproduction_text") {
2129 return make_element_by_type<invisible_element>(state, id);
2130 } else if(name == "tab_popprojects_text") {
2131 return make_element_by_type<invisible_element>(state, id);
2132 } else if(name == "factory_buttons") {
2133 auto ptr = make_element_by_type<factory_buttons_window>(state, id);
2134 factory_elements.push_back(ptr.get());
2135 ptr->set_visible(state, true);
2136 return ptr;
2137 } else if(name == "invest_buttons") {
2138 auto ptr = make_element_by_type<production_foreign_investment_window>(state, id);
2139 foreign_invest_win = ptr.get();
2140 investment_nation.push_back(ptr.get());
2141 ptr->set_visible(state, false);
2142 return ptr;
2143 } else if(name == "state_listbox") {
2144 auto ptr = make_element_by_type<production_state_listbox>(state, id);
2145 state_listbox = ptr.get();
2146 factory_elements.push_back(ptr.get());
2147 ptr->set_visible(state, true);
2148 return ptr;
2149 } else if(name == "state_listbox_invest") {
2150 auto ptr = make_element_by_type<production_state_invest_listbox>(state, id);
2151 state_listbox_invest = ptr.get();
2152 investment_nation.push_back(ptr.get());
2153 ptr->set_visible(state, false);
2154 return ptr;
2155 } else if(name == "investment_browser") {
2156 auto ptr = make_element_by_type<invest_brow_window>(state, id);
2157 investment_brow_elements.push_back(ptr.get());
2158 ptr->set_visible(state, false);
2159 return ptr;
2160 } else if(name == "sort_by_state") {
2161 auto ptr = make_element_by_type<button_element_base>(state, id);
2162 project_elements.push_back(ptr.get());
2163 ptr->set_visible(state, false);
2164 return ptr;
2165 } else if(name == "sort_by_projects") {
2166 auto ptr = make_element_by_type<button_element_base>(state, id);
2167 project_elements.push_back(ptr.get());
2168 ptr->set_visible(state, false);
2169 return ptr;
2170 } else if(name == "sort_by_completion") {
2171 auto ptr = make_element_by_type<button_element_base>(state, id);
2172 project_elements.push_back(ptr.get());
2173 ptr->set_visible(state, false);
2174 return ptr;
2175 } else if(name == "sort_by_projecteers") {
2176 auto ptr = make_element_by_type<button_element_base>(state, id);
2177 project_elements.push_back(ptr.get());
2178 ptr->set_visible(state, false);
2179 return ptr;
2180 } else if(name == "pop_sort_buttons") {
2181 auto ptr = make_element_by_type<pop_sort_buttons_window>(state, id);
2182 factory_elements.push_back(ptr.get());
2183 ptr->set_visible(state, true);
2184 return ptr;
2185 } else if(name == "project_listbox") {
2186 auto ptr = make_element_by_type<production_project_listbox>(state, id);
2187 project_elements.push_back(ptr.get());
2188 ptr->set_visible(state, false);
2189 return ptr;
2190 } else {
2191 return nullptr;
2192 }
2193 }
2194
2195 message_result get(sys::state& state, Cyto::Any& payload) noexcept override {
2196 if(payload.holds_type<production_window_tab>()) {
2197 auto enum_val = any_cast<production_window_tab>(payload);
2198 hide_sub_windows(state);
2199 switch(enum_val) {
2200 case production_window_tab::factories:
2201 set_visible_vector_elements(state, factory_elements, true);
2202 break;
2203 case production_window_tab::investments:
2204 set_visible_vector_elements(state, investment_brow_elements, true);
2205 foreign_invest_win->set_visible(state, open_foreign_invest);
2206 break;
2207 case production_window_tab::projects:
2208 set_visible_vector_elements(state, project_elements, true);
2209 break;
2210 case production_window_tab::goods:
2211 set_visible_vector_elements(state, good_elements, true);
2212 break;
2213 }
2214 active_tab = enum_val;
2215 return message_result::consumed;
2216 } else if(payload.holds_type<production_foreign_invest_target>()) {
2218 return message_result::consumed;
2219 } else if(payload.holds_type<open_investment_nation>()) {
2220 hide_sub_windows(state);
2221 auto target = any_cast<open_investment_nation>(payload).id;
2222 active_tab = production_window_tab::investments;
2223 foreign_invest_win->curr_nation = target;
2224 set_visible_vector_elements(state, investment_nation, true);
2225 return message_result::consumed;
2226 } else if(payload.holds_type<production_sort_order>()) {
2227 auto sort_type = any_cast<production_sort_order>(payload);
2228 state_listbox->sort_order = sort_type;
2229 if(state_listbox->is_visible())
2230 state_listbox->impl_on_update(state);
2231 state_listbox_invest->sort_order = sort_type;
2232 if(state_listbox_invest->is_visible())
2233 state_listbox_invest->impl_on_update(state);
2234 } else if(payload.holds_type<dcon::state_instance_id>()) {
2235 payload.emplace<dcon::state_instance_id>(focus_state);
2236 return message_result::consumed;
2237 } else if(payload.holds_type<production_selection_wrapper>()) {
2238 auto data = any_cast<production_selection_wrapper>(payload);
2239 focus_state = data.data;
2240 if(data.is_build) {
2241 build_win->set_visible(state, true);
2242 move_child_to_front(build_win);
2243 } else {
2244 nf_win->set_visible(state, true);
2245 nf_win->base_data.position = data.focus_pos;
2246 move_child_to_front(nf_win);
2247 }
2248 impl_on_update(state);
2249 return message_result::consumed;
2250 } else if(payload.holds_type<bool>()) {
2251 payload.emplace<bool>(show_empty_states);
2252 return message_result::consumed;
2253 } else if(payload.holds_type<element_selection_wrapper<bool>>()) {
2254 show_empty_states = any_cast<element_selection_wrapper<bool>>(payload).data;
2255 impl_on_update(state);
2256 return message_result::consumed;
2257 } else if(payload.holds_type<commodity_filter_query_data>()) {
2258 auto content = any_cast<commodity_filter_query_data>(payload);
2259 content.filter = commodity_filters[content.cid.index()];
2260 payload.emplace<commodity_filter_query_data>(content);
2261 return message_result::consumed;
2262 } else if(payload.holds_type<commodity_filter_toggle_data>()) {
2263 auto content = any_cast<commodity_filter_toggle_data>(payload);
2264 commodity_filters[content.data.index()] = !commodity_filters[content.data.index()];
2265 impl_on_update(state);
2266 return message_result::consumed;
2267 } else if(payload.holds_type<element_selection_wrapper<production_action>>()) {
2268 auto content = any_cast<element_selection_wrapper<production_action>>(payload).data;
2269 switch(content) {
2270 case production_action::investment_window:
2271 project_window->is_visible() ? project_window->set_visible(state, false) : project_window->set_visible(state, true);
2272 break;
2273 case production_action::foreign_invest_window:
2274 foreign_invest_win->is_visible() ? foreign_invest_win->set_visible(state, false) : foreign_invest_win->set_visible(state, true);
2275 break;
2276 default:
2277 break;
2278 }
2279 impl_on_update(state);
2280 return message_result::consumed;
2281 } else if(payload.holds_type<element_selection_wrapper<dcon::nation_id>>()) {
2282 foreign_nation = any_cast<element_selection_wrapper<dcon::nation_id>>(payload).data;
2283 open_foreign_invest = true;
2284 foreign_invest_win->set_visible(state, true);
2285 return message_result::consumed;
2286 } else if(payload.holds_type<dcon::nation_id>()) {
2287 if(foreign_invest_win->is_visible())
2288 payload.emplace<dcon::nation_id>(foreign_nation);
2289 else
2290 payload.emplace<dcon::nation_id>(state.local_player_nation);
2291 return message_result::consumed;
2292 }
2293 return message_result::unseen;
2294 }
2295};
2296
2297void open_foreign_investment(sys::state& state, dcon::nation_id n);
2298void open_build_foreign_factory(sys::state& state, dcon::state_instance_id st);
2299
2300} // namespace ui
void render(sys::state &state, int32_t x, int32_t y) noexcept override
void on_update(sys::state &state) noexcept override
void add_child_to_front(std::unique_ptr< element_base > child) noexcept final
void impl_on_update(sys::state &state) noexcept override
element_base * parent
virtual message_result test_mouse(sys::state &state, int32_t x, int32_t y, mouse_probe_type type) noexcept
virtual message_result get(sys::state &state, Cyto::Any &payload) noexcept
bool is_visible() const
message_result impl_get(sys::state &state, Cyto::Any &payload) noexcept
element_data base_data
void set_visible(sys::state &state, bool vis)
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void on_update(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void button_action(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void button_action(sys::state &state) noexcept override
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
message_result test_mouse(sys::state &state, int32_t x, int32_t y, mouse_probe_type type) 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 button_action(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
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 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
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void render(sys::state &state, int32_t x, int32_t y) noexcept override
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
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void on_create(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void button_action(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void on_update(sys::state &state) noexcept override
void button_action(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void button_ctrl_shift_action(sys::state &state) noexcept override
void button_shift_action(sys::state &state) noexcept override
void on_update(sys::state &state) noexcept override
void button_ctrl_shift_right_action(sys::state &state) noexcept override
void button_ctrl_right_action(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void button_ctrl_action(sys::state &state) noexcept override
void button_shift_right_action(sys::state &state) noexcept override
void button_right_action(sys::state &state) noexcept override
void button_action(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
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 button_action(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept override
void on_update(sys::state &state) noexcept override
message_result get(sys::state &state, Cyto::Any &payload) 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::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
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 on_update(sys::state &state) 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
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void button_right_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_action(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_update(sys::state &state) noexcept override
message_result get(sys::state &state, Cyto::Any &payload) noexcept override
std::string_view get_row_element_name() 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
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 button_action(sys::state &state) noexcept override
tooltip_behavior has_tooltip(sys::state &state) noexcept override
void set_text(sys::state &state, std::string const &new_text)
void on_create(sys::state &state) noexcept override
bool can_cancel_factory_building_construction(sys::state &state, dcon::nation_id source, dcon::state_instance_id location, dcon::factory_type_id type)
Definition: commands.cpp:453
bool can_delete_factory(sys::state &state, dcon::nation_id source, dcon::factory_id f)
Definition: commands.cpp:776
bool can_begin_factory_building_construction(sys::state &state, dcon::nation_id source, dcon::state_instance_id location, dcon::factory_type_id type, bool is_upgrade)
Definition: commands.cpp:491
bool can_change_factory_settings(sys::state &state, dcon::nation_id source, dcon::factory_id f, uint8_t priority, bool subsidized)
Definition: commands.cpp:819
bool can_set_national_focus(sys::state &state, dcon::nation_id source, dcon::state_instance_id target_state, dcon::national_focus_id focus)
Definition: commands.cpp:118
void set_national_focus(sys::state &state, dcon::nation_id source, dcon::state_instance_id target_state, dcon::national_focus_id focus)
Definition: commands.cpp:107
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)
dcon::demographics_key to_employment_key(sys::state const &state, dcon::pop_type_id v)
void for_each_new_factory(sys::state &state, dcon::state_instance_id s, F &&func)
float factory_type_input_cost(sys::state &state, dcon::nation_id n, dcon::factory_type_id factory_type)
Definition: economy.cpp:4404
float factory_desired_raw_profit(dcon::factory_fat_id fac, float spendings)
Definition: economy.cpp:1517
float factory_max_employment(sys::state const &state, dcon::factory_id f)
Definition: economy.cpp:1108
int32_t state_factory_count(sys::state &state, dcon::state_instance_id sid, dcon::nation_id n)
Definition: economy.cpp:4892
float factory_min_input_available(sys::state &state, dcon::nation_id n, dcon::factory_type_fat_id fac_type)
Definition: economy.cpp:1340
commodity_production_type get_commodity_production_type(sys::state &state, dcon::commodity_id c)
Definition: economy.cpp:5412
@ both
Definition: economy.hpp:11
@ derivative
Definition: economy.hpp:10
@ primary
Definition: economy.hpp:9
int32_t factory_priority(sys::state const &state, dcon::factory_id f)
Definition: economy.cpp:1003
constexpr float factory_closed_threshold
Definition: economy.hpp:121
float factory_throughput_multiplier(sys::state &state, dcon::factory_type_fat_id fac_type, dcon::nation_id n, dcon::province_id p, dcon::state_instance_id s)
Definition: economy.cpp:1447
float pop_factory_min_wage(sys::state &state, dcon::nation_id n, float min_wage_factor)
Definition: economy.cpp:2816
float factory_max_production_scale(sys::state &state, dcon::factory_fat_id fac, float mobilization_impact, bool occupied)
Definition: economy.cpp:1471
float commodity_daily_production_amount(sys::state &state, dcon::commodity_id c)
Definition: economy.cpp:114
void for_each_upgraded_factory(sys::state &state, dcon::state_instance_id s, F &&func)
float factory_secondary_employment(sys::state const &state, dcon::factory_id f)
Definition: economy.cpp:1116
float pop_min_wage_factor(sys::state &state, dcon::nation_id n)
Definition: economy.cpp:2797
float factory_input_multiplier(sys::state &state, dcon::factory_fat_id fac, dcon::nation_id n, dcon::province_id p, dcon::state_instance_id s)
Definition: economy.cpp:1420
float factory_input_total_cost(sys::state &state, dcon::nation_id n, dcon::factory_type_fat_id fac_type)
Definition: economy.cpp:1361
float factory_e_input_total_cost(sys::state &state, dcon::nation_id n, dcon::factory_type_fat_id fac_type)
Definition: economy.cpp:1392
float factory_type_output_cost(sys::state &state, dcon::nation_id n, dcon::factory_type_id factory_type)
Definition: economy.cpp:4396
float factory_primary_employment(sys::state const &state, dcon::factory_id f)
Definition: economy.cpp:1112
float get_artisan_distribution_slow(sys::state &state, dcon::nation_id n, dcon::commodity_id c)
Definition: economy.cpp:546
float factory_output_multiplier(sys::state &state, dcon::factory_fat_id fac, dcon::nation_id n, dcon::province_id p)
Definition: economy.cpp:1454
float factory_min_e_input_available(sys::state &state, dcon::nation_id n, dcon::factory_type_fat_id fac_type)
Definition: economy.cpp:1374
float factory_type_build_cost(sys::state &state, dcon::nation_id n, dcon::factory_type_id factory_type)
Definition: economy.cpp:4377
constexpr uint32_t build_factory
Definition: culture.hpp:8
constexpr uint32_t can_subsidise
Definition: culture.hpp:13
constexpr uint32_t allow_foreign_investment
Definition: culture.hpp:26
constexpr uint32_t factory_priority
Definition: culture.hpp:12
constexpr uint32_t expand_factory
Definition: culture.hpp:9
float mobilization_impact(sys::state const &state, dcon::nation_id n)
Definition: military.cpp:1160
bool are_at_war(sys::state const &state, dcon::nation_id a, dcon::nation_id b)
Definition: military.cpp:475
void for_each_province_in_state_instance(sys::state &state, dcon::state_instance_id s, F const &func)
float state_admin_efficiency(sys::state &state, dcon::state_instance_id id)
Definition: province.cpp:503
commodity_group
Definition: constants.hpp:223
void add_line_break_to_layout_box(sys::state &state, layout_base &dest, layout_box &box)
Definition: text.cpp:1147
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
layout_box open_layout_box(layout_base &dest, int32_t indent)
Definition: text.cpp:1799
void localised_single_sub_box(sys::state &state, layout_base &dest, layout_box &box, std::string_view key, variable_type subkey, substitution value)
Definition: text.cpp:1888
void localised_format_box(sys::state &state, layout_base &dest, layout_box &box, std::string_view key, text::substitution_map const &sub)
Definition: text.cpp:1880
std::string prettify(int64_t num)
Definition: text.cpp:762
std::string format_float(float num, size_t digits)
Definition: text.cpp:981
void add_line(sys::state &state, layout_base &dest, dcon::text_key txt, int32_t indent)
Definition: text.cpp:1899
void add_line_with_condition(sys::state &state, layout_base &dest, std::string_view key, bool condition_met, int32_t indent)
Definition: text.cpp:1955
void add_line_break_to_layout(sys::state &state, columnar_layout &dest)
Definition: text.cpp:1152
ankerl::unordered_dense::map< uint32_t, substitution > substitution_map
Definition: text.hpp:794
std::string produce_simple_string(sys::state const &state, dcon::text_key id)
Definition: text.cpp:617
std::string format_percentage(float num, size_t digits)
Definition: text.cpp:977
void add_space_to_layout_box(sys::state &state, layout_base &dest, layout_box &box)
Definition: text.cpp:1788
void close_layout_box(columnar_layout &dest, layout_box &box)
Definition: text.cpp:1807
void modifier_description(sys::state &state, text::layout_base &layout, dcon::modifier_id mid, int32_t indentation=0)
production_sort_order
Definition: constants.hpp:584
table::column< dcon::factory_type_id > factory_type_payback
table::column< dcon::factory_type_id > factory_type_profit
table::column< dcon::factory_type_id > factory_type_output_cost
table::column< dcon::factory_type_id > factory_type_cost
tooltip_behavior
void send(sys::state &state, element_base *parent, T value)
table::column< dcon::factory_type_id > factory_type_profit_margin
message_result
void populate_production_states_list(sys::state &state, std::vector< dcon::state_instance_id > &row_contents, dcon::nation_id n, bool show_empty, production_sort_order sort_order)
production_window_tab
Definition: constants.hpp:585
table::column< dcon::factory_type_id > factory_type_name
table::column< dcon::factory_type_id > factory_type_input_cost
void active_modifiers_description(sys::state &state, text::layout_base &layout, dcon::nation_id n, int32_t identation, dcon::national_modifier_value nmid, bool header)
uint uint32_t
uchar uint8_t
static constexpr uint32_t set_size
static constexpr uint32_t set_size
dcon::factory_type_id type
Definition: economy.hpp:244
int32_t x_size
Definition: text.hpp:827
float x_position
Definition: text.hpp:830
std::variant< std::monostate, economy::upgraded_factory, economy::new_factory > activity
element_base * topbar_subwindow
ankerl::unordered_dense::map< dcon::text_key, element_target, hash_text_key > defs_by_name
std::unique_ptr< element_base > root
element_base * production_subwindow