# Character Interactions for FP2 ################################################## # Share secrets # by Maxence Voleau ################################################## share_known_secrets_interaction = { icon = secret category = interaction_category_friendly common_interaction = yes send_name = SEND_PROPOSAL interface_priority = 120 ai_targets = { ai_recipients = dynasty } ai_frequency_by_tier = { barony = 0 county = 240 duchy = 180 kingdom = 180 empire = 180 hegemony = 180 } is_shown = { scope:actor = { # Standard check # Has access to the appropriate legacy perk. dynasty = { has_dynasty_perk = fp2_coterie_legacy_4 } # they are from the same house house = scope:recipient.house } } is_valid_showing_failures_only = { custom_tooltip = { text = share_known_secrets_interaction.tt.no_secrets_to_share # We try to keep the criteria vague to obfuscate things. scope:actor = { any_known_secret = { } } # Must have a secret to share OR = { scope:actor = { # At least one secret is unknown from recipient any_known_secret = { NOT = { is_known_by = scope:recipient } } } scope:recipient = { # At least one secret is unknown from actor any_known_secret = { NOT = { is_known_by = scope:actor } } } } } } desc = share_known_secrets_interaction_desc on_accept = { scope:actor = { if = { limit = { scope:recipient = { any_known_secret = { count >= 7 NOT = { is_known_by = scope:actor } } } } add_prestige = major_prestige_loss custom_description = { text = many_secrets_exchanged } } else_if = { limit = { scope:recipient = { any_known_secret = { count >= 3 NOT = { is_known_by = scope:actor } } } } add_prestige = medium_prestige_loss custom_description = { text = several_secrets_exchanged } } else = { add_prestige = minor_prestige_loss custom_description = { text = few_secrets_exchanged } } # Stress impact stress_impact = { honest = minor_stress_impact_gain just = minor_stress_impact_gain compassionate = minor_stress_impact_gain } } scope:recipient = { if = { limit = { scope:actor = { any_known_secret = { count >= 7 NOT = { is_known_by = scope:recipient } OR = { NOR = { secret_owner = scope:recipient AND = { exists = secret_target secret_target = scope:recipient } } scope:recipient = { OR = { has_trait = dull has_trait = intellect_bad has_trait = contrite } } } } } } add_prestige = major_prestige_loss custom_description = { text = many_secrets_exchanged } } else_if = { limit = { scope:actor = { any_known_secret = { count >= 3 NOT = { is_known_by = scope:recipient } OR = { NOR = { secret_owner = scope:actor AND = { exists = secret_target secret_target = scope:actor } } scope:actor = { OR = { has_trait = dull has_trait = intellect_bad has_trait = contrite } } } } } } add_prestige = medium_prestige_loss custom_description = { text = several_secrets_exchanged } } else = { add_prestige = minor_prestige_loss custom_description = { text = few_secrets_exchanged } } # Stress impact stress_impact = { honest = minor_stress_impact_gain just = minor_stress_impact_gain compassionate = minor_stress_impact_gain } } hidden_effect = { scope:recipient = { save_scope_as = END_TARGET } # This should make the loc work 2-ways, as notifs do not update themselves scope:actor = { if = { # Recipient has no secrets to share limit = { scope:recipient = { any_known_secret = { NOT = { is_known_by = scope:actor } OR = { NOR = { secret_owner = scope:recipient AND = { exists = secret_target secret_target = scope:recipient } } scope:recipient = { OR = { has_trait = dull has_trait = intellect_bad has_trait = contrite } } } count = 0 } } } send_interface_message = { type = event_intrigue_bad_with_text title = share_known_secrets_interaction_outcome_notif_title desc = share_known_secrets_interaction_recipient_had_no_secrets left_icon = scope:recipient } } else = { # They had secrets to share send_interface_message = { type = event_intrigue_good_with_text title = share_known_secrets_interaction_outcome_notif_title desc = share_known_secrets_interaction_desc_intro left_icon = scope:recipient scope:recipient = { every_known_secret = { limit = { NOT = { is_known_by = scope:actor } OR = { NOR = { secret_owner = scope:recipient AND = { exists = secret_target secret_target = scope:recipient } } scope:recipient = { OR = { has_trait = dull has_trait = intellect_bad has_trait = contrite } } } } reveal_to = scope:actor } } } } } scope:actor = { save_scope_as = END_TARGET } scope:recipient = { if = { # actor has no secrets to share limit = { scope:actor = { any_known_secret = { NOT = { is_known_by = scope:recipient } OR = { NOR = { secret_owner = scope:actor AND = { exists = secret_target secret_target = scope:actor } } scope:actor = { OR = { has_trait = dull has_trait = intellect_bad has_trait = contrite } } } count = 0 } } } send_interface_message = { type = event_intrigue_bad_with_text title = share_known_secrets_interaction_outcome_notif_title desc = share_known_secrets_interaction_recipient_had_no_secrets left_icon = scope:actor } } else = { # They had secrets to share send_interface_message = { type = event_intrigue_good_with_text title = share_known_secrets_interaction_outcome_notif_title desc = share_known_secrets_interaction_desc_intro left_icon = scope:actor scope:actor = { every_known_secret = { limit = { NOT = { is_known_by = scope:recipient } OR = { NOR = { secret_owner = scope:actor AND = { exists = secret_target secret_target = scope:actor } } scope:actor = { OR = { has_trait = dull has_trait = intellect_bad has_trait = contrite } } } } reveal_to = scope:recipient } hidden_effect = { add_prestige = major_prestige_loss } } } } } } # If we're a clan this interaction affects unity add_clan_unity_interaction_effect = { CHARACTER = scope:actor TARGET = scope:recipient VALUE = minor_unity_loss DESC = clan_unity_secret_sharing.desc REVERSE_NON_HOUSE_TARGET = no } } auto_accept = { custom_description = { text = "spending_hook" subject = scope:actor object = scope:recipient AND = { always = scope:hook scope:actor = { has_strong_hook = scope:recipient } } } } send_option = { is_valid = { scope:actor = { has_strong_hook = scope:recipient } } flag = hook localization = SCHEME_HOOK } should_use_extra_icon = { scope:actor = { has_strong_hook = scope:recipient } } extra_icon = "gfx/interface/icons/character_interactions/hook_icon.dds" send_options_exclusive = no ai_potential = { #Has access to the appropriate cultural parameter. AND = { exists = dynasty dynasty = { has_dynasty_perk = fp2_coterie_legacy_4 } } prestige > major_prestige_value } auto_accept = no ai_accept = { # AI should accept by default base = 10 modifier = { trigger = { always = scope:hook } add = 100 desc = SCHEME_WEAK_HOOK_USED } modifier = { trigger = { has_education_intrigue_trigger = yes } add = 20 desc = INTERACTION_INTRIGUE_EDUCATION } modifier = { add = -100 has_trait = honest desc = INTERACTION_HONEST } modifier = { add = -50 has_trait = just desc = INTERACTION_JUST } modifier = { add = -50 has_trait = paranoid desc = INTERACTION_PARANOID } modifier = { add = 100 has_trait = fickle desc = INTERACTION_FICKLE } modifier = { add = 100 has_trait = deceitful desc = INTERACTION_DECEITFUL } modifier = { add = 25 has_trait = ambitious desc = INTERACTION_AMBITIOUS } } ai_will_do = { base = 100 } } ################################################## # Propose Best Friendship # by Ewan Cowhig Croft ################################################## # Elevate a friendship to become a *best* friendship. propose_best_friendship_interaction = { interface_priority = 30 icon = icon_personal category = interaction_category_friendly common_interaction = yes desc = propose_best_friendship_interaction_desc greeting = positive notification_text = PROPOSE_BEST_FRIENDSHIP_NOTIFICATION popup_on_receive = yes ai_maybe = yes cooldown = { years = 5 } cooldown_against_recipient = { years = 10 } is_shown = { # Scope:actor needs to have a suitable CulTrad. scope:actor = { culture = { has_cultural_parameter = may_propose_best_friendship } } # Scope:actor needs to have scope:recipient as a friend. scope:actor = { has_relation_friend = scope:recipient } } is_valid_showing_failures_only = { # Both characters must be available adults. scope:actor = { is_available_adult = yes } scope:recipient = { is_available_adult = yes } # We can't do most of the standard checks for can_set_relation_best_friend_trigger, but we do the relevant ones individually. custom_tooltip = { text = propose_best_friendship_interaction.tt.already_best_friends scope:actor = { NOT = { has_relation_best_friend = scope:recipient } } } trigger_if = { limit = { NOT = { scope:actor = { has_relation_best_friend = scope:recipient } } } custom_tooltip = { text = propose_best_friendship_interaction.tt.actor_has_best_friend scope:actor = { num_of_relation_best_friend = 0 } } } trigger_if = { limit = { NOT = { scope:recipient = { has_relation_best_friend = scope:actor } } } custom_tooltip = { text = propose_best_friendship_interaction.tt.recipient_has_best_friend scope:recipient = { num_of_relation_best_friend = 0 } } } } on_accept = { # Notifications with most effects. scope:actor = { send_interface_toast = { type = event_toast_effect_good title = propose_best_friendship_interaction.accept.actor.tt left_icon = scope:recipient # Become best friends. show_as_tooltip = { set_relation_best_friend = scope:recipient } # Gain some strong opinion bonuses as a result. reverse_add_opinion = { target = scope:recipient modifier = friendliness_opinion opinion = 50 } # The hookening. ## Due to some weird order-of-operations stuff, we enclose this in an if statement. if = { limit = { NOT = { has_hook_of_type = { target = scope:recipient type = ritual_best_friend_hook } } can_add_hook = { target = scope:recipient type = ritual_best_friend_hook } } add_hook = { type = ritual_best_friend_hook target = scope:recipient } } } } scope:recipient = { send_interface_toast = { type = event_toast_effect_neutral title = propose_best_friendship_interaction.accept.recipient.tt left_icon = scope:actor # Become best friends. show_as_tooltip = { set_relation_best_friend = scope:actor } # Gain some strong opinion bonuses as a result. reverse_add_opinion = { target = scope:actor modifier = friendliness_opinion opinion = 50 } # The hookening part #2. ## Due to some weird order-of-operations stuff, we enclose this in an if statement. if = { limit = { NOT = { has_hook_of_type = { target = scope:actor type = ritual_best_friend_hook } } can_add_hook = { target = scope:actor type = ritual_best_friend_hook } } add_hook = { type = ritual_best_friend_hook target = scope:actor } } } } # Then we apply the actual friendship. hidden_effect = { scope:actor = { if = { limit = { NOT = { has_relation_best_friend = scope:recipient } } set_relation_best_friend = { reason = best_friend_sworn copy_reason = friend target = scope:recipient } } } } # If we're a clan this interaction affects unity add_clan_unity_interaction_effect = { CHARACTER = scope:actor TARGET = scope:recipient VALUE = minor_unity_gain DESC = clan_unity_oath_of_true_friendship.desc REVERSE_NON_HOUSE_TARGET = no } } on_decline = { # Scope:actor gains some stress over the whole ordeal. scope:actor = { send_interface_toast = { type = event_toast_effect_bad title = propose_best_friendship_interaction.decline.actor.tt left_icon = scope:recipient add_stress = medium_stress_gain } } # Scope:actor loses opinion of scope:recipient. scope:recipient = { send_interface_toast = { type = event_toast_effect_neutral title = propose_best_friendship_interaction.decline.recipient.tt left_icon = scope:actor scope:actor = { add_opinion = { target = scope:recipient modifier = hurt_opinion opinion = -50 } } } } # And set up a little hidden drama for later... hidden_effect = { scope:recipient = { if = { limit = { # We don't use the standard check for this, since they'll already be friends by definition, so the trigger would always return as false. # Instead, we just check to make sure they're not *already* potential rivals; this can happen regardless, so really we're just setting them up for drama if the friendship ever falters. NOT = { has_relation_potential_rival = scope:actor } } set_relation_potential_rival = scope:actor } } } # If we're a clan this interaction affects unity add_clan_unity_interaction_effect = { CHARACTER = scope:actor TARGET = scope:recipient VALUE = minor_unity_loss DESC = clan_unity_declined_true_friendship.desc REVERSE_NON_HOUSE_TARGET = no } } # AI ## Standard Acceptance stuff ai_accept = { # Try to make it 0 for most interactions base = 0 fp2_ritual_best_friendship_interactions_ai_accept_modifier = yes # People without the appropriate CulTrad don't quite *get* it. modifier = { add = -75 NOT = { culture = { has_cultural_parameter = may_propose_best_friendship } } desc = PROPOSE_BEST_FRIEND_OPINION_LACKING_CULTURAL_PARAMETER } } ## Performance-enhancement ai_potential = { is_imprisoned = no } ai_target_quick_trigger = { adult = yes } ai_targets = { ai_recipients = scripted_relations } ## Frequency ai_frequency_by_tier = { barony = 0 county = 72 duchy = 36 kingdom = 36 empire = 36 hegemony = 36 } ai_will_do = { base = -50 fp2_ritual_best_friendship_interactions_ai_chance_modifier = yes } } ################################################## # Re-Affirmed Best Friendship # by Ewan Cowhig Croft ################################################## # You've already got a best friend, but you feel you should have hooks on each other. reaffirm_best_friendship_interaction = { interface_priority = 30 icon = icon_personal category = interaction_category_friendly common_interaction = yes desc = reaffirm_best_friendship_interaction_desc greeting = positive notification_text = REAFFIRM_BEST_FRIENDSHIP_NOTIFICATION popup_on_receive = yes ai_maybe = yes cooldown = { years = 5 } cooldown_against_recipient = { years = 10 } is_shown = { # Scope:actor needs to have a suitable CulTrad. scope:actor = { culture = { has_cultural_parameter = may_propose_best_friendship } } # Scope:actor needs to have scope:recipient for their best friend. scope:actor = { has_relation_best_friend = scope:recipient } # Either friend lacks a strong hook on the other. NOR = { scope:actor = { has_strong_hook = scope:recipient } scope:recipient = { has_strong_hook = scope:actor } } } is_valid_showing_failures_only = { # Both characters must be available adults. scope:actor = { is_available_adult = yes } scope:recipient = { is_available_adult = yes } } on_accept = { scope:actor = { send_interface_toast = { type = event_toast_effect_good title = reaffirm_best_friendship_interaction.accept.actor.tt left_icon = scope:recipient # Pretty happy about the reaffirmation. reverse_add_opinion = { target = scope:recipient modifier = friendliness_opinion opinion = 25 } # The hookening. if = { limit = { NOT = { has_strong_hook = scope:recipient } } add_hook = { type = ritual_best_friend_hook target = scope:recipient } } } } scope:recipient = { send_interface_toast = { type = event_toast_effect_neutral title = reaffirm_best_friendship_interaction.accept.recipient.tt left_icon = scope:actor # Pretty happy about the reaffirmation. reverse_add_opinion = { target = scope:actor modifier = friendliness_opinion opinion = 25 } # The hookening part #2. if = { limit = { NOT = { has_strong_hook = scope:actor } } add_hook = { type = ritual_best_friend_hook target = scope:actor } } } } # If we're a clan this interaction affects unity add_clan_unity_interaction_effect = { CHARACTER = scope:actor TARGET = scope:recipient VALUE = minor_unity_gain DESC = clan_unity_friendship_is_magic.desc REVERSE_NON_HOUSE_TARGET = no } } on_decline = { # Scope:actor gains some stress over the whole ordeal. scope:actor = { send_interface_toast = { type = event_toast_effect_bad title = reaffirm_best_friendship_interaction.decline.actor.tt left_icon = scope:recipient # Actual effects handled in scope:recipient's toast. show_as_tooltip = { remove_relation_best_friend = scope:recipient } } } # Scope:actor loses opinion of scope:recipient. scope:recipient = { send_interface_toast = { type = event_toast_effect_neutral title = reaffirm_best_friendship_interaction.decline.recipient.tt left_icon = scope:actor remove_relation_best_friend = scope:actor } } # And set up a little hidden drama for later... hidden_effect = { scope:recipient = { if = { limit = { # We don't use the standard check for this, since they'll already be friends by definition, so the trigger would always return as false. # Instead, we just check to make sure they're not *already* potential rivals; this can happen regardless, so really we're just setting them up for drama if the friendship ever falters. NOT = { has_relation_potential_rival = scope:actor } } set_relation_potential_rival = scope:actor } } } # If we're a clan this interaction affects unity add_clan_unity_interaction_effect = { CHARACTER = scope:actor TARGET = scope:recipient VALUE = minor_unity_loss DESC = clan_unity_friendship_is_not_magic.desc REVERSE_NON_HOUSE_TARGET = no } } # AI ## Standard Acceptance stuff ai_accept = { # Try to make it 0 for most interactions base = 0 fp2_ritual_best_friendship_interactions_ai_accept_modifier = yes # People with the appropriate CulTrad understand that this is essentially required of them. modifier = { add = 50 culture = { has_cultural_parameter = may_propose_best_friendship } desc = REAFFIRM_BEST_FRIEND_OPINION_HAS_CULTURAL_PARAMETER } } ## Performance-enhancement ai_potential = { is_imprisoned = no } ai_target_quick_trigger = { adult = yes } ai_targets = { ai_recipients = scripted_relations } ## Frequency ai_frequency_by_tier = { barony = 0 county = 72 duchy = 36 kingdom = 36 empire = 36 hegemony = 36 } ai_will_do = { base = -50 fp2_ritual_best_friendship_interactions_ai_chance_modifier = yes } } ################################################## # Synergise Friendship # by Ewan Cowhig Croft ################################################## # Work together with your best friend to gain bonuses! synergise_friendship_interaction = { interface_priority = 30 icon = icon_personal category = interaction_category_friendly common_interaction = yes desc = synergise_friendship_interaction_desc greeting = positive notification_text = SYNERGISE_FRIENDSHIP_NOTIFICATION popup_on_receive = yes ai_maybe = yes cooldown = { years = 5 } cooldown_against_recipient = { years = 10 } is_shown = { # Scope:actor needs to have a suitable CulTrad. scope:actor = { culture = { has_cultural_parameter = may_select_friendship_synergy_bonus } } # Scope:actor needs to have scope:recipient for their best friend. scope:actor = { has_relation_best_friend = scope:recipient } } is_valid_showing_failures_only = { # Both characters must be available adults. scope:actor = { is_available_adult = yes } scope:recipient = { is_available_adult = yes } } on_accept = { # First, we send out some notifications. scope:actor = { send_interface_toast = { type = event_toast_effect_good title = synergise_friendship_interaction.accept.actor.tt left_icon = scope:recipient # Pretty happy about the reaffirmation. reverse_add_opinion = { target = scope:recipient modifier = friendliness_opinion opinion = 10 } # Show the bonuses. ## Hidden effect so that the modifiers don't show twice in the UI. hidden_effect = { show_as_tooltip = { synergise_friendship_interaction_actual_effect = yes } } } } scope:recipient = { send_interface_toast = { type = event_toast_effect_neutral title = synergise_friendship_interaction.accept.recipient.tt left_icon = scope:actor # Pretty happy about the reaffirmation. reverse_add_opinion = { target = scope:actor modifier = friendliness_opinion opinion = 10 } # Show the bonuses. ## Hidden effect so that the modifiers don't show twice in the UI. hidden_effect = { show_as_tooltip = { synergise_friendship_interaction_actual_effect = yes } } } } # Then remove any existing synergy modifiers they've got. scope:actor = { remove_every_best_friend_synergy_bonus_modifier_effect = yes } scope:recipient = { remove_every_best_friend_synergy_bonus_modifier_effect = yes } # Finally, calc the actual modifiers received. synergise_friendship_interaction_actual_effect = yes # If we're a clan this interaction affects unity add_clan_unity_interaction_effect = { CHARACTER = scope:actor TARGET = scope:recipient VALUE = minor_unity_gain DESC = clan_unity_synergized_friendship.desc REVERSE_NON_HOUSE_TARGET = no } } on_decline = { # Scope:actor gains some stress over the whole ordeal. scope:actor = { send_interface_toast = { type = event_toast_effect_bad title = synergise_friendship_interaction.decline.actor.tt left_icon = scope:recipient add_stress = minor_stress_gain } } # Scope:actor loses opinion of scope:recipient. scope:recipient = { send_interface_toast = { type = event_toast_effect_neutral title = synergise_friendship_interaction.decline.recipient.tt left_icon = scope:actor reverse_add_opinion = { target = scope:actor modifier = hurt_opinion opinion = -20 } } } # If we're a clan this interaction affects unity add_clan_unity_interaction_effect = { CHARACTER = scope:actor TARGET = scope:recipient VALUE = minor_unity_loss DESC = clan_unity_synergized_friendship_declined.desc REVERSE_NON_HOUSE_TARGET = no } } # Synergy Types ## Scope:actor's education send_option = { flag = synergy_bonus_actor localization = "SYNERGY_BONUS_ACTOR" } ## Scope:recipient's education send_option = { flag = synergy_bonus_recipient is_valid = { custom_description = { text = synergise_friendship_interaction_cannot_share_education NOT = { characters_have_same_education_group_trigger = { CHARACTER_1 = scope:actor CHARACTER_2 = scope:recipient } } } } localization = "SYNERGY_BONUS_RECIPIENT" } ## Scope:a mix of both educations send_option = { flag = synergy_bonus_mixed localization = "SYNERGY_BONUS_MIXED" } # AI ## Standard Acceptance stuff ai_accept = { # Try to make it 0 for most interactions base = 0 fp2_ritual_best_friendship_interactions_ai_accept_modifier = yes } ## Performance-enhancement ai_potential = { is_imprisoned = no } ai_target_quick_trigger = { adult = yes } ai_targets = { ai_recipients = scripted_relations } ## Frequency ai_frequency_by_tier = { barony = 0 county = 72 duchy = 36 kingdom = 36 empire = 36 hegemony = 36 } ai_will_do = { base = -50 fp2_ritual_best_friendship_interactions_ai_chance_modifier = yes } } ################################################## # Challenge to Chess # by Ewan Cowhig Croft ################################################## # Play someone at a game of chess, perhaps with a small wager. challenge_to_2p_chess_interaction = { interface_priority = 30 icon = icon_gaming category = interaction_category_friendly desc = challenge_to_2p_chess_interaction_desc common_interaction = no greeting = positive notification_text = CHALLENGE_TO_2P_CHESS_INTERACTION_NOTIFICATION ai_maybe = yes cooldown = { years = 1 } cooldown_against_recipient = { years = 10 } is_shown = { scope:actor = { # Actor needs to either have a CulTrad or be a fan of board games OR = { culture = { has_cultural_parameter = may_challenge_to_board_games } has_perk = befriend_perk has_character_modifier = fp3_chess_playing_monkey_modifier #addition from FP3 } # Plus be able to start & continue such a game generally. bg_can_start_board_game_trigger = yes # ... no, I'm sorry, you can't play yourself at board games. this != scope:recipient } } is_valid_showing_failures_only = { # Both characters must be available (adults or old-enough children) scope:actor = { is_available = yes can_start_board_game_eligibility_checks_trigger = yes } scope:recipient = { is_available = yes can_start_board_game_eligibility_checks_trigger = yes } # Neither of you can be currently engaged in a board game. scope:recipient = { custom_description = { text = fp2_bg_recipient_banned_from_board_games bg_can_start_board_game_is_scope_banned_checks_trigger = no } } #limit range for landless adventurers trigger_if = { limit = { scope:actor = { has_government = landless_adventurer_government } } #Has to be used instead of diplo range checks in laamp to landed interactions ep3_laamp_diplo_range_trigger = { TARGET = scope:recipient LAAMP = scope:actor } } } on_send = { # We want to set this up in advance to stop scope:actor from giving away a county for opinion that they've already wagered. if = { limit = { always = scope:chess_land } challenge_to_2p_chess_interaction_lock_in_actor_stake_land_effect = yes } # Plus lock in the game type. challenge_to_2p_chess_interaction_lock_in_game_type_effect = { GAME_TYPE_SETTER = scope:actor } } on_accept = { # Save gold & land stakes. if = { limit = { always = scope:chess_gold } save_scope_value_as = { name = bg_stake_gold value = challenge_to_chess_gold_change_value } } if = { limit = { always = scope:chess_land } # We check scope:actor's county in the on_send block to stop them sneakily giving the county away after they've staked it. show_as_tooltip = { challenge_to_2p_chess_interaction_lock_in_actor_stake_land_effect = yes } scope:recipient = { save_temporary_scope_as = ordering_char_temp ordered_held_title = { limit = { bg_stake_land_valid_neighbouring_county_to_trade_trigger = { NEIGHBOUR = scope:actor } } order_by = bg_stake_land_evaluate_appropriate_county_ordering_value save_scope_as = bg_stake_land_recipient set_variable = wagered_county } } } # Proceed with general set-up & preamble. scope:actor = { # Log scope:actor as having taken the interaction for the purposes of invalidation add_character_flag = taken_challenge_to_chess_interaction # Fire the actual first event for scope:actor. ## Sort some placeholder scopes so the UI doesn't freak out. show_as_tooltip = { challenge_to_2p_chess_interaction_lock_in_game_type_effect = { GAME_TYPE_SETTER = scope:actor } } ## Pachisi if = { limit = { scope:bg_interaction_game_type = flag:pachisi } configure_start_board_game_effect = { BG_INITIATOR = scope:actor BG_ATTACKER = scope:actor BG_DEFENDER = scope:recipient SYSTEM = pachisi LOCALE = random_nice_day OUTPUT_EVENT = perk_interaction.0121 INVALIDATION_EVENT = board_games.0021 } } ## Hnefatafl if = { limit = { scope:bg_interaction_game_type = flag:hnefatafl } configure_start_board_game_effect = { BG_INITIATOR = scope:actor BG_ATTACKER = scope:actor BG_DEFENDER = scope:recipient SYSTEM = hnefatafl LOCALE = random_nice_day OUTPUT_EVENT = perk_interaction.0121 INVALIDATION_EVENT = board_games.0021 } } ## Tabula if = { limit = { scope:bg_interaction_game_type = flag:tabula } configure_start_board_game_effect = { BG_INITIATOR = scope:actor BG_ATTACKER = scope:actor BG_DEFENDER = scope:recipient SYSTEM = tabula LOCALE = random_nice_day OUTPUT_EVENT = perk_interaction.0121 INVALIDATION_EVENT = board_games.0021 } } ## Go if = { limit = { scope:bg_interaction_game_type = flag:go } configure_start_board_game_effect = { BG_INITIATOR = scope:actor BG_ATTACKER = scope:actor BG_DEFENDER = scope:recipient SYSTEM = go LOCALE = sitting_room OUTPUT_EVENT = perk_interaction.0121 INVALIDATION_EVENT = board_games.0021 } } ## Fidchell if = { limit = { scope:bg_interaction_game_type = flag:fidchell } configure_start_board_game_effect = { BG_INITIATOR = scope:actor BG_ATTACKER = scope:actor BG_DEFENDER = scope:recipient SYSTEM = fidchell LOCALE = random_nice_day OUTPUT_EVENT = perk_interaction.0121 INVALIDATION_EVENT = board_games.0021 } } ## Chess if = { limit = { scope:bg_interaction_game_type = flag:chess } configure_start_board_game_effect = { BG_INITIATOR = scope:actor BG_ATTACKER = scope:actor BG_DEFENDER = scope:recipient SYSTEM = chess LOCALE = random_nice_day OUTPUT_EVENT = perk_interaction.0121 INVALIDATION_EVENT = board_games.0021 } } } # Notify that the game will start immediately. custom_tooltip = challenge_to_2p_chess_interaction.accept.game_commences.tt # Stakes. ## Friendlies bet opinion & stress. if = { limit = { always = scope:chess_friendly } show_as_tooltip = { random_list = { # You win. 50 = { show_chance = no desc = fp2_bg_interaction.winner.actor fp2_bg_stake_friendly_effect = { VICTOR = scope:actor LOSER = scope:recipient } } # You lose. 50 = { show_chance = no desc = fp2_bg_interaction.winner.recipient fp2_bg_stake_friendly_effect = { VICTOR = scope:recipient LOSER = scope:actor } } } } } ## Prestige bets capital. if = { limit = { always = scope:chess_prestige } show_as_tooltip = { random_list = { # You win. 50 = { show_chance = no desc = fp2_bg_interaction.winner.actor fp2_bg_stake_fame_effect = { VICTOR = scope:actor LOSER = scope:recipient } } # You lose. 50 = { show_chance = no desc = fp2_bg_interaction.winner.recipient fp2_bg_stake_fame_effect = { VICTOR = scope:recipient LOSER = scope:actor } } } } } ## Gold bets capital. if = { limit = { always = scope:chess_gold } show_as_tooltip = { random_list = { # You win. 50 = { show_chance = no desc = fp2_bg_interaction.winner.actor fp2_bg_stake_fortune_effect = { VICTOR = scope:actor LOSER = scope:recipient } } # You lose. 50 = { show_chance = no desc = fp2_bg_interaction.winner.recipient fp2_bg_stake_fortune_effect = { VICTOR = scope:recipient LOSER = scope:actor } } } } } ## Land bets a neighbouring title. if = { limit = { always = scope:chess_land } show_as_tooltip = { random_list = { # You win. 50 = { show_chance = no desc = fp2_bg_interaction.winner.actor fp2_bg_stake_titles_effect = { VICTOR = scope:actor } } # You lose. 50 = { show_chance = no desc = fp2_bg_interaction.winner.recipient fp2_bg_stake_titles_effect = { VICTOR = scope:recipient } } } } } # If we're a clan this interaction affects unity add_clan_unity_interaction_effect = { CHARACTER = scope:actor TARGET = scope:recipient VALUE = miniscule_unity_loss DESC = clan_unity_shatranj.desc REVERSE_NON_HOUSE_TARGET = no } } on_decline = { # Scope:actor is a little put out. scope:actor = { send_interface_toast = { type = event_toast_effect_bad title = challenge_to_2p_chess_interaction.decline.actor.tt left_icon = scope:recipient add_stress = minor_stress_gain } } # Scope:actor loses opinion of scope:recipient. scope:recipient = { send_interface_toast = { type = event_toast_effect_neutral title = challenge_to_2p_chess_interaction.decline.recipient.tt left_icon = scope:actor reverse_add_opinion = { target = scope:actor modifier = unfriendly_opinion opinion = -20 } } } # Failsafe: Ensure that all set variables are removed hidden_effect = { if = { limit = { exists = scope:bg_stake_land_recipient } scope:bg_stake_land_recipient = { remove_variable = wagered_county } } if = { limit = { exists = scope:bg_stake_land_actor } scope:bg_stake_land_actor = { remove_variable = wagered_county } } } # If we're a clan this interaction affects unity add_clan_unity_interaction_effect = { CHARACTER = scope:recipient TARGET = scope:actor VALUE = miniscule_unity_loss DESC = clan_unity_shatranj_decline.desc REVERSE_NON_HOUSE_TARGET = no } } # Wagers ## A friendly match send_option = { flag = chess_friendly localization = "CHESS_FRIENDLY" } ## Bet prestige send_option = { flag = chess_prestige localization = "CHESS_PRESTIGE" is_valid = { # Children should not be able to gamble with fame, but gold and land are fine scope:actor = { is_available_adult = yes } scope:recipient = { is_available_adult = yes } } } ## Bet gold send_option = { is_valid = { custom_tooltip = { scope:actor = { gold > minor_gold_value } text = bet_gold_actor_not_enough_gold } custom_tooltip = { scope:recipient = { gold > minor_gold_value } text = bet_gold_recipient_not_enough_gold } } flag = chess_gold localization = "CHESS_GOLD" } ## Bet land send_option = { # Only actual gaming nut cultures will bet something as serious as land. is_shown = { scope:actor = { culture = { has_cultural_parameter = may_wager_land_on_board_games } } scope:recipient = { culture = { has_cultural_parameter = may_wager_land_on_board_games } } } # But you need to have bordering land for it to work. is_valid = { custom_tooltip = { text = challenge_to_2p_chess_interaction.need_bordering_non_capital_domains.tt scope:actor = { any_held_title = { bg_stake_land_valid_neighbouring_county_to_trade_trigger = { NEIGHBOUR = scope:recipient } } } scope:recipient = { any_held_title = { bg_stake_land_valid_neighbouring_county_to_trade_trigger = { NEIGHBOUR = scope:actor } } } } } flag = chess_land localization = "CHESS_LAND" } # AI ## Standard Acceptance stuff ai_accept = { # Try to make it 0 for most interactions base = 0 # Weight up for personality values. ## Shy characters may not generally be sociable, but they're usually down for board games. ai_value_modifier = { who = scope:recipient trigger = { has_trait = shy } ai_boldness = { if = { limit = { scope:recipient = { NOT = { ai_boldness = 0 } } } value = 1 } } ai_sociability = { if = { limit = { scope:recipient = { NOT = { ai_honor = 0 } } } value = -0.5 } } } ## Otherwise, calc as normal. ai_value_modifier = { who = scope:recipient trigger = { NOT = { has_trait = shy } } ai_boldness = { if = { limit = { scope:recipient = { NOT = { ai_boldness = 0 } } } value = 1 } } ai_sociability = { if = { limit = { scope:recipient = { NOT = { ai_honor = 0 } } } value = 0.5 } } } # Weight up for opinion. opinion_modifier = { who = scope:recipient opinion_target = scope:actor multiplier = 0.5 desc = AI_OPINION_REASON } # Weight up for estimated skill. modifier = { add = { add = scope:recipient.martial add = scope:recipient.intrigue add = scope:recipient.learning # } desc = BG_OPINION_OWN_SKILL_ASSESSMENT } # Specific wager preferences. ## Friendlies: for folks who want a calm game with nothing more at stake than peace of mind. modifier = { add = 20 always = scope:chess_friendly # Exempt characters with traits that dislike low stakes. scope:recipient = { NOR = { has_trait = callous has_trait = greedy has_trait = arrogant } } desc = BG_OPINION_STAKES_ARE_LOW } ### Gregarious loves. modifier = { add = 40 scope:recipient = { has_trait = gregarious } always = scope:chess_friendly desc = BG_OPINION_FRIENDLY_TRAIT_GREGARIOUS } ### Humble loves. modifier = { add = 40 scope:recipient = { has_trait = humble } always = scope:chess_friendly desc = BG_OPINION_FRIENDLY_TRAIT_HUMBLE } ### Shy likes. modifier = { add = 20 scope:recipient = { has_trait = shy } always = scope:chess_friendly desc = BG_OPINION_FRIENDLY_TRAIT_SHY } ### Compassionate likes. modifier = { add = 20 scope:recipient = { has_trait = compassionate } always = scope:chess_friendly desc = BG_OPINION_FRIENDLY_TRAIT_COMPASSIONATE } ### Callous dislikes. modifier = { add = -20 scope:recipient = { has_trait = callous } always = scope:chess_friendly desc = BG_OPINION_FRIENDLY_TRAIT_CALLOUS } ### Greedy hates. modifier = { add = -40 scope:recipient = { has_trait = greedy } always = scope:chess_friendly desc = BG_OPINION_FRIENDLY_TRAIT_GREEDY } ### Arrogant hates. modifier = { add = -40 scope:recipient = { has_trait = arrogant } always = scope:chess_friendly desc = BG_OPINION_FRIENDLY_TRAIT_ARROGANT } ## Prestige: want a little more drama in your life without breaking the bank? Gamble your reputation! ### Brave loves. modifier = { add = 40 scope:recipient = { has_trait = brave } always = scope:chess_prestige desc = BG_OPINION_PRESTIGE_TRAIT_BRAVE } ### Arrogant loves. modifier = { add = 40 scope:recipient = { has_trait = arrogant } always = scope:chess_prestige desc = BG_OPINION_PRESTIGE_TRAIT_ARROGANT } ### Gregarious likes. modifier = { add = 20 scope:recipient = { has_trait = gregarious } always = scope:chess_prestige desc = BG_OPINION_PRESTIGE_TRAIT_GREGARIOUS } ### Ambitious likes. modifier = { add = 20 scope:recipient = { has_trait = ambitious } always = scope:chess_prestige desc = BG_OPINION_PRESTIGE_TRAIT_AMBITIOUS } ### Content dislikes. modifier = { add = -20 scope:recipient = { has_trait = content } always = scope:chess_prestige desc = BG_OPINION_PRESTIGE_TRAIT_CONTENT } ### Shy dislikes. modifier = { add = -20 scope:recipient = { has_trait = shy } always = scope:chess_prestige desc = BG_OPINION_PRESTIGE_TRAIT_SHY } ### Humble hates. modifier = { add = -40 scope:recipient = { has_trait = humble } always = scope:chess_prestige desc = BG_OPINION_PRESTIGE_TRAIT_HUMBLE } ### Craven hates. modifier = { add = -40 scope:recipient = { has_trait = craven } always = scope:chess_prestige desc = BG_OPINION_PRESTIGE_TRAIT_CRAVEN } ## Gold: what is life without risk? Play it bold or don't play at all! ### Profligate adores. modifier = { add = 60 scope:recipient = { has_trait = profligate } always = scope:chess_gold desc = BG_OPINION_GOLD_TRAIT_PROFLIGATE } ### Greedy loves. modifier = { add = 40 scope:recipient = { has_trait = greedy } always = scope:chess_gold desc = BG_OPINION_GOLD_TRAIT_GREEDY } ### Ambitious likes. modifier = { add = 20 scope:recipient = { has_trait = ambitious } always = scope:chess_gold desc = BG_OPINION_GOLD_TRAIT_AMBITIOUS } ### Generous likes - I mean, from their perspective, what does the money matter? modifier = { add = 20 scope:recipient = { has_trait = generous } always = scope:chess_gold desc = BG_OPINION_GOLD_TRAIT_GENEROUS } ### Lazy likes. modifier = { add = 20 scope:recipient = { has_trait = lazy } always = scope:chess_gold desc = BG_OPINION_GOLD_TRAIT_LAZY } ### Diligent hates. modifier = { add = -40 scope:recipient = { has_trait = diligent } always = scope:chess_gold desc = BG_OPINION_GOLD_TRAIT_DILIGENT } ## Land: you need to stop buying new board games, Jesse. You're way too into them. ### Profligate adores. modifier = { add = 60 scope:recipient = { has_trait = profligate } always = scope:chess_land desc = BG_OPINION_LAND_TRAIT_PROFLIGATE } ### Arbitrary loves. modifier = { add = 40 scope:recipient = { has_trait = arbitrary } always = scope:chess_land desc = BG_OPINION_LAND_TRAIT_ARBITRARY } ### Ambitious likes. modifier = { add = 20 scope:recipient = { has_trait = ambitious } always = scope:chess_land desc = BG_OPINION_LAND_TRAIT_AMBITIOUS } ### Brave likes. modifier = { add = 20 scope:recipient = { has_trait = brave } always = scope:chess_land desc = BG_OPINION_LAND_TRAIT_BRAVE } ### Craven dislikes. modifier = { add = -20 scope:recipient = { has_trait = craven } always = scope:chess_land desc = BG_OPINION_LAND_TRAIT_CRAVEN } ### Content dislikes. modifier = { add = -20 scope:recipient = { has_trait = content } always = scope:chess_land desc = BG_OPINION_LAND_TRAIT_CONTENT } ### Just loathes - this is *categorically* not how the feudal system, or really any form of loyalty, is supposed to work. modifier = { add = -60 scope:recipient = { has_trait = just } always = scope:chess_land desc = BG_OPINION_LAND_TRAIT_JUST } ### Greedy deliberately left off; they don't want to risk their own stuff but they *do* want to nab everyone else's. # Relationships ## Mildly positive relationships like to play against each other. modifier = { add = 20 scope:recipient = { has_any_mild_good_relationship_with_character_trigger = { CHARACTER = scope:actor } } desc = BG_OPINION_RELATIONSHIP_GOOD_MILD } ## Positive relationships like to play against each other. modifier = { add = 40 scope:recipient = { has_any_only_moderate_good_relationship_with_character_trigger = { CHARACTER = scope:actor } } desc = BG_OPINION_RELATIONSHIP_GOOD_MODERATE } ## Really positive relationships love to play against each other. modifier = { add = 60 scope:recipient = { has_any_best_good_relationship_with_character_trigger = { CHARACTER = scope:actor } } desc = BG_OPINION_RELATIONSHIP_GOOD_MAJOR } ## Negative relationships dislike playing each other... ### ... either mildly... modifier = { add = -20 scope:recipient = { has_any_mild_bad_relationship_with_character_trigger = { CHARACTER = scope:actor } NOT = { culture = { has_cultural_parameter = may_challenge_to_board_games } } } desc = BG_OPINION_RELATIONSHIP_BAD_MILD } ### ... moderately... modifier = { add = -40 scope:recipient = { has_any_only_moderate_bad_relationship_with_character_trigger = { CHARACTER = scope:actor } NOT = { culture = { has_cultural_parameter = may_challenge_to_board_games } } } desc = BG_OPINION_RELATIONSHIP_BAD_MODERATE } ### ... or majorly... modifier = { add = -60 scope:recipient = { has_any_worst_bad_relationship_with_character_trigger = { CHARACTER = scope:actor } NOT = { culture = { has_cultural_parameter = may_challenge_to_board_games } } } desc = BG_OPINION_RELATIONSHIP_BAD_MAJOR } ## ... unless they take their board games far too seriously, in which case, they're always down... ### ... either mildly... modifier = { add = 20 scope:recipient = { has_any_mild_bad_relationship_with_character_trigger = { CHARACTER = scope:actor } culture = { has_cultural_parameter = may_challenge_to_board_games } } desc = BG_OPINION_RELATIONSHIP_BAD_SRSGMR_MILD } ### ... moderately... modifier = { add = 40 scope:recipient = { has_any_only_moderate_bad_relationship_with_character_trigger = { CHARACTER = scope:actor } culture = { has_cultural_parameter = may_challenge_to_board_games } } desc = BG_OPINION_RELATIONSHIP_BAD_SRSGMR_MODERATE } ### ... or majorly. modifier = { add = 60 scope:recipient = { has_any_worst_bad_relationship_with_character_trigger = { CHARACTER = scope:actor } culture = { has_cultural_parameter = may_challenge_to_board_games } } desc = BG_OPINION_RELATIONSHIP_BAD_SRSGMR_MAJOR } # Apply tier differences. ## King -> Baron. modifier = { desc = AI_REFUSAL_RANK_DIFFERENCE scope:actor = { tier_difference = { target = scope:recipient value >= 4 } } add = 15 } ## Duke -> Baron. modifier = { desc = AI_REFUSAL_RANK_DIFFERENCE scope:actor = { tier_difference = { target = scope:recipient value = 3 } } add = 10 } ## Count -> Baron. modifier = { desc = AI_REFUSAL_RANK_DIFFERENCE scope:actor = { tier_difference = { target = scope:recipient value = 2 } } add = 5 } ## King <- Baron. modifier = { desc = AI_REFUSAL_RANK_DIFFERENCE scope:actor = { tier_difference = { target = scope:recipient value = -2 } } add = -10 } ## Duke <- Baron. modifier = { desc = AI_REFUSAL_RANK_DIFFERENCE scope:actor = { tier_difference = { target = scope:recipient value = -3 } } add = -20 } ## Count <- Baron. modifier = { desc = AI_REFUSAL_RANK_DIFFERENCE scope:actor = { tier_difference = { target = scope:recipient value <= -4 } } add = -30 } } ## Performance-enhancement ai_potential = { OR = { culture = { has_cultural_parameter = may_challenge_to_board_games } has_perk = befriend_perk } is_imprisoned = no } ai_target_quick_trigger = { adult = yes } # AI will only challenge adults ai_targets = { ai_recipients = scripted_relations max = 5 } ai_targets = { ai_recipients = family max = 10 } ai_targets = { ai_recipients = neighboring_rulers ai_recipients = peer_vassals max = 10 } ## Frequency ai_frequency_by_tier = { barony = 0 county = 360 duchy = 240 kingdom = 100 empire = 100 hegemony = 100 } ai_will_do = { base = -50 # Everyone likes to play boardgames with people they like opinion_modifier = { opinion_target = scope:recipient trigger = { NOT = { culture = { has_cultural_parameter = may_challenge_to_board_games } } } } # Boardgame nerds like to challenge people they dislike... opinion_modifier = { opinion_target = scope:recipient trigger = { culture = { has_cultural_parameter = may_challenge_to_board_games } opinion = { target = scope:recipient value < 0 } } multiplier = -1 } # ...but they ALSO like to play with people they like opinion_modifier = { opinion_target = scope:recipient trigger = { culture = { has_cultural_parameter = may_challenge_to_board_games } opinion = { target = scope:recipient value > 0 } } } # If you are my rival and my culture likes to play board games, I'll see you as a good opponent. modifier = { add = 50 scope:actor = { has_relation_rival = scope:recipient culture = { has_cultural_parameter = may_challenge_to_board_games } } } # Aaaaand boredom. modifier = { add = 10 scope:actor.days_of_continuous_peace >= 365 } modifier = { add = 10 scope:actor.days_of_continuous_peace >= 730 } modifier = { add = 10 scope:actor.days_of_continuous_peace >= 1095 } modifier = { add = 10 scope:actor.days_of_continuous_peace >= 1460 } modifier = { add = 10 scope:actor.days_of_continuous_peace >= 1825 } # Plus if scope:actor isn't at all interesting to scope:recipient, then tell them to just sit quietly. modifier = { factor = 0 scope:recipient = { NOR = { is_of_major_or_minor_interest_trigger = { CHARACTER = scope:actor } highest_held_title_tier >= tier_duchy sub_realm_size >= 4 } } } } } ################################################## # Purchase Truce # by Ewan Cowhig Croft ################################################## # Wars are expensive, so why not purchase a little peace preemptively? purchase_truce_interaction = { interface_priority = 30 category = interaction_category_diplomacy common_interaction = yes desc = purchase_truce_interaction_desc icon = icon_retreat greeting = positive notification_text = PURCHASE_TRUCE_NOTIFICATION popup_on_receive = yes ai_maybe = yes cooldown = { years = 5 } cooldown_against_recipient = { years = 10 } is_shown = { scope:actor != scope:recipient # Scope:actor needs to either be involved in certain struggle types or else have a specific perk. scope:actor = { is_landless_adventurer = no # If scope:recipient is a nomad and the actor is not, this is always available; otherwise, # scope:actor needs to either be involved in certain struggle types or else have a specific perk. OR = { AND = { scope:recipient = { government_has_flag = government_is_nomadic } NOT = { government_has_flag = government_is_nomadic } } fp2_purchase_truce_interaction_soft_requirements_trigger = yes } # if you are not independent you should not be able to purchase truce with other fellow vassals only trigger_if = { limit = { top_liege != this } top_liege = scope:recipient.top_liege } } # Scope:recipient must be landed, and neither over or under scope:actor. scope:recipient = { is_playable_character = yes NOR = { any_liege_or_above = { this = scope:actor } any_vassal_or_below = { this = scope:actor } } } } is_valid_showing_failures_only = { # Scope:actor must be an available (adult or child). scope:actor = { gold >= pt_sum_small_value is_available = yes } # Scope:recipient must be at least available. scope:recipient = { is_available = yes } # Make sure that scope:actor is going into this with a clean, no-recent/active/forbidden hostilities mindset. scope:actor = { NOR = { # Involved characters can't be on opposite sides in an active war. is_at_war_with = scope:recipient # Allied characters aren't allowed to do this because it _should_ be redundant. Unless you're planning something. Which you shouldn't announce like that. is_allied_to = scope:recipient # And we should just disallow anyone who already has a truce with you, even though I guess you might technically want to replace it. any_truce_holder = { this = scope:recipient } } } #limit range for landless adventurers trigger_if = { limit = { scope:actor = { has_government = landless_adventurer_government } } #Has to be used instead of diplo range checks in laamp to landed interactions ep3_laamp_diplo_range_trigger = { TARGET = scope:recipient LAAMP = scope:actor } } } on_accept = { # Notifications with most effects. scope:actor = { send_interface_toast = { type = event_toast_effect_good title = purchase_truce_interaction.accept.actor.tt left_icon = scope:recipient show_as_tooltip = { purchase_truce_interaction_work_out_truce_days_effect = { TARGET = scope:recipient } } } show_as_tooltip = { purchase_truce_interaction_work_out_purchase_cost_effect = yes } # Outside of the notification, since we'll send a separate one anyway, we want to point out the catalyst activation (if relevant). show_as_tooltip = { purchase_truce_interaction_activate_catalyst_effect = yes } } scope:recipient = { send_interface_toast = { type = event_toast_effect_neutral title = purchase_truce_interaction.accept.recipient.tt left_icon = scope:actor show_as_tooltip = { purchase_truce_interaction_work_out_truce_days_effect = { TARGET = scope:actor } } } } # Then we apply the actual truce. hidden_effect = { scope:actor = { purchase_truce_interaction_work_out_truce_days_effect = { TARGET = scope:recipient } purchase_truce_interaction_activate_catalyst_effect = yes # Variable used for checking if we should apply the "Recently Waged War" ai behavior in ai_acceptance modifiers, specifically in the Offer Vassalization interaction if = { limit = { always = scope:pt_sum_small } add_to_bought_truce_list = { TARGET = scope:recipient DAYS = purchase_truce_interaction_truce_days_small_value } } else_if = { limit = { always = scope:pt_sum_large } add_to_bought_truce_list = { TARGET = scope:recipient DAYS = purchase_truce_interaction_truce_days_large_value } } else = { add_to_bought_truce_list = { TARGET = scope:recipient DAYS = purchase_truce_interaction_truce_days_medium_value } } } purchase_truce_interaction_work_out_purchase_cost_effect = yes } # If we're a clan this interaction affects unity add_clan_unity_interaction_effect = { CHARACTER = scope:actor TARGET = scope:recipient VALUE = minor_unity_gain DESC = clan_unity_purchased_truce.desc REVERSE_NON_HOUSE_TARGET = no } } on_decline = { # Scope:actor gains some stress over the whole ordeal. scope:actor = { send_interface_toast = { type = event_toast_effect_bad title = purchase_truce_interaction.decline.actor.tt left_icon = scope:recipient add_stress = minor_stress_gain } } # Scope:actor loses opinion of scope:recipient. scope:recipient = { send_interface_toast = { type = event_toast_effect_neutral title = purchase_truce_interaction.decline.recipient.tt left_icon = scope:actor reverse_add_opinion = { target = scope:actor modifier = warmonger_opinion } } } # If we're a clan this interaction affects unity add_clan_unity_interaction_effect = { CHARACTER = scope:recipient TARGET = scope:actor VALUE = minor_unity_loss DESC = clan_unity_purchased_truce_refusal.desc REVERSE_NON_HOUSE_TARGET = no } } # Send Options ## Small Sum send_option = { is_shown = { always = yes } is_valid = { scope:actor = { gold >= pt_sum_small_value } } flag = pt_sum_small localization = "PT_SUM_SMALL" } ## Medium Sum send_option = { is_shown = { # We use the most expensive of scope:actor or scope:recipient's income, so we check both. scope:actor = { can_make_expensive_purchase_trigger = { PRICE = scope:actor.purchase_truce_interaction_medium_sum } can_make_expensive_purchase_trigger = { PRICE = scope:recipient.purchase_truce_interaction_medium_sum } } } is_valid = { scope:actor = { gold >= pt_sum_medium_value } } flag = pt_sum_medium starts_enabled = { always = yes } localization = "PT_SUM_MEDIUM" } ## Large Sum send_option = { is_shown = { # We use the most expensive of scope:actor or scope:recipient's income, so we check both. scope:actor = { can_make_expensive_purchase_trigger = { PRICE = scope:actor.purchase_truce_interaction_major_sum } can_make_expensive_purchase_trigger = { PRICE = scope:recipient.purchase_truce_interaction_major_sum } } } is_valid = { scope:actor = { gold >= pt_sum_large_value } } flag = pt_sum_large localization = "PT_SUM_LARGE" } # AI ## Standard Acceptance stuff ai_accept = { # Try to make it 0 for most interactions. base = 0 # Struggle modifier = { trigger_if = { limit = { scope:recipient = { any_character_struggle = { involvement = involved } } scope:actor = { any_character_struggle = { involvement = involved } } } } trigger_else = { always = no } add = { value = 0 if = { limit = { scope:recipient = { any_character_struggle = { phase_has_catalyst = catalyst_sign_truce_outside_war } has_character_flag = agenda_towards_escalation } } add = -50 } else_if = { limit = { scope:recipient = { any_character_struggle = { phase_has_catalyst = catalyst_sign_truce_outside_war } } } add = 100 } } desc = AI_STRUGGLE_INTENT } # Factor up or down based on the sum offered. ## Small. modifier = { add = -10 always = scope:pt_sum_small desc = PT_AMOUNT_OF_GOLD_OFFERED } ## Medium. modifier = { add = 25 always = scope:pt_sum_medium desc = PT_AMOUNT_OF_GOLD_OFFERED } ## Large. modifier = { add = 75 always = scope:pt_sum_large desc = PT_AMOUNT_OF_GOLD_OFFERED } ## Plus a bit of base-line acceptance if the AI's coffers are currently pretty anaemic. modifier = { add = 30 gold <= scope:recipient.yearly_character_income desc = PT_COULD_USE_SOME_POCKET_MONEY } # AI take opinion into account, but reduced so they'll at least occasionally accept from folks they dislike. opinion_modifier = { who = scope:recipient opinion_target = scope:actor multiplier = 0.5 desc = AI_OPINION_REASON } # Greedy AI like gold. modifier = { add = { value = ai_greed multiply = 2 } ai_greed >= 1 desc = AI_VALUE_MODIFIER_GREED } # Boldness always plays a factor. modifier = { add = { value = ai_boldness multiply = -0.5 } NOT = { ai_boldness = 0 } desc = AI_VALUE_MODIFIER_BOLDNESS } # Ambitious AI like freedom. modifier = { add = -50 has_trait = ambitious desc = PT_AI_LIKES_FREEDOM_TO_WAR_REASON } # AI who are in debt will take whatever windfalls they can. modifier = { add = { value = debt_level # Our first rank is 0, so we add one to always get a positive number. add = 1 multiply = 10 } debt_level >= 0 desc = PT_AI_IS_IN_DEBT } # Pacifist AI are happy to avoid war. modifier = { add = 25 faith = { has_doctrine_parameter = pacifist_opinion_active } desc = PT_AI_IS_PACIFIST_FAITH } modifier = { add = 25 culture = { has_cultural_parameter = reduced_cost_for_conversion_to_pacifist_faith } desc = PT_AI_IS_PACIFIST_CULTURE } # War likeliness. ## This is primarily intended to mitigate conquest, invasion, and religious CBs, so we don't account for them. ## Scope:recipient has some claim to scope:actor's lands. modifier = { add = -20 any_claim = { count = 1 exists = holder holder = scope:actor } desc = PT_AI_PERSONALLY_CLAIMS_YOUR_LAND } ## Scope:recipient has decent claim to scope:actor's lands. modifier = { add = -40 OR = { any_claim = { count >= 2 exists = holder holder = scope:actor } any_claim = { count = 1 exists = holder holder = scope:actor save_temporary_scope_as = claim_temp scope:recipient = { has_strong_claim_on = scope:claim_temp } } } desc = PT_AI_PERSONALLY_CLAIMS_YOUR_LAND } ## Scope:recipient has strong claim to scope:actor's lands. modifier = { add = -60 any_claim = { count >= 2 exists = holder holder = scope:actor save_temporary_scope_as = claim_temp scope:recipient = { has_strong_claim_on = scope:claim_temp } } desc = PT_AI_PERSONALLY_CLAIMS_YOUR_LAND } ## Scope:recipient can de jure grab your land. ### Dukes don't take much. modifier = { add = -30 highest_held_title_tier = tier_duchy purchase_truce_interaction_recipient_can_de_jure_war_actor_trigger = yes scope:actor = { any_sub_realm_county = { count >= 3 any_this_title_or_de_jure_above = { holder = scope:actor } } } desc = PT_AI_DE_JURE_CLAIMS_YOUR_LAND } ### Kings need a lot more. modifier = { add = -30 highest_held_title_tier = tier_kingdom purchase_truce_interaction_recipient_can_de_jure_war_actor_trigger = yes scope:actor = { any_sub_realm_county = { count >= 10 any_this_title_or_de_jure_above = { holder = scope:actor } } } desc = PT_AI_DE_JURE_CLAIMS_YOUR_LAND } ### Emperors take quite a bit to get fussed. modifier = { add = -30 highest_held_title_tier = tier_empire purchase_truce_interaction_recipient_can_de_jure_war_actor_trigger = yes scope:actor = { any_sub_realm_county = { count >= 20 any_this_title_or_de_jure_above = { holder = scope:actor } } } desc = PT_AI_DE_JURE_CLAIMS_YOUR_LAND } # Relative power. ## Scope:actor has far fewer levies than scope:recipient. modifier = { add = -30 scope:actor.max_military_strength <= scope:recipient.purchase_truce_interaction_recipient_far_weaker_value desc = PT_AI_RECIPIENT_IS_MUCH_STRONGER } ## Scope:actor has fewer levies than scope:recipient. modifier = { add = -10 scope:actor.max_military_strength > scope:recipient.purchase_truce_interaction_recipient_far_weaker_value scope:actor.max_military_strength <= scope:recipient.purchase_truce_interaction_recipient_somewhat_weaker_value desc = PT_AI_RECIPIENT_IS_SOMEWHAT_STRONGER } ## Scope:actor has roughly equal levies with scope:recipient. modifier = { add = 10 scope:actor.max_military_strength > scope:recipient.purchase_truce_interaction_recipient_somewhat_weaker_value scope:actor.max_military_strength <= scope:recipient.purchase_truce_interaction_recipient_somewhat_stronger_value desc = PT_AI_RECIPIENT_IS_ROUGHLY_EQUAL } ## Scope:actor has more levies than scope:recipient. modifier = { add = 25 scope:actor.max_military_strength > scope:recipient.purchase_truce_interaction_recipient_somewhat_stronger_value scope:actor.max_military_strength <= scope:recipient.purchase_truce_interaction_recipient_far_stronger_value desc = PT_AI_RECIPIENT_IS_SOMEWHAT_WEAKER } ## Scope:actor has far more levies than scope:recipient. modifier = { add = 50 scope:actor.max_military_strength > scope:recipient.purchase_truce_interaction_recipient_far_stronger_value desc = PT_AI_RECIPIENT_IS_MUCH_WEAKER } } ## Performance-enhancement ai_potential = { is_playable_character = yes is_at_war = no is_imprisoned = no # Matches the regular minimum triggers. OR = { any_character_struggle = { involvement = involved } has_perk = defensive_measures_perk } # Might actually be wurf evaluating the costs. can_make_expensive_purchase_trigger = { PRICE = purchase_truce_interaction_small_sum } } ai_target_quick_trigger = { adult = yes } ai_targets = { ai_recipients = neighboring_rulers ai_recipients = peer_vassals max = 10 } ## Frequency ai_frequency_by_tier = { barony = 0 county = 60 duchy = 60 kingdom = 0 empire = 0 hegemony = 0 } ai_will_do = { base = 0 # Some personalities & traits just don't want to fight. ## Cravens (who aren't also ambitious). modifier = { add = 25 has_trait = craven NOT = { has_trait = ambitious } } ## Those with chronically low boldness (who aren't also ambitious). modifier = { add = 25 ai_boldness <= very_high_negative_ai_value NOT = { has_trait = ambitious } } ## Pacifists. modifier = { add = 25 faith = { has_doctrine_parameter = pacifist_opinion_active } } modifier = { add = 25 culture = { has_cultural_parameter = reduced_cost_for_conversion_to_pacifist_faith } } ## Wrathful or ambitious characters don't like to bother. modifier = { add = -25 has_trait = ambitious } modifier = { add = -25 has_trait = wrathful } ## Arbitrary characters don't get truces to begin with. modifier = { add = -50 has_trait = arbitrary } ## We deliberately avoid warlike faiths *not* doing it; there's plenty of examples of such bought truces amongst these faiths, so we let them keep at it if they match other criteria. # Various gradients of having money to burn. ## You've got a goodly amount stashed away. modifier = { add = 50 can_make_expensive_purchase_trigger = { PRICE = purchase_truce_interaction_medium_sum } } ## You're somewhat loaded. modifier = { add = 50 can_make_expensive_purchase_trigger = { PRICE = purchase_truce_interaction_major_sum } } ## You're absolutely loaded. modifier = { add = 50 can_make_expensive_purchase_trigger = { PRICE = purchase_truce_interaction_massive_sum } } # Force checks. ## Try to buy truces from somewhat stronger realms... modifier = { add = 50 scope:recipient.max_military_strength >= scope:actor.purchase_truce_interaction_recipient_somewhat_stronger_value } ## ... and much stronger realms. modifier = { add = 50 scope:recipient.max_military_strength >= scope:actor.purchase_truce_interaction_recipient_far_stronger_value } # Struggle modifier = { scope:recipient = { any_character_struggle = { involvement = involved } } scope:actor = { any_character_struggle = { involvement = involved } } add = { value = 0 if = { limit = { scope:actor = { any_character_struggle = { phase_has_catalyst = catalyst_sign_truce_outside_war } has_character_flag = agenda_towards_escalation } } add = -50 } else_if = { limit = { scope:actor = { any_character_struggle = { phase_has_catalyst = catalyst_sign_truce_outside_war } } } add = 100 } } } # Finally, calculate factors. ## Only buy truces from weaker/roughly-equal realms if you're craven have been at war forever. modifier = { factor = 0 max_military_strength <= scope:actor.purchase_truce_interaction_recipient_somewhat_weaker_value NOR = { has_trait = craven days_of_continuous_war <= 3650 } } ## Never buy a truce from someone who actually can't declare war on you. modifier = { factor = 0 scope:recipient = { NOT = { has_any_cb_on = scope:actor } } } ## Don't buy truces from people who are likely going to be dead soon, or if you yourself will die soon, since they'll be wasted. modifier = { factor = 0 OR = { health <= poor_health scope:recipient = { health <= poor_health } } } } } ################################################## # Incite Revolts # by Maxence Voleau ################################################## Updated for FP3 incite_revolts_interaction = { interface_priority = 30 category = interaction_category_hostile common_interaction = yes desc = incite_revolts_interaction_desc icon = faction greeting = positive auto_accept = yes cost = { gold = { add = { value = 0 # Gold spent will provide 10x levies, e.g. 25 provides 250 - not automated yet if = { limit = { scope:small_investment_in_revolt = yes } add = 25 } if = { limit = { scope:medium_investment_in_revolt = yes } add = 75 } if = { limit = { scope:high_investment_in_revolt = yes } add = 200 } } } } is_shown = { scope:recipient != scope:actor OR = { scope:actor = { OR = { government_has_flag = government_is_landless_adventurer government_has_flag = government_is_landless_minority } OR = { any_claim = { holder = scope:recipient } has_relation_rival = scope:recipient } } # Only available during Opportunity, Hostility and Tension phases scope:actor = { any_character_struggle = { involvement = involved has_struggle_phase_parameter = unlocks_incite_revolts_interaction # Can only target involved is_secondary_character_involvement_involved_trigger = { CHAR = scope:recipient } } } AND = { scope:actor = { has_trait = fp3_struggle_detractor any_character_struggle = { involvement = involved is_struggle_type = persian_struggle } } scope:recipient = { any_character_struggle = { is_struggle_type = persian_struggle involvement = involved } } } scope:actor.domicile ?= { has_domicile_parameter = can_use_incite_revolts } } } is_valid_showing_failures_only = { custom_description = { text = at_least_one_county_with_neutral_negative_opinion scope:recipient = { any_sub_realm_county = { count > 0 holder = scope:recipient county_opinion < 0 NOR = { has_county_modifier = small_investment_in_revolt_modifier has_county_modifier = medium_investment_in_revolt_modifier has_county_modifier = high_investment_in_revolt_modifier } } } } } can_send = { custom_tooltip = { text = must_select_an_investment OR = { scope:actor = { is_ai = yes } # Temporary until we get a code fix scope:small_investment_in_revolt = yes scope:medium_investment_in_revolt = yes scope:high_investment_in_revolt = yes } } } send_options_exclusive = yes # Small investment send_option = { flag = small_investment_in_revolt localization = small_investment } # Medium investment send_option = { flag = medium_investment_in_revolt localization = medium_investment starts_enabled = { always = yes } } # High investment send_option = { flag = high_investment_in_revolt localization = high_investment } on_accept = { # Select the random county hidden_effect = { scope:recipient = { random_sub_realm_county = { limit = { NOR = { has_county_modifier = small_investment_in_revolt_modifier has_county_modifier = medium_investment_in_revolt_modifier has_county_modifier = high_investment_in_revolt_modifier } county_opinion < 0 holder = scope:recipient } weight = { base = 1 # More likely to finance county of your own Faith or Culture modifier = { add = 2 OR = { faith = scope:actor.faith culture = scope:actor.culture } } # More likely to finance county prone to trigger populist factions modifier = { add = 5 NAND = { faith = scope:recipient.faith culture = scope:recipient.culture } } # More likely to finance county bordering your Realm modifier = { add = 5 any_neighboring_county = { holder = scope:actor } } } save_scope_as = chosen_county } } } scope:actor = { stress_impact = { just = medium_stress_impact_gain honest = medium_stress_impact_gain trusting = medium_stress_impact_gain greedy = minor_stress_impact_gain } if = { limit = { scope:actor = { OR = { has_relation_rival = scope:recipient has_relation_nemesis = scope:recipient } } } stress_impact = { vengeful = medium_stress_impact_loss } } if = { limit = { scope:actor = { is_vassal_of = scope:recipient } } stress_impact = { ambitious = medium_stress_impact_loss } } } # FP3 Polish (Hugo) scope:actor = { duel = { skill = intrigue value = scope:recipient.intrigue 10 = { # Failure desc = incite_revolts_interaction_notif_failure compare_modifier = { value = scope:duel_value multiplier = -1.5 } show_as_tooltip = { if = { limit = { scope:small_investment_in_revolt = yes } custom_tooltip = apply_small_investment_in_revolt_on_random_county } else_if = { limit = { scope:medium_investment_in_revolt = yes } custom_tooltip = apply_medium_investment_in_revolt_on_random_county } else_if = { limit = { scope:high_investment_in_revolt = yes } custom_tooltip = apply_high_investment_in_revolt_on_random_county } reverse_add_opinion = { target = scope:recipient modifier = angry_opinion opinion = -50 } } hidden_effect = { send_interface_toast = { type = event_toast_effect_bad title = incite_revolts_interaction_result.tt left_icon = scope:chosen_county right_icon = scope:recipient scope:chosen_county = { if = { limit = { scope:small_investment_in_revolt = yes } add_county_modifier = { modifier = small_investment_in_revolt_modifier years = 10 } } else_if = { limit = { scope:medium_investment_in_revolt = yes } add_county_modifier = { modifier = medium_investment_in_revolt_modifier years = 10 } } else_if = { limit = { scope:high_investment_in_revolt = yes } add_county_modifier = { modifier = high_investment_in_revolt_modifier years = 10 } } } reverse_add_opinion = { target = scope:recipient modifier = angry_opinion opinion = -50 } hidden_effect = { scope:recipient = { progress_towards_rival_effect = { CHARACTER = scope:actor REASON = fp2_progress_towards_rival_funded_revolt_against_me OPINION = 0 } } } } } } 10 = { # Success desc = incite_revolts_interaction_notif_success compare_modifier = { value = scope:duel_value multiplier = 1.5 } show_as_tooltip = { if = { limit = { scope:small_investment_in_revolt = yes } custom_tooltip = apply_small_investment_in_revolt_on_random_county } else_if = { limit = { scope:medium_investment_in_revolt = yes } custom_tooltip = apply_medium_investment_in_revolt_on_random_county } else_if = { limit = { scope:high_investment_in_revolt = yes } custom_tooltip = apply_high_investment_in_revolt_on_random_county } } hidden_effect = { send_interface_toast = { type = event_toast_effect_good title = incite_revolts_interaction_result.tt left_icon = scope:chosen_county scope:chosen_county = { if = { limit = { scope:small_investment_in_revolt = yes } add_county_modifier = { modifier = small_investment_in_revolt_modifier years = 10 } } else_if = { limit = { scope:medium_investment_in_revolt = yes } add_county_modifier = { modifier = medium_investment_in_revolt_modifier years = 10 } } else_if = { limit = { scope:high_investment_in_revolt = yes } add_county_modifier = { modifier = high_investment_in_revolt_modifier years = 10 } } } } } } } } # for landless adventurers, add the county to a variable list to unlock a unique cb scope:actor = { if = { limit = { OR = { government_has_flag = government_is_landless_adventurer government_has_flag = government_is_landless_minority } } laamp_rewards_apply_criminal_xp_effect = { TRACK = bandit XP_MIN = gallowsbait_xp_minor_gain XP_MAX = gallowsbait_xp_medium_gain } add_to_variable_list = { name = war_supported_counties_list target = scope:chosen_county } } } # If we're a clan this interaction affects unity add_clan_unity_interaction_effect = { CHARACTER = scope:actor TARGET = scope:recipient VALUE = medium_unity_loss DESC = clan_unity_forment_revolt.desc REVERSE_NON_HOUSE_TARGET = no } } ai_frequency_by_tier = { barony = 0 county = 120 duchy = 60 kingdom = 60 empire = 60 hegemony = 60 } ai_potential = { short_term_gold >= medium_gold_value OR = { any_character_struggle = { has_struggle_phase_parameter = unlocks_incite_revolts_interaction involvement = involved OR = { is_struggle_phase = struggle_iberia_phase_opportunity is_struggle_phase = struggle_iberia_phase_hostility } } any_character_struggle = { is_struggle_type = persian_struggle involvement = involved } domicile ?= { has_domicile_parameter = can_use_incite_revolts } } } ai_targets = { # For the AI, we limit it to neighboring_rulers ai_recipients = neighboring_rulers } ai_will_do = { base = -50 # Let's limit it to specific character to avoid pure chaos ############### ## BASE ############### # ai values modifier = { ai_vengefulness > 0 add = ai_vengefulness } modifier = { add = { value = ai_compassion multiply = -1 } } modifier = { add = { value = ai_honor multiply = -1 } } # intrigue skill points modifier = { add = { value = intrigue multiply = 3 } } # diff faith modifier = { add = 25 faith != scope:recipient.faith } # diff culture modifier = { add = 25 NOT = { culture = { OR = { this = scope:recipient.culture cultural_acceptance = { target = scope:recipient.culture value >= 90 } } } } } ############### ## TRAITS ############### # schemer modifier = { add = 25 has_trait = schemer } # intrigue education modifier = { add = 25 OR = { has_trait = education_intrigue_1 has_trait = education_intrigue_2 has_trait = education_intrigue_3 has_trait = education_intrigue_4 } } ################ ## RELATIONSHIP ################ # more likely to do it against rival or nemesis modifier = { add = 50 scope:recipient = { OR = { has_relation_rival = scope:actor has_relation_nemesis = scope:actor } } } # boost against liege for Ambitious modifier = { add = 50 scope:actor = { has_trait = ambitious is_vassal_of = scope:recipient } } # never target your friends modifier = { add = -1000 scope:recipient = { OR = { has_relation_friend = scope:actor has_relation_lover = scope:actor has_relation_soulmate = scope:actor has_relation_best_friend = scope:actor } } } } } ################################################## # Contract Assistance # by Joe Parkin ################################################## contract_assistance_interaction = { category = interaction_category_diplomacy interface_priority = 15 common_interaction = yes interface = interfere_in_war special_interaction = interfere_in_war_interaction popup_on_receive = yes pause_on_receive = yes ai_maybe = yes desc = contract_assistance_interaction_desc icon = icon_gold greeting = positive notification_text = contract_assistance_interaction_notification cooldown_against_recipient = { years = 5 } is_shown = { # Actor is Involved in Struggle scope:actor = { NOT = { government_has_flag = government_is_herder } OR = { any_character_struggle = { involvement = involved has_struggle_phase_parameter = unlocks_contract_assistance_interaction } culture = { has_cultural_parameter = unlocks_contract_assistance } OR = { government_has_flag = government_is_landless_adventurer government_has_flag = government_is_landless_minority } } } # Recipient is Involved in Struggle, at war, and not at war with Actor scope:recipient = { trigger_if = { limit = { scope:actor = { any_character_struggle = { involvement = involved has_struggle_phase_parameter = unlocks_contract_assistance_interaction } } } any_character_struggle = { involvement = involved has_struggle_phase_parameter = unlocks_contract_assistance_interaction } } is_at_war = yes NOR = { this = scope:actor is_at_war_with = scope:actor } } } has_valid_target = { exists = scope:target } has_valid_target_showing_failures_only = { scope:target = { is_war_leader = scope:recipient } } is_valid_showing_failures_only = { scope:recipient = { # Cannot demand gold from allies NOT = { is_allied_to = scope:actor } # Cannot rejoin a war you decided to leave trigger_if = { limit = { any_character_war = { has_variable_list = left_voluntarily } } custom_tooltip = { text = laamp_war_change_sides_interaction.left_voluntarily is_target_in_variable_list = { name = left_voluntarily target = scope:actor } } } } # Recipient is not in (any) war against your liege(s) trigger_if = { limit = { exists = scope:actor.liege } custom_description = { text = join_war_interaction_recipient_warring_with_my_liege subject = scope:recipient scope:actor = { NOT = { any_liege_or_above = { is_at_war_with = scope:recipient } } } } } # Cannot join wars with raised armies scope:actor = { has_raised_armies = no trigger_if = { limit = { has_government = landless_adventurer_government } custom_tooltip = { text = reinforce_soldiers_any_regiment_tt maa_regiments_count >= 1 } } } # Can only contract one war at a time custom_tooltip = { text = contract_assistance_war_already_contracted_tt scope:actor = { NOT = { has_variable = owed_contract_assistance_war } } } # Adventurers can't join wars in places they're exiled from. custom_tooltip = { text = the_wake_1 NOT = { is_laamp_exiled_from_province_trigger = { PROVINCE = scope:recipient.capital_province LAAMP = scope:actor } } } # Sensible restrictions to keep CulTrads from making this OP. scope:recipient = { custom_tooltip = { text = contract_assistance_tier_too_high_tt OR = { highest_held_title_tier = tier_county highest_held_title_tier >= scope:actor.highest_held_title_tier sub_realm_size >= scope:actor.sub_realm_size } } } scope:actor = { NOT = { highest_held_title_tier >= tier_empire } } } can_be_picked = { # Recipient is war leader in chosen war scope:target = { is_war_leader = scope:recipient # Cannot contract against allies trigger_if = { limit = { any_war_attacker = { this = scope:recipient } } NOT = { any_war_defender = { is_allied_to = scope:actor } } } trigger_else = { NOT = { any_war_attacker = { is_allied_to = scope:actor } } } # not already in target war custom_description = { text = join_war_interaction_already_in_target_war NOR = { any_war_attacker = { this = scope:actor } any_war_defender = { this = scope:actor } } } } # Liege checks can_join_war_liege_vassal_check_trigger = { WARRIOR = scope:recipient JOINER = scope:actor } } is_highlighted = { scope:actor = { has_realm_law = camp_purpose_mercenaries } } on_accept = { # Add Actor to Recipient's war scope:target = { hidden_effect = { set_called_to = scope:actor } if = { limit = { is_attacker = scope:recipient } add_attacker = scope:actor } else = { add_defender = scope:actor } } # Actor effects scope:actor = { save_scope_as = contract_assistance_helper set_variable = { name = owed_contract_assistance_war value = scope:target } set_variable = { name = owed_contract_assistance_contribution value = offer_assistance_interaction_war_contribution_value } set_variable = { name = owed_contract_assistance_gold value = scope:recipient.offer_assistance_interaction_gold_value } stress_impact = { craven = medium_stress_impact_gain shy = minor_stress_impact_gain } # Struggle Catalyst if = { limit = { # Verify if vassal used to be independent any_character_struggle = { involvement = involved activate_struggle_catalyst_secondary_character_involvement_involved_trigger = { CATALYST = catalyst_join_war_as_assisant CHAR = scope:recipient } } } every_character_struggle = { involvement = involved limit = { activate_struggle_catalyst_secondary_character_involvement_involved_trigger = { CATALYST = catalyst_join_war_as_assisant CHAR = scope:recipient } } activate_struggle_catalyst = { catalyst = catalyst_join_war_as_assisant character = scope:actor } } } } # Recipient effects scope:recipient = { stress_impact = { greedy = medium_stress_impact_gain arrogant = medium_stress_impact_gain } custom_tooltip = contract_assistance_interaction_condition_tt show_as_tooltip = { pay_short_term_gold = { target = scope:actor gold = offer_assistance_interaction_gold_value } } } # If we're a clan this interaction affects unity add_clan_unity_interaction_effect = { CHARACTER = scope:actor TARGET = scope:recipient VALUE = medium_unity_loss DESC = clan_unity_contract_assistance.desc REVERSE_NON_HOUSE_TARGET = no } } on_decline = { # Refusal notification scope:actor = { trigger_event = char_interaction.0236 } # If we're a clan this interaction affects unity add_clan_unity_interaction_effect = { CHARACTER = scope:recipient TARGET = scope:actor VALUE = minor_unity_gain DESC = clan_unity_contract_assistance_decline.desc REVERSE_NON_HOUSE_TARGET = no } } ai_accept = { base = 0 # Reluctant to spend money without good reason # Recipient already winning war modifier = { add = -50 trigger_if = { limit = { exists = scope:target } scope:target = { fp2_struggle_contract_assistance_war_winning_trigger = yes } } trigger_else = { any_character_war = { count = all # So predicted negative modifiers are treated seperately fp2_struggle_contract_assistance_war_winning_trigger = yes } } desc = OA_AI_WINNING_WAR_REASON } # Recipient losing war modifier = { add = 50 trigger_if = { limit = { exists = scope:target } scope:target = { fp2_struggle_contract_assistance_war_losing_trigger = yes } } trigger_else = { any_character_war = { fp2_struggle_contract_assistance_war_losing_trigger = yes } } desc = OA_AI_LOSING_WAR_REASON } # Recipient already significantly outnumbers enemy modifier = { add = -50 trigger_if = { limit = { exists = scope:target } scope:target = { fp2_struggle_contract_assistance_war_outnumbering_trigger = yes } } trigger_else = { any_character_war = { count = all # So predicted negative modifiers are treated seperately fp2_struggle_contract_assistance_war_outnumbering_trigger = yes } } desc = OA_AI_OUTNUMBER_ENEMY_REASON } # Recipient is outnumbered modifier = { add = 50 trigger_if = { limit = { exists = scope:target } scope:target = { fp2_struggle_contract_assistance_war_outnumbered_minor_trigger = yes NOT = { fp2_struggle_contract_assistance_war_outnumbered_trigger = yes } } } trigger_else = { any_character_war = { fp2_struggle_contract_assistance_war_outnumbered_minor_trigger = yes NOT = { fp2_struggle_contract_assistance_war_outnumbered_trigger = yes } } } desc = OA_AI_OUTNUMBERED_MINOR_REASON } # Recipient is very outnumbered modifier = { add = 125 trigger_if = { limit = { exists = scope:target } scope:target = { fp2_struggle_contract_assistance_war_outnumbered_trigger = yes } } trigger_else = { any_character_war = { fp2_struggle_contract_assistance_war_outnumbered_trigger = yes } } desc = OA_AI_OUTNUMBERED_REASON } # Recipient has low cash modifier = { add = { value = -50 if = { limit = { gold < 0 } add = -100 } if = { limit = { debt_level >= 2 } add = -200 } if = { # Very generous or vengeful characters *will* make poor decisions limit = { OR = { ai_greed <= -50 ai_vengefulness >= 50 } } multiply = 0.5 } } gold < offer_assistance_interaction_gold_value desc = OA_AI_CANNOT_AFFORD_REASON } # Recipient has a lot of cash modifier = { add = { value = 25 if = { limit = { gold >= { value = offer_assistance_interaction_gold_value multiply = 2 } } add = 50 } if = { limit = { gold >= { value = offer_assistance_interaction_gold_value multiply = 3 } } add = 50 } } gold >= offer_assistance_interaction_gold_value desc = OA_AI_EXTRA_GOLD_REASON } # Actor's troops would be little help modifier = { add = -50 trigger_if = { limit = { exists = scope:target } scope:target = { fp2_struggle_contract_assistance_war_insufficient_trigger = yes } } trigger_else = { any_character_war = { count = all # So predicted negative modifiers are treated seperately fp2_struggle_contract_assistance_war_insufficient_trigger = yes } } desc = OA_AI_FEW_TROOPS_REASON } # Recipient is fighting a defensive war modifier = { add = 25 trigger_if = { limit = { exists = scope:target } scope:target.casus_belli.primary_defender = scope:recipient } trigger_else = { scope:recipient = { any_character_war = { primary_defender = scope:recipient } } } desc = OA_AI_DEFENSIVE_WAR_REASON } # Recipient is not interested in help for certain wars modifier = { add = -300 exists = scope:target scope:target = { OR = { using_cb = peasant_war using_cb = fp2_border_raid } } desc = OA_AI_UNINTERESTED_WAR_REASON } modifier = { add = { value = scope:actor.martial multiply = 2 } scope:actor = { martial >= 12 } desc = OA_AI_MARTIAL_REASON } modifier = { add = -50 scope:actor = { has_character_flag = fp2_contract_assistance_failure } desc = OA_AI_FAILURE_REASON } # Opinion Factor opinion_modifier = { who = scope:recipient opinion_target = scope:actor multiplier = 0.25 desc = AI_OPINION_REASON } modifier = { add = { value = ai_greed multiply = -0.2 } ai_greed <= 0.5 desc = AI_VALUE_MODIFIER_GREED } modifier = { add = { value = ai_boldness multiply = -0.2 } NOT = { ai_boldness = 0 } desc = AI_VALUE_MODIFIER_BOLDNESS } modifier = { add = 50 desc = camp_purpose_mercenaries_reason scope:actor = { has_realm_law = camp_purpose_mercenaries } } # Allegiances # fp2_contracting_ally_modifier = { # WARMONGER = scope:recipient # WARJOINER = scope:actor # } } ai_potential = { is_imprisoned = no is_at_war = no ai_boldness >= -25 current_military_strength >= 500 } ai_target_quick_trigger = { adult = yes } ai_targets = { ai_recipients = neighboring_rulers } ai_set_target = { scope:recipient = { ordered_character_war = { #We offer our services for the war where the character is losing the most limit = { is_war_leader = prev NOR = { any_war_attacker = { this = scope:actor } any_war_defender = { this = scope:actor } } save_temporary_scope_as = target can_join_war_liege_vassal_check_trigger = { WARRIOR = scope:recipient JOINER = scope:actor } } order_by = { value = 0 add = { if = { limit = { any_war_attacker = { this = scope:recipient } } subtract = attacker_war_score } else = { subtract = defender_war_score } } } save_scope_as = target } } } ai_targets = { ai_recipients = peer_vassals } # We need a quite high frequency as wars do not last forever ai_frequency_by_tier = { barony = 0 county = 24 duchy = 24 kingdom = 12 empire = 12 hegemony = 12 } ai_will_do = { base = 0 modifier = { # Increase chance if recipient is losing a war trigger_if = { limit = { exists = scope:target } scope:target = { fp2_struggle_contract_assistance_war_losing_trigger = yes } } add = 25 } modifier = { # Increase chance with amount of gold of recipient over interaction cost factor = offer_assistance_interaction_gold_modifier_value } modifier = { # Increase chance if likes recipient more than enemy scope:actor = { save_temporary_opinion_value_as = { name = contract_assistance_actor_opinion target = scope:recipient } } trigger_if = { limit = { exists = scope:target } scope:target = { any_war_participant = { is_leader_in_war = scope:target this != scope:recipient reverse_opinion = { target = scope:actor value < scope:contract_assistance_actor_opinion } } } } add = 25 } modifier = { # Increase chance for family scope:recipient = { OR = { dynasty = scope:actor.dynasty is_consort_of = scope:actor } } add = 25 } modifier = { # Decrease chance if army is small trigger_if = { limit = { exists = scope:target } scope:target = { fp2_struggle_contract_assistance_war_insufficient_trigger = yes } } add = -50 } modifier = { # Increase chance for rivalry trigger_if = { limit = { exists = scope:target } scope:target = { any_war_participant = { is_leader_in_war = scope:target this != scope:recipient has_relation_rival = scope:actor } } } add = 25 } # Higher chance to target a human player modifier = { scope:recipient = { is_ai = no } factor = 2 } } } ################################################## # Request Contract Assistance # by Maxence Voleau ################################################## request_contract_assistance_interaction = { category = interaction_category_diplomacy interface_priority = 15 common_interaction = yes interface = call_ally special_interaction = call_ally_interaction popup_on_receive = yes pause_on_receive = yes ai_maybe = yes desc = request_contract_assistance_interaction_desc icon = icon_gold greeting = positive notification_text = request_contract_assistance_interaction_notification cooldown_against_recipient = { years = 5 } is_shown = { # Actor is Involved in Struggle scope:actor = { any_character_struggle = { involvement = involved has_struggle_phase_parameter = unlocks_contract_assistance_interaction } is_at_war = yes NOR = { this = scope:recipient is_at_war_with = scope:recipient } } # Recipient is Involved in Struggle, at war, and not at war with Actor scope:recipient = { any_character_struggle = { involvement = involved has_struggle_phase_parameter = unlocks_contract_assistance_interaction } } } has_valid_target = { exists = scope:target } has_valid_target_showing_failures_only = { scope:target = { is_war_leader = scope:actor # Cannot contract against allies trigger_if = { limit = { any_war_attacker = { this = scope:recipient } } NOT = { any_war_defender = { is_allied_to = scope:actor } } } trigger_else = { NOT = { any_war_attacker = { is_allied_to = scope:actor } } } } # Adventurers can't join wars in places they're exiled from. trigger_if = { limit = { scope:actor = { top_liege != this } } custom_tooltip = { text = the_wake_1 NOT = { is_laamp_exiled_from_province_trigger = { PROVINCE = scope:actor.capital_province LAAMP = scope:recipient } } } } } is_valid_showing_failures_only = { scope:recipient = { # Cannot demand gold from allies NOT = { is_allied_to = scope:actor } } # Actor is not in (any) war against Recipient's liege(s) trigger_if = { limit = { exists = scope:recipient.liege } custom_description = { text = join_war_interaction_recipient_warring_with_my_liege subject = scope:actor scope:recipient = { NOT = { any_liege_or_above = { is_at_war_with = scope:actor } } } } } # Cannot join wars with raised armies scope:recipient = { has_raised_armies = no } # Can only contract one war at a time custom_tooltip = { text = contract_assistance_war_already_contracted_tt scope:recipient = { NOT = { has_variable = owed_contract_assistance_war } } } } can_be_picked = { # Recipient is war leader in chosen war scope:target = { is_war_leader = scope:actor # not already in target war custom_description = { text = join_war_interaction_already_in_target_war NOR = { any_war_attacker = { this = scope:recipient } any_war_defender = { this = scope:recipient } } } } # Liege checks can_join_war_liege_vassal_check_trigger = { WARRIOR = scope:actor JOINER = scope:recipient } } on_accept = { # Add Actor to Recipient's war scope:target = { hidden_effect = { set_called_to = scope:recipient } if = { limit = { is_attacker = scope:actor } add_attacker = scope:recipient } else = { add_defender = scope:recipient } } # Actor effects scope:recipient = { save_scope_as = contract_assistance_helper set_variable = { name = owed_contract_assistance_war value = scope:target } set_variable = { name = owed_contract_assistance_contribution value = offer_assistance_interaction_war_contribution_value } set_variable = { name = owed_contract_assistance_gold value = offer_assistance_interaction_gold_value } stress_impact = { craven = medium_stress_impact_gain shy = minor_stress_impact_gain } # Struggle Catalyst if = { limit = { # Verify if vassal used to be independent any_character_struggle = { involvement = involved activate_struggle_catalyst_secondary_character_involvement_involved_trigger = { CATALYST = catalyst_join_war_as_assisant CHAR = scope:recipient } } } every_character_struggle = { involvement = involved limit = { activate_struggle_catalyst_secondary_character_involvement_involved_trigger = { CATALYST = catalyst_join_war_as_assisant CHAR = scope:recipient } } activate_struggle_catalyst = { catalyst = catalyst_join_war_as_assisant character = scope:recipient } } } } # Recipient effects scope:actor = { stress_impact = { greedy = medium_stress_impact_gain arrogant = medium_stress_impact_gain } custom_tooltip = request_contract_assistance_interaction_condition_tt show_as_tooltip = { pay_short_term_gold = { target = scope:recipient gold = offer_assistance_interaction_gold_value } } } # If we're a clan this interaction affects unity add_clan_unity_interaction_effect = { CHARACTER = scope:actor TARGET = scope:recipient VALUE = medium_unity_loss DESC = clan_unity_request_assistance.desc REVERSE_NON_HOUSE_TARGET = no } } on_decline = { # Refusal notification scope:actor = { trigger_event = char_interaction.0236 } # If we're a clan this interaction affects unity add_clan_unity_interaction_effect = { CHARACTER = scope:recipient TARGET = scope:actor VALUE = minor_unity_gain DESC = clan_unity_request_assistance_decline.desc REVERSE_NON_HOUSE_TARGET = no } } ai_accept = { base = 0 # Reluctant to spend money without good reason # Recipient has low cash modifier = { add = { value = 25 if = { limit = { gold < 0 } add = { value = 25 multiply = debt_level } } if = { # Very generous or vengeful characters *will* make poor decisions limit = { OR = { ai_greed <= -50 ai_vengefulness >= 50 } } multiply = 0.5 } } desc = AI_VALUE_MODIFIER_GREED } # Recipient has a lot of cash modifier = { add = { value = -25 if = { limit = { gold >= { value = offer_assistance_interaction_gold_value multiply = 2 } } add = -50 } if = { limit = { gold >= { value = offer_assistance_interaction_gold_value multiply = 3 } } add = -50 } } gold >= offer_assistance_interaction_gold_value desc = OA_AI_EXTRA_GOLD_REASON } # Recipient is not interested in help for certain wars modifier = { add = -500 exists = scope:target scope:target = { OR = { using_cb = peasant_war using_cb = fp2_border_raid } } desc = OA_AI_UNINTERESTED_WAR_REASON } modifier = { add = { value = scope:actor.martial multiply = 2 } scope:actor = { martial >= 12 } desc = OA_AI_MARTIAL_REASON } modifier = { add = -50 scope:recipient = { has_character_flag = fp2_contract_assistance_failure } desc = OA_AI_FAILURE_REASON } # Opinion Factor opinion_modifier = { who = scope:recipient opinion_target = scope:actor multiplier = 0.25 desc = AI_OPINION_REASON } modifier = { add = { value = ai_greed multiply = 0.2 } ai_greed <= 0.5 desc = AI_VALUE_MODIFIER_GREED } modifier = { add = { value = ai_boldness multiply = 0.2 } NOT = { ai_boldness = 0 } desc = AI_VALUE_MODIFIER_BOLDNESS } # Allegiances fp2_contracting_ally_modifier = { WARMONGER = scope:actor WARJOINER = scope:recipient } } ai_potential = { # the AI cannot use it for now so let's block it is_imprisoned = no is_at_war = no gold >= ai_war_chest_desired_gold_value } ai_target_quick_trigger = { adult = yes } ai_targets = { ai_recipients = neighboring_rulers } ai_set_target = { scope:actor = { ordered_character_war = { #We offer our services for the war where the character is losing the most limit = { is_war_leader = prev NOR = { any_war_attacker = { this = scope:recipient } any_war_defender = { this = scope:recipient } } save_temporary_scope_as = target can_join_war_liege_vassal_check_trigger = { WARRIOR = scope:actor JOINER = scope:recipient } } order_by = { value = 0 add = { if = { limit = { any_war_attacker = { this = scope:actor } } subtract = attacker_war_score } else = { subtract = defender_war_score } } } save_scope_as = target } } } ai_targets = { ai_recipients = peer_vassals } ai_frequency_by_tier = { barony = 0 county = 48 duchy = 36 kingdom = 36 empire = 36 hegemony = 0 } ai_will_do = { base = 0 modifier = { # AI is losing the war trigger_if = { limit = { exists = scope:target } scope:target = { trigger_if = { limit = { scope:actor = { is_attacker_in_war = prev } } defender_war_score >= offer_assistance_interaction_already_losing_value } trigger_else = { attacker_war_score >= offer_assistance_interaction_already_losing_value } } } add = 15 } modifier = { # Increase chance for asking family scope:recipient = { OR = { dynasty = scope:actor.dynasty is_consort_of = scope:actor } } factor = 2 } modifier = { # Decrease chance if army is small trigger_if = { limit = { exists = scope:target } scope:target = { trigger_if = { limit = { scope:recipient = { is_attacker_in_war = prev } } scope:actor.max_military_strength < war_defender_total_strength_tenth_value } trigger_else = { scope:actor.max_military_strength < war_attacker_total_strength_tenth_value } } } add = -50 } modifier = { # Increase chance for rivalry trigger_if = { limit = { exists = scope:target } scope:target = { any_war_participant = { is_leader_in_war = scope:target this != scope:actor has_relation_rival = scope:recipient } } } add = 25 } modifier = { # AI is extremely rich short_term_gold >= ai_war_chest_desired_gold_value add = 50 } } } ################################################## # Enforce Truce # by Joe Parkin ################################################## enforce_truce_interaction = { category = interaction_category_diplomacy interface_priority = 30 common_interaction = yes interface = interfere_in_war special_interaction = interfere_in_war_interaction popup_on_receive = yes desc = enforce_truce_interaction_desc icon = icon_retreat greeting = positive notification_text = enforce_truce_interaction_notification cooldown = { years = 5 } is_shown = { OR = { # During the Struggle AND = { scope:actor = { any_character_struggle = { involvement = involved has_struggle_phase_parameter = unlocks_enforce_truces_interaction } primary_title.tier >= tier_duchy } scope:recipient = { any_character_struggle = { involvement = involved has_struggle_phase_parameter = unlocks_enforce_truces_interaction } tier_difference = { target = scope:actor value <= 0 } } } # Comrpomise ending AND = { scope:actor = { primary_title.tier >= tier_duchy exists = house house = { has_house_modifier = fp2_struggle_compromise_house_reward_modifier } } scope:recipient = { # Primary title in Iberia exists = house house = { has_house_modifier = fp2_struggle_compromise_house_reward_modifier } tier_difference = { target = scope:actor value <= 0 } } } } } is_valid_showing_failures_only = { scope:recipient = { is_at_war = yes trigger_if = { limit = { scope:actor = { any_character_struggle = { involvement = involved has_struggle_phase_parameter = unlocks_enforce_truces_interaction is_secondary_character_involvement_involved_trigger = { CHAR = scope:recipient } } } } any_character_struggle = { involvement = involved has_struggle_phase_parameter = unlocks_enforce_truces_interaction } } trigger_else = { exists = house house = { has_house_modifier = fp2_struggle_compromise_house_reward_modifier } } custom_tooltip = { text = fp2_enforce_truce_liege_or_independent_tt OR = { top_liege = this top_liege = scope:actor.top_liege any_character_war = { primary_attacker = { NOR = { this = scope:recipient this = scope:actor } OR = { top_liege = this top_liege = scope:actor.top_liege } } } any_character_war = { primary_defender = { NOR = { this = scope:recipient this = scope:actor } OR = { top_liege = this top_liege = scope:actor.top_liege } } } } } } } can_be_picked = { # Recipient is war leader in chosen war exists = scope:target scope:target = { is_war_leader = scope:recipient is_civil_war = no NOT = { using_cb = fp2_border_raid } trigger_if = { limit = { scope:recipient = { any_character_struggle = { involvement = involved } } } trigger_if = { limit = { primary_attacker = scope:recipient } primary_defender = { fp2_struggle_enforce_truce_war_leader_trigger = yes } } trigger_else = { primary_attacker = { fp2_struggle_enforce_truce_war_leader_trigger = yes } } } trigger_else = { scope:recipient = { capital_county.title_province = { geographical_region = world_europe_west_iberia } } } } } on_accept = { # End war and apply opinion/stress if = { limit = { exists = scope:target } scope:target = { primary_attacker = { save_scope_as = truce_1 } primary_defender = { save_scope_as = truce_2 } } show_as_tooltip = { scope:truce_1 = { add_prestige = minor_prestige_loss } scope:truce_2 = { add_prestige = minor_prestige_loss } } scope:actor = { fp2_enforce_truce_opinion_effect = yes # Best format for interaction interface show_as_tooltip = { scope:truce_1 = { add_truce_one_way = { character = scope:truce_2 years = fp2_enforce_truce_duration_value name = TRUCE_ENFORCE_TRUCE } } scope:truce_2 = { add_truce_one_way = { character = scope:truce_1 years = fp2_enforce_truce_duration_value name = TRUCE_ENFORCE_TRUCE } } } custom_tooltip = fp2_enforce_truce_peacemaker_tt hidden_effect = { add_truce_one_way = { character = scope:target.primary_attacker years = fp2_enforce_truce_duration_value name = TRUCE_ENFORCE_TRUCE } add_truce_one_way = { character = scope:target.primary_defender years = fp2_enforce_truce_duration_value name = TRUCE_ENFORCE_TRUCE } # Best format for toast send_interface_message = { type = event_truce_neutral title = enforce_truce_interaction_actor_toast left_icon = scope:truce_1 right_icon = scope:truce_2 show_as_tooltip = { fp2_enforce_truce_opinion_effect = yes } custom_tooltip = fp2_enforce_truce_other_tt custom_tooltip = fp2_enforce_truce_peacemaker_tt } } } hidden_effect = { scope:truce_1 = { send_interface_message = { type = event_truce_neutral title = enforce_truce_interaction_toast left_icon = scope:actor right_icon = scope:truce_2 add_prestige = minor_prestige_loss show_as_tooltip = { scope:target = { end_war = white_peace } add_truce_both_ways = { character = scope:truce_2 years = fp2_enforce_truce_duration_value name = TRUCE_ENFORCE_TRUCE } scope:actor = { add_truce_one_way = { character = scope:truce_1 years = fp2_enforce_truce_duration_value name = TRUCE_ENFORCE_TRUCE } } } stress_impact = { wrathful = minor_stress_impact_gain brave = minor_stress_impact_gain ambitious = minor_stress_impact_gain } } } scope:truce_2 = { send_interface_message = { type = event_truce_neutral title = enforce_truce_interaction_toast left_icon = scope:actor right_icon = scope:truce_1 add_prestige = minor_prestige_loss show_as_tooltip = { scope:target = { end_war = white_peace } add_truce_both_ways = { character = scope:truce_1 years = fp2_enforce_truce_duration_value name = TRUCE_ENFORCE_TRUCE } scope:actor = { add_truce_one_way = { character = scope:truce_2 years = fp2_enforce_truce_duration_value name = TRUCE_ENFORCE_TRUCE } } } stress_impact = { wrathful = minor_stress_impact_gain brave = minor_stress_impact_gain ambitious = minor_stress_impact_gain } } } } scope:target = { end_war = white_peace } if = { limit = { scope:actor = { any_character_struggle = { involvement = involved activate_struggle_catalyst_secondary_character_involvement_involved_trigger = { CATALYST = catalyst_truce_was_enforced CHAR = scope:target } } } } every_character_struggle = { involvement = involved activate_struggle_catalyst = { catalyst = catalyst_truce_was_enforced character = scope:actor } } } } # If we're a clan this interaction affects unity add_clan_unity_interaction_effect = { CHARACTER = scope:actor TARGET = scope:recipient VALUE = medium_unity_gain DESC = clan_unity_enforce_truce.desc REVERSE_NON_HOUSE_TARGET = no } } on_decline = { # Refusal notification scope:actor = { trigger_event = char_interaction.0236 } # If we're a clan this interaction affects unity add_clan_unity_interaction_effect = { CHARACTER = scope:recipient TARGET = scope:actor VALUE = medium_unity_loss DESC = clan_unity_enforce_truce_decline.desc REVERSE_NON_HOUSE_TARGET = no } } ai_accept = { base = -50 # Reluctant to end war without reason # Recipient only just begun modifier = { add = -25 trigger_if = { limit = { exists = scope:target } scope:target.war_days < 180 } trigger_else = { always = no } desc = ET_AI_WAR_NEW_REASON } # Recipient drags on modifier = { add = 25 trigger_if = { limit = { exists = scope:target } scope:target.war_days > 1095 } trigger_else = { always = no } desc = ET_AI_WAR_OLD_REASON } # Recipient is defender modifier = { add = 25 trigger_if = { limit = { exists = scope:target } scope:recipient = scope:target.primary_defender } trigger_else = { always = no } desc = OA_AI_DEFENSIVE_WAR_REASON } # Recipient drags on modifier = { add = 25 scope:recipient = { is_allied_to = scope:actor } desc = ET_AI_ALLY_REASON } # Recipient is vassal modifier = { add = 25 scope:recipient = { target_is_liege_or_above = scope:actor } desc = ET_AI_LIEGE_REASON } # Recipient is losing modifier = { add = 25 trigger_if = { limit = { exists = scope:target } trigger_if = { limit = { scope:recipient = scope:target.primary_defender } scope:target = { attacker_war_score >= fp2_enforce_truce_war_score_value } } trigger_else = { scope:target = { defender_war_score >= fp2_enforce_truce_war_score_value } } } trigger_else = { always = no } desc = OA_AI_LOSING_WAR_REASON } # Recipient is very outnumbered modifier = { add = 25 trigger_if = { limit = { exists = scope:target } scope:target = { fp2_struggle_contract_assistance_war_outnumbered_trigger = yes } } trigger_else = { any_character_war = { fp2_struggle_contract_assistance_war_outnumbered_trigger = yes } } desc = OA_AI_OUTNUMBERED_REASON } # Recipient is very outnumbered modifier = { add = -25 trigger_if = { limit = { exists = scope:target } scope:target = { fp2_struggle_contract_assistance_war_outnumbering_trigger = yes } } trigger_else = { any_character_war = { fp2_struggle_contract_assistance_war_outnumbering_trigger = yes } } desc = OA_AI_OUTNUMBER_ENEMY_REASON } # Actor cannot enforce truce modifier = { add = -50 trigger_if = { limit = { exists = scope:target } OR = { scope:target.war_attacker_total_strength_halved_value > scope:actor.max_military_strength scope:target.war_defender_total_strength_halved_value > scope:actor.max_military_strength } } trigger_else = { always = no } desc = ET_AI_SMALL_ARMY_REASON } # Recipient holy war modifier = { add = -25 trigger_if = { limit = { exists = scope:target } scope:recipient = { NOT = { has_trait = cynical } } scope:target = { OR = { using_cb = minor_religious_war using_cb = religious_war using_cb = major_religious_war } } } trigger_else = { always = no } desc = ET_AI_HOLY_WAR_REASON } # Actor is religious head modifier = { add = 25 scope:recipient.faith.religious_head = scope:actor desc = ET_AI_HOF_REASON } # Dynasty head modifier = { add = 50 scope:recipient.dynasty.dynast = scope:actor desc = ET_AI_DYNAST_REASON } # House head modifier = { add = 25 scope:recipient.dynasty.dynast != scope:actor scope:recipient.house.house_head = scope:actor desc = ET_AI_HOUSE_HEAD_REASON } # Opinion Factor opinion_modifier = { who = scope:recipient opinion_target = scope:actor multiplier = 1 desc = AI_OPINION_REASON } # Honor factor ai_value_modifier = { ai_boldness = -0.5 max = 0 } } ai_potential = { is_imprisoned = no } ai_target_quick_trigger = { adult = yes } ai_targets = { ai_recipients = neighboring_rulers ai_recipients = peer_vassals max = 15 } ai_frequency_by_tier = { barony = 0 county = 72 duchy = 36 kingdom = 24 empire = 24 hegemony = 24 } } ################################################## # Bargain Fealty # by Joe Parkin ################################################## bargain_fealty_interaction = { category = interaction_category_diplomacy desc = bargain_fealty_interaction_desc interface_priority = 60 interface = call_ally special_interaction = call_ally_interaction popup_on_receive = yes pause_on_receive = yes icon = icon_vassal greeting = positive notification_text = bargain_fealty_interaction_notification cooldown_against_recipient = { years = 5 } is_shown = { # Actor is Involved in Struggle scope:actor = { any_character_struggle = { involvement = involved struggle_can_access_unlocks_bargain_fealty_interaction_trigger = yes } top_liege = this is_at_war = yes any_character_war = { is_war_leader = prev primary_defender = prev } trigger_if = { limit = { scope:recipient = { is_landless_ruler = no } } tier_difference = { target = scope:recipient value <= -1 } } trigger_else = { tier_difference = { target = scope:recipient value <= -2 } } } # Recipient is not at war with Actor scope:recipient = { any_neighboring_and_across_water_top_liege_realm_owner = { this = scope:actor } primary_title = { is_mercenary_company = no } NOR = { this = scope:actor is_at_war_with = scope:actor } } } is_valid_showing_failures_only = { scope:actor = { any_character_struggle = { involvement = involved has_struggle_phase_parameter = unlocks_bargain_fealty_interaction } } } can_be_picked = { # Actor is war leader in chosen war exists = scope:target scope:target = { is_war_leader = scope:actor primary_defender = scope:actor custom_tooltip = { text = bargain_fealty_border_raid_tt NOT = { using_cb = fp2_border_raid } } custom_tooltip = { text = bargain_fealty_struggle_clash_tt NOT = { using_cb = county_struggle_cb } } } # Actor is not involved in a war involving Recipient joiner_not_already_in_another_war_with_any_target_war_participants_trigger = { WARRIOR = scope:actor JOINER = scope:recipient } } on_accept = { if = { limit = { exists = scope:target } # Add Recipient to Actor's war scope:target = { hidden_effect = { set_called_to = scope:recipient } if = { limit = { is_attacker = scope:actor } add_attacker = scope:recipient } else = { add_defender = scope:recipient } } create_title_and_vassal_change = { type = swear_fealty save_scope_as = change } scope:actor = { change_liege = { liege = scope:recipient change = scope:change } resolve_title_and_vassal_change = scope:change } # Actor effects scope:actor = { stress_impact = { arrogant = medium_stress_impact_gain craven = medium_stress_impact_gain } } # Recipient effects scope:recipient = { stress_impact = { greedy = medium_stress_impact_gain craven = medium_stress_impact_gain } } } else = { scope:actor = { send_interface_toast = { type = event_toast_effect_neutral title = war_ended_before_response left_icon = scope:recipient } } } # If we're a clan this interaction affects unity add_clan_unity_interaction_effect = { CHARACTER = scope:actor TARGET = scope:recipient VALUE = medium_unity_gain DESC = clan_unity_bargained_fealty.desc REVERSE_NON_HOUSE_TARGET = no } } on_decline = { # Refusal notification scope:actor = { trigger_event = char_interaction.0236 } # If we're a clan this interaction affects unity add_clan_unity_interaction_effect = { CHARACTER = scope:recipient TARGET = scope:actor VALUE = minor_unity_loss DESC = clan_unity_bargain_fealty_refusal.desc REVERSE_NON_HOUSE_TARGET = no } } ai_accept = { base = 25 # Recipient would be very outnumbered modifier = { add = -75 exists = scope:target scope:target = { fp2_bargain_fealty_war_outnumbered_trigger = yes } desc = BF_AI_OUTNUMBERED_REASON } # Actor is same culture as recipient modifier = { add = -10 scope:actor.culture != scope:recipient.culture desc = BF_AI_DIFFERENT_CULTURE_REASON } # Actor is same faith as recipient modifier = { add = -15 scope:actor.faith != scope:recipient.faith desc = BF_AI_DIFFERENT_FAITH_REASON } # Actor is de jure vassal of recipient modifier = { add = 25 scope:actor = { any_held_title = { target_is_de_jure_liege_or_above = scope:recipient.primary_title } } desc = BF_AI_DE_JURE_REASON } # Actor is de jure vassal of recipient modifier = { add = 25 scope:actor.dynasty = scope:recipient.dynasty desc = BF_AI_SAME_DYNASTY_REASON } # Too big to be vassal modifier = { add = -50 scope:actor.realm_size >= fp2_bargain_fealty_half_realm_size_value desc = BF_AI_TOO_LARGE_REASON } # Opinion Factor opinion_modifier = { who = scope:recipient opinion_target = scope:actor multiplier = 1 desc = AI_OPINION_REASON } ai_value_modifier = { ai_boldness = 1 max = 0 } ai_value_modifier = { ai_greed = 1 max = 0 } modifier = { add = { value = ai_greed multiply = 2 } ai_greed >= 1 desc = AI_VALUE_MODIFIER_GREED } modifier = { add = { value = ai_boldness multiply = 2 } NOT = { ai_boldness = 0 } desc = AI_VALUE_MODIFIER_BOLDNESS } } ai_will_do = { base = 5 modifier = { add = 20 any_character_war = { is_war_leader = prev primary_defender = prev NOR = { using_cb = fp2_border_raid using_cb = county_struggle_cb } casus_belli = { any_target_title = { holder = scope:actor } } } } modifier = { factor = 2 any_character_war = { is_war_leader = prev primary_defender = prev NOR = { using_cb = fp2_border_raid using_cb = county_struggle_cb } war_defender_total_strength_value < war_attacker_total_strength_halved_value } } } ai_potential = { is_imprisoned = no } ai_target_quick_trigger = { adult = yes } ai_targets = { ai_recipients = neighboring_rulers } ai_frequency_by_tier = { barony = 0 county = 36 duchy = 36 kingdom = 0 empire = 0 hegemony = 0 } } ################################################## # Invite Foreign Ruler to Feast / Hunt # by Maxence Voleau ################################################## invite_foreign_ruler_to = { interface_priority = 30 category = interaction_category_diplomacy common_interaction = yes desc = invite_foreign_ruler_to_desc icon = activity_feast greeting = positive notification_text = INVITE_FOREIGN_RULER_TO_NOTIFICATION popup_on_receive = yes ai_maybe = yes cooldown = { years = 1 } cooldown_against_recipient = { years = 5 } is_shown = { # Interaction deprecated by new activity planning system always = no scope:actor != scope:recipient # Scope:actor needs to either be involved in certain struggle types or else have a specific perk. scope:actor = { any_character_struggle = { involvement = involved is_struggle_type = iberian_struggle } } # Scope:recipient must be landed, and neither over or under scope:actor. scope:recipient = { any_character_struggle = { involvement = involved is_struggle_type = iberian_struggle } is_playable_character = yes NOR = { any_liege_or_above = { this = scope:actor } any_vassal_or_below = { this = scope:actor } } } } is_valid_showing_failures_only = { # Scope:actor must be an available adult. scope:actor = { is_available_adult = yes } # Scope:recipient must be at least available. scope:recipient = { is_available_adult = yes } # Make sure that scope:actor is going into this with a clean, no-recent/active/forbidden hostilities mindset. scope:actor = { NOT = { is_at_war_with = scope:recipient # Involved characters can't be on opposite sides in an active war. } } # Verify that you can start one of the decision # interaction deprecated by new activity planning system # custom_description = { # text = no_activity_available # scope:actor = { # OR = { # can_execute_decision = start_hunt_decision # can_execute_decision = host_feast_decision # } # } # } } on_accept = { # Notifications with most effects. if = { limit = { scope:invite_to_hunt = yes } scope:actor = { set_variable = { name = special_guest value = scope:recipient } show_as_tooltip = { remove_short_term_gold = hunt_activity_base_cost } send_interface_toast = { type = event_toast_effect_good title = invited_to_hunt.accept.actor.tt left_icon = scope:recipient progress_towards_friend_effect = { REASON = friend_invited_to_hunt CHARACTER = scope:recipient OPINION = 0 } custom_tooltip = invite_foreign_ruler_to.hunt.tooltip # interaction deprecated by new activity planning system #execute_decision = start_hunt_decision } } scope:recipient = { send_interface_toast = { title = invited_to_hunt.accept.recipient.tt left_icon = scope:actor } } } else_if = { limit = { scope:invite_to_feast = yes } scope:actor = { set_variable = { name = special_guest value = scope:recipient } show_as_tooltip = { remove_short_term_gold = feast_activity_cost } send_interface_toast = { type = event_toast_effect_good title = invited_to_feast.accept.actor.tt left_icon = scope:recipient progress_towards_friend_effect = { REASON = friend_invited_to_feast CHARACTER = scope:recipient OPINION = 0 } custom_tooltip = invite_foreign_ruler_to.feast.tooltip # interaction deprecated by new activity planning system #execute_decision = host_feast_decision } } scope:recipient = { send_interface_toast = { title = invited_to_feast.accept.recipient.tt left_icon = scope:actor } } } # If we're a clan this interaction affects unity add_clan_unity_interaction_effect = { CHARACTER = scope:actor TARGET = scope:recipient VALUE = medium_unity_gain DESC = clan_unity_feast_invite.desc REVERSE_NON_HOUSE_TARGET = no } } on_decline = { # Scope:actor gains some stress over the whole ordeal. scope:actor = { send_interface_toast = { type = event_toast_effect_bad title = invite_foreign_ruler_to.decline.actor.tt left_icon = scope:recipient add_prestige = medium_prestige_loss } } # Scope:actor loses opinion of scope:recipient. scope:recipient = { send_interface_toast = { type = event_toast_effect_neutral title = invite_foreign_ruler_to.decline.recipient.tt left_icon = scope:actor reverse_add_opinion = { target = scope:actor modifier = refusal_opinion opinion = -50 } } } # If we're a clan this interaction affects unity add_clan_unity_interaction_effect = { CHARACTER = scope:recipient TARGET = scope:actor VALUE = minor_unity_loss DESC = clan_unity_feast_invite_decline.desc REVERSE_NON_HOUSE_TARGET = no } } # Send Options ## Invite to Hunt send_option = { is_valid = { scope:actor = { # interaction deprecated by new activity planning system? #can_execute_decision = start_hunt_decision } # as an AI, don't invite human players to Hunt as we are lacking interesting content trigger_if = { limit = { scope:actor = { is_ai = yes } } scope:recipient = { is_ai = yes } } } flag = invite_to_hunt starts_enabled = { always = yes } localization = "INVITE_TO_HUNT" } ## Invite to Feast send_option = { is_valid = { scope:actor = { # interaction deprecated by new activity planning system #can_execute_decision = host_feast_decision } } flag = invite_to_feast starts_enabled = { always = yes } localization = "INVITE_TO_FEAST" } # AI ## Standard Acceptance stuff ai_accept = { # Try to make it 0 for most interactions. base = 0 # more likely if lower rank than actor modifier = { add = 20 scope:actor.primary_title.tier > primary_title.tier desc = RANK_DIFFERENCE_REASON } # less likely if that's the opposite modifier = { add = -20 scope:actor.primary_title.tier < primary_title.tier desc = RANK_DIFFERENCE_REASON } # AI take opinion into account opinion_modifier = { who = scope:recipient opinion_target = scope:actor multiplier = 1 desc = AI_OPINION_REASON } # sociability plays a lot as well ai_value_modifier = { ai_sociability = 1 } # is rival or nemesis modifier = { add = -50 has_relation_rival = scope:actor desc = WE_ARE_RIVALS } modifier = { add = -100 has_relation_nemesis = scope:actor desc = WE_ARE_NEMESES } # is friend modifier = { add = 25 has_relation_friend = scope:actor desc = WE_ARE_FRIENDS } # is best friend modifier = { add = 50 has_relation_best_friend = scope:actor desc = WE_ARE_BEST_FRIENDS } modifier = { add = 100 OR = { has_relation_lover = scope:actor has_relation_soulmate = scope:actor } desc = WE_ARE_LOVERS } # hunters love to hunt modifier = { add = 25 scope:invite_to_hunt = yes has_trait = lifestyle_hunter desc = AI_RELEVANT_TRAITS } # reveler loves feasts modifier = { add = 25 scope:invite_to_feast = yes has_trait = lifestyle_reveler desc = AI_RELEVANT_TRAITS } # Struggle agenda modifier = { desc = AI_STRUGGLE_INTENT scope:invite_to_feast = yes scope:recipient = { any_character_struggle = { involvement = involved phase_has_catalyst = catalyst_invite_diff_faith_culture_to_feast } } scope:actor = { any_character_struggle = { involvement = involved phase_has_catalyst = catalyst_invite_diff_faith_culture_to_feast } } NAND = { scope:actor.faith = scope:recipient.faith scope:actor.culture = scope:recipient.culture } add = { value = 0 if = { limit = { scope:actor = { has_character_flag = agenda_towards_deescalation } } add = 100 } else_if = { limit = { scope:actor = { has_character_flag = agenda_towards_escalation } } add = -100 } } } } ### Performance-enhancement #ai_potential = { # is_playable_character = yes # is_available_at_peace_ai_adult = yes # is_imprisoned = no # # Matches the regular minimum triggers. # any_character_struggle = { involvement = involved } # short_term_gold > standard_activity_cost #} # #ai_target_quick_trigger = { adult = yes } #ai_targets = { # ai_recipients = neighboring_rulers # ai_recipients = peer_vassals # max = 10 #} ### Frequency #ai_frequency = 60 #ai_will_do = { # base = 0 # # # sociability plays a lot as well # ai_value_modifier = { # ai_sociability = 1 # } # # # hunters love to hunt # modifier = { # add = 25 # scope:invite_to_hunt = yes # has_trait = lifestyle_hunter # } # # # small boost if no firends # modifier = { # add = 25 # num_of_relation_friend = 0 # } # # reveler loves feasts # modifier = { # add = 25 # scope:invite_to_feast = yes # has_trait = lifestyle_reveler # } # # # From Hunt decision # ai_value_modifier = { # ai_energy = 1 # ai_greed = -0.5 # ai_compassion = -0.5 # } # # modifier = { # add = 10 # scope:invite_to_hunt = yes # has_trait_rank = { # trait = education_martial # rank > 0 # } # } # modifier = { # add = 10 # scope:invite_to_hunt = yes # has_trait_rank = { # trait = education_martial # rank > 2 # } # } # # modifier = { # scope:invite_to_hunt = yes # add = 35 # stress > low_stress # } # # # Struggle agenda # modifier = { # scope:recipient = { # any_character_struggle = { # involvement = involved # } # } # scope:actor = { # any_character_struggle = { # involvement = involved # } # } # NAND = { # scope:actor.faith = scope:recipient.faith # scope:actor.culture = scope:recipient.culture # } # add = { # value = 0 # if = { # limit = { # scope:actor = { # any_character_struggle = { # phase_has_catalyst = catalyst_invite_diff_faith_culture_to_feast # # } # has_character_flag = agenda_towards_escalation # } # } # add = -100 # } # else_if = { # limit = { # scope:actor = { # any_character_struggle = { # phase_has_catalyst = catalyst_invite_diff_faith_culture_to_feast # } # } # } # add = 100 # } # } # } #} }