diff --git a/assets/alice.csv b/assets/alice.csv index 2a7a1499b..703e346f2 100644 --- a/assets/alice.csv +++ b/assets/alice.csv @@ -1092,6 +1092,8 @@ msg_crisis_defender_1;$x$ has become involved in the current crisis, backing the msg_crisis_vol_join_title;Nation Takes a Side msg_crisis_vol_join_1;$x$ has decided to join the current crisis on the side of the attackers. msg_crisis_vol_join_2;$x$ has decided to join the current crisis on the side of the defenders. +msg_entered_automatic_alliance_title;Entered alliance automatically +msg_entered_automatic_alliance_1;$x$ has entered in an alliance with us automatically, because we marked that we're interested in allying them if possible msg_n_event_title;National Event msg_p_event_title;Provincial Event msg_m_event_title;Major Event @@ -1387,6 +1389,7 @@ amsg_crisis_voluntary_join;The nation joins a crisis without an offer;;;;;;;;;;; amsg_army_built;The nation built an army;;;;;;;;;;;;x amsg_navy_built;The nation built a navy;;;;;;;;;;;;x amsg_bankruptcy;Nation goes bankrupt;;;;;;;;;;;;x +amsg_entered_automatic_alliance_title;The nation is automatically allied by another alice_stockpile_button_0_0;National stockpiles function as a condiment to your usual economic-business activities, where people see §Ggreen§W lines go up, and §Rred§W lines go down, as per usual I'm §Ynot§W a line graph so I mostly go unnoticed :) alice_stockpile_button_1_0;If you click me 10 times you will receive nothing in return, just trust me, don't click me... §ROR ELSE§W alice_stockpile_button_1_1;I see, well now I'm not gonna say anything because I know you will keep clicking until I say a §Ydifferent§W dialogue and that's just boring diff --git a/assets/alice.gui b/assets/alice.gui index 4b02bb1e3..8b334c729 100644 --- a/assets/alice.gui +++ b/assets/alice.gui @@ -4062,4 +4062,9 @@ guiTypes = { position = { 379 559 } quadTextureSprite = "GFX_checkbox_default" } + guiButtonType = { + name = "alice_interested_in_alliance" + position = { 0 0 } + quadTextureSprite = "GFX_checkbox_default" + } } diff --git a/src/ai/ai.cpp b/src/ai/ai.cpp index 571659998..8a3f126a2 100644 --- a/src/ai/ai.cpp +++ b/src/ai/ai.cpp @@ -118,8 +118,13 @@ void update_ai_general_status(sys::state& state) { static void internal_get_alliance_targets_by_adjacency(sys::state& state, dcon::nation_id n, dcon::nation_id adj, std::vector& alliance_targets) { for(auto nb : state.world.nation_get_nation_adjacency(adj)) { auto other = nb.get_connected_nations(0) != adj ? nb.get_connected_nations(0) : nb.get_connected_nations(1); - if(other != n && other.get_is_player_controlled() == false && !(other.get_overlord_as_subject().get_ruler()) && !nations::are_allied(state, n, other) && !military::are_at_war(state, other, n) && ai_will_accept_alliance(state, other, n)) + + bool b = other.get_is_player_controlled() + ? !state.world.unilateral_relationship_get_interested_in_alliance(state.world.get_unilateral_relationship_by_unilateral_pair(n, other)) + : ai_will_accept_alliance(state, other, n); + if(other != n && !(other.get_overlord_as_subject().get_ruler()) && !nations::are_allied(state, n, other) && !military::are_at_war(state, other, n) && b) { alliance_targets.push_back(other.id); + } } } static void internal_get_alliance_targets(sys::state& state, dcon::nation_id n, std::vector& alliance_targets) { @@ -160,11 +165,17 @@ void form_alliances(sys::state& state) { else return a.index() > b.index(); }); + if(state.world.nation_get_is_player_controlled(alliance_targets[0])) { + notification::post(state, notification::message{ + [source = n](sys::state& state, text::layout_base& contents) { + text::add_line(state, contents, "msg_entered_automatic_alliance_1", text::variable_type::x, source); + }, + "msg_entered_automatic_alliance_title", + n, dcon::nation_id{}, dcon::nation_id{}, + sys::message_base_type::crisis_voluntary_join + }); + } nations::make_alliance(state, n, alliance_targets[0]); - // Call our new allies into wars.... they may not accept but they may just may join! - //for(auto wp : state.world.nation_get_war_participant(n)) - // if(!military::are_allied_in_war(state, n, alliance_targets[0]) && will_join_war(state, alliance_targets[0], wp.get_war(), wp.get_is_attacker())) - // command::execute_call_to_arms(state, n, alliance_targets[0], wp.get_war()); } } } diff --git a/src/common_types/constants.hpp b/src/common_types/constants.hpp index a2447a1bb..e4806f8ab 100644 --- a/src/common_types/constants.hpp +++ b/src/common_types/constants.hpp @@ -299,6 +299,7 @@ enum class message_setting_type : uint8_t { army_built = 98, // added navy_built = 99, // added bankruptcy = 100, + entered_automatic_alliance = 101, count = 128 }; @@ -375,7 +376,8 @@ enum class message_base_type : uint8_t { army_built = 69, // added navy_built = 70, // added bankruptcy = 71, - count = 72 + entered_automatic_alliance = 72, + count = 73 }; struct msg_setting_entry { @@ -496,6 +498,7 @@ constexpr inline msg_setting_entry message_setting_map[size_t(message_base_type: msg_setting_entry{ message_setting_type::army_built, message_setting_type::count, message_setting_type::count}, //army_built = 69, // added msg_setting_entry{ message_setting_type::navy_built, message_setting_type::count, message_setting_type::count}, //navy_built = 70, // added msg_setting_entry{ message_setting_type::bankruptcy, message_setting_type::count, message_setting_type::count }, // bankruptcy = 71, + msg_setting_entry{ message_setting_type::entered_automatic_alliance, message_setting_type::count, message_setting_type::count },//entered_automatic_alliance = 72, }; namespace message_response { diff --git a/src/gamestate/commands.cpp b/src/gamestate/commands.cpp index cc998ef57..bcc17ee71 100644 --- a/src/gamestate/commands.cpp +++ b/src/gamestate/commands.cpp @@ -2325,6 +2325,28 @@ void execute_ask_for_alliance(sys::state& state, dcon::nation_id asker, dcon::na diplomatic_message::post(state, m); } +void toggle_interested_in_alliance(sys::state& state, dcon::nation_id asker, dcon::nation_id target) { + payload p; + memset(&p, 0, sizeof(payload)); + p.type = command_type::toggle_interested_in_alliance; + p.source = asker; + p.data.diplo_action.target = target; + add_to_command_queue(state, p); +} +bool can_toggle_interested_in_alliance(sys::state& state, dcon::nation_id asker, dcon::nation_id target) { + if(asker == target) + return false; + return true; +} +void execute_toggle_interested_in_alliance(sys::state& state, dcon::nation_id asker, dcon::nation_id target) { + if(!can_toggle_interested_in_alliance(state, asker, target)) + return; + auto rel = state.world.get_unilateral_relationship_by_unilateral_pair(target, asker); + if(!rel) + rel = state.world.force_create_unilateral_relationship(target, asker); + state.world.unilateral_relationship_set_interested_in_alliance(rel, !state.world.unilateral_relationship_get_interested_in_alliance(rel)); +} + void state_transfer(sys::state& state, dcon::nation_id asker, dcon::nation_id target, dcon::state_definition_id sid) { payload p; memset(&p, 0, sizeof(payload)); @@ -4945,6 +4967,8 @@ bool can_perform_command(sys::state& state, payload& c) { return true; case command_type::toggle_mobilized_is_ai_controlled: return true; + case command_type::toggle_interested_in_alliance: + return can_toggle_interested_in_alliance(state, c.source, c.data.diplo_action.target); // common mp commands case command_type::chat_message: @@ -5326,7 +5350,10 @@ void execute_command(sys::state& state, payload& c) { case command_type::toggle_mobilized_is_ai_controlled: execute_toggle_mobilized_is_ai_controlled(state, c.source); break; - + case command_type::toggle_interested_in_alliance: + execute_toggle_interested_in_alliance(state, c.source, c.data.diplo_action.target); + break; + // common mp commands case command_type::chat_message: { diff --git a/src/gamestate/commands.hpp b/src/gamestate/commands.hpp index beecfb8c8..916b21102 100644 --- a/src/gamestate/commands.hpp +++ b/src/gamestate/commands.hpp @@ -103,6 +103,7 @@ enum class command_type : uint8_t { move_capital = 94, toggle_unit_ai_control = 95, toggle_mobilized_is_ai_controlled = 96, + toggle_interested_in_alliance = 97, // network notify_player_ban = 106, @@ -700,6 +701,9 @@ void ask_for_alliance(sys::state& state, dcon::nation_id asker, dcon::nation_id bool can_ask_for_alliance(sys::state& state, dcon::nation_id asker, dcon::nation_id target, bool ignore_cost = false); void execute_ask_for_alliance(sys::state& state, dcon::nation_id asker, dcon::nation_id target); +void toggle_interested_in_alliance(sys::state& state, dcon::nation_id asker, dcon::nation_id target); +bool can_toggle_interested_in_alliance(sys::state& state, dcon::nation_id asker, dcon::nation_id target); + void call_to_arms(sys::state& state, dcon::nation_id asker, dcon::nation_id target, dcon::war_id w); void execute_call_to_arms(sys::state& state, dcon::nation_id asker, dcon::nation_id target, dcon::war_id w); bool can_call_to_arms(sys::state& state, dcon::nation_id asker, dcon::nation_id target, dcon::war_id w, bool ignore_cost = false); diff --git a/src/gamestate/dcon_generated.txt b/src/gamestate/dcon_generated.txt index 05d4e0937..b88e201d0 100644 --- a/src/gamestate/dcon_generated.txt +++ b/src/gamestate/dcon_generated.txt @@ -3871,6 +3871,11 @@ relationship{ type{ bitfield } tag{ save } } + property{ + name{ interested_in_alliance } + type{ bitfield } + tag{ save } + } } relationship{ diff --git a/src/gamestate/system_state.hpp b/src/gamestate/system_state.hpp index 9d3b2b5f3..e65e6c23d 100644 --- a/src/gamestate/system_state.hpp +++ b/src/gamestate/system_state.hpp @@ -155,6 +155,7 @@ struct user_settings_s { message_response::standard_log,//army_built = 98, message_response::standard_log,//navy_built = 99, message_response::standard_popup,//bankruptcy = 100, + message_response::standard_popup,//entered_automatic_alliance = 101, }; uint8_t interesting_message_settings[int32_t(sys::message_setting_type::count)] = { message_response::standard_log,//revolt = 0, @@ -258,6 +259,7 @@ struct user_settings_s { message_response::ignore,//army_built = 98, message_response::ignore,//navy_built = 99, message_response::standard_popup,//bankruptcy = 100, + message_response::ignore,//entered_automatic_alliance = 101, }; uint8_t other_message_settings[int32_t(sys::message_setting_type::count)] = { message_response::ignore,//revolt = 0, @@ -361,6 +363,7 @@ struct user_settings_s { message_response::ignore,//army_built = 98, message_response::ignore,//navy_built = 99, message_response::standard_popup,//bankruptcy = 100, + message_response::ignore,//entered_automatic_alliance = 101, }; bool fow_enabled = false; map_label_mode map_label = map_label_mode::quadratic; diff --git a/src/gui/gui_message_settings_window.hpp b/src/gui/gui_message_settings_window.hpp index 06b991bbf..26123c884 100644 --- a/src/gui/gui_message_settings_window.hpp +++ b/src/gui/gui_message_settings_window.hpp @@ -109,6 +109,7 @@ inline std::string get_setting_text_key(int32_t type) { "amsg_army_built", // army_built "amsg_navy_built", // navy_built "amsg_bankruptcy", //bankruptcy + "amsg_entered_automatic_alliance",//entered_automatic_alliance }; return std::string{key_str[type]}; } diff --git a/src/gui/topbar_subwindows/gui_diplomacy_window.hpp b/src/gui/topbar_subwindows/gui_diplomacy_window.hpp index 69d571289..d0b72a470 100644 --- a/src/gui/topbar_subwindows/gui_diplomacy_window.hpp +++ b/src/gui/topbar_subwindows/gui_diplomacy_window.hpp @@ -564,6 +564,19 @@ class diplomacy_priority_button : public right_click_button_element_base { } }; +class diplomacy_country_interested_in_alliance : public checkbox_button { +public: + bool is_active(sys::state& state) noexcept override { + auto const n = retrieve(state, parent); + auto const rel = state.world.get_unilateral_relationship_by_unilateral_pair(n, state.local_player_nation); + return !state.world.unilateral_relationship_get_interested_in_alliance(rel); + } + void button_action(sys::state& state) noexcept override { + auto const n = retrieve(state, parent); + command::toggle_interested_in_alliance(state, state.local_player_nation, n); + } +}; + class diplomacy_country_info : public listbox_row_element_base { public: void on_create(sys::state& state) noexcept override { @@ -582,7 +595,14 @@ class diplomacy_country_info : public listbox_row_element_base } else if(name == "country_name") { return make_element_by_type>(state, id); } else if(name == "country_prio") { - return make_element_by_type(state, id); + auto ptr = make_element_by_type(state, id); + // + auto btn = make_element_by_type(state, "alice_interested_in_alliance"); + btn->base_data.position = ptr->base_data.position; + btn->base_data.position.x -= btn->base_data.size.x; + add_child_to_front(std::move(btn)); + // + return ptr; } else if(name == "country_boss_flag") { return make_element_by_type(state, id); } else if(name == "country_prestige") {