From b3ae6868f6ff425823cdf7842a4637921409fa17 Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 4 Nov 2023 17:30:07 +0000 Subject: [PATCH 01/29] macro builder draft --- assets/alice.csv | 3 + assets/alice.gui | 91 +++++++++++++++++++++++-- src/gui/gui_graphics.hpp | 2 + src/gui/gui_minimap.hpp | 143 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 233 insertions(+), 6 deletions(-) diff --git a/assets/alice.csv b/assets/alice.csv index 0d46a271f..1d2529da9 100644 --- a/assets/alice.csv +++ b/assets/alice.csv @@ -1302,4 +1302,7 @@ e_kill_leader;Kill leader; e_annex_null;becomes unowned; meets_the_conditions_of;meets the conditions of ; does_not_meet_the_conditions_of;does not meet the conditions of ; +macro_builder;Macro-builder;;;Macro-construir +save_template;Save template;;;Guardar plantilla +new_template;New template;;;Nueva plantila ;;;;;;;;;;;;;x \ No newline at end of file diff --git a/assets/alice.gui b/assets/alice.gui index 7e8ea9a65..8e8da2bcc 100644 --- a/assets/alice.gui +++ b/assets/alice.gui @@ -2643,23 +2643,102 @@ guiTypes = { windowType = { name = "alice_macro_builder" - position = { 0 200 } - size = { 320 320 } + position = { 400 400 } + size = { 640 320 } guiButtonType = { name = "background" position = { 0 0 } - size = { 320 320 } + size = { 640 320 } quadTextureSprite = "console_background" } + guiButtonType = { + name = "close" + position = { -32 0 } + orientation = "UPPER_RIGHT" + quadTextureSprite = "GFX_main_close_button" + } instantTextBoxType = { name = "title" - text = "Macro builder" + text = "macro_builder" position = { 0 4 } font = "vic_22" borderSize = { 0 0 } - maxsize = { 320 24 } - orientation = "UPPER_LEFT" + maxsize = { 640 24 } + format = center + } + listboxType = { + name = "template_listbox" + position = { 0 28 } + size = { 210 260 } + spacing = 0 + borderSize = { 0 0 } + } + listboxType = { + name = "unit_listbox" + position = { 210 28 } + size = { 210 260 } + spacing = 0 + borderSize = { 0 0 } + } + guiButtonType = { + name = "new_template" + position = { 0 288 } + size = { 128 24 } + quadTextureSprite = "GFX_button_128wide" + buttonText = "new_template" + buttonFont = "vic_22_black" + } + guiButtonType = { + name = "save_template" + position = { 130 288 } + size = { 128 24 } + quadTextureSprite = "GFX_button_128wide" + buttonText = "save_template" + buttonFont = "vic_22_black" + } + } + windowType = { + name = "alice_macro_builder_template_entry" + position = { 0 0 } + size = { 210 24 } + guiButtonType = { + name = "background" + position = { 0 0 } + size = { 210 24 } + quadTextureSprite = "console_background" + } + instantTextBoxType = { + name = "name" + position = { 32 0 } + font = "vic_22" + borderSize = { 0 0 } + maxsize = { 188 24 } format = center } + guiButtonType = { + name = "shield" + position = { 4 4 } + quadTextureSprite = "GFX_flag_new" + Orientation = "UPPER_LEFT" + } + } + windowType = { + name = "alice_macro_builder_unit_entry" + position = { 0 0 } + size = { 300 24 } + guiButtonType = { + name = "background" + position = { 0 0 } + size = { 300 24 } + quadTextureSprite = "console_background" + } + instantTextBoxType = { + name = "name" + position = { 4 0 } + font = "vic_22" + borderSize = { 0 0 } + maxsize = { 128 24 } + format = left + } } } diff --git a/src/gui/gui_graphics.hpp b/src/gui/gui_graphics.hpp index 4be800ef8..c68a3e850 100644 --- a/src/gui/gui_graphics.hpp +++ b/src/gui/gui_graphics.hpp @@ -424,6 +424,8 @@ struct state { std::vector> endof_landcombat_windows; std::vector> endof_navalcombat_windows; + element_base* macro_builder_window = nullptr; + int32_t held_game_speed = 1; // used to keep track of speed while paused uint16_t tooltip_font = 0; diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index f664c4f19..f2753baa1 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -157,6 +157,146 @@ class minimap_ledger_button : public button_element_base { } }; +struct macro_builder_template { + char name[16]; + dcon::nation_id source; + + bool operator!=(macro_builder_template& o) { + return std::memcmp(this, &o, sizeof(*this)); + } +}; +class macro_builder_template_name : public simple_text_element_base { +public: + void on_update(sys::state& state) noexcept override { + auto content = retrieve(state, parent); + auto sv = std::string_view(content.name, content.name + sizeof(content.name)); + set_text(state, std::string(sv)); + } +}; +class macro_builder_template_flag : public flag_button { +public: + void on_update(sys::state& state) noexcept override { + auto content = retrieve(state, parent); + set_current_nation(state, state.world.nation_get_identity_from_identity_holder(content.source)); + } +}; + +class macro_builder_template_entry : public listbox_row_element_base { +public: + std::unique_ptr make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override { + if(name == "name") { + return make_element_by_type(state, id); + } else if(name == "shield") { + return make_element_by_type(state, id); + } else { + return nullptr; + } + } +}; +class macro_builder_template_listbox : public listbox_element_base { +protected: + std::string_view get_row_element_name() override { + return "alice_macro_builder_template_entry"; + } +public: + void on_update(sys::state& state) noexcept override { + row_contents.clear(); + { + macro_builder_template t; + std::memcpy(&t.name, "Template 1 ", sizeof(t.name)); + t.source = state.local_player_nation; + row_contents.push_back(t); + } + { + macro_builder_template t; + std::memcpy(&t.name, "New template ", sizeof(t.name)); + t.source = state.local_player_nation; + row_contents.push_back(t); + } + { + macro_builder_template t; + std::memcpy(&t.name, "sotrmtropper ", sizeof(t.name)); + t.source = state.local_player_nation; + row_contents.push_back(t); + } + update(state); + } +}; + +class macro_builder_unit_name : public simple_text_element_base { +public: + void on_update(sys::state& state) noexcept override { + auto content = retrieve(state, parent); + set_text(state, text::produce_simple_string(state, state.military_definitions.unit_base_definitions[content].name)); + } +}; +class macro_builder_unit_entry : public listbox_row_element_base { +public: + std::unique_ptr make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override { + if(name == "name") { + return make_element_by_type(state, id); + } else { + return nullptr; + } + } +}; +class macro_builder_unit_listbox : public listbox_element_base { +protected: + std::string_view get_row_element_name() override { + return "alice_macro_builder_unit_entry"; + } +public: + void on_update(sys::state& state) noexcept override { + row_contents.clear(); + for(dcon::unit_type_id::value_base_t i = 0; i < state.military_definitions.unit_base_definitions.size(); i++) { + row_contents.push_back(dcon::unit_type_id(i)); + } + update(state); + } +}; + +class macro_builder_window : public window_element_base { +public: + std::unique_ptr make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override { + if(name == "background") { + return make_element_by_type(state, id); + } else if(name == "close") { + return make_element_by_type(state, id); + } else if(name == "template_listbox") { + return make_element_by_type(state, id); + } else if(name == "unit_listbox") { + return make_element_by_type(state, id); + } else { + return nullptr; + } + } +}; +class minimap_macro_builder_button : public button_element_base { +public: + void button_action(sys::state& state) noexcept override { + if(!state.ui_state.macro_builder_window) { + auto window = make_element_by_type(state, "alice_macro_builder"); + state.ui_state.macro_builder_window = window.get(); + state.ui_state.root->add_child_to_front(std::move(window)); + } else if(state.ui_state.macro_builder_window->is_visible()) { + state.ui_state.macro_builder_window->set_visible(state, false); + } else { + state.ui_state.macro_builder_window->set_visible(state, true); + state.ui_state.root->move_child_to_front(state.ui_state.macro_builder_window); + } + } + + tooltip_behavior has_tooltip(sys::state& state) noexcept override { + return tooltip_behavior::tooltip; + } + + void update_tooltip(sys::state& state, int32_t x, int32_t t, text::columnar_layout& contents) noexcept override { + auto box = text::open_layout_box(contents, 0); + text::localised_format_box(state, contents, box, std::string_view("macro_builder")); + text::close_layout_box(contents, box); + } +}; + class minimap_msg_settings_button : public button_element_base { public: void button_action(sys::state& state) noexcept override { @@ -344,6 +484,9 @@ class minimap_container_window : public window_element_base { } else if(name == "button_goto") { return make_element_by_type(state, id); } else if(name == "ledger_button") { + auto ptr = make_element_by_type(state, id); + ptr->base_data.position.y += ptr->base_data.size.y; + add_child_to_front(std::move(ptr)); return make_element_by_type(state, id); } else if(name == "map_zoom_in") { return make_element_by_type(state, id); From ed500704f019cb20fa0a2264004649296b1de0e1 Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Thu, 21 Dec 2023 01:27:12 +0000 Subject: [PATCH 02/29] make macro button below goto button --- src/gui/gui_minimap.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index 2bdfd1b7f..cac28aafe 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -488,11 +488,11 @@ class minimap_container_window : public window_element_base { } else if(name == "menu_button") { return make_element_by_type(state, id); } else if(name == "button_goto") { - return make_element_by_type(state, id); - } else if(name == "ledger_button") { auto ptr = make_element_by_type(state, id); ptr->base_data.position.y += ptr->base_data.size.y; add_child_to_front(std::move(ptr)); + return make_element_by_type(state, id); + } else if(name == "ledger_button") { return make_element_by_type(state, id); } else if(name == "map_zoom_in") { return make_element_by_type(state, id); From 72a07ba9ec9c180fe87b470b579602feca6be5a9 Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 03:56:04 +0000 Subject: [PATCH 03/29] templates work --- src/common_types/container_types.hpp | 11 +++ src/gui/gui_graphics.hpp | 3 +- src/gui/gui_minimap.hpp | 129 +++++++++++++++++++-------- 3 files changed, 107 insertions(+), 36 deletions(-) diff --git a/src/common_types/container_types.hpp b/src/common_types/container_types.hpp index d3c9c5767..b785a539a 100644 --- a/src/common_types/container_types.hpp +++ b/src/common_types/container_types.hpp @@ -296,4 +296,15 @@ struct player_name { }; static_assert(sizeof(player_name) == sizeof(player_name::data)); +struct macro_builder_template { + sys::checksum_key scenario_checksum; + dcon::nation_id source; + char name[8] = { 0 }; + uint8_t amounts[32] = { 0 }; + + bool operator!=(macro_builder_template& o) { + return std::memcmp(this, &o, sizeof(*this)); + } +}; + } // namespace sys diff --git a/src/gui/gui_graphics.hpp b/src/gui/gui_graphics.hpp index 8b89f54f3..cb91e7653 100644 --- a/src/gui/gui_graphics.hpp +++ b/src/gui/gui_graphics.hpp @@ -442,7 +442,8 @@ struct state { element_base* macro_builder_window = nullptr; int32_t held_game_speed = 1; // used to keep track of speed while paused - + sys::macro_builder_template current_template; // used as the currently edited template + std::vector templates; uint16_t tooltip_font = 0; bool ctrl_held_down = false; diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index 1c338334b..505894010 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -162,31 +162,25 @@ class minimap_ledger_button : public button_element_base { } }; -struct macro_builder_template { - char name[16]; - dcon::nation_id source; - - bool operator!=(macro_builder_template& o) { - return std::memcmp(this, &o, sizeof(*this)); - } -}; class macro_builder_template_name : public simple_text_element_base { public: void on_update(sys::state& state) noexcept override { - auto content = retrieve(state, parent); - auto sv = std::string_view(content.name, content.name + sizeof(content.name)); + auto index = retrieve(state, parent); + auto& name = state.ui_state.templates[index].name; + auto sv = std::string_view(name, name + sizeof(name)); set_text(state, std::string(sv)); } }; class macro_builder_template_flag : public flag_button { public: void on_update(sys::state& state) noexcept override { - auto content = retrieve(state, parent); - set_current_nation(state, state.world.nation_get_identity_from_identity_holder(content.source)); + auto index = retrieve(state, parent); + auto nid = state.ui_state.templates[index].source; + set_current_nation(state, state.world.nation_get_identity_from_identity_holder(nid)); } }; -class macro_builder_template_entry : public listbox_row_element_base { +class macro_builder_template_entry : public listbox_row_element_base { public: std::unique_ptr make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override { if(name == "name") { @@ -198,32 +192,36 @@ class macro_builder_template_entry : public listbox_row_element_base { +class macro_builder_template_listbox : public listbox_element_base { protected: std::string_view get_row_element_name() override { return "alice_macro_builder_template_entry"; } public: - void on_update(sys::state& state) noexcept override { - row_contents.clear(); - { - macro_builder_template t; - std::memcpy(&t.name, "Template 1 ", sizeof(t.name)); - t.source = state.local_player_nation; - row_contents.push_back(t); - } - { - macro_builder_template t; - std::memcpy(&t.name, "New template ", sizeof(t.name)); - t.source = state.local_player_nation; - row_contents.push_back(t); - } - { - macro_builder_template t; - std::memcpy(&t.name, "sotrmtropper ", sizeof(t.name)); - t.source = state.local_player_nation; - row_contents.push_back(t); + void on_create(sys::state& state) noexcept override { + listbox_element_base::on_create(state); + // + auto sdir = simple_fs::get_or_create_save_game_directory(); + auto f = simple_fs::open_file(sdir, NATIVE("templates.bin")); + if(f) { + auto contents = simple_fs::view_contents(*f); + if(contents.file_size > 0) { + uint32_t num_templates = contents.file_size / sizeof(sys::macro_builder_template); + //Corruption protection + if(num_templates >= 256) + num_templates = 256; + state.ui_state.templates.resize(num_templates); + std::memcpy(state.ui_state.templates.data(), contents.data, num_templates * sizeof(sys::macro_builder_template)); + } } + // + update(state); + } + + void on_update(sys::state& state) noexcept override { + row_contents.resize(state.ui_state.templates.size(), 0); + for(uint32_t i = 0; i < uint32_t(state.ui_state.templates.size()); i++) + row_contents[i] = i; update(state); } }; @@ -232,7 +230,24 @@ class macro_builder_unit_name : public simple_text_element_base { public: void on_update(sys::state& state) noexcept override { auto content = retrieve(state, parent); - set_text(state, text::produce_simple_string(state, state.military_definitions.unit_base_definitions[content].name)); + auto name = text::produce_simple_string(state, state.military_definitions.unit_base_definitions[content].name); + int32_t amount = state.ui_state.current_template.amounts[content.index()]; + set_text(state, "(" + std::to_string(amount) + ") " + name); + } +}; +class macro_builder_unit_button : public right_click_button_element_base { +public: + void button_action(sys::state& state) noexcept override { + auto content = retrieve(state, parent); + if(state.ui_state.current_template.amounts[content.index()] < 255) { + state.ui_state.current_template.amounts[content.index()] += 1; + } + } + void button_right_action(sys::state& state) noexcept override { + auto content = retrieve(state, parent); + if(state.ui_state.current_template.amounts[content.index()] > 0) { + state.ui_state.current_template.amounts[content.index()] -= 1; + } } }; class macro_builder_unit_entry : public listbox_row_element_base { @@ -240,6 +255,8 @@ class macro_builder_unit_entry : public listbox_row_element_base make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override { if(name == "name") { return make_element_by_type(state, id); + } else if(name == "background") { + return make_element_by_type(state, id); } else { return nullptr; } @@ -253,13 +270,51 @@ class macro_builder_unit_listbox : public listbox_element_base(state.ui_state.templates.data()), uint32_t(state.ui_state.templates.size()) * sizeof(sys::macro_builder_template)); + } +}; class macro_builder_window : public window_element_base { public: std::unique_ptr make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override { @@ -271,6 +326,10 @@ class macro_builder_window : public window_element_base { return make_element_by_type(state, id); } else if(name == "unit_listbox") { return make_element_by_type(state, id); + } else if(name == "new_template") { + return make_element_by_type(state, id); + } else if(name == "save_template") { + return make_element_by_type(state, id); } else { return nullptr; } From 5adbaf3ffa8e37bde3958319c06d4d7c679c727b Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 05:11:43 +0000 Subject: [PATCH 04/29] misc macro builder fixes --- assets/alice.gui | 34 ++++++-- src/gui/gui_element_types.cpp | 159 ++++++++++++++++++++++++++++++++++ src/gui/gui_element_types.hpp | 159 +--------------------------------- src/gui/gui_minimap.hpp | 65 +++++++++++--- src/map/modes/political.hpp | 2 + 5 files changed, 240 insertions(+), 179 deletions(-) diff --git a/assets/alice.gui b/assets/alice.gui index 126323869..6d6fa374e 100644 --- a/assets/alice.gui +++ b/assets/alice.gui @@ -3586,20 +3586,20 @@ guiTypes = { listboxType = { name = "template_listbox" position = { 0 28 } - size = { 210 260 } + size = { 105 260 } spacing = 0 borderSize = { 0 0 } } listboxType = { name = "unit_listbox" - position = { 210 28 } - size = { 210 260 } + position = { 108 28 } + size = { 210 240 } spacing = 0 borderSize = { 0 0 } } guiButtonType = { name = "new_template" - position = { 0 288 } + position = { 2 288 } size = { 128 24 } quadTextureSprite = "GFX_button_128wide" buttonText = "new_template" @@ -3613,15 +3613,31 @@ guiTypes = { buttonText = "save_template" buttonFont = "vic_22_black" } + guiButtonType = { + name = "remove_template" + position = { 260 288 } + size = { 128 24 } + quadTextureSprite = "GFX_button_128wide" + buttonText = "remove_template" + buttonFont = "vic_22_black" + } + guiButtonType = { + name = "switch_type" + position = { 390 288 } + size = { 128 24 } + quadTextureSprite = "GFX_button_128wide" + buttonText = "switch_type" + buttonFont = "vic_22_black" + } } windowType = { name = "alice_macro_builder_template_entry" position = { 0 0 } - size = { 210 24 } + size = { 105 24 } guiButtonType = { name = "background" position = { 0 0 } - size = { 210 24 } + size = { 105 24 } quadTextureSprite = "console_background" } instantTextBoxType = { @@ -3629,7 +3645,7 @@ guiTypes = { position = { 32 0 } font = "vic_22" borderSize = { 0 0 } - maxsize = { 188 24 } + maxsize = { 100 24 } format = center } guiButtonType = { @@ -3642,11 +3658,11 @@ guiTypes = { windowType = { name = "alice_macro_builder_unit_entry" position = { 0 0 } - size = { 300 24 } + size = { 210 24 } guiButtonType = { name = "background" position = { 0 0 } - size = { 300 24 } + size = { 210 24 } quadTextureSprite = "console_background" } instantTextBoxType = { diff --git a/src/gui/gui_element_types.cpp b/src/gui/gui_element_types.cpp index 0ca0a3a19..ef462455d 100644 --- a/src/gui/gui_element_types.cpp +++ b/src/gui/gui_element_types.cpp @@ -2134,4 +2134,163 @@ void unit_frame_bg::update_tooltip(sys::state& state, int32_t x, int32_t y, text single_unit_tooltip(state, contents, std::get(display_unit)); } +void populate_shortcut_tooltip(sys::state& state, ui::element_base& elm, text::columnar_layout& contents) noexcept { + if(elm.base_data.get_element_type() != ui::element_type::button) + return; + if(elm.base_data.data.button.shortcut == sys::virtual_key::NONE) + return; + static const std::string_view key_names[] = { //enum class virtual_key : uint8_t { + "", //NONE = 0x00, + "Left-Button", //LBUTTON = 0x01, + "Right-Button", //RBUTTON = 0x02, + "Cancel", //CANCEL = 0x03, + "Multimedia button", //MBUTTON = 0x04, + "XButton1", //XBUTTON_1 = 0x05, + "XButton2", //XBUTTON_2 = 0x06, + "Backspace", //BACK = 0x08, + "TAB", //TAB = 0x09, + "Clear", //CLEAR = 0x0C, + "Return", //RETURN = 0x0D, + "Shift", //SHIFT = 0x10, + "Control", //CONTROL = 0x11, + "Menu", //MENU = 0x12, + "Pause", //PAUSE = 0x13, + "Capital", //CAPITAL = 0x14, + "Kana", //KANA = 0x15, + "Junja", //JUNJA = 0x17, + "Final", //FINAL = 0x18, + "Kanji", //KANJI = 0x19, + "Escape", //ESCAPE = 0x1B, + "Convert", //CONVERT = 0x1C, + "Nonconvert", //NONCONVERT = 0x1D, + "Accept", //ACCEPT = 0x1E, + "Modechange", //MODECHANGE = 0x1F, + "Spacebar", //SPACE = 0x20, + "Prior", //PRIOR = 0x21, + "Next", //NEXT = 0x22, + "End", //END = 0x23, + "Home", //HOME = 0x24, + "Left", //LEFT = 0x25, + "Up", //UP = 0x26, + "Right", //RIGHT = 0x27, + "Down", //DOWN = 0x28, + "Select", //SELECT = 0x29, + "Print", //PRINT = 0x2A, + "Execute", //EXECUTE = 0x2B, + "Snapshot", //SNAPSHOT = 0x2C, + "Insert", //INSERT = 0x2D, + "Delete", //DELETE_KEY = 0x2E, + "Help", //HELP = 0x2F, + "0", //NUM_0 = 0x30, + "1", //NUM_1 = 0x31, + "2", //NUM_2 = 0x32, + "3", //NUM_3 = 0x33, + "4", //NUM_4 = 0x34, + "5", //NUM_5 = 0x35, + "6", //NUM_6 = 0x36, + "7", //NUM_7 = 0x37, + "8", //NUM_8 = 0x38, + "9", //NUM_9 = 0x39, + "A", //A = 0x41, + "B", //B = 0x42, + "C", //C = 0x43, + "D", //D = 0x44, + "E", //E = 0x45, + "F", //F = 0x46, + "G", //G = 0x47, + "H", //H = 0x48, + "I", //I = 0x49, + "J", //J = 0x4A, + "K", //K = 0x4B, + "L", //L = 0x4C, + "M", //M = 0x4D, + "N", //N = 0x4E, + "O", //O = 0x4F, + "P", //P = 0x50, + "Q", //Q = 0x51, + "R", //R = 0x52, + "S", //S = 0x53, + "T", //T = 0x54, + "U", //U = 0x55, + "V", //V = 0x56, + "W", //W = 0x57, + "X", //X = 0x58, + "Y", //Y = 0x59, + "Z", //Z = 0x5A, + "Left Windows", //LWIN = 0x5B, + "Right Windows", //RWIN = 0x5C, + "Apps", //APPS = 0x5D, + "Sleep", //SLEEP = 0x5F, + "Numpad 0", //NUMPAD0 = 0x60, + "Numpad 1", //NUMPAD1 = 0x61, + "Numpad 2", //NUMPAD2 = 0x62, + "Numpad 3", //NUMPAD3 = 0x63, + "Numpad 4", //NUMPAD4 = 0x64, + "Numpad 5", //NUMPAD5 = 0x65, + "Numpad 6", //NUMPAD6 = 0x66, + "Numpad 7", //NUMPAD7 = 0x67, + "Numpad 8", //NUMPAD8 = 0x68, + "Numpad 9", //NUMPAD9 = 0x69, + "Numpad *", //MULTIPLY = 0x6A, + "Numpad +", //ADD = 0x6B, + "Numpad .", //SEPARATOR = 0x6C, + "Numpad -", //SUBTRACT = 0x6D, + "Numpad .", //DECIMAL = 0x6E, + "Numpad /", //DIVIDE = 0x6F, + "F1", //F1 = 0x70, + "F2", //F2 = 0x71, + "F3", //F3 = 0x72, + "F4", //F4 = 0x73, + "F5", //F5 = 0x74, + "F6", //F6 = 0x75, + "F7", //F7 = 0x76, + "F8", //F8 = 0x77, + "F9", //F9 = 0x78, + "F10", //F10 = 0x79, + "F11", //F11 = 0x7A, + "F12", //F12 = 0x7B, + "F13", //F13 = 0x7C, + "F14", //F14 = 0x7D, + "F15", //F15 = 0x7E, + "F16", //F16 = 0x7F, + "F17", //F17 = 0x80, + "F18", //F18 = 0x81, + "F19", //F19 = 0x82, + "F20", //F20 = 0x83, + "F21", //F21 = 0x84, + "F22", //F22 = 0x85, + "F23", //F23 = 0x86, + "F24", //F24 = 0x87, + "Navigation View", //NAVIGATION_VIEW = 0x88, + "Navigation Menu", //NAVIGATION_MENU = 0x89, + "Navigation Up", //NAVIGATION_UP = 0x8A, + "Navigation Down", //NAVIGATION_DOWN = 0x8B, + "Navigation Left", //NAVIGATION_LEFT = 0x8C, + "Navigation Right", //NAVIGATION_RIGHT = 0x8D, + "Navigation Accept", //NAVIGATION_ACCEPT = 0x8E, + "Navigation Cancel", //NAVIGATION_CANCEL = 0x8F, + "Numlock", //NUMLOCK = 0x90, + "Scroll lock", //SCROLL = 0x91, + "=", //OEM_NEC_EQUAL = 0x92, + "Left Shift", //LSHIFT = 0xA0, + "Right Shift", //RSHIFT = 0xA1, + "Left Control", //LCONTROL = 0xA2, + "Right Control", //RCONTROL = 0xA3, + "Left Menu", //LMENU = 0xA4, + "Right Menu", //RMENU = 0xA5, + ";", //SEMICOLON = 0xBA, + "+", //PLUS = 0xBB, + ",", //COMMA = 0xBC, + "-", //MINUS = 0xBD, + ".", //PERIOD = 0xBE, + "\\", //FORWARD_SLASH = 0xBF, + "~", //TILDA = 0xC0, + "[", //OPEN_BRACKET = 0xDB, + "/", //BACK_SLASH = 0xDC, + "]", //CLOSED_BRACKET = 0xDD, + "\"", //QUOTE = 0xDE + }; + text::add_line(state, contents, "alice_shortcut_tooltip", text::variable_type::x, key_names[uint8_t(elm.base_data.data.button.shortcut)]); +} + } // namespace ui diff --git a/src/gui/gui_element_types.hpp b/src/gui/gui_element_types.hpp index b77250bec..73b02cb7f 100644 --- a/src/gui/gui_element_types.hpp +++ b/src/gui/gui_element_types.hpp @@ -1704,163 +1704,6 @@ class grid_box : public window_element_base { } }; -void populate_shortcut_tooltip(sys::state& state, ui::element_base& elm, text::columnar_layout& contents) noexcept { - if(elm.base_data.get_element_type() != ui::element_type::button) - return; - if(elm.base_data.data.button.shortcut == sys::virtual_key::NONE) - return; - static const std::string_view key_names[] = { //enum class virtual_key : uint8_t { - "", //NONE = 0x00, - "Left-Button", //LBUTTON = 0x01, - "Right-Button", //RBUTTON = 0x02, - "Cancel", //CANCEL = 0x03, - "Multimedia button", //MBUTTON = 0x04, - "XButton1", //XBUTTON_1 = 0x05, - "XButton2", //XBUTTON_2 = 0x06, - "Backspace", //BACK = 0x08, - "TAB", //TAB = 0x09, - "Clear", //CLEAR = 0x0C, - "Return", //RETURN = 0x0D, - "Shift", //SHIFT = 0x10, - "Control", //CONTROL = 0x11, - "Menu", //MENU = 0x12, - "Pause", //PAUSE = 0x13, - "Capital", //CAPITAL = 0x14, - "Kana", //KANA = 0x15, - "Junja", //JUNJA = 0x17, - "Final", //FINAL = 0x18, - "Kanji", //KANJI = 0x19, - "Escape", //ESCAPE = 0x1B, - "Convert", //CONVERT = 0x1C, - "Nonconvert", //NONCONVERT = 0x1D, - "Accept", //ACCEPT = 0x1E, - "Modechange", //MODECHANGE = 0x1F, - "Spacebar", //SPACE = 0x20, - "Prior", //PRIOR = 0x21, - "Next", //NEXT = 0x22, - "End", //END = 0x23, - "Home", //HOME = 0x24, - "Left", //LEFT = 0x25, - "Up", //UP = 0x26, - "Right", //RIGHT = 0x27, - "Down", //DOWN = 0x28, - "Select", //SELECT = 0x29, - "Print", //PRINT = 0x2A, - "Execute", //EXECUTE = 0x2B, - "Snapshot", //SNAPSHOT = 0x2C, - "Insert", //INSERT = 0x2D, - "Delete", //DELETE_KEY = 0x2E, - "Help", //HELP = 0x2F, - "0", //NUM_0 = 0x30, - "1", //NUM_1 = 0x31, - "2", //NUM_2 = 0x32, - "3", //NUM_3 = 0x33, - "4", //NUM_4 = 0x34, - "5", //NUM_5 = 0x35, - "6", //NUM_6 = 0x36, - "7", //NUM_7 = 0x37, - "8", //NUM_8 = 0x38, - "9", //NUM_9 = 0x39, - "A", //A = 0x41, - "B", //B = 0x42, - "C", //C = 0x43, - "D", //D = 0x44, - "E", //E = 0x45, - "F", //F = 0x46, - "G", //G = 0x47, - "H", //H = 0x48, - "I", //I = 0x49, - "J", //J = 0x4A, - "K", //K = 0x4B, - "L", //L = 0x4C, - "M", //M = 0x4D, - "N", //N = 0x4E, - "O", //O = 0x4F, - "P", //P = 0x50, - "Q", //Q = 0x51, - "R", //R = 0x52, - "S", //S = 0x53, - "T", //T = 0x54, - "U", //U = 0x55, - "V", //V = 0x56, - "W", //W = 0x57, - "X", //X = 0x58, - "Y", //Y = 0x59, - "Z", //Z = 0x5A, - "Left Windows", //LWIN = 0x5B, - "Right Windows", //RWIN = 0x5C, - "Apps", //APPS = 0x5D, - "Sleep", //SLEEP = 0x5F, - "Numpad 0", //NUMPAD0 = 0x60, - "Numpad 1", //NUMPAD1 = 0x61, - "Numpad 2", //NUMPAD2 = 0x62, - "Numpad 3", //NUMPAD3 = 0x63, - "Numpad 4", //NUMPAD4 = 0x64, - "Numpad 5", //NUMPAD5 = 0x65, - "Numpad 6", //NUMPAD6 = 0x66, - "Numpad 7", //NUMPAD7 = 0x67, - "Numpad 8", //NUMPAD8 = 0x68, - "Numpad 9", //NUMPAD9 = 0x69, - "Numpad *", //MULTIPLY = 0x6A, - "Numpad +", //ADD = 0x6B, - "Numpad .", //SEPARATOR = 0x6C, - "Numpad -", //SUBTRACT = 0x6D, - "Numpad .", //DECIMAL = 0x6E, - "Numpad /", //DIVIDE = 0x6F, - "F1", //F1 = 0x70, - "F2", //F2 = 0x71, - "F3", //F3 = 0x72, - "F4", //F4 = 0x73, - "F5", //F5 = 0x74, - "F6", //F6 = 0x75, - "F7", //F7 = 0x76, - "F8", //F8 = 0x77, - "F9", //F9 = 0x78, - "F10", //F10 = 0x79, - "F11", //F11 = 0x7A, - "F12", //F12 = 0x7B, - "F13", //F13 = 0x7C, - "F14", //F14 = 0x7D, - "F15", //F15 = 0x7E, - "F16", //F16 = 0x7F, - "F17", //F17 = 0x80, - "F18", //F18 = 0x81, - "F19", //F19 = 0x82, - "F20", //F20 = 0x83, - "F21", //F21 = 0x84, - "F22", //F22 = 0x85, - "F23", //F23 = 0x86, - "F24", //F24 = 0x87, - "Navigation View", //NAVIGATION_VIEW = 0x88, - "Navigation Menu", //NAVIGATION_MENU = 0x89, - "Navigation Up", //NAVIGATION_UP = 0x8A, - "Navigation Down", //NAVIGATION_DOWN = 0x8B, - "Navigation Left", //NAVIGATION_LEFT = 0x8C, - "Navigation Right", //NAVIGATION_RIGHT = 0x8D, - "Navigation Accept", //NAVIGATION_ACCEPT = 0x8E, - "Navigation Cancel", //NAVIGATION_CANCEL = 0x8F, - "Numlock", //NUMLOCK = 0x90, - "Scroll lock", //SCROLL = 0x91, - "=", //OEM_NEC_EQUAL = 0x92, - "Left Shift", //LSHIFT = 0xA0, - "Right Shift", //RSHIFT = 0xA1, - "Left Control", //LCONTROL = 0xA2, - "Right Control", //RCONTROL = 0xA3, - "Left Menu", //LMENU = 0xA4, - "Right Menu", //RMENU = 0xA5, - ";", //SEMICOLON = 0xBA, - "+", //PLUS = 0xBB, - ",", //COMMA = 0xBC, - "-", //MINUS = 0xBD, - ".", //PERIOD = 0xBE, - "\\", //FORWARD_SLASH = 0xBF, - "~", //TILDA = 0xC0, - "[", //OPEN_BRACKET = 0xDB, - "/", //BACK_SLASH = 0xDC, - "]", //CLOSED_BRACKET = 0xDD, - "\"", //QUOTE = 0xDE - }; - text::add_line(state, contents, "alice_shortcut_tooltip", text::variable_type::x, key_names[uint8_t(elm.base_data.data.button.shortcut)]); -} +void populate_shortcut_tooltip(sys::state& state, ui::element_base& elm, text::columnar_layout& contents) noexcept; } // namespace ui diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index 505894010..7a4d64912 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -200,7 +200,6 @@ class macro_builder_template_listbox : public listbox_element_base::on_create(state); - // auto sdir = simple_fs::get_or_create_save_game_directory(); auto f = simple_fs::open_file(sdir, NATIVE("templates.bin")); if(f) { @@ -214,10 +213,7 @@ class macro_builder_template_listbox : public listbox_element_base(state, parent); for(dcon::unit_type_id::value_base_t i = 0; i < state.military_definitions.unit_base_definitions.size(); i++) { - if(state.military_definitions.unit_base_definitions[dcon::unit_type_id(i)].is_land == true) { - row_contents.push_back(dcon::unit_type_id(i)); - } - } - // Then naval after - for(dcon::unit_type_id::value_base_t i = 0; i < state.military_definitions.unit_base_definitions.size(); i++) { - if(state.military_definitions.unit_base_definitions[dcon::unit_type_id(i)].is_land == false) { + if(state.military_definitions.unit_base_definitions[dcon::unit_type_id(i)].is_land == b) { row_contents.push_back(dcon::unit_type_id(i)); } } @@ -315,8 +305,43 @@ class macro_builder_save_template_button : public button_element_base { simple_fs::write_file(sdir, NATIVE("templates.bin"), reinterpret_cast(state.ui_state.templates.data()), uint32_t(state.ui_state.templates.size()) * sizeof(sys::macro_builder_template)); } }; +class macro_builder_remove_template_button : public button_element_base { +public: + void button_action(sys::state& state) noexcept override { + sys::macro_builder_template& t = state.ui_state.current_template; + for(uint32_t i = 0; i < uint32_t(state.ui_state.templates.size()); i++) { + auto const& u = state.ui_state.templates[i]; + if(t.scenario_checksum.is_equal(u.scenario_checksum) + && std::memcmp(u.name, t.name, sizeof(sys::macro_builder_template::name)) == 0) { + state.ui_state.templates.erase(state.ui_state.templates.begin() + i); + break; + } + } + } +}; +class macro_builder_switch_type_button : public button_element_base { +public: + void on_update(sys::state& state) noexcept override { + auto b = retrieve(state, parent); + if(b) { + set_button_text(state, text::produce_simple_string(state, "switch_type_naval")); + } else { + set_button_text(state, text::produce_simple_string(state, "switch_type_land")); + } + } + void button_action(sys::state& state) noexcept override { + auto b = retrieve(state, parent); + send(state, parent, element_selection_wrapper{ !b }); + } +}; class macro_builder_window : public window_element_base { + bool is_land = true; public: + void on_create(sys::state& state) noexcept override { + window_element_base::on_create(state); + impl_on_update(state); + } + std::unique_ptr make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override { if(name == "background") { return make_element_by_type(state, id); @@ -330,10 +355,26 @@ class macro_builder_window : public window_element_base { return make_element_by_type(state, id); } else if(name == "save_template") { return make_element_by_type(state, id); + } else if(name == "remove_template") { + return make_element_by_type(state, id); + } else if(name == "switch_type") { + return make_element_by_type(state, id); } else { return nullptr; } } + + message_result get(sys::state& state, Cyto::Any& payload) noexcept override { + if(payload.holds_type()) { + payload.emplace(is_land); + return message_result::consumed; + } else if(payload.holds_type>()) { + is_land = Cyto::any_cast>(payload).data; + impl_on_update(state); + return message_result::consumed; + } + return window_element_base::impl_get(state, payload); + } }; class minimap_macro_builder_button : public button_element_base { public: diff --git a/src/map/modes/political.hpp b/src/map/modes/political.hpp index 4a0240c25..a9b3a32fe 100644 --- a/src/map/modes/political.hpp +++ b/src/map/modes/political.hpp @@ -1,5 +1,7 @@ #pragma once +#include "prng.hpp" + uint32_t derive_color_from_ol_color(sys::state& state, uint32_t ol_color, dcon::nation_id n) { auto base = sys::rgb_to_hsv(ol_color); auto roff = rng::get_random_pair(state, uint32_t(n.index()), uint32_t(n.index())); From 728db5468d0d9c243b15f9b8c8a5d4a9f77b0869 Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 06:08:17 +0000 Subject: [PATCH 05/29] show description of template in detail --- assets/alice.csv | 8 +- assets/alice.gui | 29 ++++-- src/common_types/container_types.hpp | 3 +- src/gui/gui_minimap.hpp | 139 ++++++++++++++++++++++++++- 4 files changed, 166 insertions(+), 13 deletions(-) diff --git a/assets/alice.csv b/assets/alice.csv index c108fcbc3..64077b241 100644 --- a/assets/alice.csv +++ b/assets/alice.csv @@ -1366,8 +1366,12 @@ aml_civ_s3;100% Westernized aml_civ_s4;0% Westernized aml_civ_s5;Colony macro_builder;Macro-builder;;;Macro-constructor -save_template;Save template;;;Guardar plantilla -new_template;New template;;;Nueva plantila +macro_total_desc;Total unit stats: +macro_remove_template;Delete +macro_switch_type_land;Switch to: Land +macro_switch_type_naval;Switch to: Naval +macro_save_template;Save template;;;Guardar plantilla +macro_new_template;New template;;;Nueva plantila aml_col_s1;Potential aml_col_s2;NA aml_col_s3;Can Invest diff --git a/assets/alice.gui b/assets/alice.gui index 6d6fa374e..5da648993 100644 --- a/assets/alice.gui +++ b/assets/alice.gui @@ -3560,7 +3560,7 @@ guiTypes = { windowType = { name = "alice_macro_builder" - position = { 400 400 } + position = { 420 400 } size = { 640 320 } guiButtonType = { name = "background" @@ -3586,7 +3586,7 @@ guiTypes = { listboxType = { name = "template_listbox" position = { 0 28 } - size = { 105 260 } + size = { 105 240 } spacing = 0 borderSize = { 0 0 } } @@ -3602,7 +3602,7 @@ guiTypes = { position = { 2 288 } size = { 128 24 } quadTextureSprite = "GFX_button_128wide" - buttonText = "new_template" + buttonText = "macro_new_template" buttonFont = "vic_22_black" } guiButtonType = { @@ -3610,7 +3610,7 @@ guiTypes = { position = { 130 288 } size = { 128 24 } quadTextureSprite = "GFX_button_128wide" - buttonText = "save_template" + buttonText = "macro_save_template" buttonFont = "vic_22_black" } guiButtonType = { @@ -3618,7 +3618,7 @@ guiTypes = { position = { 260 288 } size = { 128 24 } quadTextureSprite = "GFX_button_128wide" - buttonText = "remove_template" + buttonText = "macro_remove_template" buttonFont = "vic_22_black" } guiButtonType = { @@ -3626,9 +3626,26 @@ guiTypes = { position = { 390 288 } size = { 128 24 } quadTextureSprite = "GFX_button_128wide" - buttonText = "switch_type" + buttonText = "macro_switch_type_naval" buttonFont = "vic_22_black" } + editBoxType = { + name = "input" + position = { 320 28 } + textureFile = "gfx\\interface\\small_tiles_dialog.dds" + font = "FPS_Font" + borderSize = { 0 0 } + maxsize = { 128 40 } + format = center + } + instantTextBoxType = { + name = "details" + position = { 320 72 } + font = "vic_22" + borderSize = { 0 0 } + maxsize = { 128 298 } + format = center + } } windowType = { name = "alice_macro_builder_template_entry" diff --git a/src/common_types/container_types.hpp b/src/common_types/container_types.hpp index b785a539a..920faef6a 100644 --- a/src/common_types/container_types.hpp +++ b/src/common_types/container_types.hpp @@ -297,10 +297,11 @@ struct player_name { static_assert(sizeof(player_name) == sizeof(player_name::data)); struct macro_builder_template { + static constexpr uint32_t max_types = 48; sys::checksum_key scenario_checksum; dcon::nation_id source; char name[8] = { 0 }; - uint8_t amounts[32] = { 0 }; + uint8_t amounts[max_types] = { 0 }; bool operator!=(macro_builder_template& o) { return std::memcmp(this, &o, sizeof(*this)); diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index 7a4d64912..1272a9019 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -166,7 +166,7 @@ class macro_builder_template_name : public simple_text_element_base { public: void on_update(sys::state& state) noexcept override { auto index = retrieve(state, parent); - auto& name = state.ui_state.templates[index].name; + auto const& name = state.ui_state.templates[index].name; auto sv = std::string_view(name, name + sizeof(name)); set_text(state, std::string(sv)); } @@ -286,7 +286,7 @@ class macro_builder_save_template_button : public button_element_base { void button_action(sys::state& state) noexcept override { sys::macro_builder_template& t = state.ui_state.current_template; t.scenario_checksum = state.scenario_checksum; - + t.source = state.local_player_nation; // Replace templates with the same name and of the same scenario bool overwrite = false; for(auto& u : state.ui_state.templates) { @@ -322,8 +322,8 @@ class macro_builder_remove_template_button : public button_element_base { class macro_builder_switch_type_button : public button_element_base { public: void on_update(sys::state& state) noexcept override { - auto b = retrieve(state, parent); - if(b) { + auto is_land = retrieve(state, parent); + if(is_land) { set_button_text(state, text::produce_simple_string(state, "switch_type_naval")); } else { set_button_text(state, text::produce_simple_string(state, "switch_type_land")); @@ -334,6 +334,135 @@ class macro_builder_switch_type_button : public button_element_base { send(state, parent, element_selection_wrapper{ !b }); } }; +class macro_builder_name_input : public edit_box_element_base { +public: + void edit_box_enter(sys::state& state, std::string_view str) noexcept override { + auto s = parsers::remove_surrounding_whitespace(str); + if(s.empty()) + return; + std::memset(state.ui_state.current_template.name, ' ', sizeof(sys::macro_builder_template::name)); + std::memcpy(state.ui_state.current_template.name, s.data(), sizeof(sys::macro_builder_template::name)); + } +}; +class macro_builder_details : public scrollable_text { +public: + void on_update(sys::state& state) noexcept override { + auto contents = text::create_endless_layout(delegate->internal_layout, + text::layout_parameters{ 0, 0, int16_t(base_data.size.x), int16_t(base_data.size.y), + base_data.data.text.font_handle, 0, text::alignment::left, + text::is_black_from_font_id(base_data.data.text.font_handle) ? text::text_color::black : text::text_color::white, false }); + auto is_land = retrieve(state, parent); + + float reconnaissance_or_fire_range = 0.f; + float siege_or_torpedo_attack = 0.f; + float attack_or_gun_power = 0.f; + float defence_or_hull = 0.f; + float discipline_or_evasion = 0.f; + float support = 0.f; + float supply_consumption = 0.f; + float maximum_speed = 0.f; + float maneuver = 0.f; + int32_t supply_consumption_score = 0; + for(dcon::unit_type_id::value_base_t i = 0; i < sizeof(sys::macro_builder_template::max_types); i++) { + if(state.ui_state.current_template.amounts[i] == 0) //not needed to show this + continue; + dcon::unit_type_id utid = dcon::unit_type_id(i); + if(is_land != state.military_definitions.unit_base_definitions[utid].is_land) + continue; + reconnaissance_or_fire_range += state.world.nation_get_unit_stats(state.local_player_nation, utid).reconnaissance_or_fire_range; + siege_or_torpedo_attack += state.world.nation_get_unit_stats(state.local_player_nation, utid).siege_or_torpedo_attack; + attack_or_gun_power += state.world.nation_get_unit_stats(state.local_player_nation, utid).attack_or_gun_power; + defence_or_hull += state.world.nation_get_unit_stats(state.local_player_nation, utid).defence_or_hull; + discipline_or_evasion += state.world.nation_get_unit_stats(state.local_player_nation, utid).discipline_or_evasion; + supply_consumption += state.world.nation_get_unit_stats(state.local_player_nation, utid).supply_consumption; + maximum_speed += state.world.nation_get_unit_stats(state.local_player_nation, utid).maximum_speed; + if(is_land) { + support += state.world.nation_get_unit_stats(state.local_player_nation, utid).support; + maneuver += state.military_definitions.unit_base_definitions[utid].maneuver; + } else { + supply_consumption_score += state.military_definitions.unit_base_definitions[utid].supply_consumption_score; + } + } + + // Total + text::add_line(state, contents, text::produce_simple_string(state, "macro_total_desc")); + if(is_land) { + if(reconnaissance_or_fire_range > 0.f) { + text::add_line(state, contents, "alice_recon", text::variable_type::x, text::format_float(reconnaissance_or_fire_range, 2)); + } + if(siege_or_torpedo_attack > 0.f) { + text::add_line(state, contents, "alice_siege", text::variable_type::x, text::format_float(siege_or_torpedo_attack, 2)); + } + text::add_line(state, contents, "alice_attack", text::variable_type::x, text::format_float(attack_or_gun_power, 2)); + text::add_line(state, contents, "alice_defence", text::variable_type::x, text::format_float(defence_or_hull, 2)); + text::add_line(state, contents, "alice_discipline", text::variable_type::x, text::format_float(discipline_or_evasion * 100, 0)); + if(support > 0.f) { + text::add_line(state, contents, "alice_support", text::variable_type::x, text::format_float(support * 100, 0)); + } + text::add_line(state, contents, "alice_maneuver", text::variable_type::x, text::format_float(maneuver, 0)); + text::add_line(state, contents, "alice_maximum_speed", text::variable_type::x, text::format_float(maximum_speed, 2)); + text::add_line(state, contents, "alice_supply_consumption", text::variable_type::x, text::format_float(supply_consumption * 100, 0)); + } else { + text::add_line(state, contents, "alice_maximum_speed", text::variable_type::x, text::format_float(maximum_speed, 2)); + text::add_line(state, contents, "alice_attack", text::variable_type::x, text::format_float(attack_or_gun_power, 2)); + if(siege_or_torpedo_attack > 0.f) { + text::add_line(state, contents, "alice_torpedo_attack", text::variable_type::x, text::format_float(siege_or_torpedo_attack, 2)); + } + text::add_line(state, contents, "alice_hull", text::variable_type::x, text::format_float(defence_or_hull, 2)); + text::add_line(state, contents, "alice_fire_range", text::variable_type::x, text::format_float(reconnaissance_or_fire_range, 2)); + if(discipline_or_evasion > 0.f) { + text::add_line(state, contents, "alice_evasion", text::variable_type::x, text::format_float(discipline_or_evasion * 100, 0)); + } + text::add_line(state, contents, "alice_supply_consumption", text::variable_type::x, text::format_float(supply_consumption * 100, 0)); + text::add_line(state, contents, "alice_supply_load", text::variable_type::x, supply_consumption_score); + } + + // Describe for each + for(dcon::unit_type_id::value_base_t i = 0; i < sizeof(sys::macro_builder_template::max_types); i++) { + if(state.ui_state.current_template.amounts[i] == 0) //not needed to show this + continue; + dcon::unit_type_id utid = dcon::unit_type_id(i); + if(is_land != state.military_definitions.unit_base_definitions[utid].is_land) + continue; + text::add_line(state, contents, state.military_definitions.unit_base_definitions[utid].name); + if(is_land) { + if(state.world.nation_get_unit_stats(state.local_player_nation, utid).reconnaissance_or_fire_range > 0) { + text::add_line(state, contents, "alice_recon", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).reconnaissance_or_fire_range, 2)); + } + if(state.world.nation_get_unit_stats(state.local_player_nation, utid).siege_or_torpedo_attack > 0) { + text::add_line(state, contents, "alice_siege", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).siege_or_torpedo_attack, 2)); + } + text::add_line(state, contents, "alice_attack", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).attack_or_gun_power, 2)); + text::add_line(state, contents, "alice_defence", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).defence_or_hull, 2)); + text::add_line(state, contents, "alice_discipline", text::variable_type::x, text::format_float(state.military_definitions.unit_base_definitions[utid].discipline_or_evasion * 100, 0)); + if(state.military_definitions.unit_base_definitions[utid].support > 0.f) { + text::add_line(state, contents, "alice_support", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).support * 100, 0)); + } + text::add_line(state, contents, "alice_maneuver", text::variable_type::x, text::format_float(state.military_definitions.unit_base_definitions[utid].maneuver, 0)); + text::add_line(state, contents, "alice_maximum_speed", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).maximum_speed, 2)); + text::add_line(state, contents, "alice_supply_consumption", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).supply_consumption * 100, 0)); + } else { + text::add_line(state, contents, "alice_maximum_speed", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).maximum_speed, 2)); + text::add_line(state, contents, "alice_attack", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).attack_or_gun_power, 2)); + if(state.world.nation_get_unit_stats(state.local_player_nation, utid).siege_or_torpedo_attack > 0) { + text::add_line(state, contents, "alice_torpedo_attack", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).siege_or_torpedo_attack, 2)); + } + text::add_line(state, contents, "alice_hull", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).defence_or_hull, 2)); + text::add_line(state, contents, "alice_fire_range", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).reconnaissance_or_fire_range, 2)); + if(state.military_definitions.unit_base_definitions[utid].discipline_or_evasion > 0.f) { + text::add_line(state, contents, "alice_evasion", text::variable_type::x, text::format_float(state.military_definitions.unit_base_definitions[utid].discipline_or_evasion * 100, 0)); + } + text::add_line(state, contents, "alice_supply_consumption", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).supply_consumption * 100, 0)); + text::add_line(state, contents, "alice_supply_load", text::variable_type::x, state.military_definitions.unit_base_definitions[utid].supply_consumption_score); + } + } + calibrate_scrollbar(state); + } + + message_result test_mouse(sys::state& state, int32_t x, int32_t y, mouse_probe_type type) noexcept override { + return message_result::consumed; + } +}; class macro_builder_window : public window_element_base { bool is_land = true; public: @@ -347,6 +476,8 @@ class macro_builder_window : public window_element_base { return make_element_by_type(state, id); } else if(name == "close") { return make_element_by_type(state, id); + } else if(name == "input") { + return make_element_by_type(state, id); } else if(name == "template_listbox") { return make_element_by_type(state, id); } else if(name == "unit_listbox") { From 36f4861ec291e261408dcc75af2677a363234152 Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 06:14:42 +0000 Subject: [PATCH 06/29] fixups --- assets/alice.gui | 10 +++++----- src/gui/gui_minimap.hpp | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/assets/alice.gui b/assets/alice.gui index 5da648993..7909dc4f5 100644 --- a/assets/alice.gui +++ b/assets/alice.gui @@ -3631,19 +3631,19 @@ guiTypes = { } editBoxType = { name = "input" - position = { 320 28 } + position = { 330 28 } textureFile = "gfx\\interface\\small_tiles_dialog.dds" font = "FPS_Font" - borderSize = { 0 0 } - maxsize = { 128 40 } + borderSize = { 10 10 } + maxsize = { 308 40 } format = center } instantTextBoxType = { name = "details" - position = { 320 72 } + position = { 330 72 } font = "vic_22" borderSize = { 0 0 } - maxsize = { 128 298 } + maxsize = { 308 298 } format = center } } diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index 1272a9019..2c4fcb14f 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -490,6 +490,8 @@ class macro_builder_window : public window_element_base { return make_element_by_type(state, id); } else if(name == "switch_type") { return make_element_by_type(state, id); + } else if(name == "details") { + return make_element_by_type(state, id); } else { return nullptr; } From 379104e6722b9f1ce4b38f5ad8770db05b1ef14d Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 06:29:44 +0000 Subject: [PATCH 07/29] direct update notification --- assets/alice.gui | 4 ++-- src/gui/gui_minimap.hpp | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/assets/alice.gui b/assets/alice.gui index 7909dc4f5..23ee1cbb1 100644 --- a/assets/alice.gui +++ b/assets/alice.gui @@ -3626,7 +3626,7 @@ guiTypes = { position = { 390 288 } size = { 128 24 } quadTextureSprite = "GFX_button_128wide" - buttonText = "macro_switch_type_naval" + buttonText = "" buttonFont = "vic_22_black" } editBoxType = { @@ -3643,7 +3643,7 @@ guiTypes = { position = { 330 72 } font = "vic_22" borderSize = { 0 0 } - maxsize = { 308 298 } + maxsize = { 288 172 } format = center } } diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index 2c4fcb14f..b5335181e 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -238,12 +238,15 @@ class macro_builder_unit_button : public right_click_button_element_base { if(state.ui_state.current_template.amounts[content.index()] < 255) { state.ui_state.current_template.amounts[content.index()] += 1; } + parent->parent->impl_on_update(state); } void button_right_action(sys::state& state) noexcept override { auto content = retrieve(state, parent); if(state.ui_state.current_template.amounts[content.index()] > 0) { state.ui_state.current_template.amounts[content.index()] -= 1; } + + if(parent && parent->parent && parent->parent->parent) parent->parent->parent->impl_on_update(state); } }; class macro_builder_unit_entry : public listbox_row_element_base { @@ -279,6 +282,7 @@ class macro_builder_new_template_button : public button_element_base { public: void button_action(sys::state& state) noexcept override { state.ui_state.current_template = sys::macro_builder_template{}; + if(parent) parent->impl_on_update(state); } }; class macro_builder_save_template_button : public button_element_base { @@ -303,6 +307,7 @@ class macro_builder_save_template_button : public button_element_base { auto sdir = simple_fs::get_or_create_save_game_directory(); simple_fs::write_file(sdir, NATIVE("templates.bin"), reinterpret_cast(state.ui_state.templates.data()), uint32_t(state.ui_state.templates.size()) * sizeof(sys::macro_builder_template)); + if(parent) parent->impl_on_update(state); } }; class macro_builder_remove_template_button : public button_element_base { @@ -317,6 +322,7 @@ class macro_builder_remove_template_button : public button_element_base { break; } } + if(parent) parent->impl_on_update(state); } }; class macro_builder_switch_type_button : public button_element_base { @@ -324,9 +330,9 @@ class macro_builder_switch_type_button : public button_element_base { void on_update(sys::state& state) noexcept override { auto is_land = retrieve(state, parent); if(is_land) { - set_button_text(state, text::produce_simple_string(state, "switch_type_naval")); + set_button_text(state, text::produce_simple_string(state, "macro_switch_type_naval")); } else { - set_button_text(state, text::produce_simple_string(state, "switch_type_land")); + set_button_text(state, text::produce_simple_string(state, "macro_switch_type_land")); } } void button_action(sys::state& state) noexcept override { @@ -416,6 +422,7 @@ class macro_builder_details : public scrollable_text { text::add_line(state, contents, "alice_supply_consumption", text::variable_type::x, text::format_float(supply_consumption * 100, 0)); text::add_line(state, contents, "alice_supply_load", text::variable_type::x, supply_consumption_score); } + text::add_line_break_to_layout(state, contents); // Describe for each for(dcon::unit_type_id::value_base_t i = 0; i < sizeof(sys::macro_builder_template::max_types); i++) { @@ -455,6 +462,7 @@ class macro_builder_details : public scrollable_text { text::add_line(state, contents, "alice_supply_consumption", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).supply_consumption * 100, 0)); text::add_line(state, contents, "alice_supply_load", text::variable_type::x, state.military_definitions.unit_base_definitions[utid].supply_consumption_score); } + text::add_line_break_to_layout(state, contents); } calibrate_scrollbar(state); } From 6e175ca7f1bb52776125777e59f067144d88919f Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 06:38:23 +0000 Subject: [PATCH 08/29] only show active unit types --- src/gui/gui_minimap.hpp | 63 +++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index b5335181e..4d81e7257 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -269,9 +269,9 @@ class macro_builder_unit_listbox : public listbox_element_base(state, parent); + bool is_land = retrieve(state, parent); for(dcon::unit_type_id::value_base_t i = 0; i < state.military_definitions.unit_base_definitions.size(); i++) { - if(state.military_definitions.unit_base_definitions[dcon::unit_type_id(i)].is_land == b) { + if(state.military_definitions.unit_base_definitions[dcon::unit_type_id(i)].is_land == is_land && state.military_definitions.unit_base_definitions[dcon::unit_type_id(i)].active) { row_contents.push_back(dcon::unit_type_id(i)); } } @@ -358,6 +358,7 @@ class macro_builder_details : public scrollable_text { base_data.data.text.font_handle, 0, text::alignment::left, text::is_black_from_font_id(base_data.data.text.font_handle) ? text::text_color::black : text::text_color::white, false }); auto is_land = retrieve(state, parent); + auto const& t = state.ui_state.current_template; float reconnaissance_or_fire_range = 0.f; float siege_or_torpedo_attack = 0.f; @@ -370,23 +371,23 @@ class macro_builder_details : public scrollable_text { float maneuver = 0.f; int32_t supply_consumption_score = 0; for(dcon::unit_type_id::value_base_t i = 0; i < sizeof(sys::macro_builder_template::max_types); i++) { - if(state.ui_state.current_template.amounts[i] == 0) //not needed to show this + if(t.amounts[i] == 0) //not needed to show this continue; dcon::unit_type_id utid = dcon::unit_type_id(i); if(is_land != state.military_definitions.unit_base_definitions[utid].is_land) continue; - reconnaissance_or_fire_range += state.world.nation_get_unit_stats(state.local_player_nation, utid).reconnaissance_or_fire_range; - siege_or_torpedo_attack += state.world.nation_get_unit_stats(state.local_player_nation, utid).siege_or_torpedo_attack; - attack_or_gun_power += state.world.nation_get_unit_stats(state.local_player_nation, utid).attack_or_gun_power; - defence_or_hull += state.world.nation_get_unit_stats(state.local_player_nation, utid).defence_or_hull; - discipline_or_evasion += state.world.nation_get_unit_stats(state.local_player_nation, utid).discipline_or_evasion; - supply_consumption += state.world.nation_get_unit_stats(state.local_player_nation, utid).supply_consumption; - maximum_speed += state.world.nation_get_unit_stats(state.local_player_nation, utid).maximum_speed; + reconnaissance_or_fire_range += state.world.nation_get_unit_stats(state.local_player_nation, utid).reconnaissance_or_fire_range * float(t.amounts[i]); + siege_or_torpedo_attack += state.world.nation_get_unit_stats(state.local_player_nation, utid).siege_or_torpedo_attack * float(t.amounts[i]); + attack_or_gun_power += state.world.nation_get_unit_stats(state.local_player_nation, utid).attack_or_gun_power * float(t.amounts[i]); + defence_or_hull += state.world.nation_get_unit_stats(state.local_player_nation, utid).defence_or_hull * float(t.amounts[i]); + discipline_or_evasion += state.world.nation_get_unit_stats(state.local_player_nation, utid).discipline_or_evasion * float(t.amounts[i]); + supply_consumption += state.world.nation_get_unit_stats(state.local_player_nation, utid).supply_consumption * float(t.amounts[i]); + maximum_speed += state.world.nation_get_unit_stats(state.local_player_nation, utid).maximum_speed * float(t.amounts[i]); if(is_land) { - support += state.world.nation_get_unit_stats(state.local_player_nation, utid).support; - maneuver += state.military_definitions.unit_base_definitions[utid].maneuver; + support += state.world.nation_get_unit_stats(state.local_player_nation, utid).support * float(t.amounts[i]); + maneuver += state.military_definitions.unit_base_definitions[utid].maneuver * float(t.amounts[i]); } else { - supply_consumption_score += state.military_definitions.unit_base_definitions[utid].supply_consumption_score; + supply_consumption_score += state.military_definitions.unit_base_definitions[utid].supply_consumption_score * int32_t(t.amounts[i]); } } @@ -426,7 +427,7 @@ class macro_builder_details : public scrollable_text { // Describe for each for(dcon::unit_type_id::value_base_t i = 0; i < sizeof(sys::macro_builder_template::max_types); i++) { - if(state.ui_state.current_template.amounts[i] == 0) //not needed to show this + if(t.amounts[i] == 0) //not needed to show this continue; dcon::unit_type_id utid = dcon::unit_type_id(i); if(is_land != state.military_definitions.unit_base_definitions[utid].is_land) @@ -434,33 +435,33 @@ class macro_builder_details : public scrollable_text { text::add_line(state, contents, state.military_definitions.unit_base_definitions[utid].name); if(is_land) { if(state.world.nation_get_unit_stats(state.local_player_nation, utid).reconnaissance_or_fire_range > 0) { - text::add_line(state, contents, "alice_recon", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).reconnaissance_or_fire_range, 2)); + text::add_line(state, contents, "alice_recon", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).reconnaissance_or_fire_range * float(t.amounts[i]), 2)); } if(state.world.nation_get_unit_stats(state.local_player_nation, utid).siege_or_torpedo_attack > 0) { - text::add_line(state, contents, "alice_siege", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).siege_or_torpedo_attack, 2)); + text::add_line(state, contents, "alice_siege", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).siege_or_torpedo_attack * float(t.amounts[i]), 2)); } - text::add_line(state, contents, "alice_attack", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).attack_or_gun_power, 2)); - text::add_line(state, contents, "alice_defence", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).defence_or_hull, 2)); - text::add_line(state, contents, "alice_discipline", text::variable_type::x, text::format_float(state.military_definitions.unit_base_definitions[utid].discipline_or_evasion * 100, 0)); + text::add_line(state, contents, "alice_attack", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).attack_or_gun_power * float(t.amounts[i]), 2)); + text::add_line(state, contents, "alice_defence", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).defence_or_hull * float(t.amounts[i]), 2)); + text::add_line(state, contents, "alice_discipline", text::variable_type::x, text::format_float(state.military_definitions.unit_base_definitions[utid].discipline_or_evasion * 100 * float(t.amounts[i]), 0)); if(state.military_definitions.unit_base_definitions[utid].support > 0.f) { - text::add_line(state, contents, "alice_support", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).support * 100, 0)); + text::add_line(state, contents, "alice_support", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).support * 100 * float(t.amounts[i]), 0)); } - text::add_line(state, contents, "alice_maneuver", text::variable_type::x, text::format_float(state.military_definitions.unit_base_definitions[utid].maneuver, 0)); - text::add_line(state, contents, "alice_maximum_speed", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).maximum_speed, 2)); - text::add_line(state, contents, "alice_supply_consumption", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).supply_consumption * 100, 0)); + text::add_line(state, contents, "alice_maneuver", text::variable_type::x, text::format_float(state.military_definitions.unit_base_definitions[utid].maneuver * float(t.amounts[i]), 0)); + text::add_line(state, contents, "alice_maximum_speed", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).maximum_speed * float(t.amounts[i]), 2)); + text::add_line(state, contents, "alice_supply_consumption", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).supply_consumption * 100 * float(t.amounts[i]), 0)); } else { - text::add_line(state, contents, "alice_maximum_speed", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).maximum_speed, 2)); - text::add_line(state, contents, "alice_attack", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).attack_or_gun_power, 2)); + text::add_line(state, contents, "alice_maximum_speed", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).maximum_speed * float(t.amounts[i]), 2)); + text::add_line(state, contents, "alice_attack", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).attack_or_gun_power * float(t.amounts[i]), 2)); if(state.world.nation_get_unit_stats(state.local_player_nation, utid).siege_or_torpedo_attack > 0) { - text::add_line(state, contents, "alice_torpedo_attack", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).siege_or_torpedo_attack, 2)); + text::add_line(state, contents, "alice_torpedo_attack", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).siege_or_torpedo_attack * float(t.amounts[i]), 2)); } - text::add_line(state, contents, "alice_hull", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).defence_or_hull, 2)); - text::add_line(state, contents, "alice_fire_range", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).reconnaissance_or_fire_range, 2)); + text::add_line(state, contents, "alice_hull", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).defence_or_hull* float(t.amounts[i]), 2)); + text::add_line(state, contents, "alice_fire_range", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).reconnaissance_or_fire_range* float(t.amounts[i]), 2)); if(state.military_definitions.unit_base_definitions[utid].discipline_or_evasion > 0.f) { - text::add_line(state, contents, "alice_evasion", text::variable_type::x, text::format_float(state.military_definitions.unit_base_definitions[utid].discipline_or_evasion * 100, 0)); + text::add_line(state, contents, "alice_evasion", text::variable_type::x, text::format_float(state.military_definitions.unit_base_definitions[utid].discipline_or_evasion * 100 * float(t.amounts[i]), 0)); } - text::add_line(state, contents, "alice_supply_consumption", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).supply_consumption * 100, 0)); - text::add_line(state, contents, "alice_supply_load", text::variable_type::x, state.military_definitions.unit_base_definitions[utid].supply_consumption_score); + text::add_line(state, contents, "alice_supply_consumption", text::variable_type::x, text::format_float(state.world.nation_get_unit_stats(state.local_player_nation, utid).supply_consumption * 100 * float(t.amounts[i]), 0)); + text::add_line(state, contents, "alice_supply_load", text::variable_type::x, state.military_definitions.unit_base_definitions[utid].supply_consumption_score * int32_t(t.amounts[i])); } text::add_line_break_to_layout(state, contents); } From ccd406989e7544e2b8db7e328df561c64bc04420 Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 07:03:17 +0000 Subject: [PATCH 09/29] fixes --- assets/alice.csv | 3 +++ src/gui/gui_minimap.hpp | 54 ++++++++++++++++++++++++++++------------- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/assets/alice.csv b/assets/alice.csv index 64077b241..4b035d729 100644 --- a/assets/alice.csv +++ b/assets/alice.csv @@ -1372,6 +1372,9 @@ macro_switch_type_land;Switch to: Land macro_switch_type_naval;Switch to: Naval macro_save_template;Save template;;;Guardar plantilla macro_new_template;New template;;;Nueva plantila +macro_warn_overseas;§RCan't build this unit overseas!§W +macro_warn_culture;§RCan only build using primary culture POPs!§W +macro_warn_unlocked;§RUsing units not unlocked yet!§W aml_col_s1;Potential aml_col_s2;NA aml_col_s3;Can Invest diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index 4d81e7257..4ab28b882 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -179,7 +179,6 @@ class macro_builder_template_flag : public flag_button { set_current_nation(state, state.world.nation_get_identity_from_identity_holder(nid)); } }; - class macro_builder_template_entry : public listbox_row_element_base { public: std::unique_ptr make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override { @@ -238,15 +237,14 @@ class macro_builder_unit_button : public right_click_button_element_base { if(state.ui_state.current_template.amounts[content.index()] < 255) { state.ui_state.current_template.amounts[content.index()] += 1; } - parent->parent->impl_on_update(state); + send(state, parent, notify_setting_update{}); } void button_right_action(sys::state& state) noexcept override { auto content = retrieve(state, parent); if(state.ui_state.current_template.amounts[content.index()] > 0) { state.ui_state.current_template.amounts[content.index()] -= 1; } - - if(parent && parent->parent && parent->parent->parent) parent->parent->parent->impl_on_update(state); + send(state, parent, notify_setting_update{}); } }; class macro_builder_unit_entry : public listbox_row_element_base { @@ -271,7 +269,7 @@ class macro_builder_unit_listbox : public listbox_element_base(state, parent); for(dcon::unit_type_id::value_base_t i = 0; i < state.military_definitions.unit_base_definitions.size(); i++) { - if(state.military_definitions.unit_base_definitions[dcon::unit_type_id(i)].is_land == is_land && state.military_definitions.unit_base_definitions[dcon::unit_type_id(i)].active) { + if(state.military_definitions.unit_base_definitions[dcon::unit_type_id(i)].is_land == is_land) { row_contents.push_back(dcon::unit_type_id(i)); } } @@ -282,7 +280,7 @@ class macro_builder_new_template_button : public button_element_base { public: void button_action(sys::state& state) noexcept override { state.ui_state.current_template = sys::macro_builder_template{}; - if(parent) parent->impl_on_update(state); + send(state, parent, notify_setting_update{}); } }; class macro_builder_save_template_button : public button_element_base { @@ -304,10 +302,9 @@ class macro_builder_save_template_button : public button_element_base { if(!overwrite) { state.ui_state.templates.push_back(t); } - auto sdir = simple_fs::get_or_create_save_game_directory(); simple_fs::write_file(sdir, NATIVE("templates.bin"), reinterpret_cast(state.ui_state.templates.data()), uint32_t(state.ui_state.templates.size()) * sizeof(sys::macro_builder_template)); - if(parent) parent->impl_on_update(state); + send(state, parent, notify_setting_update{}); } }; class macro_builder_remove_template_button : public button_element_base { @@ -322,7 +319,9 @@ class macro_builder_remove_template_button : public button_element_base { break; } } - if(parent) parent->impl_on_update(state); + auto sdir = simple_fs::get_or_create_save_game_directory(); + simple_fs::write_file(sdir, NATIVE("templates.bin"), reinterpret_cast(state.ui_state.templates.data()), uint32_t(state.ui_state.templates.size()) * sizeof(sys::macro_builder_template)); + send(state, parent, notify_setting_update{}); } }; class macro_builder_switch_type_button : public button_element_base { @@ -336,18 +335,18 @@ class macro_builder_switch_type_button : public button_element_base { } } void button_action(sys::state& state) noexcept override { - auto b = retrieve(state, parent); - send(state, parent, element_selection_wrapper{ !b }); + auto is_land = retrieve(state, parent); + send(state, parent, element_selection_wrapper{ !is_land }); } }; class macro_builder_name_input : public edit_box_element_base { public: - void edit_box_enter(sys::state& state, std::string_view str) noexcept override { + void edit_box_update(sys::state& state, std::string_view str) noexcept override { auto s = parsers::remove_surrounding_whitespace(str); if(s.empty()) return; std::memset(state.ui_state.current_template.name, ' ', sizeof(sys::macro_builder_template::name)); - std::memcpy(state.ui_state.current_template.name, s.data(), sizeof(sys::macro_builder_template::name)); + std::memcpy(state.ui_state.current_template.name, s.data(), std::min(s.length(), sizeof(sys::macro_builder_template::name))); } }; class macro_builder_details : public scrollable_text { @@ -367,22 +366,33 @@ class macro_builder_details : public scrollable_text { float discipline_or_evasion = 0.f; float support = 0.f; float supply_consumption = 0.f; - float maximum_speed = 0.f; + float maximum_speed = std::numeric_limits::max(); float maneuver = 0.f; int32_t supply_consumption_score = 0; - for(dcon::unit_type_id::value_base_t i = 0; i < sizeof(sys::macro_builder_template::max_types); i++) { + bool warn_overseas = false; + bool warn_culture = false; + bool warn_active = false; + for(dcon::unit_type_id::value_base_t i = 0; i < sys::macro_builder_template::max_types; i++) { if(t.amounts[i] == 0) //not needed to show this continue; dcon::unit_type_id utid = dcon::unit_type_id(i); if(is_land != state.military_definitions.unit_base_definitions[utid].is_land) continue; + + if(!state.military_definitions.unit_base_definitions[utid].active && !state.world.nation_get_active_unit(state.local_player_nation, utid)) + warn_active = true; + if(state.military_definitions.unit_base_definitions[utid].primary_culture) + warn_culture = true; + if(state.military_definitions.unit_base_definitions[utid].can_build_overseas) + warn_overseas = true; + reconnaissance_or_fire_range += state.world.nation_get_unit_stats(state.local_player_nation, utid).reconnaissance_or_fire_range * float(t.amounts[i]); siege_or_torpedo_attack += state.world.nation_get_unit_stats(state.local_player_nation, utid).siege_or_torpedo_attack * float(t.amounts[i]); attack_or_gun_power += state.world.nation_get_unit_stats(state.local_player_nation, utid).attack_or_gun_power * float(t.amounts[i]); defence_or_hull += state.world.nation_get_unit_stats(state.local_player_nation, utid).defence_or_hull * float(t.amounts[i]); discipline_or_evasion += state.world.nation_get_unit_stats(state.local_player_nation, utid).discipline_or_evasion * float(t.amounts[i]); supply_consumption += state.world.nation_get_unit_stats(state.local_player_nation, utid).supply_consumption * float(t.amounts[i]); - maximum_speed += state.world.nation_get_unit_stats(state.local_player_nation, utid).maximum_speed * float(t.amounts[i]); + maximum_speed = std::min(maximum_speed, state.world.nation_get_unit_stats(state.local_player_nation, utid).maximum_speed * float(t.amounts[i])); if(is_land) { support += state.world.nation_get_unit_stats(state.local_player_nation, utid).support * float(t.amounts[i]); maneuver += state.military_definitions.unit_base_definitions[utid].maneuver * float(t.amounts[i]); @@ -391,6 +401,13 @@ class macro_builder_details : public scrollable_text { } } + if(warn_overseas) + text::add_line(state, contents, "macro_warn_overseas"); + if(warn_culture) + text::add_line(state, contents, "macro_warn_culture"); + if(warn_active) + text::add_line(state, contents, "macro_warn_unlocked"); + // Total text::add_line(state, contents, text::produce_simple_string(state, "macro_total_desc")); if(is_land) { @@ -426,7 +443,7 @@ class macro_builder_details : public scrollable_text { text::add_line_break_to_layout(state, contents); // Describe for each - for(dcon::unit_type_id::value_base_t i = 0; i < sizeof(sys::macro_builder_template::max_types); i++) { + for(dcon::unit_type_id::value_base_t i = 0; i < sys::macro_builder_template::max_types; i++) { if(t.amounts[i] == 0) //not needed to show this continue; dcon::unit_type_id utid = dcon::unit_type_id(i); @@ -514,6 +531,9 @@ class macro_builder_window : public window_element_base { is_land = Cyto::any_cast>(payload).data; impl_on_update(state); return message_result::consumed; + } else if(payload.holds_type()) { + impl_on_update(state); + return message_result::consumed; } return window_element_base::impl_get(state, payload); } From 0df986ab763cc3c8c3b44d149b0eaaede60d35d3 Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 07:13:42 +0000 Subject: [PATCH 10/29] fix --- src/gui/gui_minimap.hpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index 4ab28b882..595262b79 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -179,6 +179,15 @@ class macro_builder_template_flag : public flag_button { set_current_nation(state, state.world.nation_get_identity_from_identity_holder(nid)); } }; +struct notify_template_select {}; +class macro_builder_template_select : public button_element_base { +public: + void button_action(sys::state& state) noexcept override { + auto index = retrieve(state, parent); + std::memcpy(&state.ui_state.current_template, &state.ui_state.templates[index], sizeof(sys::macro_builder_template)); + send(state, parent, notify_template_select{}); + } +}; class macro_builder_template_entry : public listbox_row_element_base { public: std::unique_ptr make_child(sys::state& state, std::string_view name, dcon::gui_def_id id) noexcept override { @@ -186,6 +195,8 @@ class macro_builder_template_entry : public listbox_row_element_base { return make_element_by_type(state, id); } else if(name == "shield") { return make_element_by_type(state, id); + } else if(name == "background") { + return make_element_by_type(state, id); } else { return nullptr; } @@ -491,6 +502,7 @@ class macro_builder_details : public scrollable_text { }; class macro_builder_window : public window_element_base { bool is_land = true; + macro_builder_name_input* name_input = nullptr; public: void on_create(sys::state& state) noexcept override { window_element_base::on_create(state); @@ -503,7 +515,9 @@ class macro_builder_window : public window_element_base { } else if(name == "close") { return make_element_by_type(state, id); } else if(name == "input") { - return make_element_by_type(state, id); + auto ptr = make_element_by_type(state, id); + name_input = ptr.get(); + return ptr; } else if(name == "template_listbox") { return make_element_by_type(state, id); } else if(name == "unit_listbox") { @@ -531,7 +545,13 @@ class macro_builder_window : public window_element_base { is_land = Cyto::any_cast>(payload).data; impl_on_update(state); return message_result::consumed; - } else if(payload.holds_type()) { + } else if(payload.holds_type< notify_template_select>()) { + auto const& name = state.ui_state.current_template.name; + auto sv = std::string_view(name, name + sizeof(name)); + name_input->set_text(state, std::string(sv)); + impl_on_update(state); + return message_result::consumed; + } else if(payload.holds_type()) { impl_on_update(state); return message_result::consumed; } From ac870b4285f5d9e954d01a4b5d52dff9e653b018 Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 07:47:03 +0000 Subject: [PATCH 11/29] extend build command --- assets/alice.csv | 3 + src/gamestate/commands.cpp | 24 ++++---- src/gamestate/commands.hpp | 10 ++-- src/gui/gui_minimap.hpp | 115 +++++++++++++++++++++++++++++++++++++ 4 files changed, 138 insertions(+), 14 deletions(-) diff --git a/assets/alice.csv b/assets/alice.csv index 4b035d729..3835d9467 100644 --- a/assets/alice.csv +++ b/assets/alice.csv @@ -1375,6 +1375,9 @@ macro_new_template;New template;;;Nueva plantila macro_warn_overseas;§RCan't build this unit overseas!§W macro_warn_culture;§RCan only build using primary culture POPs!§W macro_warn_unlocked;§RUsing units not unlocked yet!§W +macro_select_province;Please select a province on the map +macro_warn_insuff;§RCan't build $x$ $name$ (only $y$)§W +macro_warn_invalid_province;§RProvince not part of a region§W aml_col_s1;Potential aml_col_s2;NA aml_col_s3;Can Invest diff --git a/src/gamestate/commands.cpp b/src/gamestate/commands.cpp index e309e349a..ac2e13dc3 100644 --- a/src/gamestate/commands.cpp +++ b/src/gamestate/commands.cpp @@ -589,17 +589,18 @@ void execute_begin_factory_building_construction(sys::state& state, dcon::nation } } -void start_naval_unit_construction(sys::state& state, dcon::nation_id source, dcon::province_id location, dcon::unit_type_id type) { +void start_naval_unit_construction(sys::state& state, dcon::nation_id source, dcon::province_id location, dcon::unit_type_id type, dcon::province_id template_province) { payload p; memset(&p, 0, sizeof(payload)); p.type = command_type::begin_naval_unit_construction; p.source = source; p.data.naval_unit_construction.location = location; p.data.naval_unit_construction.type = type; + p.data.naval_unit_construction.template_province = template_province; add_to_command_queue(state, p); } -bool can_start_naval_unit_construction(sys::state& state, dcon::nation_id source, dcon::province_id location, dcon::unit_type_id type) { +bool can_start_naval_unit_construction(sys::state& state, dcon::nation_id source, dcon::province_id location, dcon::unit_type_id type, dcon::province_id template_province) { /* The province must be owned and controlled by the building nation, without an ongoing siege. The unit type must be available from start / unlocked by the nation @@ -641,12 +642,13 @@ bool can_start_naval_unit_construction(sys::state& state, dcon::nation_id source } } -void execute_start_naval_unit_construction(sys::state& state, dcon::nation_id source, dcon::province_id location, dcon::unit_type_id type) { +void execute_start_naval_unit_construction(sys::state& state, dcon::nation_id source, dcon::province_id location, dcon::unit_type_id type, dcon::province_id template_province) { auto c = fatten(state.world, state.world.try_create_province_naval_construction(location, source)); c.set_type(type); + c.set_template_province(template_province); } -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) { +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) { payload p; memset(&p, 0, sizeof(payload)); p.type = command_type::begin_land_unit_construction; @@ -654,9 +656,10 @@ void start_land_unit_construction(sys::state& state, dcon::nation_id source, dco p.data.land_unit_construction.location = location; p.data.land_unit_construction.type = type; p.data.land_unit_construction.pop_culture = soldier_culture; + p.data.land_unit_construction.template_province = template_province; add_to_command_queue(state, p); } -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) { +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) { /* The province must be owned and controlled by the building nation, without an ongoing siege. The unit type must be available from start / unlocked by the nation @@ -687,11 +690,12 @@ bool can_start_land_unit_construction(sys::state& state, dcon::nation_id source, return false; } } -void execute_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) { +void execute_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) { auto soldier = military::find_available_soldier(state, location, soldier_culture); auto c = fatten(state.world, state.world.try_create_province_land_construction(soldier, source)); c.set_type(type); + c.set_template_province(template_province); } void cancel_naval_unit_construction(sys::state& state, dcon::nation_id source, dcon::province_id location, dcon::unit_type_id type) { @@ -4457,7 +4461,7 @@ bool can_perform_command(sys::state& state, payload& c) { case command_type::begin_naval_unit_construction: return can_start_naval_unit_construction(state, c.source, c.data.naval_unit_construction.location, - c.data.naval_unit_construction.type); + c.data.naval_unit_construction.type, c.data.naval_unit_construction.template_province); case command_type::cancel_naval_unit_construction: return can_cancel_naval_unit_construction(state, c.source, c.data.naval_unit_construction.location, @@ -4465,7 +4469,7 @@ bool can_perform_command(sys::state& state, payload& c) { case command_type::begin_land_unit_construction: return can_start_land_unit_construction(state, c.source, c.data.land_unit_construction.location, - c.data.land_unit_construction.pop_culture, c.data.land_unit_construction.type); + c.data.land_unit_construction.pop_culture, c.data.land_unit_construction.type, c.data.land_unit_construction.template_province); case command_type::cancel_land_unit_construction: return can_cancel_land_unit_construction(state, c.source, c.data.land_unit_construction.location, @@ -4817,7 +4821,7 @@ void execute_command(sys::state& state, payload& c) { break; case command_type::begin_naval_unit_construction: execute_start_naval_unit_construction(state, c.source, c.data.naval_unit_construction.location, - c.data.naval_unit_construction.type); + c.data.naval_unit_construction.type, c.data.naval_unit_construction.template_province); break; case command_type::cancel_naval_unit_construction: execute_cancel_naval_unit_construction(state, c.source, c.data.naval_unit_construction.location, @@ -4825,7 +4829,7 @@ void execute_command(sys::state& state, payload& c) { break; case command_type::begin_land_unit_construction: execute_start_land_unit_construction(state, c.source, c.data.land_unit_construction.location, - c.data.land_unit_construction.pop_culture, c.data.land_unit_construction.type); + c.data.land_unit_construction.pop_culture, c.data.land_unit_construction.type, c.data.land_unit_construction.template_province); break; case command_type::cancel_land_unit_construction: execute_cancel_land_unit_construction(state, c.source, c.data.land_unit_construction.location, diff --git a/src/gamestate/commands.hpp b/src/gamestate/commands.hpp index 0a9fdbdad..1028bcd48 100644 --- a/src/gamestate/commands.hpp +++ b/src/gamestate/commands.hpp @@ -173,6 +173,7 @@ struct diplo_action_data { struct naval_unit_construction_data { dcon::province_id location; dcon::unit_type_id type; + dcon::province_id template_province; }; struct rally_point_data { @@ -185,6 +186,7 @@ struct land_unit_construction_data { dcon::province_id location; dcon::culture_id pop_culture; dcon::unit_type_id type; + dcon::province_id template_province; }; struct factory_data { @@ -534,11 +536,11 @@ bool can_begin_factory_building_construction(sys::state& state, dcon::nation_id void cancel_factory_building_construction(sys::state& state, dcon::nation_id source, dcon::state_instance_id location, dcon::factory_type_id type); bool can_cancel_factory_building_construction(sys::state& state, dcon::nation_id source, dcon::state_instance_id location, dcon::factory_type_id type); -void start_naval_unit_construction(sys::state& state, dcon::nation_id source, dcon::province_id location, dcon::unit_type_id type); -bool can_start_naval_unit_construction(sys::state& state, dcon::nation_id source, dcon::province_id location, dcon::unit_type_id type); +void start_naval_unit_construction(sys::state& state, dcon::nation_id source, dcon::province_id location, dcon::unit_type_id type, dcon::province_id template_province = dcon::province_id{}); +bool can_start_naval_unit_construction(sys::state& state, dcon::nation_id source, dcon::province_id location, dcon::unit_type_id type, dcon::province_id template_province = dcon::province_id{}); -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); -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); +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 = dcon::province_id{}); +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 = dcon::province_id{}); void cancel_naval_unit_construction(sys::state& state, dcon::nation_id source, dcon::province_id location, dcon::unit_type_id type); bool can_cancel_naval_unit_construction(sys::state& state, dcon::nation_id source, dcon::province_id location, dcon::unit_type_id type); diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index 595262b79..02856d7ef 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -500,6 +500,119 @@ class macro_builder_details : public scrollable_text { return message_result::consumed; } }; +class macro_builder_apply_button : public button_element_base { +public: + void on_update(sys::state& state) noexcept override { + disabled = (state.map_state.selected_province == dcon::province_id{}); + } + void button_action(sys::state& state) noexcept override { + auto is_land = retrieve(state, parent); + auto const& t = state.ui_state.current_template; + for(dcon::unit_type_id::value_base_t i = 0; i < sys::macro_builder_template::max_types; i++) { + if(t.amounts[i] == 0) //not needed to show this + continue; + dcon::unit_type_id utid = dcon::unit_type_id(i); + if(is_land != state.military_definitions.unit_base_definitions[utid].is_land) + continue; + auto mrmb = state.world.province_get_region_membership_as_province(state.map_state.selected_province); + if(mrmb.begin() == mrmb.end()) + continue; + auto r = state.world.region_membership_get_region(*(mrmb.begin())); + if(is_land) { + for(uint8_t i = 0; i < t.amounts[i]; i++) { + bool built = false; + for(const auto rmb : state.world.region_get_region_membership_as_region(r)) { + auto p = state.world.region_membership_get_province(rmb); + for(const auto c : state.world.in_culture) { + if(command::can_start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province)) { + command::start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province); + built = true; + break; + } + } + if(built) break; + } + } + } else { + for(uint8_t i = 0; i < t.amounts[i]; i++) { + for(const auto rmb : state.world.region_get_region_membership_as_region(r)) { + auto p = state.world.region_membership_get_province(rmb); + if(command::can_start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province)) { + command::start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province); + break; + } + } + } + } + } + } + tooltip_behavior has_tooltip(sys::state& state) noexcept override { + return tooltip_behavior::variable_tooltip; + } + + void update_tooltip(sys::state& state, int32_t x, int32_t y, text::columnar_layout& contents) noexcept override { + if(state.map_state.selected_province == dcon::province_id{}) { + text::add_line(state, contents, "macro_select_province"); + return; + } + + auto is_land = retrieve(state, parent); + auto const& t = state.ui_state.current_template; + for(dcon::unit_type_id::value_base_t i = 0; i < sys::macro_builder_template::max_types; i++) { + if(t.amounts[i] == 0) //not needed to show this + continue; + dcon::unit_type_id utid = dcon::unit_type_id(i); + if(is_land != state.military_definitions.unit_base_definitions[utid].is_land) + continue; + auto mrmb = state.world.province_get_region_membership_as_province(state.map_state.selected_province); + if(mrmb.begin() == mrmb.end()) { + text::add_line(state, contents, "macro_warn_invalid_province"); + continue; + } + auto r = state.world.region_membership_get_region(*(mrmb.begin())); + + uint8_t total_built = 0; + if(is_land) { + for(uint8_t i = 0; i < t.amounts[i]; i++) { + bool built = false; + for(const auto rmb : state.world.region_get_region_membership_as_region(r)) { + auto p = state.world.region_membership_get_province(rmb); + for(const auto c : state.world.in_culture) { + if(command::can_start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province)) { + command::start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province); + built = true; + total_built++; + break; + } + } + if(built) break; + } + } + } else { + for(uint8_t i = 0; i < t.amounts[i]; i++) { + for(const auto rmb : state.world.region_get_region_membership_as_region(r)) { + auto p = state.world.region_membership_get_province(rmb); + if(command::can_start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province)) { + command::start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province); + total_built++; + break; + } + } + } + } + + if(total_built < t.amounts[i]) { + text::substitution_map sub{}; + text::add_to_substitution_map(sub, text::variable_type::x, text::int_wholenum{ t.amounts[i] }); + text::add_to_substitution_map(sub, text::variable_type::y, text::int_wholenum{ total_built }); + text::add_to_substitution_map(sub, text::variable_type::name, state.military_definitions.unit_base_definitions[utid].name); + auto box = text::open_layout_box(contents); + text::localised_format_box(state, contents, box, "macro_warn_insuff", sub); + text::close_layout_box(contents, box); + } + } + } +}; class macro_builder_window : public window_element_base { bool is_land = true; macro_builder_name_input* name_input = nullptr; @@ -530,6 +643,8 @@ class macro_builder_window : public window_element_base { return make_element_by_type(state, id); } else if(name == "switch_type") { return make_element_by_type(state, id); + } else if(name == "apply") { + return make_element_by_type(state, id); } else if(name == "details") { return make_element_by_type(state, id); } else { From 98439364d618da5f1e86e405071b7c1dab4a9b54 Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 07:48:44 +0000 Subject: [PATCH 12/29] shadow dancing --- src/gui/gui_minimap.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index 02856d7ef..f69507d08 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -519,7 +519,7 @@ class macro_builder_apply_button : public button_element_base { continue; auto r = state.world.region_membership_get_region(*(mrmb.begin())); if(is_land) { - for(uint8_t i = 0; i < t.amounts[i]; i++) { + for(uint8_t j = 0; j < t.amounts[i]; j++) { bool built = false; for(const auto rmb : state.world.region_get_region_membership_as_region(r)) { auto p = state.world.region_membership_get_province(rmb); @@ -534,7 +534,7 @@ class macro_builder_apply_button : public button_element_base { } } } else { - for(uint8_t i = 0; i < t.amounts[i]; i++) { + for(uint8_t j = 0; j < t.amounts[i]; j++) { for(const auto rmb : state.world.region_get_region_membership_as_region(r)) { auto p = state.world.region_membership_get_province(rmb); if(command::can_start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province)) { @@ -573,7 +573,7 @@ class macro_builder_apply_button : public button_element_base { uint8_t total_built = 0; if(is_land) { - for(uint8_t i = 0; i < t.amounts[i]; i++) { + for(uint8_t j = 0; j < t.amounts[i]; j++) { bool built = false; for(const auto rmb : state.world.region_get_region_membership_as_region(r)) { auto p = state.world.region_membership_get_province(rmb); @@ -589,7 +589,7 @@ class macro_builder_apply_button : public button_element_base { } } } else { - for(uint8_t i = 0; i < t.amounts[i]; i++) { + for(uint8_t j = 0; j < t.amounts[i]; j++) { for(const auto rmb : state.world.region_get_region_membership_as_region(r)) { auto p = state.world.region_membership_get_province(rmb); if(command::can_start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province)) { From f1251cd7ee612ac9618bd2507d1ee631846007b9 Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 07:54:51 +0000 Subject: [PATCH 13/29] apply button to the left --- assets/alice.gui | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/assets/alice.gui b/assets/alice.gui index 23ee1cbb1..46c772e2d 100644 --- a/assets/alice.gui +++ b/assets/alice.gui @@ -3629,6 +3629,14 @@ guiTypes = { buttonText = "" buttonFont = "vic_22_black" } + guiButtonType = { + name = "apply" + position = { 520 288 } + size = { 128 24 } + quadTextureSprite = "GFX_button_128wide" + buttonText = "" + buttonFont = "vic_22_black" + } editBoxType = { name = "input" position = { 330 28 } From 4e8b166dc48d3d62aa409a25f0a7696e494b7481 Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 08:11:38 +0000 Subject: [PATCH 14/29] get adjacent provinces --- src/gui/gui_minimap.hpp | 59 ++++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index f69507d08..969d77009 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -501,28 +501,49 @@ class macro_builder_details : public scrollable_text { } }; class macro_builder_apply_button : public button_element_base { + std::vector provinces; + std::vector marked; + void get_provinces(sys::state& state, dcon::province_id p) { + if(marked[p.index()]) + return; + marked[p.index()] = true; + if(state.world.province_get_nation_from_province_control(p) == state.local_player_nation) { + provinces.push_back(p); + for(const auto adj : state.world.province_get_province_adjacency_as_connected_provinces(p)) { + auto p2 = state.world.province_adjacency_get_connected_provinces(state.world.province_adjacency_get_connected_provinces(0) == p ? 1 : 0); + get_provinces(state, p2); + } + } + } public: + void on_create(sys::state& state) noexcept override { + button_element_base::on_create(state); + marked.resize(state.world.province_size() + 1, false); + } void on_update(sys::state& state) noexcept override { disabled = (state.map_state.selected_province == dcon::province_id{}); } void button_action(sys::state& state) noexcept override { auto is_land = retrieve(state, parent); auto const& t = state.ui_state.current_template; + + provinces.clear(); + marked.assign(marked.size(), false); + get_provinces(state, state.map_state.selected_province); + if(provinces.empty()) { + return; + } + for(dcon::unit_type_id::value_base_t i = 0; i < sys::macro_builder_template::max_types; i++) { if(t.amounts[i] == 0) //not needed to show this continue; dcon::unit_type_id utid = dcon::unit_type_id(i); if(is_land != state.military_definitions.unit_base_definitions[utid].is_land) continue; - auto mrmb = state.world.province_get_region_membership_as_province(state.map_state.selected_province); - if(mrmb.begin() == mrmb.end()) - continue; - auto r = state.world.region_membership_get_region(*(mrmb.begin())); if(is_land) { for(uint8_t j = 0; j < t.amounts[i]; j++) { bool built = false; - for(const auto rmb : state.world.region_get_region_membership_as_region(r)) { - auto p = state.world.region_membership_get_province(rmb); + for(const auto p : provinces) { for(const auto c : state.world.in_culture) { if(command::can_start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province)) { command::start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province); @@ -535,8 +556,7 @@ class macro_builder_apply_button : public button_element_base { } } else { for(uint8_t j = 0; j < t.amounts[i]; j++) { - for(const auto rmb : state.world.region_get_region_membership_as_region(r)) { - auto p = state.world.region_membership_get_province(rmb); + for(const auto p : provinces) { if(command::can_start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province)) { command::start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province); break; @@ -556,6 +576,14 @@ class macro_builder_apply_button : public button_element_base { return; } + provinces.clear(); + marked.assign(marked.size(), false); + get_provinces(state, state.map_state.selected_province); + if(provinces.empty()) { + text::add_line(state, contents, "macro_warn_invalid_province"); + return; + } + auto is_land = retrieve(state, parent); auto const& t = state.ui_state.current_template; for(dcon::unit_type_id::value_base_t i = 0; i < sys::macro_builder_template::max_types; i++) { @@ -564,22 +592,13 @@ class macro_builder_apply_button : public button_element_base { dcon::unit_type_id utid = dcon::unit_type_id(i); if(is_land != state.military_definitions.unit_base_definitions[utid].is_land) continue; - auto mrmb = state.world.province_get_region_membership_as_province(state.map_state.selected_province); - if(mrmb.begin() == mrmb.end()) { - text::add_line(state, contents, "macro_warn_invalid_province"); - continue; - } - auto r = state.world.region_membership_get_region(*(mrmb.begin())); - uint8_t total_built = 0; if(is_land) { for(uint8_t j = 0; j < t.amounts[i]; j++) { bool built = false; - for(const auto rmb : state.world.region_get_region_membership_as_region(r)) { - auto p = state.world.region_membership_get_province(rmb); + for(const auto p : provinces) { for(const auto c : state.world.in_culture) { if(command::can_start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province)) { - command::start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province); built = true; total_built++; break; @@ -590,10 +609,8 @@ class macro_builder_apply_button : public button_element_base { } } else { for(uint8_t j = 0; j < t.amounts[i]; j++) { - for(const auto rmb : state.world.region_get_region_membership_as_region(r)) { - auto p = state.world.region_membership_get_province(rmb); + for(const auto p : provinces) { if(command::can_start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province)) { - command::start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province); total_built++; break; } From 58d08549af3f5de57b249d25b9452dae551da839 Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 08:21:11 +0000 Subject: [PATCH 15/29] misc fixes --- src/gui/gui_minimap.hpp | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index 969d77009..879f1ad1b 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -420,6 +420,7 @@ class macro_builder_details : public scrollable_text { text::add_line(state, contents, "macro_warn_unlocked"); // Total + if(maximum_speed == std::numeric_limits::max()) maximum_speed = 0.f; text::add_line(state, contents, text::produce_simple_string(state, "macro_total_desc")); if(is_land) { if(reconnaissance_or_fire_range > 0.f) { @@ -510,7 +511,7 @@ class macro_builder_apply_button : public button_element_base { if(state.world.province_get_nation_from_province_control(p) == state.local_player_nation) { provinces.push_back(p); for(const auto adj : state.world.province_get_province_adjacency_as_connected_provinces(p)) { - auto p2 = state.world.province_adjacency_get_connected_provinces(state.world.province_adjacency_get_connected_provinces(0) == p ? 1 : 0); + auto p2 = adj.get_connected_provinces(adj.get_connected_provinces(0) == p ? 1 : 0); get_provinces(state, p2); } } @@ -540,28 +541,31 @@ class macro_builder_apply_button : public button_element_base { dcon::unit_type_id utid = dcon::unit_type_id(i); if(is_land != state.military_definitions.unit_base_definitions[utid].is_land) continue; + uint8_t total_built = 0; if(is_land) { for(uint8_t j = 0; j < t.amounts[i]; j++) { - bool built = false; for(const auto p : provinces) { for(const auto c : state.world.in_culture) { if(command::can_start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province)) { command::start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province); - built = true; - break; + total_built++; } + if(total_built >= t.amounts[i]) break; } - if(built) break; + if(total_built >= t.amounts[i]) break; } + if(total_built >= t.amounts[i]) break; } } else { for(uint8_t j = 0; j < t.amounts[i]; j++) { for(const auto p : provinces) { if(command::can_start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province)) { command::start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province); - break; + total_built++; } + if(total_built >= t.amounts[i]) break; } + if(total_built >= t.amounts[i]) break; } } } @@ -595,26 +599,26 @@ class macro_builder_apply_button : public button_element_base { uint8_t total_built = 0; if(is_land) { for(uint8_t j = 0; j < t.amounts[i]; j++) { - bool built = false; for(const auto p : provinces) { for(const auto c : state.world.in_culture) { if(command::can_start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province)) { - built = true; total_built++; - break; } + if(total_built >= t.amounts[i]) break; } - if(built) break; + if(total_built >= t.amounts[i]) break; } + if(total_built >= t.amounts[i]) break; } } else { for(uint8_t j = 0; j < t.amounts[i]; j++) { for(const auto p : provinces) { if(command::can_start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province)) { total_built++; - break; } + if(total_built >= t.amounts[i]) break; } + if(total_built >= t.amounts[i]) break; } } From 9eb6b395a67190d47ce0cffa3c67518f773cca1a Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 08:35:11 +0000 Subject: [PATCH 16/29] only 1 per province --- src/gui/gui_minimap.hpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index 879f1ad1b..03cd3ee7c 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -403,7 +403,7 @@ class macro_builder_details : public scrollable_text { defence_or_hull += state.world.nation_get_unit_stats(state.local_player_nation, utid).defence_or_hull * float(t.amounts[i]); discipline_or_evasion += state.world.nation_get_unit_stats(state.local_player_nation, utid).discipline_or_evasion * float(t.amounts[i]); supply_consumption += state.world.nation_get_unit_stats(state.local_player_nation, utid).supply_consumption * float(t.amounts[i]); - maximum_speed = std::min(maximum_speed, state.world.nation_get_unit_stats(state.local_player_nation, utid).maximum_speed * float(t.amounts[i])); + maximum_speed = std::min(maximum_speed, state.world.nation_get_unit_stats(state.local_player_nation, utid).maximum_speed); if(is_land) { support += state.world.nation_get_unit_stats(state.local_player_nation, utid).support * float(t.amounts[i]); maneuver += state.military_definitions.unit_base_definitions[utid].maneuver * float(t.amounts[i]); @@ -549,8 +549,8 @@ class macro_builder_apply_button : public button_element_base { if(command::can_start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province)) { command::start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province); total_built++; + break; } - if(total_built >= t.amounts[i]) break; } if(total_built >= t.amounts[i]) break; } @@ -603,8 +603,8 @@ class macro_builder_apply_button : public button_element_base { for(const auto c : state.world.in_culture) { if(command::can_start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province)) { total_built++; + break; } - if(total_built >= t.amounts[i]) break; } if(total_built >= t.amounts[i]) break; } @@ -621,8 +621,7 @@ class macro_builder_apply_button : public button_element_base { if(total_built >= t.amounts[i]) break; } } - - if(total_built < t.amounts[i]) { + if(total_built != t.amounts[i]) { text::substitution_map sub{}; text::add_to_substitution_map(sub, text::variable_type::x, text::int_wholenum{ t.amounts[i] }); text::add_to_substitution_map(sub, text::variable_type::y, text::int_wholenum{ total_built }); From dca14e14a15a5b9dc6f1f7f8769dc8c4ef5c88fc Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 08:38:47 +0000 Subject: [PATCH 17/29] proper cleanup --- assets/alice.csv | 1 + assets/alice.gui | 2 +- src/gui/gui_minimap.hpp | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/assets/alice.csv b/assets/alice.csv index 3835d9467..a9a6345fa 100644 --- a/assets/alice.csv +++ b/assets/alice.csv @@ -1378,6 +1378,7 @@ macro_warn_unlocked; macro_select_province;Please select a province on the map macro_warn_insuff;§RCan't build $x$ $name$ (only $y$)§W macro_warn_invalid_province;§RProvince not part of a region§W +macro_apply_template;Apply aml_col_s1;Potential aml_col_s2;NA aml_col_s3;Can Invest diff --git a/assets/alice.gui b/assets/alice.gui index 46c772e2d..a5611b977 100644 --- a/assets/alice.gui +++ b/assets/alice.gui @@ -3634,7 +3634,7 @@ guiTypes = { position = { 520 288 } size = { 128 24 } quadTextureSprite = "GFX_button_128wide" - buttonText = "" + buttonText = "macro_apply_template" buttonFont = "vic_22_black" } editBoxType = { diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index 03cd3ee7c..cbd94d8ca 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -291,6 +291,7 @@ class macro_builder_new_template_button : public button_element_base { public: void button_action(sys::state& state) noexcept override { state.ui_state.current_template = sys::macro_builder_template{}; + std::memset(state.ui_state.current_template.name, ' ', sizeof(sys::macro_builder_template::name)); send(state, parent, notify_setting_update{}); } }; @@ -354,10 +355,9 @@ class macro_builder_name_input : public edit_box_element_base { public: void edit_box_update(sys::state& state, std::string_view str) noexcept override { auto s = parsers::remove_surrounding_whitespace(str); - if(s.empty()) - return; std::memset(state.ui_state.current_template.name, ' ', sizeof(sys::macro_builder_template::name)); - std::memcpy(state.ui_state.current_template.name, s.data(), std::min(s.length(), sizeof(sys::macro_builder_template::name))); + if(!s.empty()) + std::memcpy(state.ui_state.current_template.name, s.data(), std::min(s.length(), sizeof(sys::macro_builder_template::name))); } }; class macro_builder_details : public scrollable_text { From 3c7d6c8b7ec2fbff809dec88401bbe72bc1bed96 Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 08:55:43 +0000 Subject: [PATCH 18/29] fixes --- src/gui/gui_minimap.hpp | 53 ++++++++----------- .../gui_build_unit_large_window.hpp | 2 +- 2 files changed, 23 insertions(+), 32 deletions(-) diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index cbd94d8ca..a14ca5e29 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -508,7 +508,7 @@ class macro_builder_apply_button : public button_element_base { if(marked[p.index()]) return; marked[p.index()] = true; - if(state.world.province_get_nation_from_province_control(p) == state.local_player_nation) { + if(state.world.province_get_nation_from_province_control(p) == state.local_player_nation && state.world.province_get_nation_from_province_ownership(p) == state.local_player_nation) { provinces.push_back(p); for(const auto adj : state.world.province_get_province_adjacency_as_connected_provinces(p)) { auto p2 = adj.get_connected_provinces(adj.get_connected_provinces(0) == p ? 1 : 0); @@ -543,30 +543,26 @@ class macro_builder_apply_button : public button_element_base { continue; uint8_t total_built = 0; if(is_land) { - for(uint8_t j = 0; j < t.amounts[i]; j++) { - for(const auto p : provinces) { - for(const auto c : state.world.in_culture) { - if(command::can_start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province)) { - command::start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province); - total_built++; - break; - } + for(const auto p : provinces) { + for(const auto c : state.world.in_culture) { + if(command::can_start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province)) { + command::start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province); + total_built++; + break; } - if(total_built >= t.amounts[i]) break; } if(total_built >= t.amounts[i]) break; } + if(total_built >= t.amounts[i]) break; } else { - for(uint8_t j = 0; j < t.amounts[i]; j++) { - for(const auto p : provinces) { - if(command::can_start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province)) { - command::start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province); - total_built++; - } - if(total_built >= t.amounts[i]) break; + for(const auto p : provinces) { + if(command::can_start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province)) { + command::start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province); + total_built++; } if(total_built >= t.amounts[i]) break; } + if(total_built >= t.amounts[i]) break; } } } @@ -598,28 +594,23 @@ class macro_builder_apply_button : public button_element_base { continue; uint8_t total_built = 0; if(is_land) { - for(uint8_t j = 0; j < t.amounts[i]; j++) { - for(const auto p : provinces) { - for(const auto c : state.world.in_culture) { - if(command::can_start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province)) { - total_built++; - break; - } + for(const auto p : provinces) { + for(const auto c : state.world.in_culture) { + if(command::can_start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province)) { + total_built++; + break; } - if(total_built >= t.amounts[i]) break; } if(total_built >= t.amounts[i]) break; } } else { - for(uint8_t j = 0; j < t.amounts[i]; j++) { - for(const auto p : provinces) { - if(command::can_start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province)) { - total_built++; - } - if(total_built >= t.amounts[i]) break; + for(const auto p : provinces) { + if(command::can_start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province)) { + total_built++; } if(total_built >= t.amounts[i]) break; } + if(total_built >= t.amounts[i]) break; } if(total_built != t.amounts[i]) { text::substitution_map sub{}; diff --git a/src/gui/topbar_subwindows/military_subwindows/gui_build_unit_large_window.hpp b/src/gui/topbar_subwindows/military_subwindows/gui_build_unit_large_window.hpp index eac3bd89e..2d16b1fe1 100644 --- a/src/gui/topbar_subwindows/military_subwindows/gui_build_unit_large_window.hpp +++ b/src/gui/topbar_subwindows/military_subwindows/gui_build_unit_large_window.hpp @@ -560,7 +560,7 @@ class units_build_listbox : public listbox_element_base= 1000.0f) { + if(pl.get_pop().get_poptype() == state.culture_definitions.soldiers && state.world.pop_get_size(pl.get_pop()) >= state.defines.pop_min_size_for_regiment) { info.pop_info = pl.get_pop(); break; } From 792798fb040383c25f15ae415508f4ff7d53153d Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 08:57:31 +0000 Subject: [PATCH 19/29] fuck --- src/gui/gui_minimap.hpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index a14ca5e29..e3bb503d9 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -548,12 +548,11 @@ class macro_builder_apply_button : public button_element_base { if(command::can_start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province)) { command::start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province); total_built++; - break; } + if(total_built >= t.amounts[i]) break; } if(total_built >= t.amounts[i]) break; } - if(total_built >= t.amounts[i]) break; } else { for(const auto p : provinces) { if(command::can_start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province)) { @@ -562,7 +561,6 @@ class macro_builder_apply_button : public button_element_base { } if(total_built >= t.amounts[i]) break; } - if(total_built >= t.amounts[i]) break; } } } @@ -598,8 +596,8 @@ class macro_builder_apply_button : public button_element_base { for(const auto c : state.world.in_culture) { if(command::can_start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province)) { total_built++; - break; } + if(total_built >= t.amounts[i]) break; } if(total_built >= t.amounts[i]) break; } @@ -610,7 +608,6 @@ class macro_builder_apply_button : public button_element_base { } if(total_built >= t.amounts[i]) break; } - if(total_built >= t.amounts[i]) break; } if(total_built != t.amounts[i]) { text::substitution_map sub{}; From bf02c55e412aa1af653151cddd501399b47689e1 Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 09:06:39 +0000 Subject: [PATCH 20/29] fix ui being off --- assets/alice.gui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/alice.gui b/assets/alice.gui index a5611b977..fdeac9616 100644 --- a/assets/alice.gui +++ b/assets/alice.gui @@ -3670,7 +3670,7 @@ guiTypes = { position = { 32 0 } font = "vic_22" borderSize = { 0 0 } - maxsize = { 100 24 } + maxsize = { 70 24 } format = center } guiButtonType = { From a630370bda52bf4e1134d98cb2347748b8eefd0c Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 19:42:25 +0000 Subject: [PATCH 21/29] more space for templates --- src/gui/gui_minimap.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index e3bb503d9..751adcf9c 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -217,8 +217,8 @@ class macro_builder_template_listbox : public listbox_element_base 0) { uint32_t num_templates = contents.file_size / sizeof(sys::macro_builder_template); //Corruption protection - if(num_templates >= 256) - num_templates = 256; + if(num_templates >= 8192 * 4) + num_templates = 8192 * 4; state.ui_state.templates.resize(num_templates); std::memcpy(state.ui_state.templates.data(), contents.data, num_templates * sizeof(sys::macro_builder_template)); } From edc7149c1acc111fbe89d118512f93d4b0b5ac28 Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 20:39:22 +0000 Subject: [PATCH 22/29] fix maneuver and discipline being additive --- src/gui/gui_minimap.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index 751adcf9c..54fe015d6 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -401,12 +401,12 @@ class macro_builder_details : public scrollable_text { siege_or_torpedo_attack += state.world.nation_get_unit_stats(state.local_player_nation, utid).siege_or_torpedo_attack * float(t.amounts[i]); attack_or_gun_power += state.world.nation_get_unit_stats(state.local_player_nation, utid).attack_or_gun_power * float(t.amounts[i]); defence_or_hull += state.world.nation_get_unit_stats(state.local_player_nation, utid).defence_or_hull * float(t.amounts[i]); - discipline_or_evasion += state.world.nation_get_unit_stats(state.local_player_nation, utid).discipline_or_evasion * float(t.amounts[i]); + discipline_or_evasion += std::min(discipline_or_evasion, state.world.nation_get_unit_stats(state.local_player_nation, utid).discipline_or_evasion); supply_consumption += state.world.nation_get_unit_stats(state.local_player_nation, utid).supply_consumption * float(t.amounts[i]); maximum_speed = std::min(maximum_speed, state.world.nation_get_unit_stats(state.local_player_nation, utid).maximum_speed); if(is_land) { support += state.world.nation_get_unit_stats(state.local_player_nation, utid).support * float(t.amounts[i]); - maneuver += state.military_definitions.unit_base_definitions[utid].maneuver * float(t.amounts[i]); + maneuver += std::min(maneuver, state.military_definitions.unit_base_definitions[utid].maneuver); } else { supply_consumption_score += state.military_definitions.unit_base_definitions[utid].supply_consumption_score * int32_t(t.amounts[i]); } From 9c8676cd8fdcd77e82ab2da41f493e3acba3d8e3 Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 21:11:07 +0000 Subject: [PATCH 23/29] fix --- src/gui/gui_minimap.hpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index 54fe015d6..f5073abc1 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -535,6 +535,8 @@ class macro_builder_apply_button : public button_element_base { return; } + std::vector marked_p(state.world.province_size() + 1, false); + std::vector marked_c(state.world.culture_size() + 1, false); for(dcon::unit_type_id::value_base_t i = 0; i < sys::macro_builder_template::max_types; i++) { if(t.amounts[i] == 0) //not needed to show this continue; @@ -545,7 +547,9 @@ class macro_builder_apply_button : public button_element_base { if(is_land) { for(const auto p : provinces) { for(const auto c : state.world.in_culture) { - if(command::can_start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province)) { + if(marked_p[p.index()] == false + && marked_c[c.id.index()] == false + && command::can_start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province)) { command::start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province); total_built++; } @@ -555,7 +559,8 @@ class macro_builder_apply_button : public button_element_base { } } else { for(const auto p : provinces) { - if(command::can_start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province)) { + if(marked_p[p.index()] == false + && command::can_start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province)) { command::start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province); total_built++; } @@ -584,6 +589,9 @@ class macro_builder_apply_button : public button_element_base { auto is_land = retrieve(state, parent); auto const& t = state.ui_state.current_template; + + std::vector marked_p(state.world.province_size() + 1, false); + std::vector marked_c(state.world.culture_size() + 1, false); for(dcon::unit_type_id::value_base_t i = 0; i < sys::macro_builder_template::max_types; i++) { if(t.amounts[i] == 0) //not needed to show this continue; @@ -594,7 +602,11 @@ class macro_builder_apply_button : public button_element_base { if(is_land) { for(const auto p : provinces) { for(const auto c : state.world.in_culture) { - if(command::can_start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province)) { + if(marked_p[p.index()] == false + && marked_c[c.id.index()] == false + && command::can_start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province)) { + marked_p[p.index()] = true; + marked_c[c.id.index()] = true; total_built++; } if(total_built >= t.amounts[i]) break; @@ -603,7 +615,9 @@ class macro_builder_apply_button : public button_element_base { } } else { for(const auto p : provinces) { - if(command::can_start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province)) { + if(marked_p[p.index()] == false + && command::can_start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province)) { + marked_p[p.index()] = true; total_built++; } if(total_built >= t.amounts[i]) break; From 2b87f17c5fd6305d9ab3b70eda7d54f2e048a446 Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 21:13:30 +0000 Subject: [PATCH 24/29] fix more bug --- src/gui/gui_minimap.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index f5073abc1..d05735815 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -551,6 +551,8 @@ class macro_builder_apply_button : public button_element_base { && marked_c[c.id.index()] == false && command::can_start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province)) { command::start_land_unit_construction(state, state.local_player_nation, p, c, utid, state.map_state.selected_province); + marked_p[p.index()] = true; + marked_c[c.id.index()] = true; total_built++; } if(total_built >= t.amounts[i]) break; @@ -562,6 +564,7 @@ class macro_builder_apply_button : public button_element_base { if(marked_p[p.index()] == false && command::can_start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province)) { command::start_naval_unit_construction(state, state.local_player_nation, p, utid, state.map_state.selected_province); + marked_p[p.index()] = true; total_built++; } if(total_built >= t.amounts[i]) break; From 4ea2c3cf8e76bc1345136e0c6439cc279ffb1c62 Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sat, 6 Jan 2024 21:19:33 +0000 Subject: [PATCH 25/29] extra fixes --- src/gui/gui_minimap.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index d05735815..7dad60731 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -374,11 +374,11 @@ class macro_builder_details : public scrollable_text { float siege_or_torpedo_attack = 0.f; float attack_or_gun_power = 0.f; float defence_or_hull = 0.f; - float discipline_or_evasion = 0.f; + float discipline_or_evasion = std::numeric_limits::max(); float support = 0.f; float supply_consumption = 0.f; float maximum_speed = std::numeric_limits::max(); - float maneuver = 0.f; + float maneuver = std::numeric_limits::max(); int32_t supply_consumption_score = 0; bool warn_overseas = false; bool warn_culture = false; @@ -421,6 +421,8 @@ class macro_builder_details : public scrollable_text { // Total if(maximum_speed == std::numeric_limits::max()) maximum_speed = 0.f; + if(discipline_or_evasion == std::numeric_limits::max()) discipline_or_evasion = 0.f; + if(maneuver == std::numeric_limits::max()) maneuver = 0.f; text::add_line(state, contents, text::produce_simple_string(state, "macro_total_desc")); if(is_land) { if(reconnaissance_or_fire_range > 0.f) { From fed9d2cb51cd5c6c7559afa2ca3f77afd73a0fc8 Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sun, 7 Jan 2024 00:34:09 +0000 Subject: [PATCH 26/29] ok fine 8192 per scenario fine --- src/filesystem/simple_fs.hpp | 1 + src/filesystem/simple_fs_nix.cpp | 7 +++++++ src/filesystem/simple_fs_win.cpp | 15 +++++++++++++++ src/gui/gui_minimap.hpp | 19 ++++++++----------- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/filesystem/simple_fs.hpp b/src/filesystem/simple_fs.hpp index fad3e71c0..085780c87 100644 --- a/src/filesystem/simple_fs.hpp +++ b/src/filesystem/simple_fs.hpp @@ -74,6 +74,7 @@ native_string get_full_name(file const& f); // functions that operate outside of a filesystem object directory get_or_create_save_game_directory(); +directory get_or_create_templates_directory(); directory get_or_create_oos_directory(); directory get_or_create_scenario_directory(); directory get_or_create_settings_directory(); diff --git a/src/filesystem/simple_fs_nix.cpp b/src/filesystem/simple_fs_nix.cpp index 0777d8926..bb2808462 100644 --- a/src/filesystem/simple_fs_nix.cpp +++ b/src/filesystem/simple_fs_nix.cpp @@ -472,6 +472,13 @@ directory get_or_create_save_game_directory() { return directory(nullptr, path); } +directory get_or_create_templates_directory() { + native_string path = native_string(getenv("HOME")) + "/.local/share/Alice/templates/"; + make_directories(path); + + return directory(nullptr, path); +} + directory get_or_create_oos_directory() { native_string path = native_string(getenv("HOME")) + "/.local/share/Alice/oos/"; make_directories(path); diff --git a/src/filesystem/simple_fs_win.cpp b/src/filesystem/simple_fs_win.cpp index 23d6ce3d8..95dd5ca76 100644 --- a/src/filesystem/simple_fs_win.cpp +++ b/src/filesystem/simple_fs_win.cpp @@ -382,6 +382,21 @@ directory get_or_create_save_game_directory() { return directory(nullptr, base_path); } +directory get_or_create_templates_directory() { + wchar_t* local_path_out = nullptr; + std::wstring base_path; + if(SHGetKnownFolderPath(FOLDERID_Documents, 0, nullptr, &local_path_out) == S_OK) { + base_path = std::wstring(local_path_out) + NATIVE("\\Project Alice"); + } + CoTaskMemFree(local_path_out); + if(base_path.length() > 0) { + CreateDirectoryW(base_path.c_str(), nullptr); + base_path += NATIVE("\\templates"); + CreateDirectoryW(base_path.c_str(), nullptr); + } + return directory(nullptr, base_path); +} + directory get_or_create_oos_directory() { wchar_t* local_path_out = nullptr; std::wstring base_path; diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index 7dad60731..76d831311 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -210,8 +210,8 @@ class macro_builder_template_listbox : public listbox_element_base::on_create(state); - auto sdir = simple_fs::get_or_create_save_game_directory(); - auto f = simple_fs::open_file(sdir, NATIVE("templates.bin")); + auto sdir = simple_fs::get_or_create_templates_directory(); + auto f = simple_fs::open_file(sdir, state.loaded_scenario_file); if(f) { auto contents = simple_fs::view_contents(*f); if(contents.file_size > 0) { @@ -299,13 +299,11 @@ class macro_builder_save_template_button : public button_element_base { public: void button_action(sys::state& state) noexcept override { sys::macro_builder_template& t = state.ui_state.current_template; - t.scenario_checksum = state.scenario_checksum; t.source = state.local_player_nation; // Replace templates with the same name and of the same scenario bool overwrite = false; for(auto& u : state.ui_state.templates) { - if(t.scenario_checksum.is_equal(u.scenario_checksum) - && std::memcmp(u.name, t.name, sizeof(sys::macro_builder_template::name)) == 0) { + if(std::memcmp(u.name, t.name, sizeof(sys::macro_builder_template::name)) == 0) { std::memcpy(&u, &t, sizeof(sys::macro_builder_template)); overwrite = true; break; @@ -314,8 +312,8 @@ class macro_builder_save_template_button : public button_element_base { if(!overwrite) { state.ui_state.templates.push_back(t); } - auto sdir = simple_fs::get_or_create_save_game_directory(); - simple_fs::write_file(sdir, NATIVE("templates.bin"), reinterpret_cast(state.ui_state.templates.data()), uint32_t(state.ui_state.templates.size()) * sizeof(sys::macro_builder_template)); + auto sdir = simple_fs::get_or_create_templates_directory(); + simple_fs::write_file(sdir, state.loaded_scenario_file, reinterpret_cast(state.ui_state.templates.data()), uint32_t(state.ui_state.templates.size()) * sizeof(sys::macro_builder_template)); send(state, parent, notify_setting_update{}); } }; @@ -325,14 +323,13 @@ class macro_builder_remove_template_button : public button_element_base { sys::macro_builder_template& t = state.ui_state.current_template; for(uint32_t i = 0; i < uint32_t(state.ui_state.templates.size()); i++) { auto const& u = state.ui_state.templates[i]; - if(t.scenario_checksum.is_equal(u.scenario_checksum) - && std::memcmp(u.name, t.name, sizeof(sys::macro_builder_template::name)) == 0) { + if(std::memcmp(u.name, t.name, sizeof(sys::macro_builder_template::name)) == 0) { state.ui_state.templates.erase(state.ui_state.templates.begin() + i); break; } } - auto sdir = simple_fs::get_or_create_save_game_directory(); - simple_fs::write_file(sdir, NATIVE("templates.bin"), reinterpret_cast(state.ui_state.templates.data()), uint32_t(state.ui_state.templates.size()) * sizeof(sys::macro_builder_template)); + auto sdir = simple_fs::get_or_create_templates_directory(); + simple_fs::write_file(sdir, state.loaded_scenario_file, reinterpret_cast(state.ui_state.templates.data()), uint32_t(state.ui_state.templates.size()) * sizeof(sys::macro_builder_template)); send(state, parent, notify_setting_update{}); } }; From c3bb1a63e60ce399e147e2f70680c68c9cb17630 Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sun, 7 Jan 2024 00:47:07 +0000 Subject: [PATCH 27/29] fix crash --- src/gui/gui_minimap.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index 76d831311..107bd286e 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -184,6 +184,8 @@ class macro_builder_template_select : public button_element_base { public: void button_action(sys::state& state) noexcept override { auto index = retrieve(state, parent); + if(index >= uint32_t(state.ui_state.templates.size())) + return; std::memcpy(&state.ui_state.current_template, &state.ui_state.templates[index], sizeof(sys::macro_builder_template)); send(state, parent, notify_template_select{}); } @@ -687,7 +689,8 @@ class macro_builder_window : public window_element_base { } else if(payload.holds_type< notify_template_select>()) { auto const& name = state.ui_state.current_template.name; auto sv = std::string_view(name, name + sizeof(name)); - name_input->set_text(state, std::string(sv)); + auto s = std::string(sv); + name_input->set_text(state, s); impl_on_update(state); return message_result::consumed; } else if(payload.holds_type()) { From 03d2ff372f3c804840816704b0bda821158aba8a Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sun, 7 Jan 2024 00:57:24 +0000 Subject: [PATCH 28/29] fix crash --- src/gui/gui_minimap.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/gui_minimap.hpp b/src/gui/gui_minimap.hpp index 107bd286e..ac8fa5727 100644 --- a/src/gui/gui_minimap.hpp +++ b/src/gui/gui_minimap.hpp @@ -690,6 +690,7 @@ class macro_builder_window : public window_element_base { auto const& name = state.ui_state.current_template.name; auto sv = std::string_view(name, name + sizeof(name)); auto s = std::string(sv); + name_input->edit_index_position(state, 0); name_input->set_text(state, s); impl_on_update(state); return message_result::consumed; From 5115b3acae30ed188e4f945cc1f289fdfb4d722f Mon Sep 17 00:00:00 2001 From: wxwisiasdf <39974089+wxwisiasdf@users.noreply.github.com> Date: Sun, 7 Jan 2024 01:06:43 +0000 Subject: [PATCH 29/29] Rebel hunter balance estimations (this makes rebels more tolerable) --- src/culture/rebels.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/culture/rebels.cpp b/src/culture/rebels.cpp index f961dc320..6e97e93a4 100644 --- a/src/culture/rebels.cpp +++ b/src/culture/rebels.cpp @@ -789,8 +789,8 @@ void sort_hunting_targets(sys::state& state, dcon::army_id ar, std::vector(ai::estimate_army_strength(state, a), 1.f); - auto bs = 0.02f * std::max(ai::estimate_army_strength(state, b), 1.f); + auto as = 0.001f * std::max(ai::estimate_army_strength(state, a), 1.f); + auto bs = 0.001f * std::max(ai::estimate_army_strength(state, b), 1.f); auto da = province::sorting_distance(state, pa, closest_prov) + as; auto db = province::sorting_distance(state, pb, closest_prov) + bs; if(da != db)