5#include "dcon_generated.hpp"
60 auto key =
state.lookup_key(
"alice_armygroup_selection_control_panel");
62 auto window = ui::make_element_by_type<ui::battleplanner_selection_control>(
state, def);
66 auto key =
state.lookup_key(
"alice_armygroup_exit_units_selection");
68 auto button = ui::make_element_by_type<ui::go_to_battleplanner_button>(
state, def);
75 state.world.for_each_province([&](dcon::province_id
id) {
76 auto ptr = ui::make_element_by_type<ui::army_group_counter_window>(
state,
"alice_army_group_on_map");
82 auto key =
state.lookup_key(
"alice_army_group_regiments_list");
84 auto new_elm_army_group = ui::make_element_by_type<ui::army_group_details_window>(
state, def);
91 auto key =
state.lookup_key(
"alice_exit_battleplanner");
93 auto button = ui::make_element_by_type<ui::go_to_base_game_button>(
state, def);
98 auto key =
state.lookup_key(
"alice_battleplanner_control_panel");
100 auto window = ui::make_element_by_type<ui::battleplanner_control>(
state, def);
108 auto ewin = ui::make_element_by_type<ui::end_window>(
state,
state.ui_state.
defs_by_name.find(
state.lookup_key(
"back_end"))->second.definition);
112 auto window = ui::make_element_by_type<ui::console_window>(
state,
"alice_console_window");
116 state.world.for_each_province([&](dcon::province_id
id) {
117 if(
state.world.province_get_port_to(
id)) {
118 auto ptr = ui::make_element_by_type<ui::port_window>(state,
"alice_port_icon");
119 static_cast<ui::port_window*>(ptr.get())->set_province(state, id);
120 state.ui_state.units_root->add_child_to_front(std::move(ptr));
124 state.world.for_each_province([&](dcon::province_id
id) {
125 auto ptr = ui::make_element_by_type<ui::unit_counter_window>(
state,
"alice_map_unit");
129 state.world.for_each_province([&](dcon::province_id
id) {
130 auto ptr = ui::make_element_by_type<ui::rgo_icon>(
state,
"alice_rgo_mapicon");
135 auto ptr = ui::make_element_by_type<ui::province_details_container>(
state,
"alice_province_values");
140 auto new_elm = ui::make_element_by_type<ui::chat_message_listbox<false>>(
state,
"chat_list");
141 new_elm->base_data.position.x += 156;
142 new_elm->base_data.position.y += 24;
143 new_elm->impl_on_update(
state);
145 state.ui_state.
root->add_child_to_front(std::move(new_elm));
148 auto new_elm = ui::make_element_by_type<ui::outliner_window>(
state,
"outliner");
150 new_elm->impl_on_update(
state);
151 state.ui_state.
root->add_child_to_front(std::move(new_elm));
156 for(
size_t i =
state.ui_defs.gui.size(); i-- > 0;) {
157 auto gdef = dcon::gui_def_id(dcon::gui_def_id::value_base_t(i));
158 if(
state.to_string_view(
state.ui_defs.gui[gdef].name) ==
"topbar_outlinerbutton_bg") {
159 auto new_bg = ui::make_element_by_type<ui::outliner_button>(
state, gdef);
160 state.ui_state.
root->add_child_to_front(std::move(new_bg));
165 for(
size_t i =
state.ui_defs.gui.size(); i-- > 0;) {
166 auto gdef = dcon::gui_def_id(dcon::gui_def_id::value_base_t(i));
167 if(
state.to_string_view(
state.ui_defs.gui[gdef].name) ==
"topbar_outlinerbutton") {
168 auto new_btn = ui::make_element_by_type<ui::outliner_button>(
state, gdef);
169 new_btn->impl_on_update(
state);
170 state.ui_state.
root->add_child_to_front(std::move(new_btn));
176 auto new_elm = ui::make_element_by_type<ui::minimap_container_window>(
state,
"alice_menubar");
178 state.ui_state.
root->add_child_to_front(std::move(new_elm));
181 auto new_elm = ui::make_element_by_type<ui::minimap_picture_window>(
state,
"minimap_pic");
182 state.ui_state.
root->add_child_to_front(std::move(new_elm));
185 auto new_elm = ui::make_element_by_type<ui::province_view_window>(
state,
"province_view");
186 state.ui_state.
root->add_child_to_front(std::move(new_elm));
189 auto new_elm_army = ui::make_element_by_type<ui::unit_details_window<dcon::army_id>>(
state,
"sup_unit_status");
192 state.ui_state.
root->add_child_to_front(std::move(new_elm_army));
194 auto new_elm_navy = ui::make_element_by_type<ui::unit_details_window<dcon::navy_id>>(
state,
"sup_unit_status");
197 state.ui_state.
root->add_child_to_front(std::move(new_elm_navy));
201 auto mselection = ui::make_element_by_type<ui::mulit_unit_selection_panel>(
state,
"alice_multi_unitpanel");
203 mselection->set_visible(
state,
false);
204 state.ui_state.
root->add_child_to_front(std::move(mselection));
207 auto new_elm = ui::make_element_by_type<ui::diplomacy_request_window>(
state,
"defaultdialog");
209 state.ui_state.
root->add_child_to_front(std::move(new_elm));
212 auto new_elm = ui::make_element_by_type<ui::message_window>(
state,
"defaultpopup");
214 state.ui_state.
root->add_child_to_front(std::move(new_elm));
217 auto new_elm = ui::make_element_by_type<ui::leader_selection_window>(
state,
"alice_leader_selection_panel");
219 state.ui_state.
root->add_child_to_front(std::move(new_elm));
222 auto new_elm = ui::make_element_by_type<ui::naval_combat_end_popup>(
state,
"endofnavalcombatpopup");
223 new_elm->set_visible(
state,
false);
224 state.ui_state.
root->add_child_to_front(std::move(new_elm));
227 auto new_elm = ui::make_element_by_type<ui::naval_combat_window>(
state,
"alice_naval_combat");
228 new_elm->set_visible(
state,
false);
229 state.ui_state.
root->add_child_to_front(std::move(new_elm));
232 auto new_elm = ui::make_element_by_type<ui::land_combat_window>(
state,
"alice_land_combat");
233 new_elm->set_visible(
state,
false);
234 state.ui_state.
root->add_child_to_front(std::move(new_elm));
237 auto new_elm = ui::make_element_by_type<ui::topbar_window>(
state,
"topbar");
238 new_elm->impl_on_update(
state);
239 state.ui_state.
root->add_child_to_front(std::move(new_elm));
242 auto legend_win = ui::make_element_by_type<ui::map_legend_gradient>(
state,
"alice_map_legend_gradient_window");
244 state.ui_state.
root->add_child_to_front(std::move(legend_win));
247 auto legend_win = ui::make_element_by_type<ui::map_legend_civ_level>(
state,
"alice_map_legend_civ_level");
249 state.ui_state.
root->add_child_to_front(std::move(legend_win));
252 auto legend_win = ui::make_element_by_type<ui::map_legend_col>(
state,
"alice_map_legend_colonial");
254 state.ui_state.
root->add_child_to_front(std::move(legend_win));
257 auto legend_win = ui::make_element_by_type<ui::map_legend_dip>(
state,
"alice_map_legend_diplomatic");
259 state.ui_state.
root->add_child_to_front(std::move(legend_win));
262 auto legend_win = ui::make_element_by_type<ui::map_legend_rr>(
state,
"alice_map_legend_infrastructure");
264 state.ui_state.
root->add_child_to_front(std::move(legend_win));
267 auto legend_win = ui::make_element_by_type<ui::map_legend_nav>(
state,
"alice_map_legend_naval");
269 state.ui_state.
root->add_child_to_front(std::move(legend_win));
272 auto legend_win = ui::make_element_by_type<ui::map_legend_rank>(
state,
"alice_map_legend_rank");
274 state.ui_state.
root->add_child_to_front(std::move(legend_win));
277 auto legend_win = ui::make_element_by_type<ui::map_legend_rec>(
state,
"alice_map_legend_rec");
279 state.ui_state.
root->add_child_to_front(std::move(legend_win));
282 auto new_elm = ui::make_element_by_type<ui::chat_window>(
state,
"ingame_lobby_window");
285 state.ui_state.
root->add_child_to_front(std::move(new_elm));
411 while(b !=
nullptr) {
473 auto game_state_was_updated =
game_state_updated.exchange(
false, std::memory_order::acq_rel);
480 if(ownership_update) {
485 if(game_state_was_updated) {
489 std::chrono::time_point<std::chrono::steady_clock> now = std::chrono::steady_clock::now();
494 auto microseconds_since_last_render = std::chrono::duration_cast<std::chrono::microseconds>(now -
ui_state.
last_render_time);
495 auto frames_per_second = 1.f / float(microseconds_since_last_render.count() / 1e6);
531 int32_t tooltip_sub_index = -1;
532 if(tooltip_probe.under_mouse) {
537 if(game_state_was_updated) {
555 world.for_each_automated_army_group([&](dcon::automated_army_group_id item) {
570 auto auto_choice =
world.national_event_get_auto_choice(c1->e);
571 if(auto_choice == 0) {
573 if(
world.national_event_get_is_major(c1->e)) {
587 auto auto_choice =
world.free_national_event_get_auto_choice(c2->e);
588 if(auto_choice == 0) {
590 if(
world.free_national_event_get_is_major(c2->e)) {
604 auto auto_choice =
world.provincial_event_get_auto_choice(c3->e);
605 if(auto_choice == 0) {
617 auto auto_choice =
world.free_provincial_event_get_auto_choice(c4->e);
618 if(auto_choice == 0) {
632 if(lr->player_on_winning_side ==
true && (!lr->attacking_nation || !lr->defending_nation)) {
657 bool had_diplo_msg =
false;
664 had_diplo_msg =
true;
675 auto base_type = c6->
type;
717 ui_pause.store(
true, std::memory_order_release);
822 text::layout_parameters{ 0, 0, tooltip_width, int16_t(root_elm->base_data.size.y - 20), ui_state.tooltip_font, 0,
823 text::alignment::left,
824 text::text_color::white, true },
830 container.used_width = -container.used_width;
831 for(
auto& t : container.base_layout.contents) {
832 t.x += 16 + container.used_width;
836 for(
auto& t : container.base_layout.contents) {
841 ui_state.
tooltip->base_data.size.x = int16_t(container.used_width + 32);
842 ui_state.
tooltip->base_data.size.y = int16_t(container.used_height + 32);
843 if(container.used_width > 0)
855 if(tooltip_probe.under_mouse) {
859 text::layout_parameters{ 0, 0, tooltip_width,int16_t(root_elm->base_data.size.y - 20), ui_state.tooltip_font, 0,
860 text::alignment::left, text::text_color::white, true }, 10);
865 container.used_width = -container.used_width;
866 for(
auto& t : container.base_layout.contents) {
867 t.x += 16 + container.used_width;
871 for(
auto& t : container.base_layout.contents) {
876 ui_state.
tooltip->base_data.size.x = int16_t(container.used_width + 32);
877 ui_state.
tooltip->base_data.size.y = int16_t(container.used_height + 32);
878 if(container.used_width > 0)
890 text::layout_parameters{ 0, 0, tooltip_width, int16_t(root_elm->base_data.size.y - 20), ui_state.tooltip_font, 0,
891 text::alignment::left, text::text_color::white, true }, 10);
895 container.used_width = -container.used_width;
896 for(
auto& t : container.base_layout.contents) {
897 t.x += 16 + container.used_width;
901 for(
auto& t : container.base_layout.contents) {
906 ui_state.
tooltip->base_data.size.x = int16_t(container.used_width + 32);
907 ui_state.
tooltip->base_data.size.y = int16_t(container.used_height + 32);
908 if(container.used_width > 0)
950 prov = dcon::province_id{};
965 auto c =
world.province_get_nation_from_province_control(prov);
981 && !mouse_probe.under_mouse
982 && !tooltip_probe.under_mouse
995 prov = dcon::province_id{};
999 text::layout_parameters{ 0, 0, tooltip_width, int16_t(ui_state.root->base_data.size.y - 20), ui_state.tooltip_font, 0, text::alignment::left, text::text_color::white, true },
1003 container.used_width = -container.used_width;
1004 for(
auto& t : container.base_layout.contents) {
1005 t.x += 16 + container.used_width;
1009 for(
auto& t : container.base_layout.contents) {
1014 ui_state.
tooltip->base_data.size.x = int16_t(container.used_width + 32);
1015 ui_state.
tooltip->base_data.size.y = int16_t(container.used_height + 32);
1016 if(container.used_width > 0) {
1018 auto mid_point =
world.province_get_mid_point(prov);
1022 glm::vec2 screen_pos;
1048 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1049 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1051 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1062 glDepthRange(-1.0f, 1.0f);
1064 if(gfx_def.primary_texture_handle) {
1076 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1084 glDepthRange(-1.0f, 1.0f);
1122 for(
auto gui_file : list_files(assets,
NATIVE(
".aui"))) {
1124 auto opened_file = open_file(gui_file);
1126 file_name.pop_back(); file_name.pop_back(); file_name.pop_back(); file_name.pop_back();
1128 auto content = view_contents(*opened_file);
1136 static const std::string_view elem_names[] = {
1138 "production_goods_name",
1140 "new_factory_option",
1141 "ledger_legend_entry",
1144 for(
const auto& elem_name : elem_names) {
1147 auto& gfx_def =
ui_defs.
gui[it->second.definition];
1148 gfx_def.flags &=
~ui::element_data::orientation_mask;
1154 static const std::string_view elem_names[] = {
1157 "event_election_window",
1158 "invest_project_window",
1163 "defaultdiplomacydialog",
1164 "gpselectdiplomacydialog",
1168 "setupcrisisbackdowndialog",
1169 "endofnavalcombatpopup",
1170 "endoflandcombatpopup",
1171 "ingame_lobby_window",
1173 for(
const auto& elem_name : elem_names) {
1176 auto& gfx_def =
ui_defs.
gui[it->second.definition];
1190 auto window = ui::make_element_by_type<ui::console_window>(*
this,
"console_wnd");
1192 window->set_visible(*
this,
false);
1196 auto new_elm = ui::make_element_by_type<ui::chat_window>(*
this,
"ingame_lobby_window");
1209 return std::string_view();
1211 auto start_position =
key_data.data() + tag.index();
1213 auto end_position = start_position;
1214 for(; end_position <
key_data.data() + data_size; ++end_position) {
1215 if(*end_position == 0)
1218 return std::string_view(
key_data.data() + tag.index(),
size_t(end_position - start_position));
1225 auto end_position = start_position;
1226 for(; end_position <
locale_text_data.data() + data_size; ++end_position) {
1227 if(*end_position == 0)
1230 return std::string_view(
locale_text_data.data() + tag,
size_t(end_position - start_position));
1241 auto assets_dir = open_directory(root_dir,
NATIVE(
"assets/localisation"));
1243 auto load_base_files = [&](int32_t column) {
1244 auto text_dir = open_directory(root_dir,
NATIVE(
"localisation"));
1245 for(
auto& file : list_files(text_dir,
NATIVE(
".csv"))) {
1246 if(
auto ofile = open_file(file); ofile) {
1247 auto content = view_contents(*ofile);
1251 for(
auto& file : list_files(assets_dir,
NATIVE(
".csv"))) {
1252 if(
auto ofile = open_file(file); ofile) {
1253 auto content = view_contents(*ofile);
1259 if(locale_name.starts_with(
"en")) {
1261 }
else if(locale_name.starts_with(
"fr")) {
1263 }
else if(locale_name.starts_with(
"de")) {
1265 }
else if(locale_name.starts_with(
"pl")) {
1267 }
else if(locale_name.starts_with(
"es")) {
1269 }
else if(locale_name.starts_with(
"it")) {
1271 }
else if(locale_name.starts_with(
"sv")) {
1273 }
else if(locale_name.starts_with(
"cs")) {
1275 }
else if(locale_name.starts_with(
"hu")) {
1277 }
else if(locale_name.starts_with(
"nl")) {
1278 load_base_files(10);
1279 }
else if(locale_name.starts_with(
"pt")) {
1280 load_base_files(11);
1281 }
else if(locale_name.starts_with(
"ru")) {
1282 load_base_files(12);
1283 }
else if(locale_name.starts_with(
"fi")) {
1284 load_base_files(13);
1288 for(
auto& file : list_files(locale_dir,
NATIVE(
".csv"))) {
1289 if(
auto ofile = open_file(file); ofile) {
1290 auto content = view_contents(*ofile);
1309 return dcon::text_key{};
1317 for(
auto c :
text) {
1319 if(unicode == 0x00A7)
1320 unicode = uint16_t(
'?');
1321 if(unicode <= 0x007F) {
1322 temp.push_back(
char(unicode));
1323 }
else if(unicode <= 0x7FF) {
1324 temp.push_back(
char(0xC0 |
uint8_t(0x1F & (unicode >> 6))));
1325 temp.push_back(
char(0x80 |
uint8_t(0x3F & unicode)));
1327 temp.push_back(
char(0xE0 |
uint8_t(0x0F & (unicode >> 12))));
1328 temp.push_back(
char(0x80 |
uint8_t(0x3F & (unicode >> 6))));
1329 temp.push_back(
char(0x80 |
uint8_t(0x3F & unicode)));
1332 assert(temp[temp.size()] ==
'\0');
1336 return add_key_utf8(std::string_view(new_text.data()));
1344 auto length = new_text.length();
1346 return dcon::text_key();
1347 key_data.resize(start + length + 1,
char(0));
1348 std::copy_n(new_text.data(), length,
key_data.data() + start);
1351 auto ret = dcon::text_key(dcon::text_key::value_base_t(start));
1360 for(
auto c :
text) {
1362 if(unicode == 0x00A7)
1363 unicode = uint16_t(
'?');
1364 if(unicode <= 0x007F) {
1366 }
else if(unicode <= 0x7FF) {
1383 auto length = new_text.length();
1394 return dcon::unit_name_id();
1397 for(
auto c :
text) {
1399 if(unicode == 0x00A7)
1400 unicode = uint16_t(
'?');
1401 if(unicode <= 0x007F) {
1402 temp.push_back(
char(unicode));
1403 }
else if(unicode <= 0x7FF) {
1404 temp.push_back(
char(0xC0 |
uint8_t(0x1F & (unicode >> 6))));
1405 temp.push_back(
char(0x80 |
uint8_t(0x3F & unicode)));
1407 temp.push_back(
char(0xE0 |
uint8_t(0x0F & (unicode >> 12))));
1408 temp.push_back(
char(0x80 |
uint8_t(0x3F & (unicode >> 6))));
1409 temp.push_back(
char(0x80 |
uint8_t(0x3F & unicode)));
1413 assert(temp[temp.size()] ==
'\0');
1415 unit_names.resize(start + temp.length() + 1,
char(0));
1416 std::copy_n(temp.data(), temp.length(),
unit_names.data() + start);
1419 return dcon::unit_name_id(dcon::unit_name_id::value_base_t(
unit_names_indices.size() - 1));
1423 return std::string_view();
1427 auto end_position = start_position;
1428 for(; end_position <
unit_names.data() + data_size; ++end_position) {
1429 if(*end_position == 0)
1442 return dcon::trigger_key();
1446 std::boyer_moore_horspool_searcher(data.data(), data.data() + data.size()));
1448 auto const start = search_result -
trigger_data.data();
1452 return dcon::trigger_key(dcon::trigger_key::value_base_t(d - 1));
1456 return dcon::trigger_key(dcon::trigger_key::value_base_t(
trigger_data_indices.size() - 1 - 1));
1460 auto size = data.size();
1462 std::copy_n(data.data(), size,
trigger_data.data() + start);
1465 return dcon::trigger_key(dcon::trigger_key::value_base_t(
trigger_data_indices.size() - 1 - 1));
1476 return dcon::effect_key();
1480 std::boyer_moore_horspool_searcher(data.data(), data.data() + data.size()));
1482 auto const start = search_result -
effect_data.data();
1486 return dcon::effect_key(dcon::effect_key::value_base_t(d - 1));
1490 return dcon::effect_key(dcon::effect_key::value_base_t(
effect_data_indices.size() - 1 - 1));
1494 auto size = data.size();
1496 std::copy_n(data.data(), size,
effect_data.data() + start);
1499 return dcon::effect_key(dcon::effect_key::value_base_t(
effect_data_indices.size() - 1 - 1));
1507 char* ptr = &buffer[0];
1510 std::memcpy(ptr, &user_settings.x, sizeof(user_settings.x)); \
1511 ptr += sizeof(user_settings.x);
1523 constexpr size_t lower_half_count = 98;
1531 constexpr size_t upper_half_count = 128 - 98;
1533 ptr += upper_half_count;
1535 ptr += upper_half_count;
1537 ptr += upper_half_count;
1546 US_SAVE(left_mouse_click_hold_and_release);
1548 US_SAVE(mouse_edge_scrolling);
1553 US_SAVE(diplomatic_message_popup);
1554 US_SAVE(wasd_for_map_movement);
1555 US_SAVE(notify_rebels_defeat);
1565 auto settings_file = open_file(settings_location,
NATIVE(
"user_settings.dat"));
1567 auto content = view_contents(*settings_file);
1568 auto ptr = content.data;
1571 if(ptr > content.data + content.file_size - sizeof(user_settings.x)) break; \
1572 std::memcpy(&user_settings.x, ptr, sizeof(user_settings.x)); \
1573 ptr += sizeof(user_settings.x);
1587 constexpr size_t lower_half_count = 98;
1599 constexpr size_t upper_half_count = 128 - 98;
1601 ptr += upper_half_count;
1603 ptr += upper_half_count;
1605 ptr += upper_half_count;
1614 US_LOAD(left_mouse_click_hold_and_release);
1616 US_LOAD(mouse_edge_scrolling);
1621 US_LOAD(diplomatic_message_popup);
1622 US_LOAD(wasd_for_map_movement);
1623 US_LOAD(notify_rebels_defeat);
1666 if(
header.timestamp > max_timestamp) {
1667 max_timestamp =
header.timestamp;
1676 bool locale_loaded =
false;
1691 for(
auto l :
world.in_locale) {
1692 auto ln = l.get_locale_name();
1693 auto ln_sv = std::string_view{ (
char const*)ln.begin(), ln.size() };
1694 if(ln_sv == lname) {
1696 locale_loaded =
true;
1701 if(!locale_loaded) {
1702 for(
auto l :
world.in_locale) {
1703 auto ln = l.get_locale_name();
1704 auto ln_sv = std::string_view{ (
char const*)ln.begin(), ln.size() };
1705 if(ln_sv ==
"en-US") {
1707 locale_loaded =
true;
1713 if(!locale_loaded) {
1729 auto poptypes = open_directory(root,
NATIVE(
"poptypes"));
1732 auto full_name = get_full_name(file);
1733 auto last = full_name.c_str() + full_name.length();
1734 auto first = full_name.c_str();
1735 for(; last > first; --last) {
1739 auto start_of_name = last;
1740 for(; start_of_name >= first; --start_of_name) {
1741 if(*start_of_name ==
NATIVE(
'\\') || *start_of_name ==
NATIVE(
'/')) {
1749 auto type_id =
state.
world.create_pop_type();
1750 state.
world.pop_type_set_name(type_id, name_id);
1751 context.
map_of_poptypes.insert_or_assign(std::string(utf8typename), type_id);
1769 auto common = open_directory(root,
NATIVE(
"common"));
1776 auto map = open_directory(root,
NATIVE(
"map"));
1779 auto def_map_file = open_file(
map,
NATIVE(
"default.map"));
1781 auto content = view_contents(*def_map_file);
1784 parsers::parse_default_map_file(gen, err, context);
1792 auto def_csv_file = open_file(
map,
NATIVE(
"definition.csv"));
1794 auto content = view_contents(*def_csv_file);
1805 auto adj_csv_file = open_file(
map,
NATIVE(
"adjacencies.csv"));
1807 auto adj_content = view_contents(*adj_csv_file);
1863 auto countries = open_file(common,
NATIVE(
"countries.txt"));
1865 auto content = view_contents(*countries);
1868 parsers::parse_national_identity_file(gen, err, context);
1876 auto religion = open_file(common,
NATIVE(
"religion.txt"));
1878 auto content = view_contents(*religion);
1881 parsers::parse_religion_file(gen, err, context);
1889 auto cultures = open_file(common,
NATIVE(
"cultures.txt"));
1891 auto content = view_contents(*cultures);
1894 parsers::parse_culture_file(gen, err, context);
1903 if(
world.commodity_size() == 0) {
1905 auto money_id =
world.create_commodity();
1906 assert(money_id.index() == 0);
1908 auto goods = open_file(common,
NATIVE(
"goods.txt"));
1910 auto content = view_contents(*goods);
1913 parsers::parse_goods_file(gen, err, context);
1922 auto buildings = open_file(common,
NATIVE(
"buildings.txt"));
1924 auto content = view_contents(*buildings);
1927 parsers::parse_building_file(gen, err, context);
1940 parsers::parse_ideology_file(gen, err, context);
1950 auto content = view_contents(*context.
issues_file);
1953 parsers::parse_issues_file(gen, err, context);
1976 auto governments = open_file(common,
NATIVE(
"governments.txt"));
1978 auto content = view_contents(*governments);
1981 parsers::parse_governments_file(gen, err, context);
1994 parsers::parse_cb_types_file(gen, err, context);
2002 auto traits = open_file(common,
NATIVE(
"traits.txt"));
2004 auto content = view_contents(*traits);
2007 parsers::parse_traits_file(gen, err, context);
2017 auto content = view_contents(*context.
crimes_file);
2020 parsers::parse_crimes_file(gen, err, context);
2031 err.
file_name =
"triggered_modifiers.txt";
2033 parsers::parse_triggered_modifiers_file(gen, err, context);
2036 err.
accumulated_errors +=
"File common/triggered_modifiers.txt could not be opened\n";
2041 auto nv_file = open_file(common,
NATIVE(
"nationalvalues.txt"));
2043 auto content = view_contents(*nv_file);
2046 parsers::parse_national_values_file(gen, err, context);
2054 auto sm_file = open_file(common,
NATIVE(
"static_modifiers.txt"));
2056 auto content = view_contents(*sm_file);
2059 parsers::parse_static_modifiers_file(gen, err, context);
2067 auto em_file = open_file(common,
NATIVE(
"event_modifiers.txt"));
2069 auto content = view_contents(*em_file);
2072 parsers::parse_event_modifiers_file(gen, err, context);
2084 auto opened_file = open_file(defines_file);
2086 auto content = view_contents(*opened_file);
2088 defines.
parse_file(*
this, std::string_view(content.data, content.data + content.file_size), err);
2102 parsers::parse_rebel_types_file(gen, err, context);
2111 auto terrain_file = open_file(
map,
NATIVE(
"terrain.txt"));
2113 auto content = view_contents(*terrain_file);
2116 parsers::parse_terrain_file(gen, err, context);
2124 auto region_file = open_file(
map,
NATIVE(
"region.txt"));
2126 auto content = view_contents(*region_file);
2129 parsers::parse_region_file(gen, err, context);
2137 auto super_region_file = open_file(
map,
NATIVE(
"super_region.txt"));
2138 if(super_region_file) {
2139 auto content = view_contents(*super_region_file);
2142 parsers::parse_region_file(gen, err, context);
2149 auto continent_file = open_file(
map,
NATIVE(
"continent.txt"));
2150 if(continent_file) {
2151 auto content = view_contents(*continent_file);
2154 parsers::parse_continent_file(gen, err, context);
2162 auto climate_file = open_file(
map,
NATIVE(
"climate.txt"));
2164 auto content = view_contents(*climate_file);
2167 parsers::parse_climate_file(gen, err, context);
2175 auto tech_file = open_file(common,
NATIVE(
"technology.txt"));
2177 auto content = view_contents(*tech_file);
2180 parsers::parse_technology_main_file(gen, err, context);
2188 auto inventions = open_directory(root,
NATIVE(
"inventions"));
2213 auto i_file = open_file(invf);
2215 auto content = view_contents(*i_file);
2218 parsers::parse_inventions_file(gen, err, invention_context);
2227 auto units = open_directory(root,
NATIVE(
"units"));
2229 auto opened_file = open_file(unit_file);
2231 auto content = view_contents(*opened_file);
2234 parsers::parse_unit_file(gen, err, context);
2253 world.political_party_resize_party_issues(
world.issue_size());
2255 world.province_resize_party_loyalty(
world.ideology_size());
2258 world.pop_type_resize_everyday_needs(
world.commodity_size());
2259 world.pop_type_resize_luxury_needs(
world.commodity_size());
2260 world.pop_type_resize_life_needs(
world.commodity_size());
2261 world.pop_type_resize_ideology(
world.ideology_size());
2262 world.pop_type_resize_issues(
world.issue_option_size());
2263 world.pop_type_resize_promotion(
world.pop_type_size());
2265 world.national_focus_resize_production_focus(
world.commodity_size());
2267 world.technology_resize_activate_building(
world.factory_type_size());
2272 world.invention_resize_activate_building(
world.factory_type_size());
2276 world.rebel_type_resize_government_change(
world.government_type_size());
2279 world.nation_resize_active_inventions(
world.invention_size());
2280 world.nation_resize_active_technologies(
world.technology_size());
2281 world.nation_resize_upper_house(
world.ideology_size());
2283 world.national_identity_resize_government_flag_type(
world.government_type_size());
2284 world.national_identity_resize_government_name(
world.government_type_size());
2285 world.national_identity_resize_government_adjective(
world.government_type_size());
2286 world.national_identity_resize_government_ruler_name(
world.government_type_size());
2287 world.national_identity_resize_government_color(
world.government_type_size());
2290 for(
auto ident :
world.in_national_identity) {
2293 auto const name = tag +
"_" + named_gov.first;
2295 ident.set_government_name(named_gov.second, name_k);
2296 auto const adj = tag +
"_" + named_gov.first +
"_ADJ";
2298 ident.set_government_adjective(named_gov.second, adj_k);
2299 auto const ruler = tag +
"_" + named_gov.first +
"_ruler";
2301 ident.set_government_ruler_name(named_gov.second, ruler_k);
2306 auto stdir = open_directory(root,
NATIVE(
"scripted triggers"));
2308 auto opened_file = open_file(st_file);
2310 auto content = view_contents(*opened_file);
2313 parsers::parse_scripted_trigger_file(gen, err, context);
2318 world.for_each_national_identity([&](dcon::national_identity_id i) {
2322 auto content = view_contents(*country_file);
2325 parsers::parse_country_file(gen, err, c_context);
2329 world.province_resize_rgo_max_size_per_good(
world.commodity_size());
2332 auto history = open_directory(root,
NATIVE(
"history"));
2334 auto prov_history = open_directory(history,
NATIVE(
"provinces"));
2335 auto const load_from_dir = [&](
auto const subdir) {
2337 for(
auto province_file : list_files(subdir,
NATIVE(
".csv"))) {
2338 auto opened_file = open_file(province_file);
2341 auto content = view_contents(*opened_file);
2345 for(
auto prov_file : list_files(subdir,
NATIVE(
".txt"))) {
2347 auto name_start = file_name.c_str();
2348 auto name_end = name_start + file_name.length();
2350 if(name_start < name_end && !isdigit(*name_start))
2353 auto value_start = name_start;
2354 for(; value_start < name_end; ++value_start) {
2355 if(isdigit(*value_start))
2358 auto value_end = value_start;
2359 for(; value_end < name_end; ++value_end) {
2360 if(!isdigit(*value_end))
2365 auto province_id =
parsers::parse_int(std::string_view(value_start, value_end), 0, err);
2367 auto opened_file = open_file(prov_file);
2371 auto content = view_contents(*opened_file);
2373 parsers::parse_province_history_file(gen, err, pf_context);
2378 load_from_dir(prov_history);
2379 for(
auto const& subdir : list_subdirectories(prov_history)) {
2380 load_from_dir(subdir);
2386 auto pop_history = open_directory(history,
NATIVE(
"pops"));
2388 auto start_dir_name = std::to_string(startdate.year) +
"." + std::to_string(startdate.month) +
"." + std::to_string(startdate.day);
2394 auto directory_file_count = list_files(date_directory,
NATIVE(
".txt")).size();
2395 if(directory_file_count == 0)
2397 for(
auto pop_file : list_files(date_directory,
NATIVE(
".txt"))) {
2398 auto opened_file = open_file(pop_file);
2401 auto content = view_contents(*opened_file);
2403 parsers::parse_pop_history_file(gen, err, context);
2409 for(
auto pop_file : list_files(date_directory,
NATIVE(
".csv"))) {
2410 auto opened_file = open_file(pop_file);
2413 auto content = view_contents(*opened_file);
2421 auto poptypes = open_directory(root,
NATIVE(
"poptypes"));
2426 auto content = view_contents(*opened_file);
2429 parsers::parse_poptype_file(gen, err, inner_context);
2439 parsers::parse_individual_ideology(pr.second.generator_state, err, new_context);
2454 err.
file_name =
"triggered_modifiers.txt";
2465 parsers::parse_cb_body(r.second.generator_state, err, new_context);
2475 world.issue_option_resize_support_modifiers(
world.issue_option_size());
2492 auto nat_focus = open_file(common,
NATIVE(
"national_focus.txt"));
2494 auto content = view_contents(*nat_focus);
2497 parsers::parse_national_focus_file(gen, err, context);
2505 auto pop_types_file = open_file(common,
NATIVE(
"pop_types.txt"));
2506 if(pop_types_file) {
2507 auto content = view_contents(*pop_types_file);
2510 parsers::parse_main_pop_type_file(gen, err, context);
2531 for(
auto inv :
world.in_invention) {
2533 auto lim_trigger = inv.get_limit();
2536 [&](uint16_t* tval) {
2537 if((tval[0] & trigger::code_mask) == trigger::technology) {
2538 auto findex = this->world.technology_get_folder_index(trigger::payload(tval[1]).tech_id);
2539 inv.set_technology_type(uint8_t(this->culture_definitions.tech_folders[findex].category));
2552 auto on_action = open_file(common,
NATIVE(
"on_actions.txt"));
2554 auto content = view_contents(*on_action);
2555 err.file_name =
"on_actions.txt";
2557 parsers::parse_on_action_file(gen, err, context);
2560 err.accumulated_errors +=
"File common/on_actions.txt could not be opened\n";
2568 err.file_name =
"production_types.txt";
2572 parsers::parse_production_types_file(gen, err, new_context);
2574 for(
const auto ft : world.in_factory_type) {
2575 if(!
bool(world.factory_type_get_output(ft))) {
2576 err.accumulated_errors +=
"No output defined for factory " + std::string(
text::produce_simple_string(*
this, world.factory_type_get_name(ft))) +
" (" + err.file_name +
")\n";
2579 if(!new_context.found_worker_types) {
2581 err.accumulated_errors +=
"Unable to identify factory worker types from production_types.txt\n";
2585 err.accumulated_errors +=
"File common/production_types.txt could not be opened\n";
2590 err.file_name =
"rebel_types.txt";
2591 for(
auto& r : context.map_of_rebeltypes) {
2599 auto opened_file =
open_file(decision_file);
2604 parsers::parse_decision_file(gen, err, context);
2611 std::vector<simple_fs::file> held_open_files;
2613 auto opened_file =
open_file(event_file);
2618 parsers::parse_event_file(gen, err, context);
2619 held_open_files.emplace_back(std::move(*opened_file));
2622 err.file_name =
"pending events";
2629 auto opened_file =
open_file(news_file);
2642 auto opened_file =
open_file(tutorial_file);
2647 parsers::parse_tutorial_file(gen, err, context);
2659 parsers::parse_battleplan_settings_file(gen, err, context);
2670 if(file_name ==
NATIVE(
"v2dd2.txt"))
2672 auto last = file_name.c_str() + file_name.length();
2673 auto first = file_name.c_str();
2674 auto start_of_name =
last;
2675 for(; start_of_name >=
first; --start_of_name) {
2676 if(*start_of_name ==
NATIVE(
'\\') || *start_of_name ==
NATIVE(
'/')) {
2681 if(last - start_of_name >= 3) {
2683 if(utf8name[0] ==
'R' && utf8name[1] ==
'E' && utf8name[2] ==
'B') {
2685 }
else if(
auto it = context.map_of_ident_names.find(
nations::tag_to_int(utf8name[0], utf8name[1], utf8name[2])); it != context.map_of_ident_names.end()) {
2686 auto holder = context.state.world.national_identity_get_nation_from_identity_holder(it->second);
2691 err.file_name = utf8name;
2694 parsers::parse_oob_file(gen, err, new_context);
2697 err.accumulated_warnings +=
"dead tag " + utf8name.substr(0, 3) +
" encountered while scanning oob files\n";
2700 err.accumulated_warnings +=
"invalid tag " + utf8name.substr(0, 3) +
" encountered while scanning oob files\n";
2705 auto startdate = current_date.to_ymd(start_date);
2706 auto start_dir_name = std::to_string(startdate.year);
2710 auto last = file_name.c_str() + file_name.length();
2711 auto first = file_name.c_str();
2712 auto start_of_name =
last;
2713 for(; start_of_name >=
first; --start_of_name) {
2714 if(*start_of_name ==
NATIVE(
'\\') || *start_of_name ==
NATIVE(
'/')) {
2719 if(last - start_of_name >= 3) {
2721 if(utf8name[0] ==
'R' && utf8name[1] ==
'E' && utf8name[2] ==
'B') {
2723 }
else if(
auto it = context.map_of_ident_names.find(
nations::tag_to_int(utf8name[0], utf8name[1], utf8name[2])); it != context.map_of_ident_names.end()) {
2724 auto holder = context.state.world.national_identity_get_nation_from_identity_holder(it->second);
2729 err.file_name = utf8name;
2732 parsers::parse_oob_file(gen, err, new_context);
2735 err.accumulated_warnings +=
"dead tag " + utf8name.substr(0, 3) +
" encountered while scanning oob files\n";
2738 err.accumulated_warnings +=
"invalid tag " + utf8name.substr(0, 3) +
" encountered while scanning oob files\n";
2752 parsers::parse_diplomacy_file(gen, err, context);
2758 world.nation_resize_flag_variables(
uint32_t(national_definitions.num_allocated_national_flags));
2759 national_definitions.global_flag_variables.resize((national_definitions.num_allocated_global_flags + 7) / 8, dcon::bitfield_type{ 0 });
2760 world.nation_resize_accepted_cultures(world.culture_size());
2762 std::vector<std::pair<dcon::nation_id, dcon::decision_id>> pending_decisions;
2769 auto last = file_name.c_str() + file_name.length();
2770 auto first = file_name.c_str();
2771 auto start_of_name =
last;
2772 for(; start_of_name >=
first; --start_of_name) {
2773 if(*start_of_name ==
NATIVE(
'\\') || *start_of_name ==
NATIVE(
'/')) {
2778 if(last - start_of_name >= 6) {
2781 if(
auto it = context.map_of_ident_names.find(
nations::tag_to_int(utf8name[0], utf8name[1], utf8name[2]));
2782 it != context.map_of_ident_names.end()) {
2783 auto holder = context.state.world.national_identity_get_nation_from_identity_holder(it->second);
2786 holder = world.create_nation();
2787 world.nation_set_diplomatic_points(holder, 1.0f);
2788 world.try_create_identity_holder(holder, it->second);
2793 auto opened_file =
open_file(country_file);
2795 err.file_name = utf8name;
2798 parsers::parse_country_history_file(gen, err, new_context);
2802 err.accumulated_warnings +=
"invalid tag " + utf8name.substr(0, 3) +
" encountered while scanning country history files\n";
2819 parsers::parse_war_history_file(gen, err, new_context);
2826 world.nation_resize_stockpiles(world.commodity_size());
2827 world.nation_resize_variables(
uint32_t(national_definitions.num_allocated_national_variables));
2829 national_definitions.global_flag_variables.resize((national_definitions.num_allocated_global_flags + 7) / 8, dcon::bitfield_type{ 0 });
2832 world.for_each_national_identity([&](dcon::national_identity_id
id) {
2833 if(!world.national_identity_get_nation_from_identity_holder(
id)) {
2834 auto new_nation = world.create_nation();
2835 world.try_create_identity_holder(new_nation, id);
2840 world.nation_resize_rgo_goods_output(world.commodity_size());
2841 world.nation_resize_factory_goods_output(world.commodity_size());
2842 world.nation_resize_factory_goods_throughput(world.commodity_size());
2843 world.nation_resize_rgo_size(world.commodity_size());
2844 world.nation_resize_unlocked_commodities(world.commodity_size());
2845 world.nation_resize_rebel_org_modifier(world.rebel_type_size());
2846 world.nation_resize_active_unit(
uint32_t(military_definitions.unit_base_definitions.size()));
2847 world.nation_resize_active_crime(
uint32_t(culture_definitions.crimes.size()));
2848 world.nation_resize_active_building(world.factory_type_size());
2849 world.nation_resize_unit_stats(
uint32_t(military_definitions.unit_base_definitions.size()));
2855 world.province_resize_rgo_profit_per_good(world.commodity_size());
2856 world.province_resize_rgo_actual_production_per_good(world.commodity_size());
2857 world.province_resize_rgo_employment_per_good(world.commodity_size());
2858 world.province_resize_rgo_target_employment_per_good(world.commodity_size());
2860 world.trade_route_resize_volume(world.commodity_size());
2861 world.nation_resize_factory_type_experience(world.factory_type_size());
2862 world.nation_resize_factory_type_experience_priority_national(world.factory_type_size());
2863 world.nation_resize_factory_type_experience_priority_private(world.factory_type_size());
2865 world.market_resize_price(world.commodity_size());
2866 world.market_resize_supply(world.commodity_size());
2867 world.market_resize_demand(world.commodity_size());
2868 world.market_resize_stockpile(world.commodity_size());
2869 world.market_resize_consumption(world.commodity_size());
2870 world.market_resize_intermediate_demand(world.commodity_size());
2872 world.market_resize_life_needs_costs(world.pop_type_size());
2873 world.market_resize_everyday_needs_costs(world.pop_type_size());
2874 world.market_resize_luxury_needs_costs(world.pop_type_size());
2875 world.market_resize_life_needs_scale(world.pop_type_size());
2876 world.market_resize_everyday_needs_scale(world.pop_type_size());
2877 world.market_resize_luxury_needs_scale(world.pop_type_size());
2878 world.market_resize_max_life_needs_satisfaction(world.pop_type_size());
2879 world.market_resize_max_everyday_needs_satisfaction(world.pop_type_size());
2880 world.market_resize_max_luxury_needs_satisfaction(world.pop_type_size());
2882 world.market_resize_import(world.commodity_size());
2883 world.market_resize_export(world.commodity_size());
2884 world.market_resize_army_demand(world.commodity_size());
2885 world.market_resize_navy_demand(world.commodity_size());
2886 world.market_resize_construction_demand(world.commodity_size());
2887 world.market_resize_private_construction_demand(world.commodity_size());
2888 world.market_resize_demand_satisfaction(world.commodity_size());
2889 world.market_resize_direct_demand_satisfaction(world.commodity_size());
2890 world.market_resize_supply_sold_ratio(world.commodity_size());
2891 world.market_resize_life_needs_weights(world.commodity_size());
2892 world.market_resize_everyday_needs_weights(world.commodity_size());
2893 world.market_resize_luxury_needs_weights(world.commodity_size());
2895 world.nation_resize_stockpile_targets(world.commodity_size());
2896 world.nation_resize_drawing_on_stockpiles(world.commodity_size());
2900 nations_by_rank.resize(2000);
2901 nations_by_industrial_score.resize(2000);
2902 nations_by_military_score.resize(2000);
2903 nations_by_prestige_score.resize(2000);
2904 crisis_participants.resize(2000);
2905 crisis_attacker_wargoals.resize(2000);
2906 crisis_defender_wargoals.resize(2000);
2912 for(
auto t : world.in_technology) {
2913 for(
auto n : world.in_nation) {
2914 if(
n.get_active_technologies(t))
2918 for(
auto t : world.in_invention) {
2919 for(
auto n : world.in_nation) {
2922 n.set_active_inventions(t,
true);
2924 if(
n.get_active_inventions(t)) {
2933 world.for_each_province_adjacency([&](dcon::province_adjacency_id
id) {
2934 auto frel =
fatten(world,
id);
2935 auto prov_a = frel.get_connected_provinces(0);
2936 auto prov_b = frel.get_connected_provinces(1);
2937 if(prov_a.id.index() < province_definitions.first_sea_province.index() && prov_b.id.index() >= province_definitions.first_sea_province.index()) {
2939 }
else if(prov_a.id.index() >= province_definitions.first_sea_province.index() && prov_b.id.index() < province_definitions.first_sea_province.index()) {
2942 if(prov_a.get_state_from_abstract_state_membership() != prov_b.get_state_from_abstract_state_membership()) {
2945 if(prov_a.get_nation_from_province_ownership() != prov_b.get_nation_from_province_ownership()) {
2952 for(int32_t i = 0; i < province_definitions.first_sea_province.index(); ++i) {
2953 dcon::province_id
id{ dcon::province_id::value_base_t(i) };
2954 if(!world.province_get_terrain(
id)) {
2956 if(terrain_type < 64) {
2957 auto modifier = context.modifier_by_terrain_index[terrain_type];
2958 world.province_set_terrain(
id, modifier);
2962 for(int32_t i = province_definitions.first_sea_province.index(); i < int32_t(world.province_size()); ++i) {
2963 dcon::province_id
id{ dcon::province_id::value_base_t(i) };
2964 world.province_set_terrain(
id, context.ocean_terrain);
2972 world.for_each_province([&](dcon::province_id
id) { world.province_set_connected_region_id(
id, 0); });
2974 std::vector<dcon::province_id> to_fill_list;
2975 std::vector<int32_t> region_sizes;
2977 uint16_t current_fill_id = 0;
2978 province_definitions.connected_region_is_coastal.clear();
2980 to_fill_list.reserve(world.province_size());
2982 for(int32_t i = int32_t(world.province_size()); i-- > province_definitions.first_sea_province.index();) {
2983 dcon::province_id
id{ dcon::province_id::value_base_t(i) };
2985 if(world.province_get_connected_region_id(
id) == 0) {
2988 region_sizes.push_back(0);
2989 to_fill_list.push_back(
id);
2991 while(!to_fill_list.empty()) {
2992 auto current_id = to_fill_list.back();
2993 to_fill_list.pop_back();
2994 region_sizes.back() += 1;
2996 world.province_set_connected_region_id(current_id, current_fill_id);
2997 for(
auto rel : world.province_get_province_adjacency(current_id)) {
2999 if(
rel.get_connected_provinces(0).get_connected_region_id() == 0)
3000 to_fill_list.push_back(
rel.get_connected_provinces(0));
3001 if(
rel.get_connected_provinces(1).get_connected_region_id() == 0)
3002 to_fill_list.push_back(
rel.get_connected_provinces(1));
3007 to_fill_list.clear();
3012 for(int32_t i = 0; i < int32_t(region_sizes.size()); ++i) {
3013 if(region_sizes[max] < region_sizes[i])
3017 if(!region_sizes.empty()) {
3018 for(
auto k =
uint32_t(context.state.province_definitions.first_sea_province.index()); k < context.state.world.province_size(); ++k) {
3019 dcon::province_id p{ dcon::province_id::value_base_t(k) };
3020 if(world.province_get_connected_region_id(p) != int16_t(max + 1)) {
3021 world.province_set_is_coast(p,
false);
3022 world.province_set_port_to(p, dcon::province_id{});
3023 for(
auto adj : context.state.world.province_get_province_adjacency(p)) {
3024 auto other =
adj.get_connected_provinces(0) != p ?
adj.get_connected_provinces(0) :
adj.get_connected_provinces(1);
3025 other.set_is_coast(
false);
3026 other.set_port_to(dcon::province_id{});
3034 for(
auto ip : context.special_impassible) {
3035 for(
auto adj : world.province_get_province_adjacency(ip)) {
3042 for(
auto adj : world.province_get_province_adjacency(p)) {
3043 auto other = adj.get_connected_provinces(0) != p ? adj.get_connected_provinces(0) : adj.get_connected_provinces(1);
3044 auto bits = adj.get_type();
3045 if(other && (bits & province::border::coastal_bit) != 0 && (bits & province::border::impassible_bit) == 0) {
3046 world.province_set_port_to(p, other.id);
3047 world.province_set_is_coast(p, true);
3055 bool is_mine = world.commodity_get_is_mine(world.province_get_rgo(p));
3057 for(
auto pop : world.province_get_pop_location(p)) {
3058 if(is_mine && pop.get_pop().get_poptype() == culture_definitions.farmers) {
3059 pop.get_pop().set_poptype(culture_definitions.laborers);
3061 if(!is_mine &&
pop.get_pop().get_poptype() == culture_definitions.laborers) {
3062 pop.get_pop().set_poptype(culture_definitions.farmers);
3067 bool gov_error =
false;
3068 for(
auto n : world.in_nation) {
3069 auto g =
n.get_government_type();
3070 if(!g &&
n.get_owned_province_count() != 0) {
3072 err.accumulated_errors +=
name +
" exists but has no governmentnt (This will result in a crash)\n";
3082 for(
auto& s : context.gfx_context.nation_buttons_allow) {
3083 if(s.button_element) {
3084 err.file_name = s.original_file;
3086 ui_defs.gui[s.button_element].data.button.scriptable_enable =
make_trigger(s.generator_state, err, t_context);
3090 for(
auto& s : context.gfx_context.nation_buttons_effect) {
3091 if(s.button_element) {
3092 err.file_name = s.original_file;
3094 ui_defs.gui[s.button_element].data.button.scriptable_effect =
make_effect(s.generator_state, err, t_context);
3098 for(
auto& s : context.gfx_context.province_buttons_allow) {
3099 if(s.button_element) {
3100 err.file_name = s.original_file;
3101 auto existing_scripting = ui_defs.gui[s.button_element].data.button.get_button_scripting();
3103 err.accumulated_errors += std::string(
"Button ") + std::string(to_string_view(ui_defs.gui[s.button_element].name)) +
"in " + err.file_name +
" has both province and nation scripting set\n";
3106 ui_defs.gui[s.button_element].data.button.scriptable_enable =
make_trigger(s.generator_state, err, t_context);
3111 for(
auto& s : context.gfx_context.province_buttons_effect) {
3112 if(s.button_element) {
3113 err.file_name = s.original_file;
3114 auto existing_scripting = ui_defs.gui[s.button_element].data.button.get_button_scripting();
3116 err.accumulated_errors += std::string(
"Button ") + std::string(to_string_view(ui_defs.gui[s.button_element].name)) +
"in " + err.file_name +
" has both province and nation scripting set\n";
3119 ui_defs.gui[s.button_element].data.button.scriptable_effect =
make_effect(s.generator_state, err, t_context);
3126 for(
auto n : world.in_navy) {
3127 auto p =
n.get_navy_location().get_location();
3128 if(p.id.index() >= province_definitions.first_sea_province.index()) {
3131 auto pp = world.province_get_port_to(p);
3132 auto adj = world.get_province_adjacency_by_province_pair(p, pp);
3134 err.accumulated_errors +=
"Navy defined in " +
text::produce_simple_string(*
this, p.get_name()) +
"; but said province isn't connected to a sea province\n";
3138 for(
auto a : world.in_army) {
3139 auto p = a.get_army_location().get_location();
3140 if(p.id.index() >= province_definitions.first_sea_province.index()) {
3149 for(
auto nid : world.in_national_identity) {
3155 std::fill(has_reported.begin(), has_reported.end(),
false);
3156 for(
auto g : world.in_government_type) {
3157 if(!has_reported[g.get_flag()]) {
3160 file_str +=
NATIVE(
".tga");
3164 has_reported[g.get_flag()] =
true;
3171 for(
auto p : world.in_pop_location) {
3172 for(
const auto src : p.get_pop().get_regiment_source()) {
3173 if(src.get_regiment().get_army_from_army_membership().get_controller_from_army_control() == p.get_province().get_nation_from_province_ownership())
3175 err.accumulated_warnings +=
"Army defined in " +
text::produce_simple_string(*
this, p.get_province().get_name()) +
"; but regiment comes from a province owned by someone else\n";
3176 if(!src.get_regiment().get_army_from_army_membership().get_is_retreating()
3177 && !src.get_regiment().get_army_from_army_membership().get_navy_from_army_transport()
3178 && !src.get_regiment().get_army_from_army_membership().get_battle_from_army_battle_participation()
3179 && !src.get_regiment().get_army_from_army_membership().get_controller_from_army_rebel_control()) {
3180 auto new_u = world.create_army();
3181 world.army_set_controller_from_army_control(new_u, p.get_province().get_nation_from_province_ownership());
3182 src.get_regiment().set_army_from_army_membership(new_u);
3185 src.get_regiment().set_strength(0.f);
3191 fill_unsaved_data();
3193 for(
auto n : world.in_nation) {
3194 auto g =
n.get_government_type();
3196 if(!(
n.get_owned_province_count() == 0 || world.government_type_is_valid(g))) {
3200 for(
auto g : world.in_government_type) {
3201 for(
auto rt : world.in_rebel_type) {
3202 auto ng = rt.get_government_change(g);
3203 if(!(!ng ||
uint32_t(ng.id.index()) < world.government_type_size())) {
3210 for(
auto pending_decision : pending_decisions) {
3211 dcon::nation_id
n = pending_decision.first;
3212 dcon::decision_id
d = pending_decision.second;
3213 if(
auto e = world.decision_get_effect(d); e)
3241 assert(great_nations.size() == 0);
3244 while(greatpowersfound <
uint32_t(defines.great_nations_count)) {
3245 if(i >= nations_by_rank.size()) {
3248 if(nations_by_rank[i] && world.overlord_get_ruler(world.nation_get_overlord_as_subject(nations_by_rank[i])) == dcon::nation_id()) {
3249 great_nations.push_back(great_nation{
sys::date{0}, nations_by_rank[i] });
3250 world.nation_set_is_great_power(nations_by_rank[i],
true);
3257 for(
auto p : world.in_province) {
3264 if(
auto rgo = world.province_get_rgo(p); !rgo) {
3265 auto name = world.province_get_name(p);
3266 err.accumulated_errors += std::string(
"province ") + text::produce_simple_string(*this, name) +
" is missing an rgo\n";
3267 world.province_set_rgo(p, economy::money);
3290void state::preload() {
3291 adjacency_data_out_of_date =
true;
3292 for(
auto si : world.in_state_instance) {
3293 si.set_naval_base_is_taken(
false);
3294 si.set_capital(dcon::province_id{});
3296 for(
auto n : world.in_nation) {
3297 n.set_combined_issue_rules(0);
3298 n.set_is_at_war(
false);
3299 n.set_allies_count(0);
3300 n.set_vassals_count(0);
3301 n.set_substates_count(0);
3302 n.set_administrative_efficiency(0.0f);
3303 n.set_is_target_of_some_cb(
false);
3304 n.set_in_sphere_of(dcon::nation_id{});
3305 n.set_is_player_controlled(
false);
3306 n.set_is_great_power(
false);
3307 n.set_is_colonial_nation(
false);
3308 n.set_has_flash_point_state(
false);
3309 n.set_ai_is_threatened(
false);
3310 n.set_ai_home_port(dcon::province_id{});
3312 for(
auto p : world.in_pop) {
3315 p.set_is_primary_or_accepted_culture(
false);
3317 for(
auto p : world.in_province) {
3318 p.set_state_membership(dcon::state_instance_id{});
3319 p.set_is_owner_core(
false);
3320 p.set_is_blockaded(
false);
3322 for(
auto m : world.in_movement) {
3323 m.set_pop_support(0.0f);
3324 m.set_radicalism(0.0f);
3326 for(
auto s : world.in_ship) {
3327 s.set_pending_split(
false);
3329 for(
auto r : world.in_regiment) {
3330 r.set_pending_split(
false);
3334void state::on_scenario_load() {
3335 world.pop_type_resize_issues_fns(world.issue_option_size());
3336 world.pop_type_resize_ideology_fns(world.ideology_size());
3337 world.pop_type_resize_promotion_fns(world.pop_type_size());
3339 ui_state.rebel_flags.resize(world.ideology_size(), 0);
3341 if(network_mode != network_mode_type::single_player)
3349 std::thread dispatch{ [&]() {
3350 jit_environment = std::make_unique<fif::environment>();
3352 int32_t error_count = 0;
3353 std::string error_list;
3354 jit_environment->report_error = [&](std::string_view s) {
3355 console_command_error += std::string(
"?R ERROR: ") + std::string(s) +
"?W\\n";
3366 for(
auto p : world.in_pop_type) {
3367 for(
auto i : world.in_issue_option) {
3368 auto mkey = world.pop_type_get_issues(p, i);
3369 std::string base_name =
"pi" + std::to_string(p.id.index()) +
"_" + std::to_string(i.id.index());
3372 fn_str +=
":export " + base_name +
"ext" +
" i32 " + base_name +
"internal ; ";
3375 std::string fn_str =
": " + base_name +
"internal" +
" drop 0.0 ; ";
3376 fn_str +=
":export " + base_name +
"ext" +
" i32 " + base_name +
"internal ; ";
3381 for(
auto id : world.in_ideology) {
3382 auto mkey = world.pop_type_get_ideology(p,
id);
3383 std::string base_name =
"pid" + std::to_string(p.id.index()) +
"_" + std::to_string(
id.
id.index());
3386 fn_str +=
":export " + base_name +
"ext" +
" i32 " + base_name +
"internal ; ";
3389 std::string fn_str =
": " + base_name +
"internal" +
" drop 0.0 ; ";
3390 fn_str +=
":export " + base_name +
"ext" +
" i32 " + base_name +
"internal ; ";
3395 for(
auto t : world.in_pop_type) {
3396 auto mkey = world.pop_type_get_promotion(p, t);
3397 std::string base_name =
"pp" + std::to_string(p.id.index()) +
"_" + std::to_string(t.id.index());
3400 fn_str +=
":export " + base_name +
"ext" +
" i32 " + base_name +
"internal ; ";
3406 auto mkey = world.pop_type_get_migration_target(p);
3407 std::string base_name =
"pmt" + std::to_string(p.id.index());
3410 fn_str +=
":export " + base_name +
"ext" +
" i32 i32 " + base_name +
"internal ; ";
3415 auto mkey = world.pop_type_get_country_migration_target(p);
3416 std::string base_name =
"pcmt" + std::to_string(p.id.index());
3419 fn_str +=
":export " + base_name +
"ext" +
" i32 i32 " + base_name +
"internal ; ";
3425 std::string fn_str =
": promote_internal >pop_id dup " +
fif_trigger::additive_modifier(*
this, culture_definitions.promotion_chance) +
" drop drop r> ; ";
3426 fn_str +=
":export promote_ext i32 promote_internal ; ";
3430 std::string fn_str =
": demote_internal >pop_id dup " +
fif_trigger::additive_modifier(*
this, culture_definitions.demotion_chance) +
" drop drop r> ; ";
3431 fn_str +=
":export demote_ext i32 demote_internal ; ";
3435 fif::perform_jit(*jit_environment);
3440 for(
auto p : world.in_pop_type) {
3441 for(
auto i : world.in_issue_option) {
3442 std::string name =
"pi" + std::to_string(p.id.index()) +
"_" + std::to_string(i.id.index()) +
"ext";
3445 auto error =
LLVMOrcLLJITLookup(jit_environment->llvm_jit, &bare_address, name.c_str());
3450 OutputDebugStringA(msg);
3451 OutputDebugStringA(
"\n");
3455 assert(bare_address != 0);
3456 world.pop_type_set_issues_fns(p, i, bare_address);
3459 for(
auto id : world.in_ideology) {
3460 std::string name =
"pid" + std::to_string(p.id.index()) +
"_" + std::to_string(
id.
id.index()) +
"ext";
3463 auto error =
LLVMOrcLLJITLookup(jit_environment->llvm_jit, &bare_address, name.c_str());
3468 OutputDebugStringA(msg);
3469 OutputDebugStringA(
"\n");
3473 assert(bare_address != 0);
3474 world.pop_type_set_ideology_fns(p,
id, bare_address);
3477 for(
auto t : world.in_pop_type) {
3478 if(world.pop_type_get_promotion(p, t)) {
3479 std::string name =
"pp" + std::to_string(p.id.index()) +
"_" + std::to_string(t.id.index()) +
"ext";
3482 auto error =
LLVMOrcLLJITLookup(jit_environment->llvm_jit, &bare_address, name.c_str());
3487 OutputDebugStringA(msg);
3488 OutputDebugStringA(
"\n");
3492 assert(bare_address != 0);
3493 world.pop_type_set_promotion_fns(p, t, bare_address);
3499 auto mkey = world.pop_type_get_migration_target(p);
3501 std::string base_name =
"pmt" + std::to_string(p.id.index()) +
"ext";
3503 auto error =
LLVMOrcLLJITLookup(jit_environment->llvm_jit, &bare_address, base_name.c_str());
3508 OutputDebugStringA(msg);
3509 OutputDebugStringA(
"\n");
3513 assert(bare_address != 0);
3514 world.pop_type_set_migration_target_fn(p, bare_address);
3519 auto mkey = world.pop_type_get_country_migration_target(p);
3521 std::string base_name =
"pcmt" + std::to_string(p.id.index()) +
"ext";
3523 auto error =
LLVMOrcLLJITLookup(jit_environment->llvm_jit, &bare_address, base_name.c_str());
3528 OutputDebugStringA(msg);
3529 OutputDebugStringA(
"\n");
3533 assert(bare_address != 0);
3534 world.pop_type_set_country_migration_target_fn(p, bare_address);
3542 auto error =
LLVMOrcLLJITLookup(jit_environment->llvm_jit, &bare_address,
"promote_ext");
3547 OutputDebugStringA(msg);
3548 OutputDebugStringA(
"\n");
3552 assert(bare_address != 0);
3553 culture_definitions.promotion_chance_fn = bare_address;
3558 auto error =
LLVMOrcLLJITLookup(jit_environment->llvm_jit, &bare_address,
"demote_ext");
3563 OutputDebugStringA(msg);
3564 OutputDebugStringA(
"\n");
3568 assert(bare_address != 0);
3569 culture_definitions.demotion_chance_fn = bare_address;
3578 auto error =
LLVMOrcLLJITLookup(jit_environment->llvm_jit, &bare_address,
"set_container");
3583 OutputDebugStringA(msg);
3584 OutputDebugStringA(
"\n");
3588 assert(bare_address != 0);
3589 using ftype = void(*)(
void*);
3590 ftype fn = (ftype)bare_address;
3596 auto error =
LLVMOrcLLJITLookup(jit_environment->llvm_jit, &bare_address,
"set_vector_storage");
3601 OutputDebugStringA(msg);
3602 OutputDebugStringA(
"\n");
3606 assert(bare_address != 0);
3607 using ftype = void(*)(
void*);
3608 ftype fn = (ftype)bare_address;
3609 fn(dcon::shared_backing_storage.allocation);
3614 auto error =
LLVMOrcLLJITLookup(jit_environment->llvm_jit, &bare_address,
"set_state");
3619 OutputDebugStringA(msg);
3620 OutputDebugStringA(
"\n");
3624 assert(bare_address != 0);
3625 using ftype = void(*)(
void*);
3626 ftype fn = (ftype)bare_address;
3640void state::fill_unsaved_data() {
3641 great_nations.reserve(int32_t(defines.great_nations_count));
3644 world.nation_resize_rgo_goods_output(world.commodity_size());
3645 world.nation_resize_factory_goods_output(world.commodity_size());
3646 world.nation_resize_factory_goods_throughput(world.commodity_size());
3647 world.nation_resize_rgo_size(world.commodity_size());
3648 world.nation_resize_unlocked_commodities(world.commodity_size());
3649 world.nation_resize_rebel_org_modifier(world.rebel_type_size());
3650 world.nation_resize_active_unit(
uint32_t(military_definitions.unit_base_definitions.size()));
3651 world.nation_resize_active_crime(
uint32_t(culture_definitions.crimes.size()));
3652 world.nation_resize_active_building(world.factory_type_size());
3653 world.nation_resize_unit_stats(
uint32_t(military_definitions.unit_base_definitions.size()));
3656 world.province_resize_modifier_values(provincial_mod_offsets::count);
3669 nations_by_rank.resize(2000);
3670 nations_by_industrial_score.resize(2000);
3671 nations_by_military_score.resize(2000);
3672 crisis_attacker_wargoals.resize(2000);
3673 crisis_defender_wargoals.resize(2000);
3674 nations_by_prestige_score.resize(2000);
3675 crisis_participants.resize(2000);
3680 world.for_each_issue([&](dcon::issue_id
id) {
3681 for(
auto& opt : world.issue_get_options(
id)) {
3683 world.issue_option_set_parent_issue(opt,
id);
3687 world.for_each_reform([&](dcon::reform_id
id) {
3688 for(
auto& opt : world.reform_get_options(
id)) {
3690 world.reform_option_set_parent_reform(opt,
id);
3694 for(
auto i : culture_definitions.party_issues) {
3697 for(
auto i : culture_definitions.military_issues) {
3700 for(
auto i : culture_definitions.economic_issues) {
3703 for(
auto i : culture_definitions.social_issues) {
3706 for(
auto i : culture_definitions.political_issues) {
3749 new_n_event.~SPSCQueue();
3762 if(local_player_nation) {
3763 world.nation_set_is_player_controlled(local_player_nation,
true);
3765 for(
auto const& e : pending_n_event) {
3766 if(e.n == local_player_nation) {
3767 auto auto_choice = world.national_event_get_auto_choice(e.e);
3768 if(auto_choice == 0)
3774 for(
auto const& e : pending_f_n_event) {
3775 if(e.n == local_player_nation) {
3776 auto auto_choice = world.free_national_event_get_auto_choice(e.e);
3777 if(auto_choice == 0)
3778 auto b = new_f_n_event.try_push(e);
3783 for(
auto const& e : pending_p_event) {
3784 if(world.province_get_nation_from_province_ownership(e.p) == local_player_nation) {
3785 auto auto_choice = world.provincial_event_get_auto_choice(e.e);
3786 if(auto_choice == 0)
3787 auto b = new_p_event.try_push(e);
3792 for(
auto const& e : pending_f_p_event) {
3793 if(world.province_get_nation_from_province_ownership(e.p) == local_player_nation) {
3794 auto auto_choice = world.free_provincial_event_get_auto_choice(e.e);
3795 if(auto_choice == 0)
3796 auto b = new_f_p_event.try_push(e);
3801 for(
auto const& m : pending_messages) {
3803 auto b = new_requests.try_push(m);
3807 ui_date = current_date;
3820 military_definitions.pending_blackflag_update =
true;
3827 for(
auto p : world.in_pop) {
3829 for(
auto i : world.in_ideology) {
3831 if(0.0 <= val && val <= 1.0f) {
3838 for(
auto i : world.in_ideology) {
3845 for(
auto a : world.in_army) {
3846 if(a.get_arrival_time() && a.get_arrival_time() <= current_date) {
3847 a.set_arrival_time(current_date + 1);
3850 for(
auto a : world.in_navy) {
3851 if(a.get_arrival_time() && a.get_arrival_time() <= current_date) {
3852 a.set_arrival_time(current_date + 1);
3855 for(
auto shp : world.in_ship) {
3856 assert(shp.get_navy_from_navy_membership());
3859 std::vector<dcon::ship_id> sin_battle;
3860 for(
auto b : world.in_naval_battle) {
3861 for(
auto slot : b.get_slots()) {
3865 assert(world.ship_is_valid(slot.ship));
3866 auto it = std::find(sin_battle.begin(), sin_battle.end(), slot.ship);
3867 assert(it == sin_battle.end());
3868 sin_battle.push_back(slot.ship);
3875 game_state_updated.store(
true, std::memory_order::release);
3878void state::single_game_tick() {
3885 game_state_updated.store(
true, std::memory_order::release);
3889 auto ymd_date = current_date.to_ymd(start_date);
3908 concurrency::parallel_for(0, 7, [&](int32_t index) {
3913 if(o >= days_in_month)
3920 auto o =
uint32_t(ymd_date.day + 1);
3921 if(o >= days_in_month)
3928 auto o =
uint32_t(ymd_date.day + 6);
3929 if(o >= days_in_month)
3936 auto o =
uint32_t(ymd_date.day + 7);
3937 if(o >= days_in_month)
3944 auto o =
uint32_t(ymd_date.day + 8);
3945 if(o >= days_in_month)
3952 auto o =
uint32_t(ymd_date.day + 9);
3953 if(o >= days_in_month)
3960 auto o =
uint32_t(ymd_date.day + 10);
3961 if(o >= days_in_month)
3972 concurrency::parallel_for(0, 8, [&](int32_t index) {
3976 auto o =
uint32_t(ymd_date.day + 0);
3977 if(o >= days_in_month)
3984 auto o =
uint32_t(ymd_date.day + 1);
3985 if(o >= days_in_month)
3992 auto o =
uint32_t(ymd_date.day + 2);
3993 if(o >= days_in_month)
4000 auto o =
uint32_t(ymd_date.day + 3);
4001 if(o >= days_in_month)
4008 auto o =
uint32_t(ymd_date.day + 4);
4009 if(o >= days_in_month)
4016 auto o =
uint32_t(ymd_date.day + 5);
4017 if(o >= days_in_month)
4024 [&](
auto ids) { world.province_set_daily_net_migration(ids, ve::fp_vector{}); });
4028 [&](
auto ids) { world.province_set_daily_net_immigration(ids, ve::fp_vector{}); });
4037 auto o =
uint32_t(ymd_date.day + 6);
4038 if(o >= days_in_month)
4043 auto o =
uint32_t(ymd_date.day + 7);
4044 if(o >= days_in_month)
4049 auto o =
uint32_t(ymd_date.day + 8);
4050 if(o >= days_in_month)
4055 auto o =
uint32_t(ymd_date.day + 9);
4056 if(o >= days_in_month)
4061 auto o =
uint32_t(ymd_date.day + 10);
4062 if(o >= days_in_month)
4071 int64_t pc_difference = 0;
4073 if(network_mode != network_mode_type::single_player)
4080 concurrency::parallel_invoke([&]() {
4082 concurrency::parallel_for(0, 17, [&](int32_t index) {
4089 for(
auto n : this->cheat_data.instant_research_nations) {
4090 auto tech = this->world.nation_get_current_research(n);
4091 if(
tech.is_valid()) {
4093 this->world.nation_set_research_points(n, points);
4176 if(current_date.value % 4 == 0) {
4180 if(defines.alice_eval_ai_mil_everyday != 0.0f) {
4188 switch(ymd_date.day) {
4203 if(!
bool(defines.alice_eval_ai_mil_everyday)) {
4213 if(!
bool(defines.alice_eval_ai_mil_everyday)) {
4260 if(!
bool(defines.alice_eval_ai_mil_everyday)) {
4276 if(!
bool(defines.alice_eval_ai_mil_everyday)) {
4298 if(!
bool(defines.alice_eval_ai_mil_everyday)) {
4314 if(ymd_date.day == 1) {
4315 if(ymd_date.month == 1) {
4317 for(
auto n : world.in_nation) {
4318 if(n.get_owned_province_count() != 0)
4326 if(ymd_date.month == 2) {
4329 if(ymd_date.month == 3 && !national_definitions.on_quarterly_pulse.empty()) {
4330 for(
auto n : world.in_nation) {
4331 if(n.get_owned_province_count() > 0) {
4336 if(ymd_date.month == 4 && ymd_date.year % 2 == 0) {
4339 if(ymd_date.month == 5) {
4343 if(ymd_date.month == 6 && !national_definitions.on_quarterly_pulse.empty()) {
4344 for(
auto n : world.in_nation) {
4345 if(n.get_owned_province_count() > 0) {
4350 if(ymd_date.month == 7) {
4354 if(ymd_date.month == 9 && !national_definitions.on_quarterly_pulse.empty()) {
4355 for(
auto n : world.in_nation) {
4356 if(n.get_owned_province_count() > 0) {
4361 if(ymd_date.month == 10 && !national_definitions.on_yearly_pulse.empty()) {
4362 for(
auto n : world.in_nation) {
4363 if(n.get_owned_province_count() > 0) {
4368 if(ymd_date.month == 11) {
4371 if(ymd_date.month == 12 && !national_definitions.on_quarterly_pulse.empty()) {
4372 for(
auto n : world.in_nation) {
4373 if(n.get_owned_province_count() > 0) {
4393 if(network_mode == network_mode_type::single_player)
4398 if(network_mode == network_mode_type::single_player) {
4399 world.nation_swap_demographics_demographics_alt();
4400 world.state_instance_swap_demographics_demographics_alt();
4401 world.province_swap_demographics_demographics_alt();
4410 player_data_cache.treasury_record[current_date.value % 32] =
nations::get_treasury(*
this, local_player_nation);
4411 player_data_cache.population_record[current_date.value % 32] = world.nation_get_demographics(local_player_nation,
demographics::total);
4412 if((current_date.value % 16) == 0) {
4414 for(
auto c : world.in_commodity) {
4419 if(((ymd_date.month % 3) == 0) && (ymd_date.day == 1)) {
4421 for(
auto n : world.in_nation) {
4426 ui_date = current_date;
4428 game_state_updated.store(
true, std::memory_order::release);
4430 switch(user_settings.autosaves) {
4431 case autosave_frequency::none:
4433 case autosave_frequency::daily:
4436 case autosave_frequency::monthly:
4437 if(ymd_date.day == 1)
4440 case autosave_frequency::yearly:
4441 if(ymd_date.month == 1 && ymd_date.day == 1)
4450 dcon::load_record loaded = world.make_serialize_record_store_save();
4451 auto buffer = std::unique_ptr<uint8_t[]>(
new uint8_t[world.serialize_size(loaded)]);
4452 std::byte* start =
reinterpret_cast<std::byte*
>(buffer.get());
4453 world.serialize(start, loaded);
4455 auto buffer_position =
reinterpret_cast<uint8_t*
>(start);
4456 int32_t total_size_used =
static_cast<int32_t
>(buffer_position - buffer.get());
4459 blake2b(&key,
sizeof(key), buffer.get(), total_size_used,
nullptr, 0);
4463void state::debug_save_oos_dump() {
4467 dcon::load_record loaded = world.make_serialize_record_store_save();
4468 auto save_buffer = std::unique_ptr<uint8_t[]>(
new uint8_t[world.serialize_size(loaded)]);
4469 auto buffer_position =
reinterpret_cast<std::byte*
>(save_buffer.get());
4470 world.serialize(buffer_position, loaded);
4471 size_t total_size_used =
reinterpret_cast<uint8_t*
>(buffer_position) - save_buffer.get();
4477 size_t total_size_used =
reinterpret_cast<uint8_t*
>(buffer_position) - buffer.get();
4482void state::debug_scenario_oos_dump() {
4486 dcon::load_record loaded = world.make_serialize_record_store_scenario();
4487 auto buffer = std::unique_ptr<uint8_t[]>(
new uint8_t[world.serialize_size(loaded)]);
4488 auto buffer_position =
reinterpret_cast<std::byte*
>(buffer.get());
4489 world.serialize(buffer_position, loaded);
4490 size_t total_size_used =
reinterpret_cast<uint8_t*
>(buffer_position) - buffer.get();
4496 size_t total_size_used =
reinterpret_cast<uint8_t*
>(buffer_position) - buffer.get();
4501void state::game_loop() {
4502 static int32_t game_speed[] = {
4509 game_speed[1] = int32_t(defines.alice_speed_1);
4510 game_speed[2] = int32_t(defines.alice_speed_2);
4511 game_speed[3] = int32_t(defines.alice_speed_3);
4512 game_speed[4] = int32_t(defines.alice_speed_4);
4514 while(quit_signaled.load(std::memory_order::acquire) ==
false) {
4517 std::lock_guard l{ ugly_ui_game_interaction_hack };
4521 std::this_thread::sleep_for(std::chrono::milliseconds(15));
4523 auto speed = actual_game_speed.load(std::memory_order::acquire);
4524 auto upause = ui_pause.load(std::memory_order::acquire);
4529 if(speed <= 0 || upause || internally_paused || current_scene.enforced_pause) {
4530 std::this_thread::sleep_for(std::chrono::milliseconds(15));
4532 auto entry_time = std::chrono::steady_clock::now();
4533 auto ms_count = std::chrono::duration_cast<std::chrono::milliseconds>(entry_time - last_update).count();
4534 if(speed >= 5 || ms_count >= game_speed[speed]) {
4535 last_update = entry_time;
4539 std::lock_guard l{ ugly_ui_game_interaction_hack };
4543 std::this_thread::sleep_for(std::chrono::milliseconds(1));
4550void state::console_log(std::string_view message) {
4551 current_scene.console_log(*
this, message);
4554void state::new_army_group(dcon::province_id hq) {
4555 bool invalid_province =
false;
4556 world.for_each_automated_army_group(
4557 [&](dcon::automated_army_group_id item) {
4558 auto item_hq = world.automated_army_group_get_hq(item);
4560 invalid_province =
true;
4564 if(invalid_province) {
4567 auto new_group = world.create_automated_army_group();
4568 world.automated_army_group_set_hq(new_group, hq);
4569 world.automated_army_group_set_owner(new_group, local_player_nation);
4571 game_state_updated.store(
true, std::memory_order_release);
4574void state::toggle_defensive_position(dcon::automated_army_group_id group, dcon::province_id position) {
4575 auto fat_group = fatten(world, group);
4577 if(fat_group.get_provinces_defend().contains(position)) {
4578 fat_group.get_provinces_defend().remove_unique(position);
4580 fat_group.get_provinces_defend().push_back(position);
4583 game_state_updated.store(
true, std::memory_order_release);
4584 map_state.unhandled_province_selection =
true;
4587void state::toggle_enforce_control_position(dcon::automated_army_group_id group, dcon::province_id position) {
4588 auto fat_group = fatten(world, group);
4590 if(fat_group.get_provinces_enforce_control().contains(position)) {
4591 fat_group.get_provinces_enforce_control().remove_unique(position);
4593 fat_group.get_provinces_enforce_control().push_back(position);
4596 game_state_updated.store(
true, std::memory_order_release);
4597 map_state.unhandled_province_selection =
true;
4600void state::toggle_designated_port(dcon::automated_army_group_id group, dcon::province_id position) {
4601 auto fat_group = fatten(world, group);
4603 if(!world.province_get_is_coast(position)) {
4607 if(fat_group.get_provinces_ferry_origin().contains(position)) {
4608 fat_group.get_provinces_ferry_origin().remove_unique(position);
4610 fat_group.get_provinces_ferry_origin().push_back(position);
4613 game_state_updated.store(
true, std::memory_order_release);
4614 map_state.unhandled_province_selection =
true;
4617void state::army_group_add_regiment(dcon::automated_army_group_id group, dcon::regiment_id
id) {
4619 auto automation_check = world.regiment_get_automation(
id);
4620 if(automation_check) {
4624 auto automation_data = world.create_regiment_automation_data();
4627 std::lock_guard l{ ugly_ui_game_interaction_hack };
4628 world.try_create_automated_army_group_membership_regiment(automation_data, group);
4629 world.try_create_automation(automation_data,
id);
4632 auto fat_automation = fatten(world, automation_data);
4634 auto army = world.regiment_get_army_from_army_membership(
id);
4635 auto location = world.army_get_location_from_army_location(army);
4637 fat_automation.set_status(army_group_regiment_status::standby);
4638 fat_automation.set_task(army_group_regiment_task::idle);
4639 fat_automation.set_target(location);
4640 fat_automation.set_ferry_origin({ });
4641 fat_automation.set_ferry_target({ });
4642 fat_automation.set_await_command_execution_flag(
false);
4645 std::array<dcon::regiment_id, command::num_packed_units> data;
4647 data.fill(dcon::regiment_id{});
4652 game_state_updated.store(
true, std::memory_order_release);
4655void state::remove_navy_from_army_group(dcon::automated_army_group_id selected_group, dcon::navy_id navy_to_delete) {
4656 std::lock_guard l{ ugly_ui_game_interaction_hack };
4658 auto membership = world.navy_get_automated_army_group_membership_navy(navy_to_delete);
4663 world.delete_automated_army_group_membership_navy(membership);
4666void state::remove_regiment_from_army_group(dcon::automated_army_group_id selected_group, dcon::regiment_id regiment_to_delete) {
4667 std::lock_guard l{ ugly_ui_game_interaction_hack };
4669 auto regiment_automation_relation = world.regiment_get_automation(regiment_to_delete);
4670 auto automation_data = world.automation_get_automation_data(regiment_automation_relation);
4672 if(!automation_data) {
4676 world.delete_regiment_automation_data(automation_data);
4679void state::remove_regiment_from_all_army_groups(dcon::regiment_id regiment_to_delete) {
4680 world.for_each_automated_army_group([&](dcon::automated_army_group_id item) {
4681 remove_regiment_from_army_group(item, regiment_to_delete);
4685void state::remove_army_army_group_clean(dcon::automated_army_group_id group, dcon::army_id army_to_delete) {
4686 for(
auto regiment_membership : world.army_get_army_membership(army_to_delete)) {
4687 remove_regiment_from_army_group(group, regiment_membership.get_regiment().id);
4691void state::add_army_to_army_group(dcon::automated_army_group_id selected_group, dcon::army_id selected_army) {
4692 for(
auto item : world.army_get_army_membership(selected_army)) {
4693 army_group_add_regiment(selected_group, item.get_regiment());
4697void state::add_navy_to_army_group(dcon::automated_army_group_id selected_group, dcon::navy_id selected_navy) {
4698 auto automation_link = world.navy_get_automated_army_group_membership_navy(selected_navy);
4699 auto current_group = world.automated_army_group_membership_navy_get_army(automation_link);
4706 std::lock_guard l{ ugly_ui_game_interaction_hack };
4707 auto new_link = world.try_create_automated_army_group_membership_navy(selected_navy, selected_group);
4710 game_state_updated.store(
true, std::memory_order_release);
4713void state::delete_army_group(dcon::automated_army_group_id group) {
4714 static std::vector<dcon::regiment_automation_data_id> to_delete = {};
4717 world.automated_army_group_for_each_automated_army_group_membership_regiment(group, [&](dcon::automated_army_group_membership_regiment_id item) {
4718 auto regiment = world.automated_army_group_membership_regiment_get_regiment(item);
4719 to_delete.push_back(regiment);
4722 std::lock_guard l{ ugly_ui_game_interaction_hack };
4724 if(!to_delete.empty()) {
4725 for(
auto& regiment : to_delete) {
4726 world.delete_regiment_automation_data(regiment);
4730 world.delete_automated_army_group(group);
4731 game_state_updated.store(
true, std::memory_order_release);
4734void state::update_armies_and_fleets(dcon::automated_army_group_id group) {
4735 auto owner = world.automated_army_group_get_owner(group);
4737 if(owner == local_player_nation) {
4739 static std::vector<dcon::regiment_automation_data_id> to_delete = {};
4742 world.automated_army_group_for_each_automated_army_group_membership_regiment(group, [&](dcon::automated_army_group_membership_regiment_id item) {
4743 auto regiment = world.automated_army_group_membership_regiment_get_regiment(item);
4744 auto regiment_true = world.regiment_automation_data_get_regiment_from_automation(regiment);
4745 if(!regiment_true) {
4746 to_delete.push_back(regiment);
4750 if(!to_delete.empty()) {
4751 std::lock_guard l{ ugly_ui_game_interaction_hack };
4752 for(
auto& regiment : to_delete) {
4753 world.delete_regiment_automation_data(regiment);
4758 delete_army_group(group);
4762void state::smart_select_army_group(dcon::automated_army_group_id selected_group) {
4763 if(!selected_army_group) {
4764 select_army_group(selected_group);
4768 if(selected_army_group == selected_group) {
4769 deselect_army_group();
4773 select_army_group(selected_group);
4776void state::select_army_group(dcon::automated_army_group_id selected_group) {
4777 selected_army_group = selected_group;
4779 game_state_updated.store(
true, std::memory_order_release);
4782void state::deselect_army_group() {
4783 selected_army_group = {};
4785 game_state_updated.store(
true, std::memory_order_release);
4788dcon::regiment_automation_data_id state::fill_province_up_to_supply_limit(
4789 dcon::automated_army_group_id group_id,
4790 dcon::province_id target,
4791 std::vector<float>& regiments_distribution,
4792 float overestimate_supply_limit,
4793 bool ignore_enemy_regiments_in_supply_calculations
4795 auto group = fatten(world, group_id);
4797 static std::vector<float> regiments_expectation_ideal;
4798 regiments_expectation_ideal.resize(military_definitions.unit_base_definitions.size() + 2);
4800 for(
uint32_t i = 0; i < military_definitions.unit_base_definitions.size(); ++i) {
4801 regiments_expectation_ideal[i] = 0.f;
4807 local_player_nation,
4809 )) * overestimate_supply_limit;
4816 if(ignore_enemy_regiments_in_supply_calculations) {
4821 for(
auto regiment_id : group.get_automated_army_group_membership_regiment()) {
4822 auto regiment =
dcon::fatten(world, regiment_id).get_regiment();
4823 if(regiment.get_target() == target && regiment.get_status() == army_group_regiment_status::move_to_target) {
4824 current_weight += 3.f;
4825 }
else if(regiment.get_ferry_target() == target && regiment.get_status() == army_group_regiment_status::move_to_port) {
4826 current_weight += 3.f;
4832 for(
uint32_t i = 0; i < military_definitions.unit_base_definitions.size(); ++i) {
4833 regiments_expectation_ideal[i] = floor(regiments_distribution[i] * floor(supply_limit / 3.f)) * 3.f;
4834 ideal += regiments_expectation_ideal[i];
4837 if(current_weight + 3.f < ideal) {
4838 return fill_province(group, target, regiments_expectation_ideal);
4844float state::army_group_available_supply(dcon::automated_army_group_id group, dcon::province_id
province) {
4846 float current_weight = 0.f;
4847 for(
auto regiment_id : world.automated_army_group_get_automated_army_group_membership_regiment(group)) {
4848 auto regiment =
dcon::fatten(world, regiment_id).get_regiment();
4849 if(regiment.get_target() ==
province) {
4850 current_weight += 3.f;
4852 regiment.get_ferry_target() ==
province
4854 regiment.get_status() == army_group_regiment_status::move_to_port
4855 || regiment.get_status() == army_group_regiment_status::await_transport
4856 || regiment.get_status() == army_group_regiment_status::is_transported
4857 || regiment.get_status() == army_group_regiment_status::disembark
4860 current_weight += 3.f;
4862 regiment.get_ferry_origin() ==
province
4864 regiment.get_status() == army_group_regiment_status::move_to_port
4865 || regiment.get_status() == army_group_regiment_status::await_transport
4868 current_weight += 3.f;
4872 return max_supply - current_weight;
4875void state::regiment_reset_order(dcon::regiment_automation_data_id regiment) {
4876 auto fat_data = fatten(world, regiment);
4878 fat_data.set_status(army_group_regiment_status::standby);
4879 fat_data.set_task(army_group_regiment_task::idle);
4882dcon::province_id state::find_available_ferry_origin(dcon::automated_army_group_id group, dcon::regiment_automation_data_id regiment) {
4883 auto fat_reg = fatten(world, regiment);
4884 auto army = fat_reg.get_regiment_from_automation().get_army_from_army_membership();
4885 auto fat_group = fatten(world, group);
4887 for(
auto& item : fat_group.get_provinces_ferry_origin()) {
4889 if(army_group_available_supply(group, item) < 3.f) {
4898 if(world.province_get_is_coast(army.get_location_from_army_location())) {
4899 return army.get_location_from_army_location();
4903 static std::vector<dcon::province_id> origin_port_candidates;
4904 origin_port_candidates.clear();
4907 origin_port_candidates.push_back(army.get_location_from_army_location());
4909 while(l < r && l < 30) {
4910 auto current_location = origin_port_candidates[l];
4912 if(world.province_get_is_coast(current_location)) {
4913 return current_location;
4916 if(current_location.value >= province_definitions.first_sea_province.value) {
4926 for(
auto adj : world.province_get_province_adjacency(current_location)) {
4927 auto other = adj.get_connected_provinces(adj.get_connected_provinces(0) == current_location ? 1 : 0);
4929 if(std::find(origin_port_candidates.begin(), origin_port_candidates.end(), other) == origin_port_candidates.end()) {
4930 origin_port_candidates.push_back(other);
4939 dcon::province_id invalid_province{};
4940 return invalid_province;
4943bool state::move_to_available_port(dcon::automated_army_group_id group, dcon::regiment_automation_data_id regiment) {
4944 auto fat_reg = fatten(world, regiment);
4945 dcon::province_id target = find_available_ferry_origin(group, regiment);
4946 auto army = fat_reg.get_regiment_from_automation().get_army_from_army_membership();
4949 if(army.get_location_from_army_location() != target) {
4951 fat_reg.set_await_command_execution_flag(
true);
4953 fat_reg.set_status(army_group_regiment_status::move_to_port);
4954 fat_reg.set_ferry_origin(target);
4961bool state::army_group_recalculate_distribution(dcon::automated_army_group_id group, std::vector<float>& regiments_distribution) {
4962 for(
uint32_t i = 0; i < military_definitions.unit_base_definitions.size(); ++i) {
4963 regiments_distribution[i] = 0.f;
4968 for(
auto regiment_id : world.automated_army_group_get_automated_army_group_membership_regiment(group)) {
4969 auto regiment =
dcon::fatten(world, regiment_id).get_regiment();
4971 auto regiment_type = regiment.get_regiment_from_automation().get_type();
4973 if(!regiment_type) {
4977 auto task = regiment.get_task();
4978 auto status = regiment.get_status();
4980 task == army_group_regiment_task::idle ||
4981 task == army_group_regiment_task::gather_at_hq
4983 regiments_distribution[regiment_type.index()] += 1.f;
4989 for(
uint32_t i = 0; i < military_definitions.unit_base_definitions.size(); ++i) {
4990 regiments_distribution[i] = regiments_distribution[i] / total;
4997void state::army_group_update_tasks(dcon::automated_army_group_id group) {
5001 dcon::province_id potential_ferry_target{};
5002 float ferry_supply_budget = 0.f;
5004 auto fat_group = fatten(world, group);
5006 for(
auto regiment_id : world.automated_army_group_get_automated_army_group_membership_regiment(group)) {
5007 auto regiment =
dcon::fatten(world, regiment_id).get_regiment();
5009 auto army = regiment.get_regiment_from_automation().get_army_from_army_membership();
5011 auto current_path = world.army_get_path(army);
5012 if(current_path.size() > 0) {
5016 auto province = world.army_get_location_from_army_location(army);
5017 auto controller = world.province_get_nation_from_province_control(
province);
5019 if(regiment.get_status() != army_group_regiment_status::standby) {
5023 switch(regiment.get_task()) {
5024 case army_group_regiment_task::idle:
5026 case army_group_regiment_task::gather_at_hq:
5028 case army_group_regiment_task::defend_position:
5029 if(!fat_group.get_provinces_defend().contains(regiment.get_target())) {
5030 regiment_reset_order(regiment);
5033 case army_group_regiment_task::siege:
5034 if(regiment.get_target() !=
province) {
5040 regiment_reset_order(regiment);
5048dcon::province_id state::get_port_for_landing(dcon::automated_army_group_id group, dcon::province_id target) {
5049 auto fat_group = fatten(world, group);
5051 if(world.province_get_is_coast(target)) {
5055 dcon::province_id potential_target_port{};
5056 for(
auto& target_port : fat_group.get_provinces_ferry_origin()) {
5058 if(path.size() > 0) {
5059 potential_target_port = target_port;
5063 return potential_target_port;
5066void state::army_group_distribute_tasks(dcon::automated_army_group_id group) {
5067 static std::vector<dcon::province_id> province_queue;
5068 static std::vector<dcon::province_id> provinces_to_reduce_weight;
5069 static std::vector<dcon::province_id> provinces_to_maintain;
5070 static std::vector<float> regiments_distribution;
5071 regiments_distribution.resize(military_definitions.unit_base_definitions.size() + 2);
5073 auto fat_group = fatten(world, group);
5078 if(army_group_recalculate_distribution(group, regiments_distribution)) {
5080 dcon::province_id candidate{};
5081 float supply_limit = 0.f;
5082 for(dcon::province_id defensive_position : fat_group.get_provinces_defend()) {
5083 auto regiment = fill_province_up_to_supply_limit(
5086 regiments_distribution,
5091 world.regiment_automation_data_set_task(regiment, army_group_regiment_task::defend_position);
5100 if(army_group_recalculate_distribution(group, regiments_distribution)) {
5101 for(dcon::province_id province_to_siege : fat_group.get_provinces_enforce_control()) {
5102 auto controller = world.province_get_nation_from_province_control(province_to_siege);
5107 auto regiment = fill_province_up_to_supply_limit(
5110 regiments_distribution,
5115 world.regiment_automation_data_set_task(regiment, army_group_regiment_task::siege);
5126 for(
auto fleet_membership : fat_group.get_automated_army_group_membership_navy()) {
5127 auto fleet = fleet_membership.get_navy();
5128 auto location = fleet.get_location_from_navy_location();
5130 auto path = fleet.get_path();
5132 if(path.size() > 0) {
5136 auto transported_armies = fleet.get_army_transport();
5137 bool wait_for_disembark =
false;
5138 for(
auto item : transported_armies) {
5139 auto army = item.get_army();
5140 auto path_army = world.army_get_path(army);
5142 if(path_army.size() > 0) {
5143 wait_for_disembark =
true;
5147 if(wait_for_disembark) {
5155 for(
auto regiment_automation_link : fat_group.get_automated_army_group_membership_regiment()) {
5156 auto regiment = regiment_automation_link.get_regiment();
5157 auto army = regiment.get_regiment_from_automation().get_army_from_army_membership();
5158 auto target = regiment.get_ferry_target();
5159 auto port_to = world.province_get_port_to(target);
5160 auto transport = world.army_get_army_transport(army);
5161 auto regiment_fleet = world.army_transport_get_navy(transport);
5162 auto fleet_location = world.navy_get_location_from_navy_location(fleet);
5164 if(regiment_fleet == fleet) {
5166 if(port_to == fleet_location) {
5178 for(
auto regiment_automation_link : fat_group.get_automated_army_group_membership_regiment()) {
5179 auto regiment = regiment_automation_link.get_regiment();
5182 regiment.get_status() != army_group_regiment_status::await_transport
5183 && regiment.get_status() != army_group_regiment_status::embark
5187 auto army = regiment.get_regiment_from_automation().get_army_from_army_membership();
5188 auto regiment_location = army.get_location_from_army_location();
5189 auto port_to = regiment_location.get_port_to();
5191 if(port_to == fleet.get_location_from_navy_location()) {
5205 province_queue.clear();
5206 provinces_to_reduce_weight.clear();
5207 provinces_to_maintain.clear();
5209 province_queue.push_back(fat_group.get_hq());
5215 auto current_location = province_queue[l];
5217 for(
auto regiment_automation_link : fat_group.get_automated_army_group_membership_regiment()) {
5219 auto regiment = regiment_automation_link.get_regiment();
5220 auto army = regiment.get_regiment_from_automation().get_army_from_army_membership();
5221 auto army_location = army.get_location_from_army_location();
5222 auto current_path = army.get_path();
5223 auto status = regiment.get_task();
5224 if(status != army_group_regiment_task::idle) {
5227 if(current_path.size() > 0) {
5230 if(current_location == army_location) {
5231 regiment.set_task(army_group_regiment_task::gather_at_hq);
5232 regiment.set_status(army_group_regiment_status::standby);
5237 if(current_location.value >= province_definitions.first_sea_province.value) {
5242 auto ownership = world.province_get_province_ownership_as_province(current_location);
5243 auto owner = world.province_ownership_get_nation(ownership);
5249 if(fat_group.get_provinces_defend().contains(current_location)) {
5256 local_player_nation,
5261 *
this, current_location
5264 auto supply_left = army_group_available_supply(group, current_location);
5266 if(4.f < supply_left) {
5268 }
else if(current_weight > supply_limit) {
5269 provinces_to_reduce_weight.push_back(current_location);
5271 provinces_to_maintain.push_back(current_location);
5275 for(
auto adj : world.province_get_province_adjacency(current_location)) {
5276 auto other = adj.get_connected_provinces(adj.get_connected_provinces(0) == current_location ? 1 : 0);
5278 if(std::find(province_queue.begin(), province_queue.end(), other) == province_queue.end()) {
5279 province_queue.push_back(other);
5288 auto target_location = province_queue[l];
5289 dcon::province_id potential_target_port = get_port_for_landing(group, fat_group.get_hq());
5291 for(
auto regiment_automation_link : fat_group.get_automated_army_group_membership_regiment()) {
5292 auto regiment = regiment_automation_link.get_regiment();
5293 auto army = regiment.get_regiment_from_automation().get_army_from_army_membership();
5294 auto army_location = army.get_location_from_army_location();
5295 auto army_path = army.get_path();
5297 if(regiment.get_task() != army_group_regiment_task::idle) {
5300 if(army_path.size() > 0) {
5303 if(army_location == target_location) {
5304 regiment.set_task(army_group_regiment_task::gather_at_hq);
5305 regiment.set_status(army_group_regiment_status::standby);
5312 if(potential_target_port) {
5313 if(move_to_available_port(group, regiment)) {
5314 regiment.set_task(army_group_regiment_task::gather_at_hq);
5315 regiment.set_target(target_location);
5316 regiment.set_ferry_target(potential_target_port);
5321 regiment.set_task(army_group_regiment_task::gather_at_hq);
5322 regiment.set_status(army_group_regiment_status::move_to_target);
5323 regiment.set_target(path[0]);
5330void state::army_group_update_regiment_status(dcon::automated_army_group_id group) {
5331 auto fat_group = fatten(world, group);
5333 for(
auto regiment_link : fat_group.get_automated_army_group_membership_regiment()) {
5334 auto regiment = regiment_link.get_regiment();
5335 auto army = regiment.get_regiment_from_automation().get_army_from_army_membership();
5340 auto current_path = army.get_path();
5341 if(current_path.size() > 0) {
5342 regiment.set_await_command_execution_flag(
false);
5346 if(regiment.get_await_command_execution_flag()) {
5350 auto location = world.army_get_location_from_army_location(army);
5351 auto target = regiment.get_target();
5355 switch(regiment.get_status()) {
5356 case army_group_regiment_status::move_to_target:
5357 if(location == target) {
5358 regiment.set_status(army_group_regiment_status::standby);
5363 regiment.set_await_command_execution_flag(
true);
5365 regiment_reset_order(regiment);
5369 case army_group_regiment_status::move_to_port:
5371 if(regiment.get_ferry_origin() == location) {
5372 regiment.set_status(army_group_regiment_status::await_transport);
5374 command::move_army(*
this, local_player_nation, army, regiment.get_ferry_origin(),
false);
5378 case army_group_regiment_status::standby:
5379 if(location != target) {
5380 regiment.set_status(army_group_regiment_status::move_to_target);
5383 case army_group_regiment_status::await_transport:
5385 if(location.value >= province_definitions.first_sea_province.value) {
5387 regiment.set_status(army_group_regiment_status::is_transported);
5392 bool at_ferry_origin = location == regiment.get_ferry_origin();
5393 if(!at_ferry_origin) {
5394 regiment_reset_order(regiment);
5397 dcon::province_id port_to = world.province_get_port_to(location);
5399 for(
auto fleet_membership : fat_group.get_automated_army_group_membership_navy()) {
5400 auto fleet = fleet_membership.get_navy();
5402 auto path = fleet.get_path();
5403 if(path.size() > 0) {
5407 auto fleet_location = world.navy_get_location_from_navy_location(fleet);
5408 if(fleet_location == port_to) {
5411 if(path_army.size() > 0) {
5413 regiment.set_status(army_group_regiment_status::embark);
5414 regiment.set_await_command_execution_flag(
true);
5422 case army_group_regiment_status::is_transported:
5423 if(location.value >= province_definitions.first_sea_province.value) {
5425 auto ferry_target = regiment.get_ferry_target();
5426 auto port_to = world.province_get_port_to(ferry_target);
5427 auto transport = world.army_get_army_transport(army);
5428 auto fleet = world.army_transport_get_navy(transport);
5429 auto fleet_location = world.navy_get_location_from_navy_location(fleet);
5432 if(fleet_location == port_to) {
5435 if(path_army.size() > 0) {
5437 regiment.set_await_command_execution_flag(
true);
5438 regiment.set_status(army_group_regiment_status::disembark);
5445 regiment_reset_order(regiment);
5447 case army_group_regiment_status::disembark:
5448 if(location == regiment.get_ferry_target()) {
5449 regiment.set_status(army_group_regiment_status::move_to_target);
5453 regiment.set_status(army_group_regiment_status::is_transported);
5455 case army_group_regiment_status::embark:
5456 if(location.value >= province_definitions.first_sea_province.value) {
5457 regiment.set_status(army_group_regiment_status::is_transported);
5461 regiment.set_status(army_group_regiment_status::await_transport);
5469dcon::regiment_automation_data_id state::fill_province(
5470 dcon::automated_army_group_id group_id,
5471 dcon::province_id target,
5472 std::vector<float>& regiments_expectation_ideal
5474 static std::vector<float> regiments_expectation_current;
5475 static std::vector<float> regiments_in_candidate_army;
5477 regiments_expectation_current.resize(military_definitions.unit_base_definitions.size() + 2);
5478 regiments_in_candidate_army.resize(military_definitions.unit_base_definitions.size() + 2);
5480 for(
uint32_t i = 0; i < military_definitions.unit_base_definitions.size(); ++i) {
5481 regiments_expectation_current[i] = 0.f;
5482 regiments_in_candidate_army[i] = 0.f;
5485 auto fat_group = fatten(world, group_id);
5487 bool success =
false;
5491 for(
auto regiment_membership : fat_group.get_automated_army_group_membership_regiment()) {
5492 auto regiment = regiment_membership.get_regiment();
5493 if(regiment.get_target() == target) {
5494 auto regiment_type = regiment.get_regiment_from_automation().get_type();
5496 regiments_expectation_current[regiment_type.index()] += 3.f;
5501 dcon::regiment_automation_data_id final_regiment{};
5504 auto target_port = get_port_for_landing(group_id, target);
5505 for(
auto regiment_membership : fat_group.get_automated_army_group_membership_regiment()) {
5506 auto regiment = regiment_membership.get_regiment();
5508 auto current_task = regiment.get_task();
5510 if(current_task != army_group_regiment_task::idle && current_task != army_group_regiment_task::gather_at_hq) {
5514 auto regiment_type = regiment.get_regiment_from_automation().get_type();
5516 if(!regiment_type) {
5521 regiments_expectation_ideal[regiment_type.index()]
5522 - regiments_expectation_current[regiment_type.index()];
5524 if(required >= 2.9f) {
5525 auto army = regiment.get_regiment_from_automation().get_army_from_army_membership();
5527 if(path.empty() && target != army.get_location_from_army_location()) {
5529 if(target_port && move_to_available_port(group_id, regiment)) {
5530 regiment.set_ferry_target(target_port);
5531 regiment.set_target(target);
5536 regiment.set_status(army_group_regiment_status::move_to_target);
5537 regiment.set_target(target);
5546void state::fill_vector_of_connected_provinces(dcon::province_id p1,
bool is_land, std::vector<dcon::province_id>& provinces) {
5548 if(world.province_get_nation_from_province_ownership(p1) == local_player_nation) {
5550 auto rid = world.province_get_connected_region_id(p1);
5551 for(
const auto pc : world.nation_get_province_ownership_as_nation(local_player_nation)) {
5552 if(pc.get_province().get_connected_region_id() == rid
5553 && pc.get_province().get_province_control().get_nation() == local_player_nation) {
5554 provinces.push_back(pc.get_province());
5558 for(
const auto pc : world.nation_get_province_ownership_as_nation(local_player_nation)) {
5559 if(pc.get_province().get_province_control().get_nation() == local_player_nation
5560 && pc.get_province().get_is_coast()) {
5561 provinces.push_back(pc.get_province());
5569 dcon::province_id
p;
5571 dcon::unit_type_id
u;
5574void state::build_up_to_template_land(
5576 dcon::province_id target_province,
5577 std::vector<dcon::province_id>& available_provinces,
5578 std::array<uint8_t, sys::macro_builder_template::max_types>& current_distribution
5581 std::vector<build_queue_data> build_queue;
5586 std::memcpy(remaining_to_build, target_template.
amounts,
sizeof(remaining_to_build));
5589 for(dcon::unit_type_id::value_base_t i = 0; i < upper_limit; i++) {
5590 dcon::unit_type_id utid = dcon::unit_type_id(i);
5591 if(remaining_to_build[i] < current_distribution[i]) {
5592 remaining_to_build[i] = 0;
5594 remaining_to_build[i] -= current_distribution[i];
5598 for(
const auto prov : available_provinces) {
5599 for(
const auto p : world.province_get_pop_location_as_province(prov)) {
5600 auto pop = p.get_pop();
5601 if(pop.get_poptype() != culture_definitions.soldiers)
5605 auto source = pop.get_regiment_source();
5606 int32_t used = int32_t(source.end() - source.begin());
5608 auto constructions = pop.get_province_land_construction_as_pop();
5609 used += int32_t(constructions.end() - constructions.begin());
5611 int32_t avail = possible - used;
5620 auto unit_types = military_definitions.unit_base_definitions.size();
5622 for(dcon::unit_type_id::value_base_t i = 0; i < unit_types; i++) {
5623 dcon::unit_type_id utid = dcon::unit_type_id(i);
5625 if(!military_definitions.unit_base_definitions[utid].is_land) {
5629 if(remaining_to_build[i] == 0) {
5635 local_player_nation,
5646 for(int32_t j = 0; j < int32_t(remaining_to_build[i]) && j < avail; j++) {
5648 remaining_to_build[i]--;
5650 if(remaining_to_build[i] == 0)
5657 for(
const auto& build : build_queue) {
5660 local_player_nation,
int blake2b(void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen)
void update_fog_of_war(sys::state &state)
bool map_to_screen(sys::state &state, glm::vec2 map_pos, glm::vec2 screen_size, glm::vec2 &screen_pos)
void on_mouse_wheel(int32_t x, int32_t y, int32_t screen_size_x, int32_t screen_size_y, sys::key_modifiers mod, float amount)
void load_map_data(parsers::scenario_building_context &context)
void on_mbuttom_up(int32_t x, int32_t y, sys::key_modifiers mod)
void on_mbuttom_down(int32_t x, int32_t y, int32_t screen_size_x, int32_t screen_size_y, sys::key_modifiers mod)
void update(sys::state &state)
void on_key_up(sys::virtual_key keycode, sys::key_modifiers mod)
glm::vec2 normalize_map_coord(glm::vec2 pos)
map_mode::mode active_map_mode
void on_mouse_move(int32_t x, int32_t y, int32_t screen_size_x, int32_t screen_size_y, sys::key_modifiers mod)
dcon::province_id get_province_under_mouse(sys::state &state, int32_t x, int32_t y, int32_t screen_size_x, int32_t screen_size_y)
void render(sys::state &state)
std::string accumulated_errors
std::string accumulated_warnings
RIGTORP_NODISCARD T * front() noexcept
RIGTORP_NODISCARD bool try_push(const T &v) noexcept(std::is_nothrow_copy_constructible< T >::value)
year_month_day to_ymd(absolute_time_point base) const noexcept
void change_locale(sys::state &state, dcon::locale_id l)
tagged_vector< element_data, dcon::gui_def_id > gui
tagged_vector< gfx_object, dcon::gfx_object_id > gfx
std::vector< diplomatic_message::message > messages
virtual message_result impl_set(sys::state &state, Cyto::Any &payload) noexcept
virtual tooltip_behavior has_tooltip(sys::state &state) noexcept
virtual void on_text(sys::state &state, char32_t ch) noexcept
virtual void update_tooltip(sys::state &state, int32_t x, int32_t y, text::columnar_layout &contents) noexcept
virtual message_result get(sys::state &state, Cyto::Any &payload) noexcept
virtual void on_hover_end(sys::state &state) noexcept
virtual message_result impl_on_scroll(sys::state &state, int32_t x, int32_t y, float amount, sys::key_modifiers mods) noexcept
virtual void impl_on_update(sys::state &state) noexcept
virtual void impl_render(sys::state &state, int32_t x, int32_t y) noexcept
virtual void on_drag_finish(sys::state &state) noexcept
virtual void on_drag(sys::state &state, int32_t oldx, int32_t oldy, int32_t x, int32_t y, sys::key_modifiers mods) noexcept
void set_visible(sys::state &state, bool vis)
virtual message_result impl_on_mouse_move(sys::state &state, int32_t x, int32_t y, sys::key_modifiers mods) noexcept
virtual mouse_probe impl_probe_mouse(sys::state &state, int32_t x, int32_t y, mouse_probe_type type) noexcept
virtual void on_hover(sys::state &state) noexcept
static void make_new_report(sys::state &state, military::land_battle_report const &r)
std::vector< notification::message > messages
#define assert(condition)
char * LLVMGetErrorMessage(LLVMErrorRef Err)
void LLVMDisposeErrorMessage(char *ErrMsg)
LLVMErrorRef LLVMOrcLLJITLookup(LLVMOrcLLJITRef J, LLVMOrcExecutorAddress *Result, const char *Name)
uint64_t LLVMOrcExecutorAddress
void bytes_to_windows(char const *bytes, size_t size, std::string const &project_name, ankerl::unordered_dense::map< std::string, sys::aui_pending_bytes > &map)
void update_crisis_leaders(sys::state &state)
void initialize_ai_tech_weights(sys::state &state)
void daily_cleanup(sys::state &state)
void take_reforms(sys::state &state)
void form_alliances(sys::state &state)
void update_ai_ruling_party(sys::state &state)
void make_war_decs(sys::state &state)
void upgrade_colonies(sys::state &state)
void update_cb_fabrication(sys::state &state)
void make_defense(sys::state &state)
void refresh_home_ports(sys::state &state)
void update_ai_colony_starting(sys::state &state)
void update_focuses(sys::state &state)
void update_budget(sys::state &state)
void update_ai_colonial_investment(sys::state &state)
void perform_influence_actions(sys::state &state)
void make_attacks(sys::state &state)
void update_ships(sys::state &state)
void update_ai_econ_construction(sys::state &state)
void build_ships(sys::state &state)
void prune_alliances(sys::state &state)
void update_war_intervention(sys::state &state)
void update_influence_priorities(sys::state &state)
void update_ai_research(sys::state &state)
void update_ai_general_status(sys::state &state)
void update_factory_types_priority(sys::state &state)
void update_land_constructions(sys::state &state)
void identify_focuses(sys::state &state)
void civilize(sys::state &state)
void make_peace_offers(sys::state &state)
void take_ai_decisions(sys::state &state)
void general_ai_unit_tick(sys::state &state)
void add_gw_goals(sys::state &state)
bool can_start_research(sys::state &state, dcon::nation_id source, dcon::technology_id tech)
void start_land_unit_construction(sys::state &state, dcon::nation_id source, dcon::province_id location, dcon::culture_id soldier_culture, dcon::unit_type_id type, dcon::province_id template_province)
void mark_regiments_to_split(sys::state &state, dcon::nation_id source, std::array< dcon::regiment_id, num_packed_units > const &list)
bool can_start_land_unit_construction(sys::state &state, dcon::nation_id source, dcon::province_id location, dcon::culture_id soldier_culture, dcon::unit_type_id type, dcon::province_id template_province)
std::vector< dcon::province_id > can_move_navy(sys::state &state, dcon::nation_id source, dcon::navy_id n, dcon::province_id dest)
void make_event_choice(sys::state &state, event::pending_human_n_event const &e, uint8_t option_id)
void execute_pending_commands(sys::state &state)
std::vector< dcon::province_id > can_move_army(sys::state &state, dcon::nation_id source, dcon::army_id a, dcon::province_id dest)
void discover_inventions(sys::state &state)
void apply_invention(sys::state &state, dcon::nation_id target_nation, dcon::invention_id i_id)
float effective_technology_cost(sys::state &state, uint32_t current_year, dcon::nation_id target_nation, dcon::technology_id tech_id)
void fix_slaves_in_province(sys::state &state, dcon::nation_id owner, dcon::province_id p)
void clear_existing_tech_effects(sys::state &state)
void repopulate_technology_effects(sys::state &state)
void update_all_nations_issue_rules(sys::state &state)
void set_default_issue_and_reform_options(sys::state &state)
void repopulate_invention_effects(sys::state &state)
void update_research(sys::state &state, uint32_t current_year)
void restore_unsaved_values(sys::state &state)
void create_initial_ideology_and_issues_distribution(sys::state &state)
void apply_technology(sys::state &state, dcon::nation_id target_nation, dcon::technology_id t_id)
pop_satisfaction_wrapper_fat fatten(data_container const &c, pop_satisfaction_wrapper_id id) noexcept
void alt_demographics_update_extras(sys::state &state)
void remove_small_pops(sys::state &state)
void update_immigration(sys::state &state, uint32_t offset, uint32_t divisions, migration_buffer &pbuf)
constexpr dcon::demographics_key total(0)
void apply_assimilation(sys::state &state, uint32_t offset, uint32_t divisions, assimilation_buffer &pbuf)
void update_internal_migration(sys::state &state, uint32_t offset, uint32_t divisions, migration_buffer &pbuf)
void apply_type_changes(sys::state &state, uint32_t offset, uint32_t divisions, promotion_buffer &pbuf)
void update_growth(sys::state &state, uint32_t offset, uint32_t divisions)
void alt_regenerate_from_pop_data_daily(sys::state &state)
void update_issues(sys::state &state, uint32_t offset, uint32_t divisions, issues_buffer &ibuf)
void apply_internal_migration(sys::state &state, uint32_t offset, uint32_t divisions, migration_buffer &pbuf)
void update_type_changes(sys::state &state, uint32_t offset, uint32_t divisions, promotion_buffer &pbuf)
void regenerate_from_pop_data_full(sys::state &state)
uint32_t size(sys::state const &state)
void update_assimilation(sys::state &state, uint32_t offset, uint32_t divisions, assimilation_buffer &pbuf)
void alt_regenerate_from_pop_data_full(sys::state &state)
void remove_size_zero_pops(sys::state &state)
void update_colonial_migration(sys::state &state, uint32_t offset, uint32_t divisions, migration_buffer &pbuf)
void apply_ideologies(sys::state &state, uint32_t offset, uint32_t divisions, ideology_buffer &pbuf)
void update_ideologies(sys::state &state, uint32_t offset, uint32_t divisions, ideology_buffer &ibuf)
void update_consciousness(sys::state &state, uint32_t offset, uint32_t divisions)
void update_literacy(sys::state &state, uint32_t offset, uint32_t divisions)
void update_militancy(sys::state &state, uint32_t offset, uint32_t divisions)
void apply_colonial_migration(sys::state &state, uint32_t offset, uint32_t divisions, migration_buffer &pbuf)
void regenerate_from_pop_data_daily(sys::state &state)
void apply_immigration(sys::state &state, uint32_t offset, uint32_t divisions, migration_buffer &pbuf)
void apply_issues(sys::state &state, uint32_t offset, uint32_t divisions, issues_buffer &pbuf)
void update_pending(sys::state &state)
void initialize(sys::state &state)
void update_factory_employment(sys::state &state)
void prune_factories(sys::state &state)
constexpr uint32_t gdp_history_length
void presimulate(sys::state &state)
void update_rgo_employment(sys::state &state)
void daily_update(sys::state &state, bool presimulation, float presimulation_stage)
float price(sys::state const &state, dcon::state_instance_id s, dcon::commodity_id c)
constexpr uint32_t price_history_length
void regenerate_unsaved_values(sys::state &state)
int32_t most_recent_price_record_index(sys::state &state)
void sanity_check(sys::state &state)
constexpr int32_t max_building_types
int32_t most_recent_gdp_record_index(sys::state &state)
float gdp_adjusted(sys::state &state, dcon::market_id n)
constexpr uint16_t no_payload
void execute(sys::state &state, dcon::effect_key key, int32_t primary, int32_t this_slot, int32_t from_slot, uint32_t r_lo, uint32_t r_hi)
void fire_fixed_event(sys::state &state, std::vector< nations::fixed_event > const &v, int32_t primary_slot, slot_type pt, dcon::nation_id this_slot, int32_t from_slot, slot_type ft)
void update_events(sys::state &state)
std::string multiplicative_modifier(sys::state &state, dcon::value_modifier_key modifier)
std::string additive_modifier(sys::state &state, dcon::value_modifier_key modifier)
void run_fif_interpreter(environment &env, std::string_view on_text)
void common_fif_environment(sys::state &state, fif::environment &env)
void on_lbutton_up(sys::state &state, int32_t x, int32_t y, sys::key_modifiers mod)
void switch_scene(sys::state &state, scene_id ui_scene)
void on_rbutton_down(sys::state &state, int32_t x, int32_t y, sys::key_modifiers mod)
void on_key_down(sys::state &state, sys::virtual_key keycode, sys::key_modifiers mod)
void on_lbutton_down(sys::state &state, int32_t x, int32_t y, sys::key_modifiers mod)
void set_map_mode(sys::state &state, mode mode)
constexpr float zoom_close
void update_text_lines(sys::state &state, display_data &map_data)
void run_gc(sys::state &state)
void update_naval_supply_points(sys::state &state)
void army_arrives_in_province(sys::state &state, dcon::army_id a, dcon::province_id p, crossing_type crossing, dcon::land_battle_id from)
int32_t free_transport_capacity(sys::state &state, dcon::navy_id n)
void apply_base_unit_stat_modifiers(sys::state &state)
void update_blockade_status(sys::state &state)
void update_ticking_war_score(sys::state &state)
void increase_dig_in(sys::state &state)
void apply_attrition(sys::state &state)
void reset_unit_stats(sys::state &state)
void update_land_battles(sys::state &state)
void update_cbs(sys::state &state)
float local_enemy_army_weight_max(sys::state &state, dcon::province_id prov, dcon::nation_id nation)
void regenerate_land_unit_average(sys::state &state)
void recover_org(sys::state &state)
void advance_mobilizations(sys::state &state)
void update_movement(sys::state &state)
int32_t regiments_possible_from_pop(sys::state &state, dcon::pop_id p)
void reinforce_regiments(sys::state &state)
void apply_regiment_damage(sys::state &state)
void monthly_leaders_update(sys::state &state)
float local_army_weight_max(sys::state &state, dcon::province_id prov)
void update_naval_battles(sys::state &state)
void update_siege_progress(sys::state &state)
void update_all_recruitable_regiments(sys::state &state)
bool are_at_war(sys::state const &state, dcon::nation_id a, dcon::nation_id b)
void set_initial_leaders(sys::state &state)
void regenerate_total_regiment_counts(sys::state &state)
int32_t supply_limit_in_province(sys::state &state, dcon::nation_id n, dcon::province_id p)
int32_t transport_capacity(sys::state &state, dcon::navy_id n)
void repair_ships(sys::state &state)
void daily_leaders_update(sys::state &state)
void restore_unsaved_values(sys::state &state)
void regenerate_ship_scores(sys::state &state)
void update_blackflag_status(sys::state &state, dcon::province_id p)
bool siege_potential(sys::state &state, dcon::nation_id army_controller, dcon::nation_id province_controller)
std::string int_to_tag(uint32_t v)
void run_gc(sys::state &state)
void restore_unsaved_values(sys::state &state)
void daily_update_flashpoint_tension(sys::state &state)
void monthly_flashpoint_update(sys::state &state)
void update_administrative_efficiency(sys::state &state)
void update_influence(sys::state &state)
void update_military_scores(sys::state &state)
void update_monthly_points(sys::state &state)
void generate_initial_state_instances(sys::state &state)
void update_cached_values(sys::state &state)
void update_revanchism(sys::state &state)
uint32_t tag_to_int(char first, char second, char third)
void update_industrial_scores(sys::state &state)
void update_research_points(sys::state &state)
void restore_state_instances(sys::state &state)
void generate_sea_trade_routes(sys::state &state)
void update_great_powers(sys::state &state)
void recalculate_markets_distance(sys::state &state)
void generate_initial_trade_routes(sys::state &state)
float get_treasury(sys::state &state, dcon::nation_id n)
void update_ui_rankings(sys::state &state)
void update_rankings(sys::state &state)
void update_crisis(sys::state &state)
void send_and_receive_commands(sys::state &state)
bool nation_is_interesting(sys::state &state, dcon::nation_id n)
void initialize_msaa(sys::state &state, int32_t size_x, int32_t size_y)
void deinitialize_msaa(sys::state &state)
void render_textured_rect(sys::state const &state, color_modification enabled, float x, float y, float width, float height, GLuint texture_handle, ui::rotation r, bool flipped, bool rtl)
GLuint get_texture_handle(sys::state &state, dcon::texture_id id, bool keep_data)
native_string flag_type_to_name(sys::state &state, culture::flag_type type)
void parse_csv_pop_history_file(sys::state &state, const char *start, const char *end, error_handler &err, scenario_building_context &context)
void read_map_adjacency(char const *start, char const *end, error_handler &err, scenario_building_context &context)
void read_pending_rebel_type(dcon::rebel_type_id id, token_generator &gen, error_handler &err, scenario_building_context &context)
dcon::trigger_key read_triggered_modifier_condition(token_generator &gen, error_handler &err, scenario_building_context &context)
dcon::trigger_key make_trigger(token_generator &gen, error_handler &err, trigger_building_context &context)
void parse_csv_province_history_file(sys::state &state, const char *start, const char *end, error_handler &err, scenario_building_context &context)
void read_pending_technology(dcon::technology_id id, token_generator &gen, error_handler &err, scenario_building_context &context)
void commit_pending_events(error_handler &err, scenario_building_context &context)
void read_pending_reform(dcon::reform_option_id id, token_generator &gen, error_handler &err, scenario_building_context &context)
void read_pending_invention(dcon::invention_id id, token_generator &gen, error_handler &err, scenario_building_context &context)
void read_pending_option(dcon::issue_option_id id, token_generator &gen, error_handler &err, scenario_building_context &context)
void read_pending_crime(dcon::crime_id id, token_generator &gen, error_handler &err, scenario_building_context &context)
void make_leader_images(scenario_building_context &outer_context)
int32_t parse_int(std::string_view content, int32_t line, error_handler &err)
void add_locale(sys::state &state, std::string_view locale_name, char const *data_start, char const *data_end)
dcon::effect_key make_effect(token_generator &gen, error_handler &err, effect_building_context &context)
void make_base_units(scenario_building_context &context)
void read_map_colors(char const *start, char const *end, error_handler &err, scenario_building_context &context)
void daily_party_loyalty_update(sys::state &state)
void recalculate_upper_house(sys::state &state, dcon::nation_id n)
void update_displayed_identity(sys::state &state, dcon::nation_id id)
void update_elections(sys::state &state)
void set_political_reform_desire(sys::state &state, dcon::pop_id p, float v)
void set_social_reform_desire(sys::state &state, dcon::pop_id p, float v)
uint32_t size(sys::state const &state)
void regenerate_is_primary_or_accepted(sys::state &state)
void set_demo(sys::state &state, dcon::pop_id p, dcon::pop_demographics_key k, float v)
dcon::pop_demographics_key to_key(sys::state const &state, dcon::ideology_id v)
float get_demo(sys::state const &state, dcon::pop_id p, dcon::pop_demographics_key k)
constexpr uint8_t impassible_bit
constexpr uint8_t state_bit
constexpr uint8_t national_bit
constexpr uint8_t coastal_bit
void update_connected_regions(sys::state &state)
void update_blockaded_cache(sys::state &state)
void update_nationalism(sys::state &state)
void update_crimes(sys::state &state)
std::vector< dcon::province_id > make_safe_land_path(sys::state &state, dcon::province_id start, dcon::province_id end, dcon::nation_id nation_as)
void ve_for_each_land_province(sys::state &state, F const &func)
void restore_unsaved_values(sys::state &state)
void for_each_land_province(sys::state &state, F const &func)
void update_cached_values(sys::state &state)
void update_colonization(sys::state &state)
constexpr uint16_t to_map_id(dcon::province_id id)
void restore_distances(sys::state &state)
void execute_province_defections(sys::state &state)
void rebel_risings_check(sys::state &state)
void update_movement_values(sys::state &state)
void update_armies(sys::state &state)
void update_factions(sys::state &state)
void execute_rebel_victories(sys::state &state)
void daily_update_rebel_organization(sys::state &state)
void update_movements(sys::state &state)
void rebel_hunting_check(sys::state &state)
std::vector< unopened_file > list_files(directory const &dir, native_char const *extension)
native_string win1250_to_native(std::string_view data_in)
std::vector< directory > list_subdirectories(directory const &dir)
directory open_directory(directory const &dir, native_string_view directory_name)
native_string utf8_to_native(std::string_view data_in)
void write_file(directory const &dir, native_string_view file_name, char const *file_data, uint32_t file_size)
directory get_or_create_oos_directory()
directory get_or_create_settings_directory()
native_string get_full_name(directory const &f)
directory get_or_create_save_game_directory()
std::optional< file > open_file(directory const &dir, native_string_view file_name)
std::optional< unopened_file > peek_file(directory const &dir, native_string_view file_name)
std::string native_to_utf8(native_string_view data_in)
file_contents view_contents(file const &f)
native_string get_file_name(unopened_file const &f)
audio_instance & get_peace_sound(sys::state &state)
audio_instance & get_minor_event_sound(sys::state &state)
audio_instance & get_revolt_sound(sys::state &state)
audio_instance & get_army_built_sound(sys::state &state)
audio_instance & get_accept_sound(sys::state &state)
audio_instance & get_technology_finished_sound(sys::state &state)
audio_instance & get_declaration_of_war_sound(sys::state &state)
audio_instance & get_naval_base_built_sound(sys::state &state)
audio_instance & get_major_event_sound(sys::state &state)
audio_instance & get_railroad_built_sound(sys::state &state)
void play_effect(sys::state &state, audio_instance &s, float volume)
audio_instance & get_decline_sound(sys::state &state)
audio_instance & get_election_sound(sys::state &state)
audio_instance & get_navy_built_sound(sys::state &state)
audio_instance & get_fort_built_sound(sys::state &state)
void play_interface_sound(sys::state &state, audio_instance &s, float volume)
audio_instance & get_diplomatic_request_sound(sys::state &state)
audio_instance & get_chat_message_sound(sys::state &state)
audio_instance & get_factory_built_sound(sys::state &state)
MOD_NAT_LIST constexpr uint32_t count
MOD_PROV_LIST constexpr uint32_t count
int32_t days_difference(year_month_day start, year_month_day end)
uint8_t * write_scenario_section(uint8_t *ptr_in, sys::state &state)
void selected_ships_add(sys::state &state, dcon::ship_id sh)
void selected_ships_clear(sys::state &state)
constexpr msg_setting_entry message_setting_map[size_t(message_base_type::count)]
size_t sizeof_save_section(sys::state &state)
uint8_t const * read_save_header(uint8_t const *ptr_in, save_header &header_out)
void selected_regiments_clear(sys::state &state)
uint32_t pack_color(float r, float g, float b)
constexpr size_t const_max_selected_units
void repopulate_modifier_effects(sys::state &state)
@ crisis_join_offer_accepted
@ crisis_join_offer_declined
@ crisis_resolution_declined
@ crisis_resolution_accepted
uint8_t * write_save_section(uint8_t *ptr_in, sys::state &state)
scenario_size sizeof_scenario_section(sys::state &state)
constexpr int32_t tooltip_width
void update_modifier_effects(sys::state &state)
constexpr int32_t max_autosaves
size_t sizeof_save_header(save_header const &header_in)
bool is_playable_date(date d, absolute_time_point start, absolute_time_point end)
void write_save_file(sys::state &state, save_type type, std::string const &name)
void selected_regiments_add(sys::state &state, dcon::regiment_id reg)
void list_pop_types(sys::state &state, parsers::scenario_building_context &context)
columnar_layout create_columnar_layout(sys::state &state, layout &dest, layout_parameters const ¶ms, int32_t column_width)
char16_t win1250toUTF16(char in)
uint16_t name_into_font_id(sys::state &state, std::string_view txt)
std::string produce_simple_string(sys::state const &state, dcon::text_key id)
dcon::text_key get_name(sys::state &state, dcon::nation_id id)
void consume_csv_file(sys::state &state, char const *file_content, uint32_t file_size, int32_t target_column, bool as_unicode)
dcon::text_key find_or_add_key(sys::state &state, std::string_view key, bool as_unicode)
int32_t to_generic(dcon::province_id v)
constexpr uint16_t no_payload
bool evaluate(sys::state &state, dcon::trigger_key key, int32_t primary, int32_t this_slot, int32_t from_slot)
float evaluate_additive_modifier(sys::state &state, dcon::value_modifier_key modifier, int32_t primary, int32_t this_slot, int32_t from_slot)
uint16_t * recurse_over_triggers(uint16_t *source, T const &f)
constexpr uint16_t association_ne
void populate_map_tooltip(sys::state &state, text::columnar_layout &contents, dcon::province_id prov)
@ position_sensitive_tooltip
void create_in_game_windows(sys::state &state)
ogl::color_modification get_color_modification(bool is_under_mouse, bool is_disabled, bool is_interactable)
void load_text_gui_definitions(sys::state &state, parsers::building_gfx_context &context, parsers::error_handler &err)
bool events_pause_test(sys::state &state)
void new_event_window(sys::state &state, event_data_wrapper dat)
void change_cursor(sys::state &state, cursor_type type)
std::string_view native_string_view
std::string native_string
#define NATIVE_DIR_SEPARATOR
std::vector< dcon::issue_id > political_issues
std::vector< dcon::reform_id > military_issues
tagged_vector< crime_info, dcon::crime_id > crimes
std::vector< dcon::reform_id > economic_issues
std::vector< dcon::issue_id > party_issues
std::vector< dcon::issue_id > social_issues
dcon::ideology_id conservative
std::function< void(sys::state &state)> on_game_state_update
std::function< ui::mouse_probe(sys::state &state, ui::mouse_probe mouse_probe, ui::mouse_probe tooltip_probe)> recalculate_tooltip_probe
std::function< void(sys::state &state)> clean_up
std::function< void(sys::state &state)> on_game_state_update_update_ui
bool overwrite_map_tooltip
std::function< void(sys::state &state)> render_map
std::function< ui::mouse_probe(sys::state &state, ui::mouse_probe mouse_probe, ui::mouse_probe tooltip_probe)> recalculate_mouse_probe
std::function< ui::element_base *(sys::state &state)> get_root
std::function< void(sys::state &state)> render_ui
dcon::unit_type_id irregular
tagged_vector< unit_definition, dcon::unit_type_id > unit_base_definitions
dcon::unit_type_id infantry
dcon::unit_type_id artillery
static constexpr uint16_t mode_retreated
static constexpr uint16_t mode_sunk
static constexpr uint16_t mode_mask
std::vector< triggered_modifier > triggered_modifiers
sys::message_base_type type
GLuint ui_shader_screen_height_uniform
GLuint ui_shader_secondary_texture_sampler_uniform
GLuint ui_shader_screen_width_uniform
GLuint ui_shader_texture_sampler_uniform
GLuint ui_shader_gamma_uniform
std::optional< simple_fs::file > ideologies_file
tagged_vector< std::string, dcon::national_identity_id > file_names_for_idents
std::optional< simple_fs::file > crimes_file
ankerl::unordered_dense::map< std::string, pending_invention_content > map_of_inventions
std::vector< simple_fs::file > tech_and_invention_files
ankerl::unordered_dense::map< std::string, pending_roption_content > map_of_roptions
ankerl::unordered_dense::map< std::string, pending_tech_content > map_of_technologies
ankerl::unordered_dense::map< std::string, dcon::pop_type_id > map_of_poptypes
ankerl::unordered_dense::map< std::string, pending_ideology_content > map_of_ideologies
std::optional< simple_fs::file > issues_file
std::vector< dcon::province_id > original_id_to_prov_id_map
ankerl::unordered_dense::map< std::string, pending_crime_content > map_of_crimes
std::optional< simple_fs::file > rebel_types_file
ankerl::unordered_dense::map< std::string, pending_option_content > map_of_ioptions
ankerl::unordered_dense::map< std::string, pending_cb_content > map_of_cb_types
std::optional< simple_fs::file > cb_types_file
std::vector< pending_triggered_modifier_content > set_of_triggered_modifiers
building_gfx_context gfx_context
std::optional< simple_fs::file > triggered_modifiers_file
ankerl::unordered_dense::map< uint32_t, dcon::province_id > map_color_to_province_id
ankerl::unordered_dense::map< std::string, dcon::government_type_id > map_of_governments
void parse_file(sys::state &state, std::string_view data, parsers::error_handler &err)
uint8_t amounts[max_types]
static constexpr uint32_t max_types
Holds important data about the game world, state, and other data regarding windowing,...
text::font_manager font_collection
uint32_t add_locale_data_win1252(std::string const &text)
culture::global_cultural_state culture_definitions
network_mode_type network_mode
std::vector< char > key_data
user_settings_s user_settings
void save_user_settings() const
dcon::text_key add_key_win1252(std::string const &text)
dcon::trigger_key commit_trigger_data(std::vector< uint16_t > data)
std::atomic< bool > ui_pause
std::vector< dcon::army_id > selected_armies
ankerl::unordered_dense::set< dcon::text_key, text::vector_backed_ci_hash, text::vector_backed_ci_eq > untrans_key_to_text_sequence
void on_resize(int32_t x, int32_t y, window::window_state win_state)
std::vector< dcon::navy_id > selected_navies
dcon::data_container world
uint32_t add_locale_data_utf8(std::string const &text)
void on_lbutton_down(int32_t x, int32_t y, key_modifiers mod)
rigtorp::SPSCQueue< event::pending_human_p_event > new_p_event
void army_group_distribute_tasks(dcon::automated_army_group_id group)
std::vector< uint16_t > effect_data
ogl::animation ui_animation
void on_rbutton_down(int32_t x, int32_t y, key_modifiers mod)
dcon::nation_id local_player_nation
std::atomic< bool > game_state_updated
dcon::effect_key commit_effect_data(std::vector< uint16_t > data)
std::vector< char > unit_names
std::vector< int32_t > trigger_data_indices
std::string_view to_string_view(dcon::text_key tag) const
std::string_view locale_string_view(uint32_t tag) const
void on_mouse_wheel(int32_t x, int32_t y, key_modifiers mod, float amount)
std::vector< char > locale_text_data
simple_fs::file_system common_fs
game_scene::scene_properties current_scene
absolute_time_point start_date
absolute_time_point end_date
rigtorp::SPSCQueue< military::land_battle_report > land_battle_reports
void army_group_update_tasks(dcon::automated_army_group_id group)
military::global_military_state military_definitions
rigtorp::SPSCQueue< notification::message > new_messages
std::vector< dcon::ship_id > selected_ships
void open_diplomacy(dcon::nation_id target)
dcon::unit_name_id add_unit_name(std::string_view text)
void start_state_selection(state_selection_data &data)
std::vector< dcon::regiment_id > selected_regiments
std::vector< int32_t > unit_names_indices
void on_drag_finished(int32_t x, int32_t y, key_modifiers mod)
void on_rbutton_up(int32_t x, int32_t y, key_modifiers mod)
void on_key_up(virtual_key keycode, key_modifiers mod)
void on_mouse_move(int32_t x, int32_t y, key_modifiers mod)
dcon::text_key lookup_key(std::string_view text) const
void load_user_settings()
void on_lbutton_up(int32_t x, int32_t y, key_modifiers mod)
ankerl::unordered_dense::map< dcon::text_key, uint32_t, text::vector_backed_ci_hash, text::vector_backed_ci_eq > locale_key_to_text_sequence
void on_mouse_drag(int32_t x, int32_t y, key_modifiers mod)
void update_armies_and_fleets(dcon::automated_army_group_id group)
void on_key_down(virtual_key keycode, key_modifiers mod)
rigtorp::SPSCQueue< event::pending_human_f_p_event > new_f_p_event
void load_locale_strings(std::string_view locale_name)
void on_mbutton_up(int32_t x, int32_t y, key_modifiers mod)
void army_group_update_regiment_status(dcon::automated_army_group_id group)
rigtorp::SPSCQueue< diplomatic_message::message > new_requests
rigtorp::SPSCQueue< event::pending_human_n_event > new_n_event
void load_scenario_data(parsers::error_handler &err, sys::year_month_day bookmark_date)
void on_mbutton_down(int32_t x, int32_t y, key_modifiers mod)
dcon::text_key add_key_utf8(std::string const &text)
bool key_is_localized(dcon::text_key tag) const
std::vector< int32_t > effect_data_indices
rigtorp::SPSCQueue< military::naval_battle_report > naval_battle_reports
void state_select(dcon::state_definition_id sdef)
std::vector< uint16_t > trigger_data
void update_ui_scale(float new_scale)
std::optional< state_selection_data > state_selection
rigtorp::SPSCQueue< event::pending_human_f_n_event > new_f_n_event
std::atomic< bool > province_ownership_changed
nations::global_national_state national_definitions
bool wasd_for_map_movement
bool diplomatic_message_popup
uint8_t interesting_message_settings[int32_t(sys::message_setting_type::count)]
uint8_t self_message_settings[int32_t(sys::message_setting_type::count)]
bool notify_rebels_defeat
uint8_t other_message_settings[int32_t(sys::message_setting_type::count)]
element_base * under_mouse
std::unique_ptr< element_base > army_group_selector_root
element_base * map_rr_legend
element_base * msg_log_window
element_base * menubar_window
int32_t last_tooltip_sub_index
element_base * map_rec_legend
std::unique_ptr< element_base > end_screen
std::chrono::time_point< std::chrono::steady_clock > last_render_time
element_base * chat_window
std::unique_ptr< element_base > nation_picker
element_base * multi_unit_selection_window
element_base * last_tooltip
std::unique_ptr< grid_box > unit_details_box
uint16_t default_body_font
std::unique_ptr< element_base > province_details_root
element_base * map_nav_legend
std::unique_ptr< tool_tip > tooltip
std::unique_ptr< element_base > rgos_root
std::unique_ptr< element_base > select_states_legend
xy_pair relative_mouse_location
element_base * topbar_subwindow
element_base * change_leader_window
element_base * r_chat_window
unit_details_window< dcon::army_id > * army_status_window
unit_details_window< dcon::navy_id > * navy_status_window
ankerl::unordered_dense::map< dcon::text_key, element_target, hash_text_key > defs_by_name
std::unique_ptr< element_base > root
element_base * edit_target
element_base * map_civ_level_legend
ankerl::unordered_dense::map< std::string, sys::aui_pending_bytes > new_ui_windows
uint16_t default_header_font
element_base * left_mouse_hold_target
std::vector< std::unique_ptr< element_base > > endof_navalcombat_windows
std::vector< simple_fs::file > held_open_ui_files
element_base * request_window
element_base * request_topbar_listbox
element_base * console_window
element_base * army_group_window_land
element_base * map_col_legend
bool scrollbar_continuous_movement
element_base * map_rank_legend
element_base * tl_chat_list
std::vector< dcon::technology_id > tech_queue
element_base * outliner_window
std::unique_ptr< element_base > economy_viewer_root
dcon::gfx_object_id bg_gfx_id
element_base * mouse_sensitive_target
element_base * map_dip_legend
element_base * diplomacy_subwindow
std::unique_ptr< element_base > military_root
element_base * drag_target
element_base * under_mouse
element_base * msg_window
element_base * scroll_target
element_base * map_gradient_legend
element_base * console_window_r
std::unique_ptr< element_base > units_root
static constexpr uint8_t is_moveable_mask