﻿
on_game_start_after_lobby = {
    on_actions = { domcom_after_lobby_profile_init }
}

on_birthday = {
    on_actions = {
        domcom_profile_on_birthday
        domcom_endowment_sanity_on_birthday
    }
}

on_join_court = {
    on_actions = { domcom_profile_on_life_event }
}

on_title_gain = {
    on_actions = {
        domcom_profile_on_life_event
        domcom_client_family_on_title_gain
    }
}

# A Noble Family that submitted through Final Collapse remains in the Patron's political orbit when
# its Tōshu changes. This does not rename or transfer the House title; it preserves the vassal/client
# relationship while the recorded Patron is alive and can legally host Noble Families.
domcom_client_family_on_title_gain = {
    trigger = {
        scope:title = {
            is_noble_family_title = yes
            has_variable = domcom_client_family_patron
            var:domcom_client_family_patron = { is_alive = yes }
        }
    }
    effect = {
        scope:title = { var:domcom_client_family_patron = { save_scope_as = domcom_client_family_patron } }
        if = {
            limit = {
                NOT = { this = scope:domcom_client_family_patron }
                NOT = { is_vassal_of = scope:domcom_client_family_patron }
                highest_held_title_tier < scope:domcom_client_family_patron.highest_held_title_tier
                scope:domcom_client_family_patron = {
                    OR = {
                        government_allows = noble_families
                        government_allows = administrative
                    }
                }
            }
            if = { limit = { is_landed = no } set_employer = scope:domcom_client_family_patron }
            create_title_and_vassal_change = { type = swear_fealty save_scope_as = domcom_client_family_succession_change }
            change_liege = { liege = scope:domcom_client_family_patron change = scope:domcom_client_family_succession_change }
            resolve_title_and_vassal_change = scope:domcom_client_family_succession_change
        }
    }
}

domcom_profile_on_life_event = {
    trigger = {
        age >= 18
        has_global_variable = domcom_profile_runtime_ready
    }
    effect = { domcom_initialize_profile_effect = yes }
}

domcom_after_lobby_profile_init = {
    effect = {
        # Ruler Designer is authoritative. At this point CK3 has selected the human ruler, so convert any
        # chosen Dominion Endowment trait into its permanent measurements before the broad world seed can
        # ever touch it.
        every_player = {
            # Preserve Ruler Designer anatomy choices before the 18+ expression cleanup runs.
            domcom_capture_ruler_designer_body_choices_effect = yes
            domcom_initialize_profile_effect = yes
            # 2.6.2 Human Amongst AI save/Ruler-Designer initialization. The trait itself now carries
            # the statistics; this restores the compatibility marker immediately on load.
            domcom_human_ai_sync_power_effect = yes
            # Save migration / state visibility: if Jolly Rancher Mode was already enabled in an older
            # build, restore its visible marker immediately on load rather than waiting for a monthly pulse.
            if = {
                limit = {
                    exists = dynasty
                    dynasty = { has_variable = domcom_jolly_rancher_mode var:domcom_jolly_rancher_mode = 1 }
                }
                domcom_jolly_rancher_player_dynasty_effect = yes
            }
            else = {
                remove_character_modifier = domcom_jolly_rancher_active_modifier
            }
        }

        # Seed everyone else and cover the player's visible orbit.
        domcom_seed_world_endowments_once_effect = yes
        domcom_migrate_size_preferences_once_effect = yes
        domcom_migrate_preference_classification_v110_once_effect = yes
        domcom_migrate_realistic_endowment_bands_v234_once_effect = yes
        domcom_migrate_endowment_mastery_v240_once_effect = yes
        domcom_migrate_native_mastery_and_cuck_repair_v241_once_effect = yes
        domcom_migrate_nickname_repair_v242_once_effect = yes
        domcom_migrate_world_outcomes_v243_once_effect = yes
        domcom_migrate_mastery_track_scale_v250_once_effect = yes
        domcom_migrate_endowment_expression_v256_once_effect = yes
        domcom_migrate_breast_profiles_v258_once_effect = yes
        domcom_migrate_breast_mastery_legacy_v259_once_effect = yes
        domcom_migrate_devoted_fixed_sizes_v2512_once_effect = yes
        every_player = {
            domcom_initialize_existing_ruler_endowments_once_effect = yes
            domcom_initialize_local_population_effect = yes
            # Save-safe plural-marriage integrity migration. Existing historical records are preserved
            # when strong Dominion evidence survives; unsupported co-spouse/self attributions are repaired.
            domcom_migrate_cospouse_integrity_1101_once_effect = yes
            domcom_external_save_load_sync_effect = yes
        }

        # Only now may generic on_title_gain/on_join_court hooks initialize new adults. This prevents
        # game-setup title grants from racing the designer.
        set_global_variable = domcom_profile_runtime_ready
    }
}

domcom_profile_on_birthday = {
    trigger = { domcom_needs_profile_init_trigger = yes }
    effect = { domcom_initialize_profile_effect = yes }
}

domcom_endowment_sanity_on_birthday = {
    effect = {
        domcom_refresh_endowment_expression_effect = yes
        domcom_sync_size_preference_trait_effect = yes
        domcom_assign_breast_profile_effect = yes
        domcom_initialize_breast_mastery_effect = yes
        domcom_breast_mastery_backfill_recorded_children_once_effect = yes
        domcom_assign_breast_preference_effect = yes
        domcom_jealousy_hostile_yearly_effect = yes
        if = { limit = { has_variable = domcom_obedience } domcom_apply_obedience_weight_effect = yes }
        if = {
            limit = { has_character_flag = domcom_first_generation_slave_obligation }
            domcom_activate_first_generation_slave_obligation_effect = yes
        }
    }
}

quarterly_playable_pulse = {
    on_actions = {
        domcom_alpha_budget_reset
        domcom_owned_legitimacy_quarterly
        domcom_local_population_init
        domcom_quarterly_dominion_digest
    }
}

# v2.6.67 performance: do not create delayed monthly Patron jobs for rulers that have no
# Dominion state. The human player always retains the original monthly cadence. AI rulers
# receive the same cadence only while cheap local-state checks show real work to maintain.
domcom_alpha_budget_reset = {
    trigger = { is_ai = no }
    effect = { domcom_reset_alpha_budget_effect = yes }
}

domcom_owned_legitimacy_quarterly = {
    trigger = { is_ai = no is_alive = yes }
    effect = { domcom_owned_legitimacy_quarterly_effect = yes }
}

# Consolidated non-pausing player notification for strategic prospects and ready Final Collapses.
domcom_quarterly_dominion_digest = {
    trigger = { is_ai = no is_alive = yes }
    effect = { domcom_quarterly_dominion_digest_effect = yes }
}

domcom_local_population_init = {
    trigger = {
        is_ai = no
        NOT = { has_character_flag = domcom_local_population_safety_pass_v2656 }
    }
    effect = {
        # 2.6.56 performance: life-event hooks already initialize new adults. Keep one safety/migration
        # pass per ruler/save instead of walking the player's entire visible orbit every quarter.
        add_character_flag = domcom_local_population_safety_pass_v2656
        domcom_seed_world_endowments_once_effect = yes
        domcom_initialize_existing_ruler_endowments_once_effect = yes
        domcom_refresh_endowment_expression_once_effect = yes
        domcom_migrate_cuck_stigma_once_effect = yes
        domcom_cleanup_cucked_display_modifier_once_effect = yes
        domcom_migrate_size_preferences_once_effect = yes
        domcom_migrate_preference_classification_v110_once_effect = yes
        domcom_migrate_endowment_classification_v19_once_effect = yes
        domcom_migrate_canonical_endowments_v1102_once_effect = yes
        domcom_migrate_realistic_endowment_bands_v234_once_effect = yes
        domcom_migrate_endowment_mastery_v240_once_effect = yes
        domcom_migrate_native_mastery_and_cuck_repair_v241_once_effect = yes
        domcom_migrate_nickname_repair_v242_once_effect = yes
        domcom_migrate_world_outcomes_v243_once_effect = yes
        domcom_migrate_mastery_track_scale_v250_once_effect = yes
        domcom_migrate_endowment_expression_v256_once_effect = yes
        domcom_migrate_breast_profiles_v258_once_effect = yes
        domcom_migrate_breast_mastery_legacy_v259_once_effect = yes
        domcom_initialize_local_population_effect = yes
    }
}

random_yearly_playable_pulse = {
    on_actions = {
        domcom_ai_yearly_pulse
        domcom_marital_preference_yearly_pulse
        domcom_crowned_heart_yearly_pulse
        domcom_human_ai_random_yearly
    }
}

on_birth_child = {
    on_actions = {
        domcom_on_birth_child
        domcom_cucked_nickname_check
    }
}

on_death = {
    on_actions = { domcom_on_death }
}

on_war_started = {
    on_actions = { domcom_on_war_started }
}

# The legacy name remains the entry point for jobs already stored in campaign saves.
# A pending marker coalesces overlapping AI callbacks before expensive work starts.
# v2.6.72 performance: this now runs directly from CK3's native monthly playable pulse.
# Do not serialize new per-ruler callbacks. The one-day guard inside the effect still
# coalesces unusual duplicate invocations, while the relevance trigger keeps idle AI cheap.
domcom_monthly_patron_pulse = {
    trigger = {
        is_alive = yes
        OR = { is_ai = no domcom_ai_monthly_patron_relevant_trigger = yes }
    }
    effect = { domcom_run_patron_maintenance_once_effect = yes }
}

# Legacy drain only. Saves made on 2.6.71 may already contain one of these delayed jobs.
# Execute it once if still relevant, but never schedule another delayed callback from here.
domcom_delayed_ai_patron_work = {
    effect = {
        remove_character_flag = domcom_patron_work_pending_v2671
        if = {
            limit = {
                is_alive = yes
                OR = { is_ai = no domcom_ai_monthly_patron_relevant_trigger = yes }
            }
            domcom_run_patron_maintenance_once_effect = yes
        }
    }
}

domcom_ai_yearly_pulse = {
    trigger = {
        is_ai = yes
        is_alive = yes
        age >= 18
        is_imprisoned = no
        domcom_ai_is_enabled_trigger = yes
    }
    effect = {
        random = {
            chance = domcom_ai_relationship_dominion_activity_chance_value
            domcom_ai_seek_dominion_effect = yes
        }
        random = {
            chance = domcom_ai_extra_relationship_activity_chance_value
            domcom_ai_seek_dominion_effect = yes
        }
        domcom_ai_try_general_alpha_effect = yes
        random = { chance = domcom_ai_devotion_activity_chance_value domcom_ai_deepen_devotion_effect = yes }
        # AI rulers can build the same political cult. One yearly public test is intentionally lighter
        # than player micro while still allowing large successful rulers to cross the 100-adherent threshold.
        if = { limit = { is_landed = yes NOT = { has_character_flag = domcom_lick_test_cooldown } } random = { chance = 45 domcom_call_lick_test_effect = yes } }
        domcom_ai_acknowledge_blood_effect = yes
        domcom_ai_manage_succession_effect = yes
    }
}

domcom_on_birth_child = {
    effect = {
        domcom_deactivate_endowment_traits_effect = yes
        domcom_carn_suppress_dt_traits_effect = yes

        domcom_capture_endowment_heredity_effect = yes

        # Breast Mastery: childbirth is the largest single progression event (+15 per child).
        if = {
            limit = { exists = mother }
            mother = {
                domcom_assign_breast_profile_effect = yes
                domcom_breast_mastery_childbirth_effect = yes
                save_scope_as = domcom_breast_legacy_mother
            }
            domcom_apply_maternal_breast_legacy_effect = yes
        }

        # Children of a numbered Slave inherit one generation of submission. This checks only an actual
        # Slave parent, so grandchildren do not inherit from a merely inherited-submission parent.
        if = {
            limit = {
                exists = father
                father = { has_character_flag = domcom_pet has_variable = domcom_pet_patron var:domcom_pet_patron = { is_alive = yes } }
            }
            father = { var:domcom_pet_patron = { save_scope_as = domcom_inherited_submission_patron } }
            domcom_apply_first_generation_slave_obligation_effect = yes
        }
        else_if = {
            limit = {
                exists = mother
                mother = { has_character_flag = domcom_pet has_variable = domcom_pet_patron var:domcom_pet_patron = { is_alive = yes } }
            }
            mother = { var:domcom_pet_patron = { save_scope_as = domcom_inherited_submission_patron } }
            domcom_apply_first_generation_slave_obligation_effect = yes
        }

        # Children conceived through a Power Trip remain sortable/traceable by Dominion/DDM later.
        if = {
            limit = {
                exists = mother
                exists = father
                mother = {
                    has_character_flag = domcom_power_trip_apex_mother
                    has_variable = domcom_human_ai_apex_patron
                    var:domcom_human_ai_apex_patron = father
                }
                father = { has_trait = domcom_human_among_ai_trait }
            }
            add_character_flag = domcom_power_trip_offspring
        }

        # First apply the Dominion interpretation to detectable marital conceptions.
        domcom_process_dominion_summons_birth_effect = yes

        # Hidden real-father data remains actionable later through Acknowledge My Blood.
        if = {
            limit = { exists = real_father NOT = { father ?= root.real_father } }
            add_character_flag = domcom_hidden_blood_child
        }

        # Fresh child evidence increases the relevant cuck's experience for any patron, player or AI.
        # Male and female patrons are both supported.
        if = {
            limit = { exists = real_father exists = mother }
            real_father = { save_scope_as = domcom_birth_patron }
            mother = {
                every_spouse = {
                    limit = {
                        has_character_flag = domcom_cucked
                        OR = {
                            AND = { has_variable = domcom_cuck_patron var:domcom_cuck_patron = scope:domcom_birth_patron }
                            AND = { has_variable = domcom_patron var:domcom_patron = scope:domcom_birth_patron }
                        }
                    }
                    change_variable = { name = domcom_cuck_xp add = 125 }
                    add_opinion = { target = root modifier = domcom_cucked_child_opinion }
                    domcom_refresh_cuck_stage_effect = yes
                    domcom_check_final_collapse_effect = yes
                }
            }
        }
        else_if = {
            limit = { exists = father exists = mother }
            father = { save_scope_as = domcom_birth_patron }
            mother = {
                every_spouse = {
                    limit = {
                        has_character_flag = domcom_cucked
                        OR = {
                            AND = { has_variable = domcom_cuck_patron var:domcom_cuck_patron = scope:domcom_birth_patron }
                            AND = { has_variable = domcom_patron var:domcom_patron = scope:domcom_birth_patron }
                        }
                    }
                    change_variable = { name = domcom_cuck_xp add = 125 }
                    add_opinion = { target = root modifier = domcom_cucked_child_opinion }
                    domcom_refresh_cuck_stage_effect = yes
                    domcom_check_final_collapse_effect = yes
                }
            }
        }

        if = {
            limit = { exists = mother exists = father }
            mother = { save_scope_as = domcom_birth_patron }
            father = {
                every_spouse = {
                    limit = {
                        has_character_flag = domcom_cucked
                        OR = {
                            AND = { has_variable = domcom_cuck_patron var:domcom_cuck_patron = scope:domcom_birth_patron }
                            AND = { has_variable = domcom_patron var:domcom_patron = scope:domcom_birth_patron }
                        }
                    }
                    change_variable = { name = domcom_cuck_xp add = 125 }
                    add_opinion = { target = root modifier = domcom_cucked_child_opinion }
                    domcom_refresh_cuck_stage_effect = yes
                    domcom_check_final_collapse_effect = yes
                }
            }
        }

        # Apply/repair Spawn of a Cuck only after Dominion Summons and hidden parentage have been
        # processed, so an assumed cuck father is not mistaken for the biological father.
        domcom_refresh_spawn_of_cuck_effect = yes

        # New dynasty members inherit strong leverage over living subjects tied to their dynasty's
        # Dominion registry.
        if = {
            limit = { exists = dynasty dynasty = { has_variable_list = domcom_owned_subjects } }
            dynasty = {
                every_in_list = {
                    variable = domcom_owned_subjects
                    limit = { is_alive = yes has_character_flag = domcom_owned_cuck }
                    save_temporary_scope_as = domcom_owned_subject
                    root = {
                        if = {
                            limit = { can_add_hook = { target = scope:domcom_owned_subject type = loyalty_hook } }
                            add_hook_no_toast = { target = scope:domcom_owned_subject type = loyalty_hook }
                        }
                    }
                }
            }
        }
    }
}

domcom_on_death = {
    effect = {
        domcom_trophy_on_death_cleanup_effect = yes
        domcom_inner_household_on_death_cleanup_effect = yes
        if = {
            limit = { is_target_in_global_variable_list = { name = domcom_all_cucked target = this } }
            save_temporary_scope_as = domcom_dead_cuck
            remove_list_global_variable = { name = domcom_all_cucked target = scope:domcom_dead_cuck }
        }
        # Remove dead cucks from their patron-local fast Ledger registry.
        if = {
            limit = { has_character_flag = domcom_cucked has_variable = domcom_cuck_patron }
            save_scope_as = domcom_dead_cuck_subject
            var:domcom_cuck_patron = {
                if = {
                    limit = { has_variable_list = domcom_cucked_registry }
                    remove_list_variable = { name = domcom_cucked_registry target = scope:domcom_dead_cuck_subject }
                }
            }
        }
        if = {
            limit = { has_character_flag = domcom_owned_cuck has_variable = domcom_patron }
            save_scope_as = domcom_dead_owned_subject
            var:domcom_patron = {
                if = {
                    limit = { has_variable_list = domcom_owned_registry }
                    remove_list_variable = { name = domcom_owned_registry target = scope:domcom_dead_owned_subject }
                }
            }
        }
        if = {
            limit = { has_character_flag = domcom_owned_cuck has_variable = domcom_patron_dynasty }
            save_scope_as = domcom_dead_owned_subject
            var:domcom_patron_dynasty = {
                if = {
                    limit = { has_variable_list = domcom_owned_subjects }
                    remove_list_variable = { name = domcom_owned_subjects target = scope:domcom_dead_owned_subject }
                }
            }
        }

        # Dominion inheritance is no longer player-only. A player uses the player heir when available; an
        # AI patron uses the primary heir.
        if = {
            limit = { exists = dynasty dynasty = { has_variable_list = domcom_owned_subjects } }
            save_scope_as = domcom_dead_patron
            if = {
                limit = { is_ai = no exists = player_heir }
                player_heir = { save_scope_as = domcom_new_patron }
            }
            else_if = {
                limit = { exists = primary_heir }
                primary_heir = { save_scope_as = domcom_new_patron }
            }
            if = {
                limit = { exists = scope:domcom_new_patron }
                dynasty = {
                    every_in_list = {
                        variable = domcom_owned_subjects
                        limit = {
                            is_alive = yes
                            NOT = { this = scope:domcom_new_patron }
                            has_variable = domcom_patron
                            var:domcom_patron = scope:domcom_dead_patron
                        }
                        save_temporary_scope_as = domcom_inherited_subject
                        set_variable = { name = domcom_patron value = scope:domcom_new_patron }
                        set_variable = { name = domcom_cuck_patron value = scope:domcom_new_patron }
                        save_temporary_scope_as = domcom_inherited_registry_subject
                        scope:domcom_new_patron = {
                            if = {
                                limit = {
                                    NOT = {
                                        any_in_list = {
                                            variable = domcom_owned_registry
                                            this = scope:domcom_inherited_registry_subject
                                        }
                                    }
                                }
                                add_to_variable_list = { name = domcom_owned_registry target = scope:domcom_inherited_registry_subject }
                            }
                            save_scope_as = domcom_communion_patron
                        }
                        domcom_apply_communion_tolerance_subject_effect = yes
                        add_opinion = { target = scope:domcom_new_patron modifier = domcom_owned_by_patron_opinion }
                        scope:domcom_new_patron = {
                            if = {
                                limit = { can_add_hook = { target = scope:domcom_inherited_subject type = loyalty_hook } }
                                add_hook_no_toast = { target = scope:domcom_inherited_subject type = loyalty_hook }
                            }
                        }
                    }
                }
            }
        }
    }
}

domcom_on_war_started = {
    effect = {
        # A Cucked subject attacking their Patron can break before the first battle. Broken (500+) starts
        # the roll, Abject (750+) is highly likely, and 1000 is certain. Owned subjects preserve the old
        # player-facing surrender event as a fallback if the immediate roll fails.
        if = {
            limit = {
                scope:attacker = {
                    is_alive = yes
                    OR = {
                        AND = {
                            has_variable = domcom_cuck_xp
                            var:domcom_cuck_xp >= 500
                            OR = {
                                AND = { has_variable = domcom_patron var:domcom_patron = scope:defender }
                                AND = { has_variable = domcom_cuck_patron var:domcom_cuck_patron = scope:defender }
                            }
                        }
                        AND = { has_character_flag = domcom_pet has_variable = domcom_pet_patron var:domcom_pet_patron = scope:defender }
                        AND = { has_variable = domcom_inherited_slave_patron var:domcom_inherited_slave_patron = scope:defender has_character_modifier = domcom_inherited_submission_modifier }
                    }
                }
            }
            scope:attacker = { save_scope_as = domcom_war_subject }
            scope:defender = { save_scope_as = domcom_war_patron }
            scope:war = { save_scope_as = domcom_submission_war }
            scope:attacker = {
                if = {
                    limit = { has_character_flag = domcom_owned_cuck }
                    change_variable = { name = domcom_cuck_xp add = 100 }
                    if = { limit = { var:domcom_cuck_xp > 1000 } set_variable = { name = domcom_cuck_xp value = 1000 } }
                    domcom_refresh_cuck_stage_effect = yes
                }
                add_character_flag = domcom_direct_war_submission_failed
                random = {
                    chance = domcom_direct_war_submission_chance_value
                    remove_character_flag = domcom_direct_war_submission_failed
                    if = { limit = { has_character_flag = domcom_owned_cuck } domcom_apply_defensive_capitulation_effect = yes }
                    if = {
                        limit = { scope:domcom_war_patron = { is_ai = no } }
                        scope:domcom_war_patron = {
                            send_interface_toast = {
                                type = event_toast_effect_good
                                title = DOMCOM_DIRECT_WAR_SUBMISSION_TOAST
                                left_icon = scope:domcom_war_patron
                                right_icon = scope:domcom_war_subject
                            }
                        }
                    }
                    scope:domcom_submission_war = { end_war = defender }
                }
                if = {
                    limit = { has_character_flag = domcom_direct_war_submission_failed }
                    remove_character_flag = domcom_direct_war_submission_failed
                    if = {
                        limit = { has_character_flag = domcom_owned_cuck }
                        if = {
                            limit = { scope:domcom_war_patron = { is_ai = no } }
                            scope:domcom_war_patron = { trigger_event = { id = domcom.400 days = 1 } }
                        }
                        else = {
                            domcom_apply_defensive_capitulation_effect = yes
                            scope:domcom_submission_war = { end_war = defender }
                        }
                    }
                }
            }
        }
        # Patron attacking a Cucked subject uses the same pressure roll. An Owned target that resists the
        # immediate roll still receives the old surrender event one day later for a human Patron.
        else_if = {
            limit = {
                scope:defender = {
                    is_alive = yes
                    OR = {
                        AND = {
                            has_variable = domcom_cuck_xp
                            var:domcom_cuck_xp >= 500
                            OR = {
                                AND = { has_variable = domcom_patron var:domcom_patron = scope:attacker }
                                AND = { has_variable = domcom_cuck_patron var:domcom_cuck_patron = scope:attacker }
                            }
                        }
                        AND = { has_character_flag = domcom_pet has_variable = domcom_pet_patron var:domcom_pet_patron = scope:attacker }
                        AND = { has_variable = domcom_inherited_slave_patron var:domcom_inherited_slave_patron = scope:attacker has_character_modifier = domcom_inherited_submission_modifier }
                    }
                }
            }
            scope:defender = { save_scope_as = domcom_war_subject }
            scope:attacker = { save_scope_as = domcom_war_patron }
            scope:war = { save_scope_as = domcom_submission_war }
            scope:defender = {
                if = {
                    limit = { has_character_flag = domcom_owned_cuck }
                    change_variable = { name = domcom_cuck_xp add = 100 }
                    if = { limit = { var:domcom_cuck_xp > 1000 } set_variable = { name = domcom_cuck_xp value = 1000 } }
                    domcom_refresh_cuck_stage_effect = yes
                }
                add_character_flag = domcom_direct_war_submission_failed
                random = {
                    chance = domcom_direct_war_submission_chance_value
                    remove_character_flag = domcom_direct_war_submission_failed
                    if = {
                        limit = { scope:domcom_war_patron = { is_ai = no } }
                        scope:domcom_war_patron = {
                            send_interface_toast = {
                                type = event_toast_effect_good
                                title = DOMCOM_DIRECT_WAR_SUBMISSION_TOAST
                                left_icon = scope:domcom_war_patron
                                right_icon = scope:domcom_war_subject
                            }
                        }
                    }
                    scope:domcom_submission_war = { end_war = attacker }
                }
                if = {
                    limit = { has_character_flag = domcom_direct_war_submission_failed }
                    remove_character_flag = domcom_direct_war_submission_failed
                    if = {
                        limit = { has_character_flag = domcom_owned_cuck }
                        if = {
                            limit = { scope:domcom_war_patron = { is_ai = no } }
                            scope:domcom_war_patron = { trigger_event = { id = domcom.400 days = 1 } }
                        }
                        else = { scope:domcom_submission_war = { end_war = attacker } }
                    }
                }
            }
        }
    }
}

carn_character_initialization_pulse = {
    on_actions = { domcom_carn_character_profile_bridge }
}

carn_on_sex_v2 = {
    on_actions = { domcom_carn_on_sex_bridge }
}

domcom_carn_character_profile_bridge = {
    trigger = { is_alive = yes age >= 18 }
    effect = {
        # Keep the Carnalitas world-wide initialization bridge deliberately cheap: Endowment only. Full
        # attraction preferences remain lazy until relevant.
        domcom_assign_endowment_effect = yes
        trigger_event = { on_action = domcom_profile_initialized }
    }
}

domcom_carn_on_sex_bridge = {
    trigger = {
        scope:carn_sex_partner = { is_alive = yes age >= 18 }
        OR = {
            AND = {
                exists = scope:carn_sex_player
                scope:carn_sex_player = { is_alive = yes age >= 18 }
            }
            AND = {
                NOT = { exists = scope:carn_sex_player }
                is_alive = yes
                age >= 18
            }
        }
    }
    effect = { domcom_record_carnalitas_sex_effect = yes }
}

# Public extension points used by the optional compatibility submod.
domcom_profile_initialized = { effect = { } }
domcom_pet_created = { effect = { } }

# Individual attraction can affect marriages even when the player never opens Dominion. This remains one
# bounded spouse check per playable ruler per year.
domcom_marital_preference_yearly_pulse = {
    trigger = { is_alive = yes age >= 18 is_married = yes }
    effect = { domcom_marital_preference_yearly_effect = yes }
}


domcom_crowned_heart_yearly_pulse = {
    trigger = {
        is_ai = yes
        is_alive = yes
        age >= 18
        is_female = yes
        is_landed = yes
        is_married = yes
        is_imprisoned = no
        highest_held_title_tier >= tier_kingdom
        domcom_crowned_heart_actor_trigger = yes
        NOT = { has_character_flag = domcom_crowned_offer_pending }
        NOT = { has_character_flag = domcom_crowned_heart_rejected }
    }
    effect = { domcom_ai_try_crowned_heart_effect = yes }
}


monthly_playable_pulse = {
    on_actions = {
        domcom_monthly_patron_pulse
        domcom_monthly_dominion_upkeep
        domcom_monthly_protected_bond_repair
        domcom_monthly_household_intrigue_hook
        domcom_monthly_jolly_rancher_hook
        domcom_human_ai_monthly_sync
        domcom_monthly_journal_noise_cleanup
    }
}


# 2.6.57 — this iterates only the human character's finite memory book, not world characters.
# Monthly cleanup keeps vanilla relation churn out of the Journal without reintroducing a world scan.
domcom_monthly_journal_noise_cleanup = {
    trigger = { is_ai = no is_alive = yes }
    effect = { domcom_cleanup_routine_lover_memories_effect = yes }
}

domcom_monthly_household_intrigue_hook = {
    trigger = { is_ai = no is_alive = yes age >= 18 }
    effect = { domcom_household_intrigue_monthly_hook_effect = yes }
}

domcom_monthly_dominion_upkeep = {
    trigger = { is_ai = no }
    effect = { domcom_monthly_dominion_upkeep_effect = yes }
}

# v2.4.3: intentionally runs for AI playable rulers too. This is what lets a player mark a
# relationship as persistent, switch to Observer, and have the former player character keep it.
domcom_monthly_protected_bond_repair = {
    trigger = {
        is_alive = yes
        has_variable_list = domcom_intimate_registry
    }
    effect = { domcom_repair_protected_intimates_effect = yes }
}

# Immediate birth-time reputation refresh is included in the consolidated on_birth_child hook above.

domcom_cucked_nickname_check = {
    effect = {
        if = {
            limit = { exists = father }
            father = { domcom_award_cucked_nickname_effect = yes }
        }
    }
}


domcom_monthly_digest = {
    trigger = { is_ai = no }
    effect = { domcom_monthly_digest_effect = yes }
}


domcom_monthly_jolly_rancher_hook = {
    trigger = {
        is_ai = no
        is_alive = yes
        exists = dynasty
        dynasty = { has_variable = domcom_jolly_rancher_mode var:domcom_jolly_rancher_mode = 1 }
    }
    effect = { domcom_jolly_rancher_player_dynasty_effect = yes }
}


# 2.6.0 Human Amongst AI maintenance/AI reaction.
domcom_human_ai_random_yearly = {
    trigger = { is_ai = no is_alive = yes has_trait = domcom_human_among_ai_trait }
    effect = { domcom_human_ai_yearly_threat_effect = yes }
}

domcom_human_ai_monthly_sync = {
    trigger = { is_ai = no is_alive = yes }
    effect = { domcom_human_ai_sync_power_effect = yes }
}
